panvk: allow sysvals to be dynamically-indexed
We already do this for push constants, just extend the existing implementation. We need to update the push_consts sysval inside the cmd_prepare_push_uniforms loop now because indirect draws patch the sysvals. Previously this value was only used to read push constant FAUs, so we didn't care. Signed-off-by: Olivia Lee <olivia.lee@collabora.com> Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> Acked-by: Erik Faye-Lund <erik.faye-lund@collabora.com> Reviewed-by: Lars-Ivar Hesselberg Simonsen <lars-ivar.simonsen@arm.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35408>
This commit is contained in:
@@ -104,7 +104,8 @@ struct panvk_graphics_sysvals {
|
||||
uint32_t noperspective_varyings;
|
||||
} vs;
|
||||
|
||||
aligned_u64 push_consts;
|
||||
/* Address of sysval/push constant buffer used for indirect loads */
|
||||
aligned_u64 push_uniforms;
|
||||
aligned_u64 printf_buffer_address;
|
||||
|
||||
struct panvk_input_attachment_info iam[INPUT_ATTACHMENT_MAP_SIZE];
|
||||
@@ -123,9 +124,9 @@ struct panvk_graphics_sysvals {
|
||||
|
||||
static_assert((sizeof(struct panvk_graphics_sysvals) % FAU_WORD_SIZE) == 0,
|
||||
"struct panvk_graphics_sysvals must be 8-byte aligned");
|
||||
static_assert((offsetof(struct panvk_graphics_sysvals, push_consts) %
|
||||
static_assert((offsetof(struct panvk_graphics_sysvals, push_uniforms) %
|
||||
FAU_WORD_SIZE) == 0,
|
||||
"panvk_graphics_sysvals::push_consts must be 8-byte aligned");
|
||||
"panvk_graphics_sysvals::push_uniforms must be 8-byte aligned");
|
||||
#if PAN_ARCH <= 7
|
||||
static_assert((offsetof(struct panvk_graphics_sysvals, desc) % FAU_WORD_SIZE) ==
|
||||
0,
|
||||
@@ -143,7 +144,8 @@ struct panvk_compute_sysvals {
|
||||
uint32_t x, y, z;
|
||||
} local_group_size;
|
||||
|
||||
aligned_u64 push_consts;
|
||||
/* Address of sysval/push constant buffer used for indirect loads */
|
||||
aligned_u64 push_uniforms;
|
||||
aligned_u64 printf_buffer_address;
|
||||
|
||||
#if PAN_ARCH <= 7
|
||||
@@ -155,9 +157,9 @@ struct panvk_compute_sysvals {
|
||||
|
||||
static_assert((sizeof(struct panvk_compute_sysvals) % FAU_WORD_SIZE) == 0,
|
||||
"struct panvk_compute_sysvals must be 8-byte aligned");
|
||||
static_assert((offsetof(struct panvk_compute_sysvals, push_consts) %
|
||||
static_assert((offsetof(struct panvk_compute_sysvals, push_uniforms) %
|
||||
FAU_WORD_SIZE) == 0,
|
||||
"panvk_compute_sysvals::push_consts must be 8-byte aligned");
|
||||
"panvk_compute_sysvals::push_uniforms must be 8-byte aligned");
|
||||
#if PAN_ARCH <= 7
|
||||
static_assert((offsetof(struct panvk_compute_sysvals, desc) % FAU_WORD_SIZE) ==
|
||||
0,
|
||||
@@ -241,11 +243,9 @@ static_assert((offsetof(struct panvk_compute_sysvals, desc) % FAU_WORD_SIZE) ==
|
||||
#define load_sysval_entry(__b, __ptype, __bitsz, __name, __dyn_idx) \
|
||||
nir_load_push_constant( \
|
||||
__b, sysval_entry_size(__ptype, __name) / ((__bitsz) / 8), __bitsz, \
|
||||
nir_iadd_imm( \
|
||||
__b, \
|
||||
nir_imul_imm(__b, __dyn_idx, sysval_entry_size(__ptype, __name)), \
|
||||
sysval_offset(__ptype, __name)), \
|
||||
.base = SYSVALS_PUSH_CONST_BASE)
|
||||
nir_imul_imm(__b, __dyn_idx, sysval_entry_size(__ptype, __name)), \
|
||||
.base = SYSVALS_PUSH_CONST_BASE + sysval_offset(__ptype, __name), \
|
||||
.range = sysval_size(__ptype, __name))
|
||||
|
||||
#if PAN_ARCH <= 7
|
||||
enum panvk_bifrost_desc_table_type {
|
||||
|
||||
@@ -47,14 +47,6 @@ panvk_per_arch(cmd_prepare_push_uniforms)(struct panvk_cmd_buffer *cmdbuf,
|
||||
if (!push_uniforms.gpu)
|
||||
return VK_ERROR_OUT_OF_DEVICE_MEMORY;
|
||||
|
||||
if (shader->vk.stage == MESA_SHADER_COMPUTE) {
|
||||
cmdbuf->state.compute.sysvals.push_consts =
|
||||
push_uniforms.gpu + (shader->fau.sysval_count * FAU_WORD_SIZE);
|
||||
} else {
|
||||
cmdbuf->state.gfx.sysvals.push_consts =
|
||||
push_uniforms.gpu + (shader->fau.sysval_count * FAU_WORD_SIZE);
|
||||
}
|
||||
|
||||
uint64_t *sysvals = shader->vk.stage == MESA_SHADER_COMPUTE
|
||||
? (uint64_t *)&cmdbuf->state.compute.sysvals
|
||||
: (uint64_t *)&cmdbuf->state.gfx.sysvals;
|
||||
@@ -63,6 +55,13 @@ panvk_per_arch(cmd_prepare_push_uniforms)(struct panvk_cmd_buffer *cmdbuf,
|
||||
uint32_t w, fau = 0;
|
||||
|
||||
for (uint32_t i = 0; i < repeat_count; i++) {
|
||||
uint64_t addr =
|
||||
push_uniforms.gpu + i * shader->fau.total_count * sizeof(uint64_t);
|
||||
if (shader->vk.stage == MESA_SHADER_COMPUTE)
|
||||
cmdbuf->state.compute.sysvals.push_uniforms = addr;
|
||||
else
|
||||
cmdbuf->state.gfx.sysvals.push_uniforms = addr;
|
||||
|
||||
/* After packing, the sysvals come first, followed by the user push
|
||||
* constants. The ordering is encoded shader side, so don't re-order
|
||||
* these loops. */
|
||||
|
||||
@@ -571,9 +571,6 @@ collect_push_constant(struct nir_builder *b, nir_intrinsic_instr *intr,
|
||||
bool is_sysval = base >= SYSVALS_PUSH_CONST_BASE;
|
||||
uint32_t offset, size;
|
||||
|
||||
/* Sysvals should have a constant offset. */
|
||||
assert(!is_sysval || nir_src_is_const(intr->src[0]));
|
||||
|
||||
if (is_sysval)
|
||||
base -= SYSVALS_PUSH_CONST_BASE;
|
||||
|
||||
@@ -583,11 +580,12 @@ collect_push_constant(struct nir_builder *b, nir_intrinsic_instr *intr,
|
||||
offset = base;
|
||||
size = nir_intrinsic_range(intr);
|
||||
|
||||
/* Flag the push_consts sysval as needed if we have an indirect offset. */
|
||||
/* Flag the push_uniforms sysval as needed if we have an indirect offset.
|
||||
*/
|
||||
if (b->shader->info.stage == MESA_SHADER_COMPUTE)
|
||||
shader_use_sysval(shader, compute, push_consts);
|
||||
shader_use_sysval(shader, compute, push_uniforms);
|
||||
else
|
||||
shader_use_sysval(shader, graphics, push_consts);
|
||||
shader_use_sysval(shader, graphics, push_uniforms);
|
||||
} else {
|
||||
offset = base + nir_src_as_uint(intr->src[0]);
|
||||
size = (intr->def.bit_size / 8) * intr->def.num_components;
|
||||
@@ -614,9 +612,6 @@ move_push_constant(struct nir_builder *b, nir_intrinsic_instr *intr, void *data)
|
||||
if (is_sysval)
|
||||
base -= SYSVALS_PUSH_CONST_BASE;
|
||||
|
||||
/* Sysvals should have a constant offset. */
|
||||
assert(!is_sysval || nir_src_is_const(intr->src[0]));
|
||||
|
||||
b->cursor = nir_before_instr(&intr->instr);
|
||||
|
||||
if (nir_src_is_const(intr->src[0])) {
|
||||
@@ -642,12 +637,13 @@ move_push_constant(struct nir_builder *b, nir_intrinsic_instr *intr, void *data)
|
||||
* zero in this pass. */
|
||||
unsigned push_const_buf_offset = shader_remapped_sysval_offset(
|
||||
shader, b->shader->info.stage == MESA_SHADER_COMPUTE
|
||||
? sysval_offset(compute, push_consts)
|
||||
: sysval_offset(graphics, push_consts));
|
||||
? sysval_offset(compute, push_uniforms)
|
||||
: sysval_offset(graphics, push_uniforms));
|
||||
nir_def *push_const_buf = nir_load_push_constant(
|
||||
b, 1, 64, nir_imm_int(b, push_const_buf_offset));
|
||||
unsigned push_const_offset =
|
||||
shader_remapped_fau_offset(shader, push_consts, base);
|
||||
unsigned push_const_offset = is_sysval ?
|
||||
shader_remapped_sysval_offset(shader, base) :
|
||||
shader_remapped_push_const_offset(shader, base);
|
||||
nir_def *offset = nir_iadd_imm(b, intr->src[0].ssa, push_const_offset);
|
||||
unsigned align = nir_combined_align(nir_intrinsic_align_mul(intr),
|
||||
nir_intrinsic_align_offset(intr));
|
||||
|
||||
Reference in New Issue
Block a user