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 <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31908>
This commit is contained in:
Alyssa Rosenzweig
2024-10-26 22:21:23 -04:00
parent 02e29bdea4
commit a7843643c6
8 changed files with 112 additions and 346 deletions
+1 -2
View File
@@ -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
+1 -3
View File
@@ -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);
+4 -23
View File
@@ -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;
+8 -92
View File
@@ -22,7 +22,6 @@
#include "geometry.h"
#include "tessellator.h"
#include <agx_pack.h>
#if 0
#include <math.h>
@@ -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;
}
}
}
+1 -5
View File
@@ -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. */
+30 -108
View File
@@ -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, &params, 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) {
+67 -112
View File
@@ -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;
}
}
-1
View File
@@ -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;