freedreno/computerator: pass iova of buffer to const register
The syntax is: @buf 32 (c2.x) The "(c2.x)" is optional. This makes possible to test stg, ldg, and global atomics. Signed-off-by: Danylo Piliaiev <dpiliaiev@igalia.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11431>
This commit is contained in:
parent
e791b2045a
commit
ba1c989348
|
@ -14,9 +14,10 @@ Headers
|
|||
The shader assembly can be prefixed with headers to control state setup:
|
||||
|
||||
* ``@localsize X, Y, Z`` - configures local workgroup size
|
||||
* ``@buf SZ`` - configures an SSBO of the specified size (in dwords).
|
||||
* ``@buf SZ (cN.c)`` - configures an SSBO of the specified size (in dwords).
|
||||
The order of the ``@buf`` headers determines the index, ie the first
|
||||
``@buf`` header is ``g[0]``, the second ``g[1]``, and so on
|
||||
``@buf`` header is ``g[0]``, the second ``g[1]``, and so on.
|
||||
The iova of the buffer is written as a vec2 to ``cN.c``
|
||||
* ``@const(cN.c)`` configures a const vec4 starting at specified
|
||||
const register, ie ``@const(c1.x) 1.0, 2.0, 3.0, 4.0`` will populate
|
||||
``c1.xyzw`` with ``vec4(1.0, 2.0, 3.0, 4.0)``
|
||||
|
|
|
@ -232,6 +232,18 @@ cs_const_emit(struct fd_ringbuffer *ring, struct kernel *kernel,
|
|||
const_state->immediates[idx * 4 + 2] = grid[2];
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_BUFS; i++) {
|
||||
if (kernel->buf_addr_regs[i] != INVALID_REG) {
|
||||
assert((kernel->buf_addr_regs[i] & 0x3) == 0);
|
||||
int idx = kernel->buf_addr_regs[i] >> 2;
|
||||
|
||||
uint64_t iova = fd_bo_get_iova(kernel->bufs[i]);
|
||||
|
||||
const_state->immediates[idx * 4 + 1] = iova >> 32;
|
||||
const_state->immediates[idx * 4 + 0] = (iova << 32) >> 32;
|
||||
}
|
||||
}
|
||||
|
||||
/* truncate size to avoid writing constants that shader
|
||||
* does not use:
|
||||
*/
|
||||
|
|
|
@ -46,6 +46,8 @@ ir3_asm_assemble(struct ir3_compiler *c, FILE *in)
|
|||
kernel->base.num_bufs = kernel->info.num_bufs;
|
||||
memcpy(kernel->base.buf_sizes, kernel->info.buf_sizes,
|
||||
sizeof(kernel->base.buf_sizes));
|
||||
memcpy(kernel->base.buf_addr_regs, kernel->info.buf_addr_regs,
|
||||
sizeof(kernel->base.buf_addr_regs));
|
||||
|
||||
unsigned sz = v->info.size;
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ struct kernel {
|
|||
uint32_t local_size[3];
|
||||
uint32_t num_bufs;
|
||||
uint32_t buf_sizes[MAX_BUFS]; /* size in dwords */
|
||||
uint32_t buf_addr_regs[MAX_BUFS];
|
||||
|
||||
/* filled in by frontend before launching grid: */
|
||||
struct fd_bo *bufs[MAX_BUFS];
|
||||
|
|
|
@ -47,6 +47,10 @@ ir3_parse_asm(struct ir3_compiler *c, struct ir3_kernel_info *info, FILE *in)
|
|||
|
||||
info->numwg = INVALID_REG;
|
||||
|
||||
for (int i = 0; i < MAX_BUFS; i++) {
|
||||
info->buf_addr_regs[i] = INVALID_REG;
|
||||
}
|
||||
|
||||
/* Provide a default local_size in case the shader doesn't set it, so that
|
||||
* we don't crash at least.
|
||||
*/
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
struct ir3_kernel_info {
|
||||
uint32_t num_bufs;
|
||||
uint32_t buf_sizes[MAX_BUFS]; /* size in dwords */
|
||||
uint32_t buf_addr_regs[MAX_BUFS];
|
||||
|
||||
/* driver-param uniforms: */
|
||||
unsigned numwg;
|
||||
|
|
|
@ -667,11 +667,21 @@ const_header: T_A_CONST '(' T_CONSTANT ')' const_val ',' const_val ',' cons
|
|||
add_const($3, $5, $7, $9, $11);
|
||||
}
|
||||
|
||||
buf_header_addr_reg:
|
||||
| '(' T_CONSTANT ')' {
|
||||
assert(($2 & 0x1) == 0); /* half-reg not allowed */
|
||||
unsigned reg = $2 >> 1;
|
||||
|
||||
info->buf_addr_regs[info->num_bufs - 1] = reg;
|
||||
/* reserve space in immediates for the actual value to be plugged in later: */
|
||||
add_const($2, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
invocationid_header: T_A_INVOCATIONID '(' T_REGISTER ')' {
|
||||
assert(($3 & 0x1) == 0); /* half-reg not allowed */
|
||||
|
|
Loading…
Reference in New Issue