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:
Olivia Lee
2025-06-04 00:49:53 -07:00
committed by Marge Bot
parent 7ca2d51cf6
commit a268412533
3 changed files with 27 additions and 32 deletions
+11 -11
View File
@@ -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. */
+9 -13
View File
@@ -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));