From: Jonathan Marek Date: Mon, 6 Jul 2020 02:53:39 +0000 (-0400) Subject: freedreno/ir3: add support for a650 tess shared storage X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f472c9844309f20b19f179cffc84c00a561c8f70;p=mesa.git freedreno/ir3: add support for a650 tess shared storage A650 uses LDL/STL, and the "local_primitive_id" in tess ctrl shader comes from bits 16-21 in the header instead of 0-5. Signed-off-by: Jonathan Marek Part-of: --- diff --git a/src/freedreno/ir3/ir3_compiler.c b/src/freedreno/ir3/ir3_compiler.c index 9fc00d8f91f..342282ca7db 100644 --- a/src/freedreno/ir3/ir3_compiler.c +++ b/src/freedreno/ir3/ir3_compiler.c @@ -93,6 +93,9 @@ ir3_compiler_create(struct fd_device *dev, uint32_t gpu_id) * TODO: is this true on earlier gen's? */ compiler->max_const_compute = 256; + + if (compiler->gpu_id == 650) + compiler->tess_use_shared = true; } else { compiler->max_const_pipeline = 512; compiler->max_const_geom = 512; diff --git a/src/freedreno/ir3/ir3_compiler.h b/src/freedreno/ir3/ir3_compiler.h index 54a1afd5a25..663e0c531e0 100644 --- a/src/freedreno/ir3/ir3_compiler.h +++ b/src/freedreno/ir3/ir3_compiler.h @@ -74,6 +74,9 @@ struct ir3_compiler { */ bool samgq_workaround; + /* on a650, vertex shader <-> tess control io uses LDL/STL */ + bool tess_use_shared; + /* The maximum number of constants, in vec4's, across the entire graphics * pipeline. */ diff --git a/src/freedreno/ir3/ir3_compiler_nir.c b/src/freedreno/ir3/ir3_compiler_nir.c index ad0124a8adb..342f5e3ce17 100644 --- a/src/freedreno/ir3/ir3_compiler_nir.c +++ b/src/freedreno/ir3/ir3_compiler_nir.c @@ -928,6 +928,10 @@ emit_intrinsic_load_shared_ir3(struct ir3_context *ctx, nir_intrinsic_instr *int create_immed(b, intr->num_components), 0, create_immed(b, base), 0); + /* for a650, use LDL for tess ctrl inputs: */ + if (ctx->so->type == MESA_SHADER_TESS_CTRL && ctx->compiler->tess_use_shared) + load->opc = OPC_LDL; + load->cat6.type = utype_dst(intr->dest); load->regs[0]->wrmask = MASK(intr->num_components); @@ -952,6 +956,11 @@ emit_intrinsic_store_shared_ir3(struct ir3_context *ctx, nir_intrinsic_instr *in ir3_create_collect(ctx, value, intr->num_components), 0, create_immed(b, intr->num_components), 0); + /* for a650, use STL for vertex outputs used by tess ctrl shader: */ + if (ctx->so->type == MESA_SHADER_VERTEX && ctx->so->key.tessellation && + ctx->compiler->tess_use_shared) + store->opc = OPC_STL; + store->cat6.dst_offset = nir_intrinsic_base(intr); store->cat6.type = utype_src(intr->src[0]); store->barrier_class = IR3_BARRIER_SHARED_W; diff --git a/src/freedreno/ir3/ir3_nir.c b/src/freedreno/ir3/ir3_nir.c index f37d2994799..903f136860b 100644 --- a/src/freedreno/ir3/ir3_nir.c +++ b/src/freedreno/ir3/ir3_nir.c @@ -379,7 +379,7 @@ ir3_nir_lower_variant(struct ir3_shader_variant *so, nir_shader *s) break; case MESA_SHADER_TESS_CTRL: NIR_PASS_V(s, ir3_nir_lower_tess_ctrl, so, so->key.tessellation); - NIR_PASS_V(s, ir3_nir_lower_to_explicit_input); + NIR_PASS_V(s, ir3_nir_lower_to_explicit_input, so->shader->compiler); progress = true; break; case MESA_SHADER_TESS_EVAL: @@ -389,7 +389,7 @@ ir3_nir_lower_variant(struct ir3_shader_variant *so, nir_shader *s) progress = true; break; case MESA_SHADER_GEOMETRY: - NIR_PASS_V(s, ir3_nir_lower_to_explicit_input); + NIR_PASS_V(s, ir3_nir_lower_to_explicit_input, so->shader->compiler); progress = true; break; default: diff --git a/src/freedreno/ir3/ir3_nir.h b/src/freedreno/ir3/ir3_nir.h index 8bc6d342fe0..4126d4e4868 100644 --- a/src/freedreno/ir3/ir3_nir.h +++ b/src/freedreno/ir3/ir3_nir.h @@ -46,7 +46,7 @@ bool ir3_nir_lower_tex_prefetch(nir_shader *shader); void ir3_nir_lower_to_explicit_output(nir_shader *shader, struct ir3_shader_variant *v, unsigned topology); -void ir3_nir_lower_to_explicit_input(nir_shader *shader); +void ir3_nir_lower_to_explicit_input(nir_shader *shader, struct ir3_compiler *compiler); void ir3_nir_lower_tess_ctrl(nir_shader *shader, struct ir3_shader_variant *v, unsigned topology); void ir3_nir_lower_tess_eval(nir_shader *shader, unsigned topology); void ir3_nir_lower_gs(nir_shader *shader); diff --git a/src/freedreno/ir3/ir3_nir_lower_tess.c b/src/freedreno/ir3/ir3_nir_lower_tess.c index 4c06b458665..e084f99402d 100644 --- a/src/freedreno/ir3/ir3_nir_lower_tess.c +++ b/src/freedreno/ir3/ir3_nir_lower_tess.c @@ -42,6 +42,9 @@ struct state { struct exec_list old_outputs; struct exec_list emit_outputs; + + /* tess ctrl shader on a650 gets the local primitive id at different bits: */ + bool local_primitive_id_start; }; static nir_ssa_def * @@ -66,7 +69,7 @@ build_vertex_id(nir_builder *b, struct state *state) static nir_ssa_def * build_local_primitive_id(nir_builder *b, struct state *state) { - return bitfield_extract(b, state->header, 0, 63); + return bitfield_extract(b, state->header, state->local_primitive_id_start, 63); } static nir_variable * @@ -301,10 +304,16 @@ lower_block_to_explicit_input(nir_block *block, nir_builder *b, struct state *st } void -ir3_nir_lower_to_explicit_input(nir_shader *shader) +ir3_nir_lower_to_explicit_input(nir_shader *shader, struct ir3_compiler *compiler) { struct state state = { }; + /* when using stl/ldl (instead of stlw/ldlw) for linking VS and HS, + * HS uses a different primitive id, which starts at bit 16 in the header + */ + if (shader->info.stage == MESA_SHADER_TESS_CTRL && compiler->tess_use_shared) + state.local_primitive_id_start = 16; + nir_function_impl *impl = nir_shader_get_entrypoint(shader); assert(impl);