libagx: make points mode dynamic
it's a cold enough path. 16 to 10 tessellator variants. Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31908>
This commit is contained in:
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user