From 87e6324459dae97aebf81d78f5370abb1702efd7 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Sat, 26 Oct 2024 22:38:46 -0400 Subject: [PATCH] libagx: make points mode dynamic it's a cold enough path. 16 to 10 tessellator variants. Signed-off-by: Alyssa Rosenzweig Part-of: --- src/asahi/lib/agx_nir_lower_gs.c | 8 +++--- src/asahi/lib/agx_nir_lower_gs.h | 8 +++--- src/asahi/lib/shaders/tessellator.cl | 38 +++++++++++---------------- src/asahi/lib/shaders/tessellator.h | 14 ++++------ src/asahi/vulkan/hk_cmd_draw.c | 8 ++---- src/gallium/drivers/asahi/agx_state.c | 10 +++---- 6 files changed, 35 insertions(+), 51 deletions(-) diff --git a/src/asahi/lib/agx_nir_lower_gs.c b/src/asahi/lib/agx_nir_lower_gs.c index 4d370c870dd..d691d054e05 100644 --- a/src/asahi/lib/agx_nir_lower_gs.c +++ b/src/asahi/lib/agx_nir_lower_gs.c @@ -1567,14 +1567,14 @@ agx_nir_tessellate(nir_builder *b, const void *data) nir_def *params = nir_load_preamble(b, 1, 64, .base = 0); nir_def *patch = nir_channel(b, nir_load_global_invocation_id(b, 32), 0); nir_def *mode = nir_imm_int(b, key->mode); - nir_def *output_prim = nir_imm_int(b, key->output_primitive); + nir_def *ccw = nir_imm_bool(b, key->ccw); if (key->prim == TESS_PRIMITIVE_ISOLINES) - libagx_tess_isoline(b, params, mode, output_prim, patch); + libagx_tess_isoline(b, params, mode, ccw, patch); else if (key->prim == TESS_PRIMITIVE_TRIANGLES) - libagx_tess_tri(b, params, mode, output_prim, patch); + libagx_tess_tri(b, params, mode, ccw, patch); else if (key->prim == TESS_PRIMITIVE_QUADS) - libagx_tess_quad(b, params, mode, output_prim, patch); + libagx_tess_quad(b, params, mode, ccw, patch); else unreachable("invalid tess primitive"); } diff --git a/src/asahi/lib/agx_nir_lower_gs.h b/src/asahi/lib/agx_nir_lower_gs.h index 5334266449e..ed76471d0ab 100644 --- a/src/asahi/lib/agx_nir_lower_gs.h +++ b/src/asahi/lib/agx_nir_lower_gs.h @@ -52,10 +52,10 @@ struct agx_unroll_restart_key { void agx_nir_unroll_restart(struct nir_builder *b, const void *key); struct agx_tessellator_key { - enum tess_primitive_mode prim : 8; - enum libagx_tess_output_primitive output_primitive : 8; - enum libagx_tess_mode mode : 8; - unsigned pad : 8; + enum tess_primitive_mode prim : 8; + enum libagx_tess_mode mode : 8; + bool ccw; + unsigned pad : 8; }; static_assert(sizeof(struct agx_tessellator_key) == 4, "padded"); diff --git a/src/asahi/lib/shaders/tessellator.cl b/src/asahi/lib/shaders/tessellator.cl index d5137bb683b..b26b9da9497 100644 --- a/src/asahi/lib/shaders/tessellator.cl +++ b/src/asahi/lib/shaders/tessellator.cl @@ -96,7 +96,7 @@ struct INDEX_PATCH_CONTEXT2 { }; struct CHWTessellator { - enum libagx_tess_output_primitive outputPrimitive; + bool cw; enum libagx_tess_mode mode; uint index_bias; @@ -187,7 +187,6 @@ libagx_draw_points(private struct CHWTessellator *ctx, static void libagx_draw_empty(constant struct libagx_tess_args *p, enum libagx_tess_mode mode, - enum libagx_tess_output_primitive output_primitive, uint patch) { if (mode == LIBAGX_TESS_MODE_COUNT) { @@ -347,11 +346,9 @@ DefineClockwiseTriangle(private struct CHWTessellator *ctx, int index0, int index1, int index2, int indexStorageBaseOffset) { // inputs a clockwise triangle, stores a CW or CCW triangle per state state - bool cw = ctx->outputPrimitive == LIBAGX_TESS_OUTPUT_TRIANGLE_CW; - DefineIndex(ctx, index0, indexStorageBaseOffset); - DefineIndex(ctx, cw ? index1 : index2, indexStorageBaseOffset + 1); - DefineIndex(ctx, cw ? index2 : index1, indexStorageBaseOffset + 2); + DefineIndex(ctx, ctx->cw ? index1 : index2, indexStorageBaseOffset + 1); + DefineIndex(ctx, ctx->cw ? index2 : index1, indexStorageBaseOffset + 2); } static uint32_t @@ -744,9 +741,7 @@ StitchTransition(private struct CHWTessellator *ctx, int baseIndexOffset, void libagx_tess_isoline(constant struct libagx_tess_args *p, - enum libagx_tess_mode mode, - enum libagx_tess_output_primitive output_primitive, - uint patch) + enum libagx_tess_mode mode, bool ccw, uint patch) { enum libagx_tess_partitioning partitioning = p->partitioning; @@ -761,7 +756,7 @@ libagx_tess_isoline(constant struct libagx_tess_args *p, // Is the patch culled? NaN will pass. if (!(TessFactor_V_LineDensity > 0) || !(TessFactor_U_LineDetail > 0)) { - libagx_draw_empty(p, mode, output_primitive, patch); + libagx_draw_empty(p, mode, patch); return; } @@ -821,7 +816,7 @@ libagx_tess_isoline(constant struct libagx_tess_args *p, ctx.index_bias = patch * LIBAGX_TES_PATCH_ID_STRIDE; /* Connectivity */ - if (output_primitive != LIBAGX_TESS_OUTPUT_POINT) { + if (!p->points_mode) { uint num_indices = numLines * (numPointsPerLine - 1) * 2; ctx.Index = libagx_draw(p, mode, true, patch, num_indices); @@ -845,7 +840,7 @@ libagx_tess_isoline(constant struct libagx_tess_args *p, void libagx_tess_tri(constant struct libagx_tess_args *p, enum libagx_tess_mode mode, - enum libagx_tess_output_primitive output_primitive, uint patch) + bool ccw, uint patch) { enum libagx_tess_partitioning partitioning = p->partitioning; @@ -856,7 +851,7 @@ libagx_tess_tri(constant struct libagx_tess_args *p, enum libagx_tess_mode mode, float insideTessFactor_f = factors[4]; struct CHWTessellator ctx; - ctx.outputPrimitive = output_primitive; + ctx.cw = !ccw; ctx.Point = NULL; ctx.Index = NULL; ctx.mode = mode; @@ -868,7 +863,7 @@ libagx_tess_tri(constant struct libagx_tess_args *p, enum libagx_tess_mode mode, if (!(tessFactor_Ueq0 > 0) || !(tessFactor_Veq0 > 0) || !(tessFactor_Weq0 > 0)) { - libagx_draw_empty(p, mode, output_primitive, patch); + libagx_draw_empty(p, mode, patch); return; } @@ -940,7 +935,7 @@ libagx_tess_tri(constant struct libagx_tess_args *p, enum libagx_tess_mode mode, DefinePoint(&points[2], FXP_ONE, 0); // U=1 (beginning of Weq0 edge UV) - if (output_primitive != LIBAGX_TESS_OUTPUT_POINT) { + if (!p->points_mode) { ctx.Index = libagx_draw(p, mode, false, patch, 3); DefineClockwiseTriangle(&ctx, 0, 1, 2, @@ -1073,7 +1068,7 @@ libagx_tess_tri(constant struct libagx_tess_args *p, enum libagx_tess_mode mode, } } - if (output_primitive == LIBAGX_TESS_OUTPUT_POINT) { + if (p->points_mode) { libagx_draw_points(&ctx, p, patch, NumPoints); return; } @@ -1177,8 +1172,7 @@ libagx_tess_tri(constant struct libagx_tess_args *p, enum libagx_tess_mode mode, void libagx_tess_quad(constant struct libagx_tess_args *p, - enum libagx_tess_mode mode, - enum libagx_tess_output_primitive output_primitive, uint patch) + enum libagx_tess_mode mode, bool ccw, uint patch) { enum libagx_tess_partitioning partitioning = p->partitioning; global float *factors = tess_factors(p, patch); @@ -1193,7 +1187,7 @@ libagx_tess_quad(constant struct libagx_tess_args *p, // TODO: fix designated initializer optimization in NIR struct CHWTessellator ctx; - ctx.outputPrimitive = output_primitive; + ctx.cw = !ccw; ctx.Point = NULL; ctx.Index = NULL; ctx.mode = mode; @@ -1205,7 +1199,7 @@ libagx_tess_quad(constant struct libagx_tess_args *p, if (!(tessFactor_Ueq0 > 0) || // NaN will pass !(tessFactor_Veq0 > 0) || !(tessFactor_Ueq1 > 0) || !(tessFactor_Veq1 > 0)) { - libagx_draw_empty(p, mode, output_primitive, patch); + libagx_draw_empty(p, mode, patch); return; } @@ -1275,7 +1269,7 @@ libagx_tess_quad(constant struct libagx_tess_args *p, (FXP_ONE == outsideTessFactor[Veq1])) { /* Just do minimum tess factor */ - if (output_primitive != LIBAGX_TESS_OUTPUT_POINT) { + if (!p->points_mode) { ctx.Index = libagx_draw(p, mode, false, patch, 6); if (mode == LIBAGX_TESS_MODE_COUNT) return; @@ -1422,7 +1416,7 @@ libagx_tess_quad(constant struct libagx_tess_args *p, } } - if (output_primitive == LIBAGX_TESS_OUTPUT_POINT) { + if (p->points_mode) { libagx_draw_points(&ctx, p, patch, NumPoints); return; } diff --git a/src/asahi/lib/shaders/tessellator.h b/src/asahi/lib/shaders/tessellator.h index 52d5c51ce14..4913ab8811c 100644 --- a/src/asahi/lib/shaders/tessellator.h +++ b/src/asahi/lib/shaders/tessellator.h @@ -13,12 +13,6 @@ enum libagx_tess_partitioning { LIBAGX_TESS_PARTITIONING_INTEGER, }; -enum libagx_tess_output_primitive { - LIBAGX_TESS_OUTPUT_POINT, - LIBAGX_TESS_OUTPUT_TRIANGLE_CW, - LIBAGX_TESS_OUTPUT_TRIANGLE_CCW, -}; - enum libagx_tess_mode { /* Do not actually tessellate, just write the index counts */ LIBAGX_TESS_MODE_COUNT, @@ -130,9 +124,11 @@ struct libagx_tess_args { /* Number of patches being tessellated */ uint32_t nr_patches; - /* Partitioning. This affects per-patch setup code but not the hot - * tessellation loop so we make it dynamic to reduce tessellator variants. + /* Partitioning and points mode. These affect per-patch setup code but not + * the hot tessellation loop so we make them dynamic to reduce tessellator + * variants. */ enum libagx_tess_partitioning partitioning; + uint32_t points_mode; } PACKED; -AGX_STATIC_ASSERT(sizeof(struct libagx_tess_args) == 49 * 4); +AGX_STATIC_ASSERT(sizeof(struct libagx_tess_args) == 50 * 4); diff --git a/src/asahi/vulkan/hk_cmd_draw.c b/src/asahi/vulkan/hk_cmd_draw.c index bd0be504a55..428fb383066 100644 --- a/src/asahi/vulkan/hk_cmd_draw.c +++ b/src/asahi/vulkan/hk_cmd_draw.c @@ -1282,6 +1282,7 @@ hk_upload_tess_params(struct hk_cmd_buffer *cmd, struct libagx_tess_args *out, .tcs_patch_constants = tcs->info.tess.tcs_nr_patch_outputs, .tcs_per_vertex_outputs = tcs->info.tess.tcs_per_vertex_outputs, .partitioning = partitioning, + .points_mode = gfx->tess.info.points, }; uint32_t draw_stride_el = 5; @@ -1675,14 +1676,9 @@ hk_launch_tess(struct hk_cmd_buffer *cmd, struct hk_cs *cs, struct hk_draw draw) bool ccw = info.ccw; ccw ^= dyn->ts.domain_origin == VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT; - enum libagx_tess_output_primitive prim = - info.points ? LIBAGX_TESS_OUTPUT_POINT - : ccw ? LIBAGX_TESS_OUTPUT_TRIANGLE_CCW - : LIBAGX_TESS_OUTPUT_TRIANGLE_CW; - struct agx_tessellator_key key = { .prim = info.mode, - .output_primitive = prim, + .ccw = ccw, }; /* Generate counts */ diff --git a/src/gallium/drivers/asahi/agx_state.c b/src/gallium/drivers/asahi/agx_state.c index c955a7a72bc..d76dd1caff4 100644 --- a/src/gallium/drivers/asahi/agx_state.c +++ b/src/gallium/drivers/asahi/agx_state.c @@ -4586,11 +4586,6 @@ agx_draw_patches(struct agx_context *ctx, const struct pipe_draw_info *info, enum libagx_tess_partitioning partitioning = (enum libagx_tess_partitioning)pspacing; - enum libagx_tess_output_primitive prim = - point_mode ? LIBAGX_TESS_OUTPUT_POINT - : !tes->tess.ccw ? LIBAGX_TESS_OUTPUT_TRIANGLE_CCW - : LIBAGX_TESS_OUTPUT_TRIANGLE_CW; - struct agx_bo *draw_bo = NULL; size_t draw_stride = 5 * sizeof(uint32_t); @@ -4633,6 +4628,7 @@ agx_draw_patches(struct agx_context *ctx, const struct pipe_draw_info *info, .tcs_per_vertex_outputs = tcs->tess.per_vertex_outputs, .patch_coord_buffer = agx_resource(ctx->heap)->bo->va->addr, .partitioning = partitioning, + .points_mode = point_mode, }; memcpy(&args.tess_level_outer_default, ctx->default_outer_level, @@ -4752,7 +4748,9 @@ agx_draw_patches(struct agx_context *ctx, const struct pipe_draw_info *info, struct agx_tessellator_key key = { .prim = mode, - .output_primitive = prim, + + /* Yes, OpenGL is backwards. */ + .ccw = !tes->tess.ccw, }; /* Generate counts */