From 8f3caec5dc393581f359d4a55a9edf8e9b00c607 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Fri, 20 Sep 2024 13:51:31 -0400 Subject: [PATCH] agx: handle hw tess eval shaders Signed-off-by: Alyssa Rosenzweig Part-of: --- src/asahi/compiler/agx_compile.c | 33 +++++++++++++++++++--- src/asahi/compiler/agx_register_allocate.c | 4 ++- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/asahi/compiler/agx_compile.c b/src/asahi/compiler/agx_compile.c index b958316e3e9..3ad27c10f87 100644 --- a/src/asahi/compiler/agx_compile.c +++ b/src/asahi/compiler/agx_compile.c @@ -69,6 +69,18 @@ agx_cached_preload(agx_context *ctx, unsigned base, enum agx_size size) return ctx->preloaded[base]; } +static agx_index +agx_tess_coord_x(agx_builder *b) +{ + return agx_cached_preload(b->shader, 4, AGX_SIZE_32); +} + +static agx_index +agx_tess_coord_y(agx_builder *b) +{ + return agx_cached_preload(b->shader, 6, AGX_SIZE_32); +} + static agx_index agx_vertex_id(agx_builder *b) { @@ -1264,7 +1276,7 @@ agx_emit_intrinsic(agx_builder *b, nir_intrinsic_instr *instr) return NULL; case nir_intrinsic_store_uvs_agx: - assert(stage == MESA_SHADER_VERTEX); + assert(stage == MESA_SHADER_VERTEX || stage == MESA_SHADER_TESS_EVAL); return agx_st_vary(b, agx_src_index(&instr->src[1]), agx_src_index(&instr->src[0])); @@ -1359,9 +1371,20 @@ agx_emit_intrinsic(agx_builder *b, nir_intrinsic_instr *instr) /* We don't assert the HW stage since we use this same ABI with SW VS */ return agx_mov_to(b, dst, agx_abs(agx_vertex_id(b))); + case nir_intrinsic_load_primitive_id: + assert(stage == MESA_SHADER_TESS_EVAL); + return agx_mov_to(b, dst, agx_abs(agx_vertex_id(b))); + case nir_intrinsic_load_instance_id: return agx_mov_to(b, dst, agx_abs(agx_instance_id(b))); + case nir_intrinsic_load_tess_coord_xy: { + assert(stage == MESA_SHADER_TESS_EVAL); + + agx_index coords[] = {agx_tess_coord_x(b), agx_tess_coord_y(b)}; + return agx_emit_collect_to(b, dst, 2, coords); + } + case nir_intrinsic_load_preamble: return agx_emit_load_preamble(b, dst, instr); @@ -3441,8 +3464,9 @@ agx_compile_function_nir(nir_shader *nir, nir_function_impl *impl, out->scratch_size = stack_size; } - if (ctx->stage == MESA_SHADER_VERTEX && !impl->function->is_preamble && - !ctx->key->secondary) + if ((ctx->stage == MESA_SHADER_VERTEX || + ctx->stage == MESA_SHADER_TESS_EVAL) && + !impl->function->is_preamble && !ctx->key->secondary) agx_set_st_vary_final(ctx); agx_insert_waits(ctx); @@ -3748,7 +3772,8 @@ agx_compile_shader_nir(nir_shader *nir, struct agx_shader_key *key, BITSET_TEST(nir->info.system_values_read, SYSTEM_VALUE_BASE_VERTEX) || BITSET_TEST(nir->info.system_values_read, SYSTEM_VALUE_BASE_INSTANCE); - if (nir->info.stage == MESA_SHADER_VERTEX) { + if (nir->info.stage == MESA_SHADER_VERTEX || + nir->info.stage == MESA_SHADER_TESS_EVAL) { info->nonzero_viewport = nir->info.outputs_written & VARYING_BIT_VIEWPORT; info->writes_layer_viewport = diff --git a/src/asahi/compiler/agx_register_allocate.c b/src/asahi/compiler/agx_register_allocate.c index c27d237449c..b68edaab82a 100644 --- a/src/asahi/compiler/agx_register_allocate.c +++ b/src/asahi/compiler/agx_register_allocate.c @@ -1503,8 +1503,10 @@ agx_ra(agx_context *ctx) /* Vertex shaders preload the vertex/instance IDs (r5, r6) even if the shader * don't use them. Account for that so the preload doesn't clobber GPRs. + * Hardware tessellation eval shaders preload patch/instance IDs there. */ - if (ctx->nir->info.stage == MESA_SHADER_VERTEX) + if (ctx->nir->info.stage == MESA_SHADER_VERTEX || + ctx->nir->info.stage == MESA_SHADER_TESS_EVAL) ctx->max_reg = MAX2(ctx->max_reg, 6 * 2); assert(ctx->max_reg <= max_regs);