poly,asahi: Fetch directly from poly_vertex_state::output_buffer in GS

We have access to the poly_vertex_state from the GS so we might as well
use it.  Asahi uses a single poly_vertex_state for VS and TCS and just
assumes the tessellator stalls before we update it for TCS.  If a driver
wants to use two separate poly_vertex_state buffers, it will be the
driver's responsibility to make the system values return the right one.

Acked-by: Alyssa Rosenzweig <alyssa.rosenzweig@intel.com>
Reviewed-by: Mary Guillemard <mary@mary.zone>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38404>
This commit is contained in:
Faith Ekstrand 2025-11-13 18:24:04 -05:00 committed by Marge Bot
parent 89fbb9cf84
commit 05723bfa35
6 changed files with 23 additions and 27 deletions

View file

@ -1100,9 +1100,7 @@ hk_rast_prim(struct hk_cmd_buffer *cmd)
} }
static uint64_t static uint64_t
hk_upload_geometry_params(struct hk_cmd_buffer *cmd, hk_upload_geometry_params(struct hk_cmd_buffer *cmd, struct agx_draw draw)
uint64_t vertex_output_buffer,
struct agx_draw draw)
{ {
struct hk_device *dev = hk_cmd_buffer_device(cmd); struct hk_device *dev = hk_cmd_buffer_device(cmd);
struct hk_descriptor_state *desc = &cmd->state.gfx.descriptors; struct hk_descriptor_state *desc = &cmd->state.gfx.descriptors;
@ -1127,7 +1125,6 @@ hk_upload_geometry_params(struct hk_cmd_buffer *cmd,
/* Overriden by the indirect setup kernel. As tess->GS is always indirect, /* Overriden by the indirect setup kernel. As tess->GS is always indirect,
* we can assume here that we're VS->GS. * we can assume here that we're VS->GS.
*/ */
.input_buffer = vertex_output_buffer,
.input_mask = desc->root.draw.vertex_outputs, .input_mask = desc->root.draw.vertex_outputs,
}; };
@ -3091,7 +3088,7 @@ hk_flush_dynamic_state(struct hk_cmd_buffer *cmd, struct hk_cs *cs,
if (gfx->shaders[MESA_SHADER_GEOMETRY]) { if (gfx->shaders[MESA_SHADER_GEOMETRY]) {
gfx->descriptors.root.draw.geometry_params = gfx->descriptors.root.draw.geometry_params =
hk_upload_geometry_params(cmd, vertex_output_buffer, draw); hk_upload_geometry_params(cmd, draw);
gfx->descriptors.root_dirty = true; gfx->descriptors.root_dirty = true;
} }

View file

@ -1436,6 +1436,10 @@ system_value("input_topology_poly", 1)
system_value("vs_outputs_poly", 1, bit_sizes=[64]) system_value("vs_outputs_poly", 1, bit_sizes=[64])
# Address of poly_vertex_param for vertex and tessellation evaluation # Address of poly_vertex_param for vertex and tessellation evaluation
# shaders. In tessellation control shaders, this is the poly_vertex_param
# for the vertex shader. In geometry shaders, this is the poly_vertex_param
# For whichever of vertex or tessellation evaluation shader preceeded the
# geometry shader.
system_value("vertex_param_buffer_poly", 1, bit_sizes=[64]) system_value("vertex_param_buffer_poly", 1, bit_sizes=[64])
# Address of the parameter buffer for poly geometry shaders # Address of the parameter buffer for poly geometry shaders

View file

@ -4025,7 +4025,6 @@ agx_batch_geometry_params(struct agx_batch *batch, uint64_t input_index_buffer,
if (vb_size) { if (vb_size) {
vp.output_buffer = vp.output_buffer =
agx_pool_alloc_aligned(&batch->pool, vb_size, 4).gpu; agx_pool_alloc_aligned(&batch->pool, vb_size, 4).gpu;
params.input_buffer = vp.output_buffer;
} }
struct poly_gs_info *gsi = &batch->ctx->gs->gs; struct poly_gs_info *gsi = &batch->ctx->gs->gs;

View file

@ -364,19 +364,18 @@ poly_vertex_output_buffer(constant struct poly_vertex_params *p)
} }
uintptr_t uintptr_t
poly_vertex_output_address(uintptr_t buffer, uint64_t mask, uint vtx, poly_vertex_output_address(constant struct poly_vertex_params *p,
gl_varying_slot location) uint64_t mask, uint vtx, gl_varying_slot location)
{ {
/* Written like this to let address arithmetic work */ /* Written like this to let address arithmetic work */
return buffer + ((uintptr_t)poly_tcs_in_offs_el(vtx, location, mask)) * 16; return p->output_buffer +
((uintptr_t)poly_tcs_in_offs_el(vtx, location, mask)) * 16;
} }
uintptr_t uint64_t
poly_geometry_input_address(constant struct poly_geometry_params *p, uint vtx, poly_geometry_input_mask(constant struct poly_geometry_params *p)
gl_varying_slot location)
{ {
return poly_vertex_output_address(p->input_buffer, p->input_mask, vtx, return p->input_mask;
location);
} }
unsigned unsigned

View file

@ -234,7 +234,6 @@ struct poly_geometry_params {
* reflect the vertex shader for VS->GS or instead the tessellation * reflect the vertex shader for VS->GS or instead the tessellation
* evaluation shader for TES->GS. * evaluation shader for TES->GS.
*/ */
uint64_t input_buffer;
uint64_t input_mask; uint64_t input_mask;
/* Location-indexed mask of flat outputs, used for lowering GL edge flags. */ /* Location-indexed mask of flat outputs, used for lowering GL edge flags. */
@ -278,7 +277,7 @@ struct poly_geometry_params {
*/ */
uint32_t input_topology; uint32_t input_topology;
} PACKED; } PACKED;
static_assert(sizeof(struct poly_geometry_params) == 86 * 4); static_assert(sizeof(struct poly_geometry_params) == 84 * 4);
/* TCS shared memory layout: /* TCS shared memory layout:
* *
@ -576,10 +575,8 @@ poly_gs_setup_indirect(uint64_t index_buffer, constant uint *draw,
heap, p->input_primitives * p->count_buffer_stride); heap, p->input_primitives * p->count_buffer_stride);
} }
const uintptr_t vertex_buffer = vp->output_buffer =
(uintptr_t)poly_heap_alloc_nonatomic(heap, vertex_buffer_size); (uintptr_t)poly_heap_alloc_nonatomic(heap, vertex_buffer_size);
vp->output_buffer = vertex_buffer;
p->input_buffer = vertex_buffer;
p->input_mask = vs_outputs; p->input_mask = vs_outputs;

View file

@ -285,20 +285,21 @@ poly_load_per_vertex_input(nir_builder *b, nir_intrinsic_instr *intr,
nir_def *location = nir_iadd_imm(b, intr->src[1].ssa, sem.location); nir_def *location = nir_iadd_imm(b, intr->src[1].ssa, sem.location);
nir_def *addr; nir_def *addr;
nir_def *input_mask;
if (b->shader->info.stage == MESA_SHADER_GEOMETRY) { if (b->shader->info.stage == MESA_SHADER_GEOMETRY) {
/* GS may be preceded by VS or TES so specified as param */ /* GS may be preceded by VS or TES so specified as param */
addr = poly_geometry_input_address( input_mask = poly_geometry_input_mask(
b, nir_load_geometry_param_buffer_poly(b), vertex, location); b, nir_load_geometry_param_buffer_poly(b));
} else { } else {
assert(b->shader->info.stage == MESA_SHADER_TESS_CTRL); assert(b->shader->info.stage == MESA_SHADER_TESS_CTRL);
/* TCS always preceded by VS so we use the VS state directly */ /* TCS always preceded by VS so we use the VS state directly */
nir_def *vp = nir_load_vertex_param_buffer_poly(b); input_mask = nir_load_vs_outputs_poly(b);
addr = poly_vertex_output_address(b, poly_vertex_output_buffer(b, vp),
nir_load_vs_outputs_poly(b), vertex,
location);
} }
nir_def *vp = nir_load_vertex_param_buffer_poly(b);
addr = poly_vertex_output_address(b, vp, input_mask, vertex, location);
addr = nir_iadd_imm(b, addr, 4 * nir_intrinsic_component(intr)); addr = nir_iadd_imm(b, addr, 4 * nir_intrinsic_component(intr));
return nir_load_global_constant(b, intr->def.num_components, return nir_load_global_constant(b, intr->def.num_components,
intr->def.bit_size, addr, .align_mul = 4); intr->def.bit_size, addr, .align_mul = 4);
@ -1403,7 +1404,6 @@ lower_vs_before_gs(nir_builder *b, nir_intrinsic_instr *intr, void *data)
nir_def *location = nir_iadd_imm(b, intr->src[1].ssa, sem.location); nir_def *location = nir_iadd_imm(b, intr->src[1].ssa, sem.location);
nir_def *vp = nir_load_vertex_param_buffer_poly(b); nir_def *vp = nir_load_vertex_param_buffer_poly(b);
nir_def *buffer = poly_vertex_output_buffer(b, vp);
/* Instancing is unrolled during tessellation so nr_verts is ignored. */ /* Instancing is unrolled during tessellation so nr_verts is ignored. */
nir_def *nr_verts = b->shader->info.stage == MESA_SHADER_VERTEX ? nir_def *nr_verts = b->shader->info.stage == MESA_SHADER_VERTEX ?
@ -1423,7 +1423,7 @@ lower_vs_before_gs(nir_builder *b, nir_intrinsic_instr *intr, void *data)
nir_iadd(b, nir_imul(b, instance_id, nr_verts), primitive_id); nir_iadd(b, nir_imul(b, instance_id, nr_verts), primitive_id);
nir_def *addr = poly_vertex_output_address( nir_def *addr = poly_vertex_output_address(
b, buffer, nir_imm_int64(b, b->shader->info.outputs_written), linear_id, b, vp, nir_imm_int64(b, b->shader->info.outputs_written), linear_id,
location); location);
assert(nir_src_bit_size(intr->src[0]) == 32); assert(nir_src_bit_size(intr->src[0]) == 32);