From 8d55b6155c22c09781d6b64d11b9a221c91fa85b Mon Sep 17 00:00:00 2001 From: Job Noorman Date: Mon, 8 Apr 2024 10:38:31 +0200 Subject: [PATCH] freedreno,computerator: support initialization of buffers The following syntax can now be used to set the initial content of buffers: @buf size (reg) val0, val1, ... If the buffer is not fully initialized, remaining values will be set to zero. Signed-off-by: Job Noorman Part-of: --- .../computerator/examples/buf-init.asm | 9 ++++++++ src/freedreno/computerator/ir3_asm.cc | 2 ++ src/freedreno/computerator/main.cc | 7 ++++++ src/freedreno/computerator/main.h | 1 + src/freedreno/ir3/ir3_assembler.h | 2 ++ src/freedreno/ir3/ir3_parser.y | 22 ++++++++++++++++++- 6 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 src/freedreno/computerator/examples/buf-init.asm diff --git a/src/freedreno/computerator/examples/buf-init.asm b/src/freedreno/computerator/examples/buf-init.asm new file mode 100644 index 00000000000..1964a6f3884 --- /dev/null +++ b/src/freedreno/computerator/examples/buf-init.asm @@ -0,0 +1,9 @@ +@localsize 8, 1, 1 +@buf 8 1, 2, 3, 4, 5, 6, 7, 8 +@invocationid(r0.x) + +ldib.b.untyped.1d.u32.4.imm r1.x, r0.x, 0 +(sy)add.u r1.x, r1.x, 5 +(rpt5)nop +stib.b.untyped.1d.u32.4.imm r1.x, r0.x, 0 +end diff --git a/src/freedreno/computerator/ir3_asm.cc b/src/freedreno/computerator/ir3_asm.cc index f9cd259a00a..5733af89c92 100644 --- a/src/freedreno/computerator/ir3_asm.cc +++ b/src/freedreno/computerator/ir3_asm.cc @@ -46,6 +46,8 @@ ir3_asm_assemble(struct ir3_compiler *c, FILE *in) sizeof(kernel->base.buf_sizes)); memcpy(kernel->base.buf_addr_regs, kernel->info.buf_addr_regs, sizeof(kernel->base.buf_addr_regs)); + memcpy(kernel->base.buf_init_data, kernel->info.buf_init_data, + sizeof(kernel->base.buf_init_data)); unsigned sz = v->info.size; diff --git a/src/freedreno/computerator/main.cc b/src/freedreno/computerator/main.cc index 14dc6841266..464123b6eaa 100644 --- a/src/freedreno/computerator/main.cc +++ b/src/freedreno/computerator/main.cc @@ -269,6 +269,13 @@ main(int argc, char **argv) for (int i = 0; i < kernel->num_bufs; i++) { printf("buf[%d]: size=%u\n", i, kernel->buf_sizes[i]); kernel->bufs[i] = fd_bo_new(dev, kernel->buf_sizes[i] * 4, 0, "buf[%d]", i); + + if (kernel->buf_init_data[i]) { + fd_bo_cpu_prep(kernel->bufs[i], pipe, FD_BO_PREP_WRITE); + void *map = fd_bo_map(kernel->bufs[i]); + memcpy(map, kernel->buf_init_data[i], kernel->buf_sizes[i] * 4); + free(kernel->buf_init_data[i]); + } } if (disasm) diff --git a/src/freedreno/computerator/main.h b/src/freedreno/computerator/main.h index d43ba7b634a..16134b37c95 100644 --- a/src/freedreno/computerator/main.h +++ b/src/freedreno/computerator/main.h @@ -42,6 +42,7 @@ struct kernel { uint32_t num_bufs; uint32_t buf_sizes[MAX_BUFS]; /* size in dwords */ uint32_t buf_addr_regs[MAX_BUFS]; + uint32_t *buf_init_data[MAX_BUFS]; /* filled in by frontend before launching grid: */ struct fd_bo *bufs[MAX_BUFS]; diff --git a/src/freedreno/ir3/ir3_assembler.h b/src/freedreno/ir3/ir3_assembler.h index 6d7a71900e9..8b3779c6d6a 100644 --- a/src/freedreno/ir3/ir3_assembler.h +++ b/src/freedreno/ir3/ir3_assembler.h @@ -37,6 +37,8 @@ struct ir3_kernel_info { uint32_t num_bufs; uint32_t buf_sizes[MAX_BUFS]; /* size in dwords */ uint32_t buf_addr_regs[MAX_BUFS]; + uint32_t *buf_init_data[MAX_BUFS]; + uint32_t buf_init_data_sizes[MAX_BUFS]; uint64_t shader_print_buffer_iova; diff --git a/src/freedreno/ir3/ir3_parser.y b/src/freedreno/ir3/ir3_parser.y index 6549e4bbe56..f16fe903432 100644 --- a/src/freedreno/ir3/ir3_parser.y +++ b/src/freedreno/ir3/ir3_parser.y @@ -236,6 +236,21 @@ static void add_const(unsigned reg, unsigned c0, unsigned c1, unsigned c2, unsig const_state->immediates[idx * 4 + 3] = c3; } +static void add_buf_init_val(uint32_t val) +{ + assert(info->num_bufs > 0); + unsigned idx = info->num_bufs - 1; + + if (!info->buf_init_data[idx]) { + unsigned sz = info->buf_sizes[idx] * 4; + info->buf_init_data[idx] = malloc(sz); + memset(info->buf_init_data[idx], 0, sz); + } + + assert(info->buf_init_data_sizes[idx] < info->buf_sizes[idx]); + info->buf_init_data[idx][info->buf_init_data_sizes[idx]++] = val; +} + static void add_sysval(unsigned reg, unsigned compmask, gl_system_value sysval) { unsigned n = variant->inputs_count++; @@ -752,6 +767,11 @@ const_header: T_A_CONST '(' T_CONSTANT ')' const_val ',' const_val ',' cons add_const($3, $5, $7, $9, $11); } +buf_header_init_val: const_val { add_buf_init_val($1); } +buf_header_init_vals: buf_header_init_val +| buf_header_init_val ',' buf_header_init_vals +| + buf_header_addr_reg: '(' T_CONSTANT ')' { assert(($2 & 0x1) == 0); /* half-reg not allowed */ @@ -767,7 +787,7 @@ buf_header: T_A_BUF const_val { int idx = info->num_bufs++; assert(idx < MAX_BUFS); info->buf_sizes[idx] = $2; -} buf_header_addr_reg +} buf_header_addr_reg buf_header_init_vals invocationid_header: T_A_INVOCATIONID '(' T_REGISTER ')' { assert(($3 & 0x1) == 0); /* half-reg not allowed */