From 3cedeba7c9cc41b798eda14bd28f32f35490d1ab Mon Sep 17 00:00:00 2001 From: "Kristian H. Kristensen" Date: Tue, 22 Oct 2019 19:37:53 -0700 Subject: [PATCH] freedreno/ir3: Setup inputs and outputs for tessellation stages Similar to GS, some inputs are reused when the chsh from VS to TCS or TES to GS, so we need to make sure we setup the right inputs and make the shared system values outputs so they don't get clobbered. Signed-off-by: Kristian H. Kristensen Acked-by: Eric Anholt Reviewed-by: Rob Clark --- src/freedreno/ir3/ir3_compiler_nir.c | 59 ++++++++++++++++++++++++---- 1 file changed, 52 insertions(+), 7 deletions(-) diff --git a/src/freedreno/ir3/ir3_compiler_nir.c b/src/freedreno/ir3/ir3_compiler_nir.c index 2341c359324..f58f1a04b55 100644 --- a/src/freedreno/ir3/ir3_compiler_nir.c +++ b/src/freedreno/ir3/ir3_compiler_nir.c @@ -2883,6 +2883,7 @@ setup_output(struct ir3_context *ctx, nir_variable *out) gl_frag_result_name(slot)); } } else if (ctx->so->type == MESA_SHADER_VERTEX || + ctx->so->type == MESA_SHADER_TESS_EVAL || ctx->so->type == MESA_SHADER_GEOMETRY) { switch (slot) { case VARYING_SLOT_POS: @@ -2914,6 +2915,9 @@ setup_output(struct ir3_context *ctx, nir_variable *out) _mesa_shader_stage_to_string(ctx->so->type), gl_varying_slot_name(slot)); } + } else if (ctx->so->type == MESA_SHADER_TESS_CTRL) { + /* output lowered to buffer writes. */ + return; } else { ir3_context_error(ctx, "unknown shader type: %d\n", ctx->so->type); } @@ -2958,6 +2962,8 @@ max_drvloc(struct exec_list *vars) static const unsigned max_sysvals[] = { [MESA_SHADER_VERTEX] = 16, + [MESA_SHADER_TESS_CTRL] = 16, + [MESA_SHADER_TESS_EVAL] = 16, [MESA_SHADER_GEOMETRY] = 16, [MESA_SHADER_FRAGMENT] = 24, // TODO [MESA_SHADER_COMPUTE] = 16, // TODO how many do we actually need? @@ -2976,7 +2982,8 @@ emit_instructions(struct ir3_context *ctx) /* we need to leave room for sysvals: */ ninputs += max_sysvals[ctx->so->type]; - if (ctx->so->type == MESA_SHADER_VERTEX) + if (ctx->so->type == MESA_SHADER_VERTEX || + ctx->so->type == MESA_SHADER_TESS_EVAL) noutputs += 8; /* gs or tess header + primitive_id */ ctx->ir = ir3_create(ctx->compiler, ctx->so->type, ninputs, noutputs); @@ -2988,12 +2995,38 @@ emit_instructions(struct ir3_context *ctx) ninputs -= max_sysvals[ctx->so->type]; - if (ctx->so->key.has_gs) { - if (ctx->so->type == MESA_SHADER_VERTEX || - ctx->so->type == MESA_SHADER_GEOMETRY) { + /* Tesselation shaders always need primitive ID for indexing the + * BO. Geometry shaders don't always need it but when they do it has be + * delivered and unclobbered in the VS. To make things easy, we always + * make room for it in VS/DS. + */ + bool has_tess = ctx->so->key.tessellation != IR3_TESS_NONE; + bool has_gs = ctx->so->key.has_gs; + switch (ctx->so->type) { + case MESA_SHADER_VERTEX: + if (has_tess) { + ctx->tcs_header = create_input(ctx, 0); + ctx->primitive_id = create_input(ctx, 0); + } else if (has_gs) { ctx->gs_header = create_input(ctx, 0); ctx->primitive_id = create_input(ctx, 0); } + break; + case MESA_SHADER_TESS_CTRL: + ctx->tcs_header = create_input(ctx, 0); + ctx->primitive_id = create_input(ctx, 0); + break; + case MESA_SHADER_TESS_EVAL: + if (has_gs) + ctx->gs_header = create_input(ctx, 0); + ctx->primitive_id = create_input(ctx, 0); + break; + case MESA_SHADER_GEOMETRY: + ctx->gs_header = create_input(ctx, 0); + ctx->primitive_id = create_input(ctx, 0); + break; + default: + break; } /* for fragment shader, the vcoord input register is used as the @@ -3032,15 +3065,19 @@ emit_instructions(struct ir3_context *ctx) add_sysval_input(ctx, SYSTEM_VALUE_PRIMITIVE_ID, ctx->primitive_id); if (ctx->gs_header) add_sysval_input(ctx, SYSTEM_VALUE_GS_HEADER_IR3, ctx->gs_header); + if (ctx->tcs_header) + add_sysval_input(ctx, SYSTEM_VALUE_TCS_HEADER_IR3, ctx->tcs_header); /* Setup outputs: */ nir_foreach_variable(var, &ctx->s->outputs) { setup_output(ctx, var); } - /* Set up the gs header as an output for the vertex shader so it won't - * clobber it for the tess ctrl shader. */ - if (ctx->so->type == MESA_SHADER_VERTEX) { + /* Set up the shared system values as outputs for the vertex and tess eval + * shaders so they don't clobber them for the next shader in the pipeline. + */ + if (ctx->so->type == MESA_SHADER_VERTEX || + (has_gs && ctx->so->type == MESA_SHADER_TESS_EVAL)) { struct ir3_shader_variant *so = ctx->so; if (ctx->primitive_id) { unsigned n = so->outputs_count++; @@ -3060,6 +3097,14 @@ emit_instructions(struct ir3_context *ctx) compile_assert(ctx, n * 4 < ctx->ir->noutputs); } + if (ctx->tcs_header) { + unsigned n = so->outputs_count++; + so->outputs[n].slot = VARYING_SLOT_TCS_HEADER_IR3; + so->outputs[n].regid = regid(n, 0); + ctx->ir->outputs[n * 4] = ctx->tcs_header; + + compile_assert(ctx, n * 4 < ctx->ir->noutputs); + } } /* Find # of samplers: */ -- 2.30.2