diff --git a/src/asahi/lib/cmdbuf.xml b/src/asahi/lib/cmdbuf.xml
index 9d15ab320c2..c9b2564cdc4 100644
--- a/src/asahi/lib/cmdbuf.xml
+++ b/src/asahi/lib/cmdbuf.xml
@@ -471,13 +471,18 @@
+
+
+
+
-
+
+
-
+
@@ -486,7 +491,7 @@
-
+
@@ -494,7 +499,7 @@
-
+
@@ -502,69 +507,51 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/asahi/lib/decode.c b/src/asahi/lib/decode.c
index a0c3835967c..242a6ea68d9 100644
--- a/src/asahi/lib/decode.c
+++ b/src/asahi/lib/decode.c
@@ -305,64 +305,63 @@ agxdecode_stateful(uint64_t va, const char *label, decode_cmd decoder, bool verb
}
}
-unsigned COUNTER = 0;
static unsigned
-agxdecode_pipeline(const uint8_t *map, uint64_t *link, UNUSED bool verbose)
+agxdecode_usc(const uint8_t *map, UNUSED uint64_t *link, UNUSED bool verbose)
{
- uint8_t zeroes[16] = { 0 };
+ enum agx_usc_control type = map[0];
- if (map[0] == 0x4D && (map[11] & BITFIELD_BIT(5))) {
- agx_unpack(agxdecode_dump_stream, map, SET_SHADER_EXTENDED, cmd);
- DUMP_UNPACKED(SET_SHADER_EXTENDED, cmd, "Set shader\n");
+#define USC_CASE(name, human) \
+ case AGX_USC_CONTROL_##name: { \
+ DUMP_CL(USC_##name, map, human); \
+ return AGX_USC_##name##_LENGTH; \
+ }
- if (cmd.preshader_mode == AGX_PRESHADER_MODE_PRESHADER) {
- agxdecode_log("Preshader\n");
- agx_disassemble(agxdecode_fetch_gpu_mem(cmd.preshader_code, 2048),
- 2048, agxdecode_dump_stream);
- agxdecode_log("\n---\n");
+ switch (type) {
+ case AGX_USC_CONTROL_NO_PRESHADER: {
+ DUMP_CL(USC_NO_PRESHADER, map, "No preshader");
+ return STATE_DONE;
+ }
+
+ case AGX_USC_CONTROL_PRESHADER: {
+ agx_unpack(agxdecode_dump_stream, map, USC_PRESHADER, ctrl);
+ DUMP_UNPACKED(USC_PRESHADER, ctrl, "Preshader\n");
+
+ agx_disassemble(agxdecode_fetch_gpu_mem(ctrl.code, 2048),
+ 8192, agxdecode_dump_stream);
+
+ return STATE_DONE;
+ }
+
+ case AGX_USC_CONTROL_SHADER: {
+ agx_unpack(agxdecode_dump_stream, map, USC_SHADER, ctrl);
+ DUMP_UNPACKED(USC_SHADER, ctrl, "Shader\n");
+
+ agxdecode_log("\n");
+ agx_disassemble(agxdecode_fetch_gpu_mem(ctrl.code, 2048),
+ 8192, agxdecode_dump_stream);
+ agxdecode_log("\n");
+
+ return AGX_USC_SHADER_LENGTH;
+ }
+
+ case AGX_USC_CONTROL_SAMPLER: {
+ agx_unpack(agxdecode_dump_stream, map, USC_SAMPLER, temp);
+ DUMP_UNPACKED(USC_SAMPLER, temp, "Sampler state\n");
+
+ uint8_t *samp = agxdecode_fetch_gpu_mem(temp.buffer,
+ AGX_SAMPLER_LENGTH * temp.count);
+
+ for (unsigned i = 0; i < temp.count; ++i) {
+ DUMP_CL(SAMPLER, samp, "Sampler");
+ samp += AGX_SAMPLER_LENGTH;
}
- agxdecode_log("\n");
- agx_disassemble(agxdecode_fetch_gpu_mem(cmd.code, 2048),
- 2048, agxdecode_dump_stream);
- agxdecode_log("\n");
+ return AGX_USC_SAMPLER_LENGTH;
+ }
- char *name;
- asprintf(&name, "file%u.bin", COUNTER++);
- FILE *fp = fopen(name, "wb");
- fwrite(agxdecode_fetch_gpu_mem(cmd.code, 2048), 1, 2048, fp);
- fclose(fp);
- free(name);
- agxdecode_log("\n");
-
- return AGX_SET_SHADER_EXTENDED_LENGTH;
- } else if (map[0] == 0x4D) {
- agx_unpack(agxdecode_dump_stream, map, SET_SHADER, cmd);
- DUMP_UNPACKED(SET_SHADER, cmd, "Set shader\n");
- fflush(agxdecode_dump_stream);
-
- if (cmd.preshader_mode == AGX_PRESHADER_MODE_PRESHADER) {
- agxdecode_log("Preshader\n");
- agx_disassemble(agxdecode_fetch_gpu_mem(cmd.preshader_code, 2048),
- 2048, agxdecode_dump_stream);
- agxdecode_log("\n---\n");
- }
-
- agxdecode_log("\n");
- agx_disassemble(agxdecode_fetch_gpu_mem(cmd.code, 2048),
- 2048, agxdecode_dump_stream);
- char *name;
- asprintf(&name, "file%u.bin", COUNTER++);
- FILE *fp = fopen(name, "wb");
- fwrite(agxdecode_fetch_gpu_mem(cmd.code, 2048), 1, 2048, fp);
- fclose(fp);
- free(name);
- agxdecode_log("\n");
-
- return AGX_SET_SHADER_LENGTH;
- } else if (map[0] == 0xDD) {
- agx_unpack(agxdecode_dump_stream, map, BIND_TEXTURE, temp);
- DUMP_UNPACKED(BIND_TEXTURE, temp, "Bind texture\n");
+ case AGX_USC_CONTROL_TEXTURE: {
+ agx_unpack(agxdecode_dump_stream, map, USC_TEXTURE, temp);
+ DUMP_UNPACKED(USC_TEXTURE, temp, "Texture state\n");
uint8_t *tex = agxdecode_fetch_gpu_mem(temp.buffer,
AGX_TEXTURE_LENGTH * temp.count);
@@ -376,29 +375,22 @@ agxdecode_pipeline(const uint8_t *map, uint64_t *link, UNUSED bool verbose)
tex += AGX_TEXTURE_LENGTH;
}
- return AGX_BIND_TEXTURE_LENGTH;
- } else if (map[0] == 0x9D) {
- agx_unpack(agxdecode_dump_stream, map, BIND_SAMPLER, temp);
- DUMP_UNPACKED(BIND_SAMPLER, temp, "Bind sampler\n");
-
- uint8_t *samp = agxdecode_fetch_gpu_mem(temp.buffer,
- AGX_SAMPLER_LENGTH * temp.count);
-
- for (unsigned i = 0; i < temp.count; ++i) {
- DUMP_CL(SAMPLER, samp, "Sampler");
- samp += AGX_SAMPLER_LENGTH;
- }
-
- return AGX_BIND_SAMPLER_LENGTH;
- } else if (map[0] == 0x1D) {
- DUMP_CL(BIND_UNIFORM, map, "Bind uniform");
- return AGX_BIND_UNIFORM_LENGTH;
- } else if (memcmp(map, zeroes, 16) == 0) {
- /* TODO: Termination */
- return STATE_DONE;
- } else {
- return 0;
+ return AGX_USC_TEXTURE_LENGTH;
}
+
+ USC_CASE(FRAGMENT_PROPERTIES, "Fragment properties");
+ USC_CASE(UNIFORM, "Uniform");
+ USC_CASE(SHARED, "Shared");
+ USC_CASE(REGISTERS, "Registers");
+
+ default:
+ fprintf(agxdecode_dump_stream, "Unknown USC control type: %u\n",
+ type);
+ hexdump(agxdecode_dump_stream, map, 8, false);
+ return 8;
+ }
+
+#undef USC_CASE
}
#define PPP_PRINT(map, header_name, struct_name, human) \
@@ -438,7 +430,7 @@ agxdecode_record(uint64_t va, size_t size, bool verbose)
if (hdr.fragment_shader) {
agx_unpack(agxdecode_dump_stream, map, FRAGMENT_SHADER, frag);
- agxdecode_stateful(frag.pipeline, "Fragment pipeline", agxdecode_pipeline, verbose);
+ agxdecode_stateful(frag.pipeline, "Fragment pipeline", agxdecode_usc, verbose);
if (frag.cf_bindings) {
uint8_t *cf = agxdecode_fetch_gpu_mem(frag.cf_bindings, 128);
@@ -476,7 +468,7 @@ agxdecode_cdm(const uint8_t *map, uint64_t *link, bool verbose)
switch (block_type) {
case AGX_CDM_BLOCK_TYPE_COMPUTE_KERNEL: {
agx_unpack(agxdecode_dump_stream, map, LAUNCH, cmd);
- agxdecode_stateful(cmd.pipeline, "Pipeline", agxdecode_pipeline, verbose);
+ agxdecode_stateful(cmd.pipeline, "Pipeline", agxdecode_usc, verbose);
DUMP_UNPACKED(LAUNCH, cmd, "Launch\n");
return AGX_LAUNCH_LENGTH;
}
@@ -541,7 +533,7 @@ agxdecode_vdm(const uint8_t *map, uint64_t *link, bool verbose)
agx_unpack(agxdecode_dump_stream, map, VDM_STATE_VERTEX_SHADER_WORD_1,
word_1);
fprintf(agxdecode_dump_stream, "Pipeline %X\n", (uint32_t) word_1.pipeline);
- agxdecode_stateful(word_1.pipeline, "Pipeline", agxdecode_pipeline, verbose);
+ agxdecode_stateful(word_1.pipeline, "Pipeline", agxdecode_usc, verbose);
}
VDM_PRINT(vertex_shader_word_1, VERTEX_SHADER_WORD_1, "Vertex shader word 1");
@@ -615,24 +607,24 @@ agxdecode_gfx(uint32_t *cmdbuf, uint64_t encoder, bool verbose)
if (gfx.clear_pipeline_unk) {
fprintf(agxdecode_dump_stream, "Unk: %X\n", gfx.clear_pipeline_unk);
agxdecode_stateful(gfx.clear_pipeline, "Clear pipeline",
- agxdecode_pipeline, verbose);
+ agxdecode_usc, verbose);
}
if (gfx.store_pipeline_unk) {
assert(gfx.store_pipeline_unk == 0x4);
agxdecode_stateful(gfx.store_pipeline, "Store pipeline",
- agxdecode_pipeline, verbose);
+ agxdecode_usc, verbose);
}
assert((gfx.partial_reload_pipeline_unk & 0xF) == 0x4);
if (gfx.partial_reload_pipeline) {
agxdecode_stateful(gfx.partial_reload_pipeline,
- "Partial reload pipeline", agxdecode_pipeline, verbose);
+ "Partial reload pipeline", agxdecode_usc, verbose);
}
if (gfx.partial_store_pipeline) {
agxdecode_stateful(gfx.partial_store_pipeline,
- "Partial store pipeline", agxdecode_pipeline, verbose);
+ "Partial store pipeline", agxdecode_usc, verbose);
}
}
diff --git a/src/gallium/drivers/asahi/agx_state.c b/src/gallium/drivers/asahi/agx_state.c
index 23be68e6e82..7a324d87faf 100644
--- a/src/gallium/drivers/asahi/agx_state.c
+++ b/src/gallium/drivers/asahi/agx_state.c
@@ -1193,20 +1193,68 @@ agx_delete_shader_state(struct pipe_context *ctx,
free(so);
}
-/* Pipeline consists of a sequence of binding commands followed by a set shader command */
+struct agx_usc_builder {
+ struct agx_ptr T;
+ uint8_t *head;
+
+#ifndef NDEBUG
+ size_t size;
+#endif
+};
+
+static struct agx_usc_builder
+agx_alloc_usc_control(struct agx_pool *pool,
+ unsigned num_reg_bindings)
+{
+ STATIC_ASSERT(AGX_USC_TEXTURE_LENGTH == AGX_USC_UNIFORM_LENGTH);
+ STATIC_ASSERT(AGX_USC_SAMPLER_LENGTH == AGX_USC_UNIFORM_LENGTH);
+
+ size_t size = AGX_USC_UNIFORM_LENGTH * num_reg_bindings;
+
+ size += AGX_USC_SHARED_LENGTH;
+ size += AGX_USC_SHADER_LENGTH;
+ size += AGX_USC_REGISTERS_LENGTH;
+ size += MAX2(AGX_USC_NO_PRESHADER_LENGTH, AGX_USC_PRESHADER_LENGTH);
+ size += AGX_USC_FRAGMENT_PROPERTIES_LENGTH;
+
+ struct agx_usc_builder b = {
+ .T = agx_pool_alloc_aligned(pool, size, 64),
+
+#ifndef NDEBUG
+ .size = size,
+#endif
+ };
+
+ b.head = (uint8_t *) b.T.cpu;
+
+ return b;
+}
+
+static bool
+agx_usc_builder_validate(struct agx_usc_builder *b, size_t size)
+{
+#ifndef NDEBUG
+ assert(((b->head - (uint8_t *) b->T.cpu) + size) <= b->size);
+#endif
+
+ return true;
+}
+
+#define agx_usc_pack(b, struct_name, template) \
+ for (bool it = agx_usc_builder_validate((b), AGX_USC_##struct_name##_LENGTH); \
+ it; it = false, (b)->head += AGX_USC_##struct_name##_LENGTH) \
+ agx_pack((b)->head, USC_##struct_name, template)
+
+static uint32_t
+agx_usc_fini(struct agx_usc_builder *b)
+{
+ assert(b->T.gpu <= (1ull << 32) && "pipelines must be in low memory");
+ return b->T.gpu;
+}
+
static uint32_t
agx_build_pipeline(struct agx_context *ctx, struct agx_compiled_shader *cs, enum pipe_shader_type stage)
{
- /* Pipelines must be 64-byte aligned */
- struct agx_ptr ptr = agx_pool_alloc_aligned(&ctx->batch->pipeline_pool,
- (cs->info.push_ranges * AGX_BIND_UNIFORM_LENGTH) +
- AGX_BIND_TEXTURE_LENGTH +
- AGX_BIND_SAMPLER_LENGTH +
- AGX_SET_SHADER_EXTENDED_LENGTH + 8,
- 64);
-
- uint8_t *record = ptr.cpu;
-
unsigned nr_textures = ctx->stage[stage].texture_count;
unsigned nr_samplers = ctx->stage[stage].sampler_count;
@@ -1235,25 +1283,26 @@ agx_build_pipeline(struct agx_context *ctx, struct agx_compiled_shader *cs, enum
samplers[i] = sampler->desc;
}
+ struct agx_usc_builder b =
+ agx_alloc_usc_control(&ctx->batch->pipeline_pool,
+ cs->info.push_ranges + 2);
+
if (nr_textures) {
- agx_pack(record, BIND_TEXTURE, cfg) {
+ agx_usc_pack(&b, TEXTURE, cfg) {
cfg.start = 0;
cfg.count = nr_textures;
cfg.buffer = T_tex.gpu;
}
ctx->batch->textures = T_tex.gpu;
- record += AGX_BIND_TEXTURE_LENGTH;
}
if (nr_samplers) {
- agx_pack(record, BIND_SAMPLER, cfg) {
+ agx_usc_pack(&b, SAMPLER, cfg) {
cfg.start = 0;
cfg.count = nr_samplers;
cfg.buffer = T_samp.gpu;
}
-
- record += AGX_BIND_SAMPLER_LENGTH;
}
/* Must only upload uniforms after uploading textures so we can implement the
@@ -1262,97 +1311,81 @@ agx_build_pipeline(struct agx_context *ctx, struct agx_compiled_shader *cs, enum
for (unsigned i = 0; i < cs->info.push_ranges; ++i) {
struct agx_push push = cs->info.push[i];
- agx_pack(record, BIND_UNIFORM, cfg) {
+ agx_usc_pack(&b, UNIFORM, cfg) {
cfg.start_halfs = push.base;
cfg.size_halfs = push.length;
cfg.buffer = agx_push_location(ctx, push, stage);
}
-
- record += AGX_BIND_UNIFORM_LENGTH;
}
- /* TODO: Can we prepack this? */
- if (stage == PIPE_SHADER_FRAGMENT) {
- bool writes_sample_mask = ctx->fs->info.writes_sample_mask;
-
- agx_pack(record, SET_SHADER_EXTENDED, cfg) {
- cfg.code = cs->bo->ptr.gpu;
- cfg.register_quadwords = 0;
- cfg.unk_3 = 0x8d;
- cfg.unk_1 = 0x10bd;
+ agx_usc_pack(&b, SHARED, cfg) {
+ if (stage == PIPE_SHADER_FRAGMENT) {
+ cfg.uses_shared_memory = true;
+ cfg.unk_1 = 0x10bc;
cfg.shared_memory_per_threadgroup_in_256_bytes = 32;
- cfg.unk_2 = 0x0d;
- cfg.loads_varyings = true;
- cfg.fragment_parameters.early_z_testing = !writes_sample_mask;
- cfg.unk_4 = 0x800;
- cfg.preshader_unk = 0xc080;
- cfg.spill_size = 0x2;
+ } else {
+ cfg.unk_1 = 0x90;
}
-
- record += AGX_SET_SHADER_EXTENDED_LENGTH;
- } else {
- agx_pack(record, SET_SHADER, cfg) {
- cfg.code = cs->bo->ptr.gpu;
- cfg.register_quadwords = 0;
- cfg.unk_2b = cs->info.varyings.vs.nr_index;
- cfg.unk_2 = 0x0d;
- }
-
- record += AGX_SET_SHADER_LENGTH;
}
- /* End pipeline */
- memset(record, 0, 8);
- assert(ptr.gpu < (1ull << 32));
- return ptr.gpu;
+ agx_usc_pack(&b, SHADER, cfg) {
+ cfg.loads_varyings = (stage == PIPE_SHADER_FRAGMENT);
+ cfg.code = cs->bo->ptr.gpu;
+ cfg.unk_2 = (stage == PIPE_SHADER_FRAGMENT) ? 2 : 3;
+ }
+
+ agx_usc_pack(&b, REGISTERS, cfg) {
+ cfg.register_quadwords = 0;
+ cfg.unk_1 = (stage == PIPE_SHADER_FRAGMENT);
+ }
+
+ if (stage == PIPE_SHADER_FRAGMENT) {
+ agx_usc_pack(&b, FRAGMENT_PROPERTIES, cfg) {
+ bool writes_sample_mask = ctx->fs->info.writes_sample_mask;
+ cfg.early_z_testing = !writes_sample_mask;
+ cfg.unk_4 = 0x2;
+ cfg.unk_5 = 0x0;
+ }
+ }
+
+ agx_usc_pack(&b, NO_PRESHADER, cfg);
+
+ return agx_usc_fini(&b);
}
/* Internal pipelines (TODO: refactor?) */
uint64_t
agx_build_clear_pipeline(struct agx_context *ctx, uint32_t code, uint64_t clear_buf)
{
- struct agx_ptr ptr = agx_pool_alloc_aligned(&ctx->batch->pipeline_pool,
- (1 * AGX_BIND_UNIFORM_LENGTH) +
- AGX_SET_SHADER_EXTENDED_LENGTH + 8,
- 64);
+ struct agx_usc_builder b =
+ agx_alloc_usc_control(&ctx->batch->pipeline_pool, 1);
- uint8_t *record = ptr.cpu;
-
- agx_pack(record, BIND_UNIFORM, cfg) {
+ agx_usc_pack(&b, UNIFORM, cfg) {
cfg.start_halfs = (6 * 2);
cfg.size_halfs = 4;
cfg.buffer = clear_buf;
}
- record += AGX_BIND_UNIFORM_LENGTH;
-
- /* TODO: Can we prepack this? */
- agx_pack(record, SET_SHADER, cfg) {
- cfg.code = code;
- cfg.unk_1 = 0x10bd;
+ agx_usc_pack(&b, SHARED, cfg) {
+ cfg.uses_shared_memory = true;
+ cfg.unk_1 = 0x10bc;
cfg.shared_memory_per_threadgroup_in_256_bytes = 32;
- cfg.unk_2 = 0x0d;
- cfg.unk_3 = 0x8d;
- cfg.register_quadwords = 1;
}
- record += AGX_SET_SHADER_LENGTH;
+ agx_usc_pack(&b, SHADER, cfg) {
+ cfg.code = code;
+ cfg.unk_2 = 3;
+ }
- /* End pipeline */
- memset(record, 0, 8);
- return ptr.gpu;
+ agx_usc_pack(&b, REGISTERS, cfg) cfg.register_quadwords = 1;
+ agx_usc_pack(&b, NO_PRESHADER, cfg);
+
+ return agx_usc_fini(&b);
}
uint64_t
agx_build_reload_pipeline(struct agx_context *ctx, uint32_t code, struct pipe_surface *surf)
{
- struct agx_ptr ptr = agx_pool_alloc_aligned(&ctx->batch->pipeline_pool,
- (1 * AGX_BIND_TEXTURE_LENGTH) +
- (1 * AGX_BIND_SAMPLER_LENGTH) +
- AGX_SET_SHADER_EXTENDED_LENGTH + 8,
- 64);
-
- uint8_t *record = ptr.cpu;
struct agx_ptr sampler = agx_pool_alloc_aligned(&ctx->batch->pool, AGX_SAMPLER_LENGTH, 64);
struct agx_ptr texture = agx_pool_alloc_aligned(&ctx->batch->pool, AGX_TEXTURE_LENGTH, 64);
@@ -1398,91 +1431,70 @@ agx_build_reload_pipeline(struct agx_context *ctx, uint32_t code, struct pipe_su
cfg.unk_tiled = true;
}
- agx_pack(record, BIND_TEXTURE, cfg) {
+ struct agx_usc_builder b =
+ agx_alloc_usc_control(&ctx->batch->pipeline_pool, 2);
+
+ agx_usc_pack(&b, TEXTURE, cfg) {
cfg.start = 0;
cfg.count = 1;
cfg.buffer = texture.gpu;
}
- record += AGX_BIND_TEXTURE_LENGTH;
-
- agx_pack(record, BIND_SAMPLER, cfg) {
+ agx_usc_pack(&b, SAMPLER, cfg) {
cfg.start = 0;
cfg.count = 1;
cfg.buffer = sampler.gpu;
}
- record += AGX_BIND_SAMPLER_LENGTH;
-
- /* TODO: Can we prepack this? */
- agx_pack(record, SET_SHADER_EXTENDED, cfg) {
- cfg.code = code;
- cfg.register_quadwords = 0;
- cfg.unk_3 = 0x8d;
- cfg.unk_2 = 0x0d;
- cfg.unk_4 = 0;
- cfg.fragment_parameters.unk_1 = 0x880100;
- cfg.fragment_parameters.early_z_testing = false;
- cfg.fragment_parameters.unk_2 = false;
- cfg.fragment_parameters.unk_3 = 0;
- cfg.preshader_mode = 0; // XXX
+ agx_usc_pack(&b, SHARED, cfg) {
+ cfg.uses_shared_memory = true;
+ cfg.unk_1 = 0x10bc;
+ cfg.shared_memory_per_threadgroup_in_256_bytes = 32;
}
- record += AGX_SET_SHADER_EXTENDED_LENGTH;
+ agx_usc_pack(&b, SHADER, cfg) {
+ cfg.code = code;
+ cfg.unk_2 = 3;
+ }
- /* End pipeline */
- memset(record, 0, 8);
- return ptr.gpu;
+ agx_usc_pack(&b, REGISTERS, cfg) cfg.register_quadwords = 0;
+ agx_usc_pack(&b, NO_PRESHADER, cfg);
+
+ return agx_usc_fini(&b);
}
uint64_t
agx_build_store_pipeline(struct agx_context *ctx, uint32_t code,
uint64_t render_target)
{
- struct agx_ptr ptr = agx_pool_alloc_aligned(&ctx->batch->pipeline_pool,
- (1 * AGX_BIND_TEXTURE_LENGTH) +
- (1 * AGX_BIND_UNIFORM_LENGTH) +
- AGX_SET_SHADER_EXTENDED_LENGTH + 8,
- 64);
+ struct agx_usc_builder b =
+ agx_alloc_usc_control(&ctx->batch->pipeline_pool, 2);
- uint8_t *record = ptr.cpu;
-
- agx_pack(record, BIND_TEXTURE, cfg) {
+ agx_usc_pack(&b, TEXTURE, cfg) {
cfg.start = 0;
cfg.count = 1;
cfg.buffer = render_target;
}
- record += AGX_BIND_TEXTURE_LENGTH;
-
uint32_t unk[] = { 0, ~0 };
- agx_pack(record, BIND_UNIFORM, cfg) {
+ agx_usc_pack(&b, UNIFORM, cfg) {
cfg.start_halfs = 4;
cfg.size_halfs = 4;
cfg.buffer = agx_pool_upload_aligned(&ctx->batch->pool, unk, sizeof(unk), 16);
}
- record += AGX_BIND_UNIFORM_LENGTH;
-
- /* TODO: Can we prepack this? */
- agx_pack(record, SET_SHADER_EXTENDED, cfg) {
- cfg.code = code;
- cfg.register_quadwords = 1;
- cfg.unk_2 = 0xd;
- cfg.unk_3 = 0x8d;
- cfg.fragment_parameters.unk_1 = 0x880100;
- cfg.fragment_parameters.early_z_testing = false;
- cfg.fragment_parameters.unk_2 = false;
- cfg.fragment_parameters.unk_3 = 0;
- cfg.preshader_mode = 0; // XXX
+ agx_usc_pack(&b, SHARED, cfg) {
+ cfg.uses_shared_memory = true;
+ cfg.unk_1 = 0x10bc;
+ cfg.shared_memory_per_threadgroup_in_256_bytes = 32;
}
- record += AGX_SET_SHADER_EXTENDED_LENGTH;
+ agx_usc_pack(&b, SHADER, cfg) cfg.code = code;
+ agx_usc_pack(&b, REGISTERS, cfg) cfg.register_quadwords = 1;
+ agx_usc_pack(&b, NO_PRESHADER, cfg);
- /* End pipeline */
- memset(record, 0, 8);
- return ptr.gpu;
+ return agx_usc_fini(&b);
}
void