hk: fix tessellation + clipper queries

fixes upcoming cts

Backport-to: 25.1
Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34585>
(cherry picked from commit d959557669f9deb5647e2481afbe1f3d55aa79f9)
This commit is contained in:
Alyssa Rosenzweig
2025-04-17 11:30:11 -04:00
committed by Eric Engestrom
parent c196a64471
commit 5c048f7860
5 changed files with 47 additions and 15 deletions

View File

@@ -1434,7 +1434,7 @@
"description": "hk: fix tessellation + clipper queries", "description": "hk: fix tessellation + clipper queries",
"nominated": true, "nominated": true,
"nomination_type": 4, "nomination_type": 4,
"resolution": 0, "resolution": 1,
"main_sha": null, "main_sha": null,
"because_sha": null, "because_sha": null,
"notes": null "notes": null

View File

@@ -758,7 +758,8 @@ libagx_prefix_sum_geom(constant struct agx_geometry_params *p)
} }
KERNEL(1024) KERNEL(1024)
libagx_prefix_sum_tess(global struct libagx_tess_args *p) libagx_prefix_sum_tess(global struct libagx_tess_args *p, global uint *c_prims,
global uint *c_invs, uint increment_stats__2)
{ {
_libagx_prefix_sum(p->counts, p->nr_patches, 1 /* words */, 0 /* word */); _libagx_prefix_sum(p->counts, p->nr_patches, 1 /* words */, 0 /* word */);
@@ -786,6 +787,19 @@ libagx_prefix_sum_tess(global struct libagx_tess_args *p)
desc[2] = alloc_B / elsize_B; /* start */ desc[2] = alloc_B / elsize_B; /* start */
desc[3] = 0; /* index_bias */ desc[3] = 0; /* index_bias */
desc[4] = 0; /* start_instance */ desc[4] = 0; /* start_instance */
/* If necessary, increment clipper statistics too. This is only used when
* there's no geometry shader following us. See agx_nir_lower_gs.c for more
* info on the emulation. We just need to calculate the # of primitives
* tessellated.
*/
if (increment_stats__2) {
uint prims = p->points_mode ? total
: p->isolines ? (total / 2)
: (total / 3);
increment_counters(c_prims, c_invs, NULL, prims);
}
} }
uintptr_t uintptr_t

View File

@@ -97,6 +97,7 @@ struct libagx_tess_args {
*/ */
enum libagx_tess_partitioning partitioning; enum libagx_tess_partitioning partitioning;
uint32_t points_mode; uint32_t points_mode;
uint32_t isolines;
/* When fed into a geometry shader, triangles should be counter-clockwise. /* When fed into a geometry shader, triangles should be counter-clockwise.
* The tessellator always produces clockwise triangles, but we can swap * The tessellator always produces clockwise triangles, but we can swap
@@ -104,4 +105,4 @@ struct libagx_tess_args {
*/ */
uint32_t ccw; uint32_t ccw;
} PACKED; } PACKED;
static_assert(sizeof(struct libagx_tess_args) == 35 * 4); static_assert(sizeof(struct libagx_tess_args) == 36 * 4);

View File

