mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-02 03:38:06 +02:00
freedreno/a6xx: Emit constant parameters for tessellation stages
Assemble the information the stages need and emit the constants. Signed-off-by: Kristian H. Kristensen <hoegsberg@google.com> Acked-by: Eric Anholt <eric@anholt.net> Reviewed-by: Rob Clark <robdclark@gmail.com>
This commit is contained in:
parent
5dd51d2da7
commit
03a30e7c3d
1 changed files with 86 additions and 12 deletions
|
|
@ -790,25 +790,99 @@ fd6_emit_streamout(struct fd_ringbuffer *ring, struct fd6_emit *emit, struct ir3
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
emit_tess_bos(struct fd_ringbuffer *ring, struct fd6_emit *emit, struct ir3_shader_variant *s)
|
||||
{
|
||||
struct fd_context *ctx = emit->ctx;
|
||||
const unsigned regid = s->shader->const_state.offsets.primitive_param * 4 + 4;
|
||||
uint32_t dwords = 16;
|
||||
|
||||
OUT_PKT7(ring, fd6_stage2opcode(s->type), 3);
|
||||
OUT_RING(ring, CP_LOAD_STATE6_0_DST_OFF(regid / 4) |
|
||||
CP_LOAD_STATE6_0_STATE_TYPE(ST6_CONSTANTS)|
|
||||
CP_LOAD_STATE6_0_STATE_SRC(SS6_INDIRECT) |
|
||||
CP_LOAD_STATE6_0_STATE_BLOCK(fd6_stage2shadersb(s->type)) |
|
||||
CP_LOAD_STATE6_0_NUM_UNIT(dwords / 4));
|
||||
OUT_RB(ring, ctx->batch->tess_addrs_constobj);
|
||||
}
|
||||
|
||||
static void
|
||||
emit_stage_tess_consts(struct fd_ringbuffer *ring, struct ir3_shader_variant *v,
|
||||
uint32_t *params, int num_params)
|
||||
{
|
||||
const unsigned regid = v->shader->const_state.offsets.primitive_param;
|
||||
int size = MIN2(1 + regid, v->constlen) - regid;
|
||||
if (size > 0)
|
||||
fd6_emit_const(ring, v->type, regid * 4, 0, num_params, params, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
fd6_emit_tess_const(struct fd6_emit *emit)
|
||||
{
|
||||
struct fd_context *ctx = emit->ctx;
|
||||
const unsigned vs_regid = emit->vs->shader->const_state.offsets.primitive_param;
|
||||
const unsigned gs_regid = emit->gs->shader->const_state.offsets.primitive_param;
|
||||
uint32_t num_vertices = emit->gs->shader->nir->info.gs.vertices_in;
|
||||
|
||||
uint32_t params[4] = {
|
||||
emit->vs->shader->output_size * num_vertices * 4, /* vs primitive stride */
|
||||
emit->vs->shader->output_size * 4, /* vs vertex stride */
|
||||
0, 0,
|
||||
};
|
||||
|
||||
struct fd_ringbuffer *constobj = fd_submit_new_ringbuffer(
|
||||
ctx->batch->submit, 0x1000, FD_RINGBUFFER_STREAMING);
|
||||
|
||||
fd6_emit_const(constobj, emit->vs->type, vs_regid * 4, 0, ARRAY_SIZE(params), params, NULL);
|
||||
fd6_emit_const(constobj, emit->gs->type, gs_regid * 4, 0, ARRAY_SIZE(params), params, NULL);
|
||||
/* VS sizes are in bytes since that's what STLW/LDLW use, while the HS
|
||||
* size is dwords, since that's what LDG/STG use.
|
||||
*/
|
||||
unsigned num_vertices =
|
||||
emit->hs ?
|
||||
emit->info->vertices_per_patch :
|
||||
emit->gs->shader->nir->info.gs.vertices_in;
|
||||
|
||||
uint32_t vs_params[4] = {
|
||||
emit->vs->shader->output_size * num_vertices * 4, /* vs primitive stride */
|
||||
emit->vs->shader->output_size * 4, /* vs vertex stride */
|
||||
0,
|
||||
0
|
||||
};
|
||||
|
||||
emit_stage_tess_consts(constobj, emit->vs, vs_params, ARRAY_SIZE(vs_params));
|
||||
|
||||
if (emit->hs) {
|
||||
uint32_t hs_params[4] = {
|
||||
emit->vs->shader->output_size * num_vertices * 4, /* vs primitive stride */
|
||||
emit->vs->shader->output_size * 4, /* vs vertex stride */
|
||||
emit->hs->shader->output_size,
|
||||
emit->info->vertices_per_patch
|
||||
};
|
||||
|
||||
emit_stage_tess_consts(constobj, emit->hs, hs_params, ARRAY_SIZE(hs_params));
|
||||
emit_tess_bos(constobj, emit, emit->hs);
|
||||
|
||||
if (emit->gs)
|
||||
num_vertices = emit->gs->shader->nir->info.gs.vertices_in;
|
||||
|
||||
uint32_t ds_params[4] = {
|
||||
emit->ds->shader->output_size * num_vertices * 4, /* ds primitive stride */
|
||||
emit->ds->shader->output_size * 4, /* ds vertex stride */
|
||||
emit->hs->shader->output_size, /* hs vertex stride (dwords) */
|
||||
emit->hs->shader->nir->info.tess.tcs_vertices_out
|
||||
};
|
||||
|
||||
emit_stage_tess_consts(constobj, emit->ds, ds_params, ARRAY_SIZE(ds_params));
|
||||
emit_tess_bos(constobj, emit, emit->ds);
|
||||
}
|
||||
|
||||
if (emit->gs) {
|
||||
struct ir3_shader_variant *prev;
|
||||
if (emit->ds)
|
||||
prev = emit->ds;
|
||||
else
|
||||
prev = emit->vs;
|
||||
|
||||
uint32_t gs_params[4] = {
|
||||
prev->shader->output_size * num_vertices * 4, /* ds primitive stride */
|
||||
prev->shader->output_size * 4, /* ds vertex stride */
|
||||
0,
|
||||
0,
|
||||
};
|
||||
|
||||
num_vertices = emit->gs->shader->nir->info.gs.vertices_in;
|
||||
emit_stage_tess_consts(constobj, emit->gs, gs_params, ARRAY_SIZE(gs_params));
|
||||
}
|
||||
|
||||
fd6_emit_take_group(emit, constobj, FD6_GROUP_PRIMITIVE_PARAMS, 0x7);
|
||||
}
|
||||
|
|
@ -990,7 +1064,7 @@ fd6_emit_state(struct fd_ringbuffer *ring, struct fd6_emit *emit)
|
|||
fd6_emit_consts(emit, gs, PIPE_SHADER_GEOMETRY, FD6_GROUP_GS_CONST, 0x7);
|
||||
fd6_emit_consts(emit, fs, PIPE_SHADER_FRAGMENT, FD6_GROUP_FS_CONST, 0x6);
|
||||
|
||||
if (emit->key.key.has_gs)
|
||||
if (emit->key.key.has_gs || emit->key.key.tessellation)
|
||||
fd6_emit_tess_const(emit);
|
||||
|
||||
/* if driver-params are needed, emit each time: */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue