diff --git a/src/asahi/lib/agx_nir_lower_gs.c b/src/asahi/lib/agx_nir_lower_gs.c index 0fcf6bb005c..4dedeedcf26 100644 --- a/src/asahi/lib/agx_nir_lower_gs.c +++ b/src/asahi/lib/agx_nir_lower_gs.c @@ -1461,22 +1461,25 @@ lower_vs_before_gs(nir_builder *b, nir_intrinsic_instr *intr, void *data) */ nir_def *mask = nir_imm_int64(b, b->shader->info.outputs_written); + nir_def *buffer; nir_def *nr_verts; if (b->shader->info.stage == MESA_SHADER_VERTEX) { + buffer = nir_load_vs_output_buffer_agx(b); nr_verts = libagx_input_vertices(b, nir_load_input_assembly_buffer_agx(b)); } else { - /* TODO: Do something similar for tessellation, load_num_workgroups is - * annoying in a software graphics shader. - */ - nr_verts = nir_channel(b, nir_load_num_workgroups(b), 0); + assert(b->shader->info.stage == MESA_SHADER_TESS_EVAL); + + /* Instancing is unrolled during tessellation so nr_verts is ignored. */ + nr_verts = nir_imm_int(b, 0); + buffer = libagx_tes_buffer(b, nir_load_tess_param_buffer_agx(b)); } nir_def *linear_id = nir_iadd(b, nir_imul(b, load_instance_id(b), nr_verts), load_primitive_id(b)); - nir_def *addr = libagx_vertex_output_address( - b, nir_load_vs_output_buffer_agx(b), mask, linear_id, location); + nir_def *addr = + libagx_vertex_output_address(b, buffer, mask, linear_id, location); assert(nir_src_bit_size(intr->src[0]) == 32); addr = nir_iadd_imm(b, addr, nir_intrinsic_component(intr) * 4); diff --git a/src/asahi/lib/shaders/tessellation.cl b/src/asahi/lib/shaders/tessellation.cl index a001d71ce97..d0bcbb68017 100644 --- a/src/asahi/lib/shaders/tessellation.cl +++ b/src/asahi/lib/shaders/tessellation.cl @@ -25,6 +25,12 @@ libagx_tcs_unrolled_id(constant struct libagx_tess_args *p, uint3 wg_id) return (wg_id.y * p->patches_per_instance) + wg_id.x; } +uint64_t +libagx_tes_buffer(constant struct libagx_tess_args *p) +{ + return p->tes_buffer; +} + /* * Helper to lower indexing for a tess eval shader ran as a compute shader. This * handles the tess+geom case. This is simpler than the general input assembly diff --git a/src/asahi/lib/shaders/tessellator.h b/src/asahi/lib/shaders/tessellator.h index ec674f43764..a2547e51e38 100644 --- a/src/asahi/lib/shaders/tessellator.h +++ b/src/asahi/lib/shaders/tessellator.h @@ -91,6 +91,11 @@ struct libagx_tess_args { */ GLOBAL(uint64_t) vertex_output_buffer_ptr; + /* When geom+tess used together, the buffer containing TES outputs (executed + * as a hardware compute shader). + */ + uint64_t tes_buffer; + /* For indirect draws, the bitfield of VS outputs */ uint64_t vertex_outputs; @@ -121,4 +126,4 @@ struct libagx_tess_args { /* Number of patches being tessellated */ uint32_t nr_patches; } PACKED; -AGX_STATIC_ASSERT(sizeof(struct libagx_tess_args) == 40 * 4); +AGX_STATIC_ASSERT(sizeof(struct libagx_tess_args) == 42 * 4);