From a7843643c6c2d93042d8c1a72afb69bfe286e3d9 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Sat, 26 Oct 2024 22:21:23 -0400 Subject: [PATCH] libagx: drop generated VDM tess path (for now?) this was definitely the coolest thing I did in my career. but it has a lot of drawbacks: * complexity across the whole stack. * perf #s even for synthetic tess workloads are... lackluster. couple % on terraintess. and games tend not to be tess heavy (and if they are we're screwed and this won't save us.) ironically, sascha willem's non-terrain tess is sped up a ton by the prefix sum path, so.. lol? * more brittle for (M3?) porting. * makes it harder to make the tessellator common code. * doesn't play nice with the indirect path. * pile of extra tessellator variants. * harder to test, coverage is already not great here. so... drop it, for now. the code isn't gone, and the idea may come back in a future iteration, perhaps based on mesh shaders. but in its current form I don't think it's worth keeping right now. my main resevation is actually about heap usage from doubling the index buffer size. hopefully this is tolerable in practice. this gets us from 24 to 16 tessellator variants. Signed-off-by: Alyssa Rosenzweig Part-of: --- src/asahi/lib/agx_nir_lower_gs.c | 3 +- src/asahi/lib/agx_nir_lower_gs.h | 4 +- src/asahi/lib/shaders/tessellation.cl | 27 +--- src/asahi/lib/shaders/tessellator.cl | 100 ++------------ src/asahi/lib/shaders/tessellator.h | 6 +- src/asahi/vulkan/hk_cmd_draw.c | 138 +++++--------------- src/gallium/drivers/asahi/agx_state.c | 179 ++++++++++---------------- src/gallium/drivers/asahi/agx_state.h | 1 - 8 files changed, 112 insertions(+), 346 deletions(-) diff --git a/src/asahi/lib/agx_nir_lower_gs.c b/src/asahi/lib/agx_nir_lower_gs.c index a13a619076a..4d370c870dd 100644 --- a/src/asahi/lib/agx_nir_lower_gs.c +++ b/src/asahi/lib/agx_nir_lower_gs.c @@ -1585,10 +1585,9 @@ agx_nir_tess_setup_indirect(nir_builder *b, const void *data) const struct agx_tess_setup_indirect_key *key = data; nir_def *params = nir_load_preamble(b, 1, 64, .base = 0); - nir_def *with_counts = nir_imm_bool(b, key->with_counts); nir_def *point_mode = nir_imm_bool(b, key->point_mode); - libagx_tess_setup_indirect(b, params, with_counts, point_mode); + libagx_tess_setup_indirect(b, params, point_mode); } void diff --git a/src/asahi/lib/agx_nir_lower_gs.h b/src/asahi/lib/agx_nir_lower_gs.h index bac4b5e4732..5334266449e 100644 --- a/src/asahi/lib/agx_nir_lower_gs.h +++ b/src/asahi/lib/agx_nir_lower_gs.h @@ -61,10 +61,8 @@ static_assert(sizeof(struct agx_tessellator_key) == 4, "padded"); struct agx_tess_setup_indirect_key { bool point_mode; - bool with_counts; - bool padding[2]; }; -static_assert(sizeof(struct agx_tess_setup_indirect_key) == 4, "padded"); +static_assert(sizeof(struct agx_tess_setup_indirect_key) == 1, "padded"); void agx_nir_tessellate(struct nir_builder *b, const void *key); diff --git a/src/asahi/lib/shaders/tessellation.cl b/src/asahi/lib/shaders/tessellation.cl index 1ad831460df..c1fda5367db 100644 --- a/src/asahi/lib/shaders/tessellation.cl +++ b/src/asahi/lib/shaders/tessellation.cl @@ -129,8 +129,7 @@ libagx_tess_level_inner_default(constant struct libagx_tess_args *p) } void -libagx_tess_setup_indirect(global struct libagx_tess_args *p, bool with_counts, - bool point_mode) +libagx_tess_setup_indirect(global struct libagx_tess_args *p, bool point_mode) { uint count = p->indirect[0], instance_count = p->indirect[1]; unsigned in_patches = count / p->input_patch_size; @@ -140,9 +139,7 @@ libagx_tess_setup_indirect(global struct libagx_tess_args *p, bool with_counts, *(p->tcs_statistic) += in_patches; } - size_t draw_stride = - ((!with_counts && point_mode) ? 4 : 6) * sizeof(uint32_t); - + size_t draw_stride = 5 * sizeof(uint32_t); unsigned unrolled_patches = in_patches * instance_count; uint32_t alloc = 0; @@ -153,8 +150,7 @@ libagx_tess_setup_indirect(global struct libagx_tess_args *p, bool with_counts, alloc += unrolled_patches * 4; uint32_t count_offs = alloc; - if (with_counts) - alloc += unrolled_patches * sizeof(uint32_t); + alloc += unrolled_patches * sizeof(uint32_t); uint vb_offs = alloc; uint vb_size = libagx_tcs_in_size(count * instance_count, p->vertex_outputs); @@ -170,22 +166,7 @@ libagx_tess_setup_indirect(global struct libagx_tess_args *p, bool with_counts, p->nr_patches = unrolled_patches; *(p->vertex_output_buffer_ptr) = (uintptr_t)(blob + vb_offs); - - if (with_counts) { - p->counts = (global uint32_t *)(blob + count_offs); - } else { -#if 0 - /* Arrange so we return after all generated draws. agx_pack would be nicer - * here but designated initializers lead to scratch access... - */ - global uint32_t *ret = - (global uint32_t *)(blob + draw_offs + - (draw_stride * unrolled_patches)); - - *ret = (AGX_VDM_BLOCK_TYPE_BARRIER << 29) | /* with return */ (1u << 27); -#endif - /* TODO */ - } + p->counts = (global uint32_t *)(blob + count_offs); global struct agx_ia_state *ia = p->ia; ia->verts_per_instance = count; diff --git a/src/asahi/lib/shaders/tessellator.cl b/src/asahi/lib/shaders/tessellator.cl index baa353e2f06..d5137bb683b 100644 --- a/src/asahi/lib/shaders/tessellator.cl +++ b/src/asahi/lib/shaders/tessellator.cl @@ -22,7 +22,6 @@ #include "geometry.h" #include "tessellator.h" -#include #if 0 #include @@ -154,50 +153,6 @@ libagx_draw(constant struct libagx_tess_args *p, enum libagx_tess_mode mode, p->counts[patch] = count; } - if (mode == LIBAGX_TESS_MODE_VDM) { - uint32_t elsize_B = sizeof(uint16_t); - uint32_t alloc_B = libagx_heap_alloc(p->heap, elsize_B * count); - uint64_t ib = ((uintptr_t)p->heap->heap) + alloc_B; - - global uint32_t *desc = p->out_draws + (patch * 6); - agx_pack(&desc[0], INDEX_LIST, cfg) { - cfg.index_buffer_hi = (ib >> 32); - cfg.primitive = lines ? AGX_PRIMITIVE_LINES : AGX_PRIMITIVE_TRIANGLES; - cfg.restart_enable = false; - cfg.index_size = AGX_INDEX_SIZE_U16; - cfg.index_buffer_size_present = true; - cfg.index_buffer_present = true; - cfg.index_count_present = true; - cfg.instance_count_present = true; - cfg.start_present = true; - cfg.unk_1_present = false; - cfg.indirect_buffer_present = false; - cfg.unk_2_present = false; - } - - agx_pack(&desc[1], INDEX_LIST_BUFFER_LO, cfg) { - cfg.buffer_lo = ib & 0xffffffff; - } - - agx_pack(&desc[2], INDEX_LIST_COUNT, cfg) { - cfg.count = count; - } - - agx_pack(&desc[3], INDEX_LIST_INSTANCES, cfg) { - cfg.count = 1; - } - - agx_pack(&desc[4], INDEX_LIST_START, cfg) { - cfg.start = patch * LIBAGX_TES_PATCH_ID_STRIDE; - } - - agx_pack(&desc[5], INDEX_LIST_BUFFER_SIZE, cfg) { - cfg.size = align(count * 2, 4); - } - - return (global void *)ib; - } - if (mode == LIBAGX_TESS_MODE_WITH_COUNTS) { /* The index buffer is already allocated, get a pointer inside it. * p->counts has had an inclusive prefix sum hence the subtraction. @@ -216,47 +171,16 @@ static void libagx_draw_points(private struct CHWTessellator *ctx, constant struct libagx_tess_args *p, uint patch, uint count) { - if (ctx->mode == LIBAGX_TESS_MODE_VDM) { - /* Generate a non-indexed draw for points mode tessellation. */ - global uint32_t *desc = p->out_draws + (patch * 4); - agx_pack(&desc[0], INDEX_LIST, cfg) { - cfg.index_buffer_hi = 0; - cfg.primitive = AGX_PRIMITIVE_POINTS; - cfg.restart_enable = false; - cfg.index_size = 0; - cfg.index_buffer_size_present = false; - cfg.index_buffer_present = false; - cfg.index_count_present = true; - cfg.instance_count_present = true; - cfg.start_present = true; - cfg.unk_1_present = false; - cfg.indirect_buffer_present = false; - cfg.unk_2_present = false; - } + /* For points mode with a single draw, we need to generate a trivial index + * buffer to stuff in the patch ID in the right place. + */ + global uint32_t *indices = libagx_draw(p, ctx->mode, false, patch, count); - agx_pack(&desc[1], INDEX_LIST_COUNT, cfg) { - cfg.count = count; - } + if (ctx->mode == LIBAGX_TESS_MODE_COUNT) + return; - agx_pack(&desc[2], INDEX_LIST_INSTANCES, cfg) { - cfg.count = 1; - } - - agx_pack(&desc[3], INDEX_LIST_START, cfg) { - cfg.start = patch * LIBAGX_TES_PATCH_ID_STRIDE; - } - } else { - /* For points mode with a single draw, we need to generate a trivial index - * buffer to stuff in the patch ID in the right place. - */ - global uint32_t *indices = libagx_draw(p, ctx->mode, false, patch, count); - - if (ctx->mode == LIBAGX_TESS_MODE_COUNT) - return; - - for (int i = 0; i < count; ++i) { - indices[i] = ctx->index_bias + i; - } + for (int i = 0; i < count; ++i) { + indices[i] = ctx->index_bias + i; } } @@ -268,14 +192,6 @@ libagx_draw_empty(constant struct libagx_tess_args *p, { if (mode == LIBAGX_TESS_MODE_COUNT) { p->counts[patch] = 0; - } else if (mode == LIBAGX_TESS_MODE_VDM) { - uint32_t words = (output_primitive == LIBAGX_TESS_OUTPUT_POINT) ? 4 : 6; - global uint32_t *desc = p->out_draws + (patch * words); - uint32_t nop_token = AGX_VDM_BLOCK_TYPE_BARRIER << 29; - - for (uint32_t i = 0; i < words; ++i) { - desc[i] = nop_token; - } } } diff --git a/src/asahi/lib/shaders/tessellator.h b/src/asahi/lib/shaders/tessellator.h index af4b2c74f9d..52d5c51ce14 100644 --- a/src/asahi/lib/shaders/tessellator.h +++ b/src/asahi/lib/shaders/tessellator.h @@ -25,9 +25,6 @@ enum libagx_tess_mode { /* Tessellate using the count buffers to allocate indices */ LIBAGX_TESS_MODE_WITH_COUNTS, - - /* Tessellate without count buffers by generating VDM index list words */ - LIBAGX_TESS_MODE_VDM, }; struct libagx_tess_point { @@ -51,8 +48,7 @@ struct libagx_tess_args { */ GLOBAL(uint32_t) coord_allocs; - /* Space for output draws from the tessellator. Either API draw calls or - * VDM control words, depending on the mode. */ + /* Space for output draws from the tessellator. API draw calls. */ GLOBAL(uint32_t) out_draws; /* Tessellation control shader output buffer. */ diff --git a/src/asahi/vulkan/hk_cmd_draw.c b/src/asahi/vulkan/hk_cmd_draw.c index 54434b993f8..bd0be504a55 100644 --- a/src/asahi/vulkan/hk_cmd_draw.c +++ b/src/asahi/vulkan/hk_cmd_draw.c @@ -78,11 +78,6 @@ struct hk_draw { uint32_t index_bias; uint32_t start_instance; - /* Indicates that the indirect draw consists of raw VDM commands and should - * be stream linked to. Used to accelerate tessellation. - */ - bool raw; - /* Set within hk_draw() but here so geometry/tessellation can override */ bool restart; enum agx_index_size index_size; @@ -101,9 +96,6 @@ print_draw(struct hk_draw d, FILE *fp) else fprintf(fp, " non-indexed"); - if (d.raw) - fprintf(fp, " raw"); - if (d.restart) fprintf(fp, " restart"); @@ -1262,26 +1254,6 @@ hk_upload_geometry_params(struct hk_cmd_buffer *cmd, struct hk_draw draw) return hk_pool_upload(cmd, ¶ms, sizeof(params), 8); } -/* - * Tessellation has a fast path where the tessellator generates a VDM Index List - * command per patch, as well as a slow path using prefix sums to generate a - * single combined API draw. We need the latter if tessellation is fed into - * another software stage (geometry shading), or if we need accurate primitive - * IDs in the linked fragment shader (since that would require a prefix sum - * anyway). - * - * The indirect tess path currently only supports indexed, but that part of - * libagx is on life support until I get to a wholesale replacement. - */ -static bool -hk_tess_needs_prefix_sum(struct hk_cmd_buffer *cmd, struct hk_draw draw) -{ - struct hk_graphics_state *gfx = &cmd->state.gfx; - - return gfx->shaders[MESA_SHADER_GEOMETRY] || gfx->generate_primitive_id || - draw.b.indirect; -} - static void hk_upload_tess_params(struct hk_cmd_buffer *cmd, struct libagx_tess_args *out, struct hk_draw draw) @@ -1312,8 +1284,7 @@ hk_upload_tess_params(struct hk_cmd_buffer *cmd, struct libagx_tess_args *out, .partitioning = partitioning, }; - bool with_counts = hk_tess_needs_prefix_sum(cmd, draw); - uint32_t draw_stride_el = with_counts ? 5 : (gfx->tess.info.points ? 4 : 6); + uint32_t draw_stride_el = 5; size_t draw_stride_B = draw_stride_el * sizeof(uint32_t); /* heap is allocated by hk_geometry_state */ @@ -1334,19 +1305,11 @@ hk_upload_tess_params(struct hk_cmd_buffer *cmd, struct libagx_tess_args *out, alloc += unrolled_patches * 4 * 32; uint32_t count_offs = alloc; - if (with_counts) - alloc += unrolled_patches * sizeof(uint32_t) * 32; + alloc += unrolled_patches * sizeof(uint32_t) * 32; + /* Single API draw */ uint32_t draw_offs = alloc; - - if (with_counts) { - /* Single API draw */ - alloc += draw_stride_B; - } else { - /* Padding added because VDM overreads */ - alloc += (draw_stride_B * unrolled_patches) + - (AGX_VDM_BARRIER_LENGTH + 0x800); - } + alloc += draw_stride_B; struct agx_ptr blob = hk_pool_alloc(cmd, alloc, 4); args.tcs_buffer = blob.gpu + tcs_out_offs; @@ -1354,18 +1317,7 @@ hk_upload_tess_params(struct hk_cmd_buffer *cmd, struct libagx_tess_args *out, args.coord_allocs = blob.gpu + patch_coord_offs; args.nr_patches = unrolled_patches; args.out_draws = blob.gpu + draw_offs; - - if (with_counts) { - args.counts = blob.gpu + count_offs; - } else { - /* Arrange so we return after all generated draws */ - uint8_t *ret = (uint8_t *)blob.cpu + draw_offs + - (draw_stride_B * unrolled_patches); - - agx_pack(ret, VDM_BARRIER, cfg) { - cfg.returns = true; - } - } + args.counts = blob.gpu + count_offs; } else { args.tcs_statistic = hk_pipeline_stat_addr( cmd, @@ -1384,12 +1336,7 @@ hk_upload_tess_params(struct hk_cmd_buffer *cmd, struct libagx_tess_args *out, gfx->root + offsetof(struct hk_root_descriptor_table, draw.vertex_output_buffer); args.ia = gfx->descriptors.root.draw.input_assembly; - - if (with_counts) { - args.out_draws = hk_pool_alloc(cmd, draw_stride_B, 4).gpu; - } else { - unreachable("need an extra indirection..."); - } + args.out_draws = hk_pool_alloc(cmd, draw_stride_B, 4).gpu; if (draw.indexed) { args.in_index_buffer = draw.index.addr; @@ -1652,7 +1599,6 @@ hk_launch_tess(struct hk_cmd_buffer *cmd, struct hk_cs *cs, struct hk_draw draw) struct vk_dynamic_graphics_state *dyn = &cmd->vk.dynamic_graphics_state; uint32_t input_patch_size = dyn->ts.patch_control_points; - bool with_counts = hk_tess_needs_prefix_sum(cmd, draw); uint64_t state = gfx->descriptors.root.draw.tess_params; struct hk_tess_info info = gfx->tess.info; @@ -1669,7 +1615,6 @@ hk_launch_tess(struct hk_cmd_buffer *cmd, struct hk_cs *cs, struct hk_draw draw) struct agx_tess_setup_indirect_key key = { .point_mode = info.points, - .with_counts = with_counts, }; struct hk_shader *tsi = @@ -1740,37 +1685,31 @@ hk_launch_tess(struct hk_cmd_buffer *cmd, struct hk_cs *cs, struct hk_draw draw) .output_primitive = prim, }; - if (with_counts) { - perf_debug(dev, "Tessellation with counts"); + /* Generate counts */ + key.mode = LIBAGX_TESS_MODE_COUNT; + { + struct hk_shader *tess = + hk_meta_kernel(dev, agx_nir_tessellate, &key, sizeof(key)); - /* Generate counts */ - key.mode = LIBAGX_TESS_MODE_COUNT; - { - struct hk_shader *tess = - hk_meta_kernel(dev, agx_nir_tessellate, &key, sizeof(key)); - - hk_dispatch_with_usc( - dev, cs, tess, - hk_upload_usc_words_kernel(cmd, tess, &state, sizeof(state)), - grid_tess, hk_grid(64, 1, 1)); - } - - /* Prefix sum counts, allocating index buffer space. */ - { - struct hk_shader *sum = - hk_meta_kernel(dev, agx_nir_prefix_sum_tess, NULL, 0); - - hk_dispatch_with_usc( - dev, cs, sum, - hk_upload_usc_words_kernel(cmd, sum, &state, sizeof(state)), - hk_grid(1024, 1, 1), hk_grid(1024, 1, 1)); - } - - key.mode = LIBAGX_TESS_MODE_WITH_COUNTS; - } else { - key.mode = LIBAGX_TESS_MODE_VDM; + hk_dispatch_with_usc( + dev, cs, tess, + hk_upload_usc_words_kernel(cmd, tess, &state, sizeof(state)), + grid_tess, hk_grid(64, 1, 1)); } + /* Prefix sum counts, allocating index buffer space. */ + { + struct hk_shader *sum = + hk_meta_kernel(dev, agx_nir_prefix_sum_tess, NULL, 0); + + hk_dispatch_with_usc( + dev, cs, sum, + hk_upload_usc_words_kernel(cmd, sum, &state, sizeof(state)), + hk_grid(1024, 1, 1), hk_grid(1024, 1, 1)); + } + + key.mode = LIBAGX_TESS_MODE_WITH_COUNTS; + /* Now we can tessellate */ { struct hk_shader *tess = @@ -1787,10 +1726,8 @@ hk_launch_tess(struct hk_cmd_buffer *cmd, struct hk_cs *cs, struct hk_draw draw) .range = dev->heap->size, }; - struct hk_draw out = hk_draw_indexed_indirect(gfx->tess.out_draws, range, - AGX_INDEX_SIZE_U32, false); - out.raw = !with_counts; - return out; + return hk_draw_indexed_indirect(gfx->tess.out_draws, range, + AGX_INDEX_SIZE_U32, false); } void @@ -3558,21 +3495,6 @@ hk_draw(struct hk_cmd_buffer *cmd, uint16_t draw_id, struct hk_draw draw_) if (tess) { draw = hk_launch_tess(cmd, ccs, draw); - - if (draw.raw) { - assert(!geom); - assert(draw.b.indirect); - - agx_push(out, VDM_STREAM_LINK, cfg) { - cfg.target_lo = draw.b.ptr & BITFIELD_MASK(32); - cfg.target_hi = draw.b.ptr >> 32; - cfg.with_return = true; - } - - cs->current = out; - cs->stats.cmds++; - continue; - } } if (geom) { diff --git a/src/gallium/drivers/asahi/agx_state.c b/src/gallium/drivers/asahi/agx_state.c index be0c4ae88f8..c955a7a72bc 100644 --- a/src/gallium/drivers/asahi/agx_state.c +++ b/src/gallium/drivers/asahi/agx_state.c @@ -4592,10 +4592,7 @@ agx_draw_patches(struct agx_context *ctx, const struct pipe_draw_info *info, : LIBAGX_TESS_OUTPUT_TRIANGLE_CW; struct agx_bo *draw_bo = NULL; - bool with_counts = - indirect || ctx->stage[MESA_SHADER_GEOMETRY].shader != NULL; - size_t draw_stride = - ((!with_counts && point_mode) ? 4 : 6) * sizeof(uint32_t); + size_t draw_stride = 5 * sizeof(uint32_t); struct agx_batch *batch = agx_get_batch(ctx); agx_batch_init_state(batch); @@ -4679,18 +4676,10 @@ agx_draw_patches(struct agx_context *ctx, const struct pipe_draw_info *info, alloc += unrolled_patches * 4; uint32_t count_offs = alloc; - if (with_counts) - alloc += unrolled_patches * sizeof(uint32_t); + alloc += unrolled_patches * sizeof(uint32_t); uint32_t draw_offs = alloc; - - if (with_counts) { - alloc += draw_stride; - } else { - /* Padding added because VDM overreads */ - alloc += - (draw_stride * unrolled_patches) + (AGX_VDM_BARRIER_LENGTH + 0x800); - } + alloc += draw_stride; struct agx_ptr blob = agx_pool_alloc_aligned_with_bo(&batch->pool, alloc, 4, &draw_bo); @@ -4700,18 +4689,7 @@ agx_draw_patches(struct agx_context *ctx, const struct pipe_draw_info *info, args.coord_allocs = blob.gpu + patch_coord_offs; args.nr_patches = unrolled_patches; args.out_draws = blob.gpu + draw_offs; - - if (with_counts) { - args.counts = blob.gpu + count_offs; - } else { - /* Arrange so we return after all generated draws */ - uint8_t *ret = - (uint8_t *)blob.cpu + draw_offs + (draw_stride * unrolled_patches); - - agx_pack(ret, VDM_BARRIER, cfg) { - cfg.returns = true; - } - } + args.counts = blob.gpu + count_offs; unsigned vb_size = libagx_tcs_in_size(draws->count * info->instance_count, batch->uniforms.vertex_outputs); @@ -4747,13 +4725,9 @@ agx_draw_patches(struct agx_context *ctx, const struct pipe_draw_info *info, batch->uniforms.vertex_output_buffer_ptr = args.vertex_output_buffer_ptr; - if (with_counts) { - args.out_draws = agx_pool_alloc_aligned_with_bo( - &batch->pool, draw_stride, 4, &draw_bo) - .gpu; - } else { - unreachable("need an extra indirection..."); - } + args.out_draws = + agx_pool_alloc_aligned_with_bo(&batch->pool, draw_stride, 4, &draw_bo) + .gpu; } uint64_t state = @@ -4763,7 +4737,6 @@ agx_draw_patches(struct agx_context *ctx, const struct pipe_draw_info *info, const struct agx_grid indirect_grid = agx_grid_direct(1, 1, 1, 1, 1, 1); struct agx_tess_setup_indirect_key indirect_key = { .point_mode = point_mode, - .with_counts = with_counts, }; agx_launch_with_uploaded_data(batch, &indirect_grid, @@ -4782,23 +4755,19 @@ agx_draw_patches(struct agx_context *ctx, const struct pipe_draw_info *info, .output_primitive = prim, }; - if (with_counts) { - /* Generate counts */ - key.mode = LIBAGX_TESS_MODE_COUNT; - agx_launch_with_uploaded_data(batch, &tess_grid, agx_nir_tessellate, &key, - sizeof(key), state); + /* Generate counts */ + key.mode = LIBAGX_TESS_MODE_COUNT; + agx_launch_with_uploaded_data(batch, &tess_grid, agx_nir_tessellate, &key, + sizeof(key), state); - /* Prefix sum counts, allocating index buffer space. */ - const struct agx_grid prefix_sum_grid = - agx_grid_direct(1024, 1, 1, 1024, 1, 1); + /* Prefix sum counts, allocating index buffer space. */ + const struct agx_grid prefix_sum_grid = + agx_grid_direct(1024, 1, 1, 1024, 1, 1); - agx_launch_with_uploaded_data(batch, &prefix_sum_grid, - agx_nir_prefix_sum_tess, NULL, 0, state); + agx_launch_with_uploaded_data(batch, &prefix_sum_grid, + agx_nir_prefix_sum_tess, NULL, 0, state); - key.mode = LIBAGX_TESS_MODE_WITH_COUNTS; - } else { - key.mode = LIBAGX_TESS_MODE_VDM; - } + key.mode = LIBAGX_TESS_MODE_WITH_COUNTS; /* Now we can tessellate */ agx_launch_with_uploaded_data(batch, &tess_grid, agx_nir_tessellate, &key, @@ -4809,12 +4778,11 @@ agx_draw_patches(struct agx_context *ctx, const struct pipe_draw_info *info, void *tes_cso = ctx->stage[PIPE_SHADER_TESS_EVAL].shader; ctx->base.bind_vs_state(&ctx->base, tes_cso); ctx->in_tess = true; - ctx->in_generated_vdm = !with_counts; struct pipe_draw_info draw_info = { .mode = out_prim, - .index_size = with_counts ? 4 : (point_mode ? 0 : 2), - .index.resource = (!with_counts && point_mode) ? NULL : ctx->heap, + .index_size = 4, + .index.resource = ctx->heap, .instance_count = 1, }; @@ -4832,7 +4800,6 @@ agx_draw_patches(struct agx_context *ctx, const struct pipe_draw_info *info, /* Restore vertex state */ ctx->base.bind_vs_state(&ctx->base, vs_cso); - ctx->in_generated_vdm = false; ctx->in_tess = false; if (unbind_tcs_when_done) { @@ -5221,75 +5188,63 @@ agx_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info, uint8_t *out = agx_encode_state(batch, batch->vdm.current); - if (ctx->in_generated_vdm) { + if (info->index_size && info->primitive_restart) { + agx_push(out, VDM_STATE, cfg) + cfg.restart_index_present = true; + + agx_push(out, VDM_STATE_RESTART_INDEX, cfg) + cfg.value = info->restart_index; + } + + agx_push(out, INDEX_LIST, cfg) { + cfg.primitive = agx_primitive_for_pipe(info->mode); + + if (indirect != NULL) { + cfg.indirect_buffer_present = true; + } else { + cfg.instance_count_present = true; + cfg.index_count_present = true; + cfg.start_present = true; + } + + if (info->index_size) { + cfg.restart_enable = info->primitive_restart; + cfg.index_buffer_hi = (ib >> 32); + cfg.index_size = agx_translate_index_size(info->index_size); + cfg.index_buffer_present = true; + cfg.index_buffer_size_present = true; + } + } + + if (info->index_size) { + agx_push(out, INDEX_LIST_BUFFER_LO, cfg) { + cfg.buffer_lo = ib & BITFIELD_MASK(32); + } + } + + if (indirect) { struct agx_resource *indirect_rsrc = agx_resource(indirect->buffer); uint64_t address = indirect_rsrc->bo->va->addr + indirect->offset; - agx_push(out, VDM_STREAM_LINK, cfg) { - cfg.target_lo = address & BITFIELD_MASK(32); - cfg.target_hi = address >> 32; - cfg.with_return = true; + agx_push(out, INDEX_LIST_INDIRECT_BUFFER, cfg) { + cfg.address_hi = address >> 32; + cfg.address_lo = address & BITFIELD_MASK(32); } } else { + agx_push(out, INDEX_LIST_COUNT, cfg) + cfg.count = draws->count; - if (info->index_size && info->primitive_restart) { - agx_push(out, VDM_STATE, cfg) - cfg.restart_index_present = true; + agx_push(out, INDEX_LIST_INSTANCES, cfg) + cfg.count = info->instance_count; - agx_push(out, VDM_STATE_RESTART_INDEX, cfg) - cfg.value = info->restart_index; + agx_push(out, INDEX_LIST_START, cfg) { + cfg.start = info->index_size ? draws->index_bias : draws->start; } + } - agx_push(out, INDEX_LIST, cfg) { - cfg.primitive = agx_primitive_for_pipe(info->mode); - - if (indirect != NULL) { - cfg.indirect_buffer_present = true; - } else { - cfg.instance_count_present = true; - cfg.index_count_present = true; - cfg.start_present = true; - } - - if (info->index_size) { - cfg.restart_enable = info->primitive_restart; - cfg.index_buffer_hi = (ib >> 32); - cfg.index_size = agx_translate_index_size(info->index_size); - cfg.index_buffer_present = true; - cfg.index_buffer_size_present = true; - } - } - - if (info->index_size) { - agx_push(out, INDEX_LIST_BUFFER_LO, cfg) { - cfg.buffer_lo = ib & BITFIELD_MASK(32); - } - } - - if (indirect) { - struct agx_resource *indirect_rsrc = agx_resource(indirect->buffer); - uint64_t address = indirect_rsrc->bo->va->addr + indirect->offset; - - agx_push(out, INDEX_LIST_INDIRECT_BUFFER, cfg) { - cfg.address_hi = address >> 32; - cfg.address_lo = address & BITFIELD_MASK(32); - } - } else { - agx_push(out, INDEX_LIST_COUNT, cfg) - cfg.count = draws->count; - - agx_push(out, INDEX_LIST_INSTANCES, cfg) - cfg.count = info->instance_count; - - agx_push(out, INDEX_LIST_START, cfg) { - cfg.start = info->index_size ? draws->index_bias : draws->start; - } - } - - if (info->index_size) { - agx_push(out, INDEX_LIST_BUFFER_SIZE, cfg) { - cfg.size = ib_extent; - } + if (info->index_size) { + agx_push(out, INDEX_LIST_BUFFER_SIZE, cfg) { + cfg.size = ib_extent; } } diff --git a/src/gallium/drivers/asahi/agx_state.h b/src/gallium/drivers/asahi/agx_state.h index 2af5a98ad93..37426b1d677 100644 --- a/src/gallium/drivers/asahi/agx_state.h +++ b/src/gallium/drivers/asahi/agx_state.h @@ -689,7 +689,6 @@ struct agx_context { bool is_noop; bool in_tess; - bool in_generated_vdm; struct blitter_context *blitter; struct asahi_blitter compute_blitter;