From ad30ebccb6b0e0bbd9f9a42e0ad580c7e3d604f8 Mon Sep 17 00:00:00 2001 From: Faith Ekstrand Date: Wed, 12 Nov 2025 10:15:24 -0500 Subject: [PATCH] poly,asahi: Put the indirect draw directly in the geometry params Acked-by: Alyssa Rosenzweig Reviewed-by: Mary Guillemard Part-of: --- src/asahi/vulkan/hk_cmd_buffer.c | 1 - src/asahi/vulkan/hk_cmd_buffer.h | 1 - src/asahi/vulkan/hk_cmd_draw.c | 11 +++---- src/gallium/drivers/asahi/agx_state.c | 11 +++---- src/gallium/drivers/asahi/agx_state.h | 4 --- src/poly/geometry.h | 47 ++++++++++++++++++--------- 6 files changed, 40 insertions(+), 35 deletions(-) diff --git a/src/asahi/vulkan/hk_cmd_buffer.c b/src/asahi/vulkan/hk_cmd_buffer.c index a7a990ca599..5321662a0ea 100644 --- a/src/asahi/vulkan/hk_cmd_buffer.c +++ b/src/asahi/vulkan/hk_cmd_buffer.c @@ -144,7 +144,6 @@ hk_reset_cmd_buffer(struct vk_command_buffer *vk_cmd_buffer, cmd->current_cs.pre_gfx = NULL; assert(!cmd->in_meta); - cmd->geom_indirect = 0; cmd->geom_index_buffer = 0; cmd->geom_index_count = 0; cmd->geom_instance_count = 0; diff --git a/src/asahi/vulkan/hk_cmd_buffer.h b/src/asahi/vulkan/hk_cmd_buffer.h index d9a0979133a..b8f16d3f3ac 100644 --- a/src/asahi/vulkan/hk_cmd_buffer.h +++ b/src/asahi/vulkan/hk_cmd_buffer.h @@ -503,7 +503,6 @@ struct hk_cmd_buffer { * * Indirect draw generated by the indirect GS translator. */ - uint64_t geom_indirect; uint64_t geom_index_buffer; uint32_t geom_index_count; uint32_t geom_instance_count; diff --git a/src/asahi/vulkan/hk_cmd_draw.c b/src/asahi/vulkan/hk_cmd_draw.c index 65974b99350..8965345d077 100644 --- a/src/asahi/vulkan/hk_cmd_draw.c +++ b/src/asahi/vulkan/hk_cmd_draw.c @@ -1200,10 +1200,6 @@ hk_upload_geometry_params(struct hk_cmd_buffer *cmd, struct agx_draw draw) struct poly_gs_info *gsi = &count->info.gs; if (indirect) { - /* TODO: size */ - cmd->geom_indirect = hk_pool_alloc(cmd, 64, 4).gpu; - - params.indirect_desc = cmd->geom_indirect; params.vs_grid[2] = params.gs_grid[2] = 1; if (gsi->shape == POLY_GS_SHAPE_DYNAMIC_INDEXED) { @@ -1574,8 +1570,8 @@ hk_launch_gs_prerast(struct hk_cmd_buffer *cmd, struct hk_cs *cs, if (agx_is_indirect(draw.b)) { return agx_draw_indexed_indirect( - cmd->geom_indirect, cmd->geom_index_buffer, cmd->geom_index_count, - index_size, true); + geometry_params + offsetof(struct poly_geometry_params, draw), + cmd->geom_index_buffer, cmd->geom_index_count, index_size, true); } else { return agx_draw_indexed(cmd->geom_index_count, cmd->geom_instance_count, 0, 0, 0, @@ -1584,7 +1580,8 @@ hk_launch_gs_prerast(struct hk_cmd_buffer *cmd, struct hk_cs *cs, } } else { if (agx_is_indirect(draw.b)) { - return agx_draw_indirect(cmd->geom_indirect); + return agx_draw_indirect( + geometry_params + offsetof(struct poly_geometry_params, draw)); } else { return (struct agx_draw){ .b = agx_3d(cmd->geom_index_count, cmd->geom_instance_count, 1), diff --git a/src/gallium/drivers/asahi/agx_state.c b/src/gallium/drivers/asahi/agx_state.c index 7d0aaa64b41..76e2cc65112 100644 --- a/src/gallium/drivers/asahi/agx_state.c +++ b/src/gallium/drivers/asahi/agx_state.c @@ -3932,7 +3932,6 @@ agx_batch_geometry_params(struct agx_batch *batch, uint64_t input_index_buffer, }; struct poly_geometry_params params = { - .indirect_desc = batch->geom_indirect, .flat_outputs = batch->ctx->stage[MESA_SHADER_FRAGMENT].shader->info.inputs_flat_shaded, .input_topology = info->mode, @@ -5019,10 +5018,6 @@ agx_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info, agx_update_gs(ctx, info, indirect); if (ctx->gs) { - batch->geom_indirect = agx_pool_alloc_aligned_with_bo( - &batch->pool, 64, 4, &batch->geom_indirect_bo) - .gpu; - batch->uniforms.geometry_params = agx_batch_geometry_params(batch, ib, ib_extent, info, draws, indirect); @@ -5121,7 +5116,7 @@ agx_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info, struct pipe_draw_start_count_bias draw_gs; /* Wrap the pool allocation in a fake resource for meta-Gallium use */ - struct agx_resource indirect_rsrc = {.bo = batch->geom_indirect_bo}; + struct agx_resource indirect_rsrc = {.bo = batch->geom_params_bo}; struct agx_resource index_rsrc = {}; if (ctx->gs) { @@ -5143,7 +5138,9 @@ agx_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info, indirect_gs = (struct pipe_draw_indirect_info){ .draw_count = 1, .buffer = &indirect_rsrc.base, - .offset = batch->geom_indirect - indirect_rsrc.bo->va->addr, + .offset = batch->uniforms.geometry_params + - indirect_rsrc.bo->va->addr + + offsetof(struct poly_geometry_params, draw), }; indirect = &indirect_gs; diff --git a/src/gallium/drivers/asahi/agx_state.h b/src/gallium/drivers/asahi/agx_state.h index 23d425137de..f1666e7561c 100644 --- a/src/gallium/drivers/asahi/agx_state.h +++ b/src/gallium/drivers/asahi/agx_state.h @@ -408,10 +408,6 @@ struct agx_batch { struct agx_draw_uniforms uniforms; struct agx_stage_uniforms stage_uniforms[MESA_SHADER_STAGES]; - /* Indirect buffer allocated for geometry shader */ - uint64_t geom_indirect; - struct agx_bo *geom_indirect_bo; - /* Heap descriptor if dynamic allocation is required */ uint64_t heap; diff --git a/src/poly/geometry.h b/src/poly/geometry.h index ad14cf73f19..049c5d8ba98 100644 --- a/src/poly/geometry.h +++ b/src/poly/geometry.h @@ -209,10 +209,27 @@ poly_index_buffer_range_el(uint size_el, uint offset_el) return offset_el < size_el ? (size_el - offset_el) : 0; } -struct poly_geometry_params { - /* Address of associated indirect draw buffer */ - DEVICE(uint) indirect_desc; +/* This must match VkDraw[Indexed]IndirectCommand + * + * The vertex/index_count and first_vertex/index fields line up, as does + * instance_count. The only ones that don't are vertexOffset and + * firstInstance but we always set those to zero. + */ +struct poly_indirect_draw { + union { + uint32_t vertex_count; + uint32_t index_count; + }; + uint32_t instance_count; + union { + uint32_t first_vertex; + uint32_t first_index; + }; + uint32_t zeros[2]; +}; +static_assert(sizeof(struct poly_indirect_draw) == 5 * 4); +struct poly_geometry_params { /* Address of count buffer. For an indirect draw, this will be written by the * indirect setup kernel. */ @@ -257,6 +274,9 @@ struct poly_geometry_params { uint32_t vs_grid[6]; uint32_t gs_grid[6]; + /* Indirect draw command */ + struct poly_indirect_draw draw; + /* Number of input primitives across all instances, calculated by the CPU for * a direct draw or the GS indirect setup kernel for an indirect draw. */ @@ -279,7 +299,7 @@ struct poly_geometry_params { */ uint32_t input_topology; } PACKED; -static_assert(sizeof(struct poly_geometry_params) == 82 * 4); +static_assert(sizeof(struct poly_geometry_params) == 85 * 4); /* TCS shared memory layout: * @@ -582,22 +602,19 @@ poly_gs_setup_indirect(uint64_t index_buffer, constant uint *draw, vp->outputs = vs_outputs; - /* Allocate the index buffer and write the draw consuming it */ - global VkDrawIndexedIndirectCommand *cmd = (global void *)p->indirect_desc; - - *cmd = (VkDrawIndexedIndirectCommand){ - .indexCount = poly_gs_rast_vertices(shape, max_indices, prim_per_instance, - instance_count), - .instanceCount = poly_gs_rast_instances( + p->draw = (struct poly_indirect_draw) { + .index_count = poly_gs_rast_vertices( + shape, max_indices, prim_per_instance, instance_count), + .instance_count = poly_gs_rast_instances( shape, max_indices, prim_per_instance, instance_count), }; if (shape == POLY_GS_SHAPE_DYNAMIC_INDEXED) { - cmd->firstIndex = - poly_heap_alloc_nonatomic_offs(heap, cmd->indexCount * 4) / 4; + const uint32_t index_offset = + poly_heap_alloc_nonatomic_offs(heap, p->draw.index_count * 4); - p->output_index_buffer = - (global uint *)(heap->base + (cmd->firstIndex * 4)); + p->draw.first_index = index_offset / 4; + p->output_index_buffer = (global uint *)(heap->base + index_offset); } }