@@ -1230,6 +1230,7 @@ hk_upload_tess_params(struct hk_cmd_buffer *cmd, struct libagx_tess_args *out,
.tcs_per_vertex_outputs = tcs->info.tess.tcs_per_vertex_outputs, .tcs_per_vertex_outputs = tcs->info.tess.tcs_per_vertex_outputs,
.partitioning = partitioning, .partitioning = partitioning,
.points_mode = gfx->tess.info.points, .points_mode = gfx->tess.info.points,
.isolines = gfx->tess.info.mode == TESS_PRIMITIVE_ISOLINES,
}; };
if (!args.points_mode && gfx->tess.info.mode != TESS_PRIMITIVE_ISOLINES) { if (!args.points_mode && gfx->tess.info.mode != TESS_PRIMITIVE_ISOLINES) {
@@ -1538,7 +1539,7 @@ hk_launch_gs_prerast(struct hk_cmd_buffer *cmd, struct hk_cs *cs,
static struct agx_draw static struct agx_draw
hk_launch_tess(struct hk_cmd_buffer *cmd, struct hk_cs *cs, hk_launch_tess(struct hk_cmd_buffer *cmd, struct hk_cs *cs,
struct agx_draw draw) struct agx_draw draw, uint64_t c_prims, uint64_t c_inv)
{ {
struct hk_device *dev = hk_cmd_buffer_device(cmd); struct hk_device *dev = hk_cmd_buffer_device(cmd);
struct hk_graphics_state *gfx = &cmd->state.gfx; struct hk_graphics_state *gfx = &cmd->state.gfx;
@@ -1621,7 +1622,7 @@ hk_launch_tess(struct hk_cmd_buffer *cmd, struct hk_cs *cs,
LIBAGX_TESS_MODE_COUNT, state); LIBAGX_TESS_MODE_COUNT, state);
libagx_prefix_sum_tess(cmd, agx_1d(1024), AGX_BARRIER_ALL | AGX_PREGFX, libagx_prefix_sum_tess(cmd, agx_1d(1024), AGX_BARRIER_ALL | AGX_PREGFX,
state); state, c_prims, c_inv, c_prims || c_inv);
libagx_tessellate(cmd, grid_tess, AGX_BARRIER_ALL | AGX_PREGFX, info.mode, libagx_tessellate(cmd, grid_tess, AGX_BARRIER_ALL | AGX_PREGFX, info.mode,
LIBAGX_TESS_MODE_WITH_COUNTS, state); LIBAGX_TESS_MODE_WITH_COUNTS, state);
@@ -3373,8 +3374,6 @@ hk_ia_update(struct hk_cmd_buffer *cmd, struct agx_draw draw,
/* Clipper counters depend on geom/tess outputs and must be written with the /* Clipper counters depend on geom/tess outputs and must be written with the
* geom/tess output. They are updated as IA counters only when geom/tess is * geom/tess output. They are updated as IA counters only when geom/tess is
* not used. * not used.
*
* TODO: Tessellation clipper counters not actually wired up, pending CTS.
*/ */
if (geom || tess) { if (geom || tess) {
c_prims = 0; c_prims = 0;
@@ -3471,7 +3470,8 @@ hk_draw(struct hk_cmd_buffer *cmd, uint16_t draw_id, struct agx_draw draw_)
} }
if (tess) { if (tess) {
draw = hk_launch_tess(cmd, ccs, draw); draw = hk_launch_tess(cmd, ccs, draw, geom ? 0 : stat_c_prims,
geom ? 0 : stat_c_inv);
} }
if (geom) { if (geom) {

View File

@@ -3907,13 +3907,14 @@ agx_ia_update(struct agx_batch *batch, const struct pipe_draw_info *info,
uint64_t c_invs = agx_get_query_address( uint64_t c_invs = agx_get_query_address(
batch, ctx->pipeline_statistics[PIPE_STAT_QUERY_C_INVOCATIONS]); batch, ctx->pipeline_statistics[PIPE_STAT_QUERY_C_INVOCATIONS]);
/* With a geometry shader, clipper counters are written by the pre-GS kernel /* With a geometry/tessellation shader, clipper counters are written by the
* since they depend on the output on the geometry shader. Without a geometry * pre-GS/tess prefix sum kernel since they depend on the output on the
* shader, they are written along with IA. * geometry/tessellation shader. Without a geometry/tessellation shader,
* * they are written along with IA.
* TODO: Broken tessellation interaction, but nobody cares.
*/ */
if (ctx->stage[PIPE_SHADER_GEOMETRY].shader) { if (ctx->stage[PIPE_SHADER_GEOMETRY].shader ||
ctx->stage[PIPE_SHADER_TESS_EVAL].shader) {
c_prims = 0; c_prims = 0;
c_invs = 0; c_invs = 0;
} }
@@ -4620,6 +4621,7 @@ agx_draw_patches(struct agx_context *ctx, const struct pipe_draw_info *info,
.patch_coord_buffer = agx_resource(ctx->heap)->bo->va->addr, .patch_coord_buffer = agx_resource(ctx->heap)->bo->va->addr,
.partitioning = partitioning, .partitioning = partitioning,
.points_mode = point_mode, .points_mode = point_mode,
.isolines = mode == TESS_PRIMITIVE_ISOLINES,
}; };
if (!point_mode && tes->tess.primitive != TESS_PRIMITIVE_ISOLINES) { if (!point_mode && tes->tess.primitive != TESS_PRIMITIVE_ISOLINES) {
@@ -4736,10 +4738,24 @@ agx_draw_patches(struct agx_context *ctx, const struct pipe_draw_info *info,
batch->uniforms.vertex_output_buffer_ptr = 0; batch->uniforms.vertex_output_buffer_ptr = 0;
uint64_t c_prims = agx_get_query_address(
batch, ctx->pipeline_statistics[PIPE_STAT_QUERY_C_PRIMITIVES]);
uint64_t c_invs = agx_get_query_address(
batch, ctx->pipeline_statistics[PIPE_STAT_QUERY_C_INVOCATIONS]);
/* If there's a geometry shader, it will increment the clipper stats.
* Otherwise, we do when tessellating.
*/
if (ctx->stage[PIPE_SHADER_GEOMETRY].shader) {
c_prims = 0;
c_invs = 0;
}
/* Generate counts, then prefix sum them, then finally tessellate. */ /* Generate counts, then prefix sum them, then finally tessellate. */
libagx_tessellate(batch, tess_grid, AGX_BARRIER_ALL, mode, libagx_tessellate(batch, tess_grid, AGX_BARRIER_ALL, mode,
LIBAGX_TESS_MODE_COUNT, state); LIBAGX_TESS_MODE_COUNT, state);
libagx_prefix_sum_tess(batch, agx_1d(1024), AGX_BARRIER_ALL, state); libagx_prefix_sum_tess(batch, agx_1d(1024), AGX_BARRIER_ALL, state, c_prims,
c_invs, c_prims || c_invs);
libagx_tessellate(batch, tess_grid, AGX_BARRIER_ALL, mode, libagx_tessellate(batch, tess_grid, AGX_BARRIER_ALL, mode,
LIBAGX_TESS_MODE_WITH_COUNTS, state); LIBAGX_TESS_MODE_WITH_COUNTS, state);
@@ -4949,6 +4965,7 @@ agx_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
ctx->pipeline_statistics[PIPE_STAT_QUERY_VS_INVOCATIONS] || ctx->pipeline_statistics[PIPE_STAT_QUERY_VS_INVOCATIONS] ||
((ctx->pipeline_statistics[PIPE_STAT_QUERY_C_PRIMITIVES] || ((ctx->pipeline_statistics[PIPE_STAT_QUERY_C_PRIMITIVES] ||
ctx->pipeline_statistics[PIPE_STAT_QUERY_C_INVOCATIONS]) && ctx->pipeline_statistics[PIPE_STAT_QUERY_C_INVOCATIONS]) &&
!ctx->stage[PIPE_SHADER_TESS_EVAL].shader &&
!ctx->stage[PIPE_SHADER_GEOMETRY].shader))) { !ctx->stage[PIPE_SHADER_GEOMETRY].shader))) {
uint64_t ptr; uint64_t ptr;