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:
Kristian H. Kristensen 2019-10-22 19:58:59 -07:00
parent 5dd51d2da7
commit 03a30e7c3d

View file

@ -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: */