poly: Move vs_grid to poly_vertex_params

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-17 12:37:22 -05:00 committed by Marge Bot
parent 70a1a4013f
commit 27b2290abe
4 changed files with 64 additions and 35 deletions

View file

@ -1045,8 +1045,10 @@ hk_upload_vertex_params(struct hk_cmd_buffer *cmd, struct agx_draw draw)
struct hk_graphics_state *gfx = &cmd->state.gfx;
struct hk_descriptor_state *desc = &cmd->state.gfx.descriptors;
const uint32_t wg_size[3] = { 64, 1, 1 };
struct poly_vertex_params params;
poly_vertex_params_init(&params, 0);
poly_vertex_params_init(&params, 0, wg_size);
/* XXX: We should deduplicate this logic */
bool indirect = agx_is_indirect(draw.b) || draw.restart;
@ -1149,7 +1151,7 @@ hk_upload_geometry_params(struct hk_cmd_buffer *cmd, struct agx_draw draw)
const uint32_t wg_size[3] = { 64, 1, 1 };
struct poly_geometry_params params;
poly_geometry_params_init(&params, mode, wg_size, wg_size);
poly_geometry_params_init(&params, mode, wg_size);
params.flat_outputs = fs->info.fs.interp.flat;
@ -1459,6 +1461,7 @@ hk_launch_gs_prerast(struct hk_cmd_buffer *cmd, struct hk_cs *cs,
struct hk_shader *count = hk_count_gs_variant(gs);
struct hk_shader *pre_gs = hk_pre_gs_variant(gs);
uint64_t vertex_params = desc->root.draw.vertex_params;
uint64_t geometry_params = desc->root.draw.geometry_params;
unsigned count_words = count->info.gs.count_words;
struct agx_workgroup wg = agx_workgroup(64, 1, 1);
@ -1501,10 +1504,10 @@ hk_launch_gs_prerast(struct hk_cmd_buffer *cmd, struct hk_cs *cs,
AGX_BARRIER_ALL | AGX_PREGFX, gsi);
grid_vs = agx_grid_indirect_local(
geometry_params + offsetof(struct poly_geometry_params, vs_grid));
vertex_params + offsetof(struct poly_vertex_params, grid));
grid_gs = agx_grid_indirect_local(
geometry_params + offsetof(struct poly_geometry_params, gs_grid));
geometry_params + offsetof(struct poly_geometry_params, grid));
} else {
grid_vs = grid_gs = draw.b;
grid_gs.count[0] = u_decomposed_prims_for_vertices(mode, draw.b.count[0]);

View file

@ -3928,7 +3928,7 @@ agx_batch_geometry_params(struct agx_batch *batch, uint64_t input_index_buffer,
const uint32_t wg_size[3] = { 64, 1, 1 };
struct poly_vertex_params vp;
poly_vertex_params_init(&vp, batch->ctx->vs->b.info.outputs);
poly_vertex_params_init(&vp, batch->ctx->vs->b.info.outputs, wg_size);
if (info->index_size) {
vp.index_size_B = info->index_size;
@ -3937,7 +3937,7 @@ agx_batch_geometry_params(struct agx_batch *batch, uint64_t input_index_buffer,
}
struct poly_geometry_params params;
poly_geometry_params_init(&params, info->mode, wg_size, wg_size);
poly_geometry_params_init(&params, info->mode, wg_size);
params.flat_outputs =
batch->ctx->stage[MESA_SHADER_FRAGMENT].shader->info.inputs_flat_shaded;
@ -4084,6 +4084,7 @@ agx_launch_gs_prerast(struct agx_batch *batch,
assert(!info->primitive_restart && "should have been lowered");
uint64_t vp = batch->uniforms.vertex_params;
uint64_t gp = batch->uniforms.geometry_params;
struct agx_grid grid_vs, grid_gs;
struct agx_workgroup wg = agx_workgroup(64, 1, 1);
@ -4116,10 +4117,10 @@ agx_launch_gs_prerast(struct agx_batch *batch,
libagx_gs_setup_indirect_struct(batch, agx_1d(1), AGX_BARRIER_ALL, gsi);
grid_vs = agx_grid_indirect_local(
gp + offsetof(struct poly_geometry_params, vs_grid));
vp + offsetof(struct poly_vertex_params, grid));
grid_gs = agx_grid_indirect_local(
gp + offsetof(struct poly_geometry_params, gs_grid));
gp + offsetof(struct poly_geometry_params, grid));
} else {
grid_vs = agx_3d(draws->count, info->instance_count, 1);
@ -4555,8 +4556,10 @@ agx_draw_patches(struct agx_context *ctx, const struct pipe_draw_info *info,
batch->uniforms.vertex_outputs = ctx->vs->b.info.outputs;
const uint32_t wg_size[3] = { 64, 1, 1 };
struct poly_vertex_params vp;
poly_vertex_params_init(&vp, batch->ctx->vs->b.info.outputs);
poly_vertex_params_init(&vp, batch->ctx->vs->b.info.outputs, wg_size);
if (info->index_size) {
size_t ib_extent = 0;

View file

@ -193,6 +193,14 @@ struct poly_vertex_params {
*/
uint32_t verts_per_instance;
/* Within an indirect VS draw, the grids used to dispatch the VS written
* out by the GS indirect setup kernel or the CPU for a direct draw. This is
* the "indirect local" format: first 3 is in threads, second 3 is in grid
* blocks. This lets us use nontrivial workgroups with indirect draws without
* needing any predication.
*/
uint32_t grid[6];
uint32_t _pad;
/* Output buffer for vertex data */
@ -201,13 +209,18 @@ struct poly_vertex_params {
/* Mask of outputs present in the output buffer */
uint64_t outputs;
} PACKED;
static_assert(sizeof(struct poly_vertex_params) == 10 * 4);
static_assert(sizeof(struct poly_vertex_params) == 16 * 4);
static inline void
poly_vertex_params_init(struct poly_vertex_params *p, uint64_t outputs)
poly_vertex_params_init(struct poly_vertex_params *p,
uint64_t outputs, const uint32_t wg_size[3])
{
*p = (struct poly_vertex_params) {
.outputs = outputs,
.grid = {
0, 0, 1, /* x/y are set by poly_vertex_params_set_draw() */
wg_size[0], wg_size[1], wg_size[2],
},
};
}
@ -215,7 +228,10 @@ static inline void
poly_vertex_params_set_draw(struct poly_vertex_params *p,
uint32_t vertex_count, uint32_t instance_count)
{
/* Invoke VS as (vertices, instances) */
p->verts_per_instance = vertex_count;
p->grid[0] = vertex_count;
p->grid[1] = instance_count;
}
static inline uint
@ -280,14 +296,13 @@ struct poly_geometry_params {
*/
uint32_t xfb_verts[POLY_MAX_VERTEX_STREAMS];
/* Within an indirect GS draw, the grids used to dispatch the VS/GS written
/* Within an indirect GS draw, the grids used to dispatch the GS written
* out by the GS indirect setup kernel or the CPU for a direct draw. This is
* the "indirect local" format: first 3 is in threads, second 3 is in grid
* blocks. This lets us use nontrivial workgroups with indirect draws without
* needing any predication.
*/
uint32_t vs_grid[6];
uint32_t gs_grid[6];
uint32_t grid[6];
/* Indirect draw command */
struct poly_indirect_draw draw;
@ -314,23 +329,17 @@ struct poly_geometry_params {
*/
uint32_t input_topology;
} PACKED;
static_assert(sizeof(struct poly_geometry_params) == 85 * 4);
static_assert(sizeof(struct poly_geometry_params) == 79 * 4);
static inline void
poly_geometry_params_init(struct poly_geometry_params *p,
enum mesa_prim prim,
const uint32_t vs_wg_size[3],
const uint32_t gs_wg_size[3])
enum mesa_prim prim, const uint32_t wg_size[3])
{
*p = (struct poly_geometry_params) {
.input_topology = prim,
.vs_grid = {
.grid = {
0, 0, 1, /* x/y are set by poly_geometry_params_set_draw() */
vs_wg_size[0], vs_wg_size[1], vs_wg_size[2],
},
.gs_grid = {
0, 0, 1, /* x/y are set by poly_geometry_params_set_draw() */
gs_wg_size[0], gs_wg_size[1], gs_wg_size[2],
wg_size[0], wg_size[1], wg_size[2],
},
};
}
@ -345,12 +354,9 @@ poly_geometry_params_set_draw(struct poly_geometry_params *p,
const uint32_t prim_per_instance =
u_decomposed_prims_for_vertices(prim, vertex_count);
/* Invoke VS as (vertices, instances); GS as (primitives, instances) */
p->vs_grid[0] = vertex_count;
p->vs_grid[1] = instance_count;
p->gs_grid[0] = prim_per_instance;
p->gs_grid[1] = instance_count;
/* Invoke GS as (primitives, instances) */
p->grid[0] = prim_per_instance;
p->grid[1] = instance_count;
p->input_primitives = prim_per_instance * instance_count;
p->primitives_log2 = util_logbase2_ceil(prim_per_instance);

View file

@ -170,6 +170,23 @@ struct lower_gs_state {
struct poly_gs_info *info;
};
/* Helpers for loading from the vertex state buffer */
static nir_def *
load_vertex_param_offset(nir_builder *b, uint32_t offset, uint8_t bytes)
{
nir_def *base = nir_load_vertex_param_buffer_poly(b);
nir_def *addr = nir_iadd_imm(b, base, offset);
assert((offset % bytes) == 0 && "must be naturally aligned");
return nir_load_global_constant(b, 1, bytes * 8, addr);
}
#define load_vertex_param(b, field) \
load_vertex_param_offset( \
b, offsetof(struct poly_vertex_params, field), \
sizeof(((struct poly_vertex_params *)0)->field))
/* Helpers for loading from the geometry state buffer */
static nir_def *
load_geometry_param_offset(nir_builder *b, uint32_t offset, uint8_t bytes)
@ -249,7 +266,7 @@ vertex_id_for_topology_class(nir_builder *b, nir_def *vert, enum mesa_prim cls)
{
nir_def *prim = nir_load_primitive_id(b);
nir_def *flatshade_first = nir_ieq_imm(b, nir_load_provoking_last(b), 0);
nir_def *nr = load_geometry_param(b, gs_grid[0]);
nir_def *nr = load_geometry_param(b, grid[0]);
nir_def *topology = nir_load_input_topology_poly(b);
switch (cls) {
@ -318,7 +335,7 @@ lower_gs_inputs(nir_builder *b, nir_intrinsic_instr *intr, void *_)
nir_def *vertex = vertex_id_for_topology_class(
b, vert_in_prim, b->shader->info.gs.input_primitive);
nir_def *verts = load_geometry_param(b, vs_grid[0]);
nir_def *verts = load_vertex_param(b, grid[0]);
nir_def *unrolled =
nir_iadd(b, nir_imul(b, nir_load_instance_id(b), verts), vertex);
@ -335,7 +352,7 @@ static nir_def *
calc_unrolled_id(nir_builder *b)
{
return nir_iadd(
b, nir_imul(b, load_instance_id(b), load_geometry_param(b, gs_grid[0])),
b, nir_imul(b, load_instance_id(b), load_geometry_param(b, grid[0])),
load_primitive_id(b));
}
@ -673,7 +690,7 @@ create_gs_rast_shader(const nir_shader *gs, const struct lower_gs_state *state)
case POLY_GS_SHAPE_STATIC_INDEXED:
case POLY_GS_SHAPE_STATIC_PER_PRIM: {
nir_def *stride = load_geometry_param(b, gs_grid[0]);
nir_def *stride = load_geometry_param(b, grid[0]);
rs.output_id = raw_vertex_id;
rs.instance_id = nir_udiv(b, rs.raw_instance_id, stride);
@ -728,7 +745,7 @@ create_gs_rast_shader(const nir_shader *gs, const struct lower_gs_state *state)
struct nir_xfb_info *xfb = gs->xfb_info;
nir_def *unrolled = nir_iadd(
b, nir_imul(b, rs.instance_id, load_geometry_param(b, gs_grid[0])),
b, nir_imul(b, rs.instance_id, load_geometry_param(b, grid[0])),
rs.primitive_id);
nir_def *n = nir_imm_int(b, n_);