mesa/src/panfrost/vulkan/panvk_vX_cmd_dispatch.c
Faith Ekstrand cbd0c9eb3b panvk: Add a panvk_common_sysvals struct
For geometry shaders, we're going to need to compile various graphics
shaders down to compute shaders.  This means that they'll look like
compute shaders to much of the compile pipeline but ultimately get
executed as graphics shaders.  Most of the time, the compiler will just
happily take whatever offset you give and try to load the sysval from
there so you can load a graphics sysval from a compute shader just fine.
However, for the common ones, we switch on the shader stage and load
from a different offset for 3D vs. compute.  This breaks the moment you
have a compute shader that's going to actually load from a 3D sysval
space.

The solution here is to ensure that any common sysvals (currently just
the push uniforms address and the printf buffer) are at exactly the same
offset in both.  This is done by adding a panvk_common_sysvals struct,
some static asserts, and a bit of macro magic to keep things eurgonamic.
This also changes push uniform upload to just swap in the push uniform
address instead of writing it to the command buffer on every iteration.

Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38508>
2025-11-19 23:10:41 +00:00

71 lines
2.6 KiB
C

/*
* Copyright © 2024 Collabora Ltd.
* Copyright © 2024 Arm Ltd.
*
* SPDX-License-Identifier: MIT
*/
#include "panvk_cmd_buffer.h"
#include "panvk_cmd_dispatch.h"
void
panvk_per_arch(cmd_prepare_dispatch_sysvals)(
struct panvk_cmd_buffer *cmdbuf, const struct panvk_dispatch_info *info)
{
const struct panvk_shader_variant *cs =
panvk_shader_only_variant(cmdbuf->state.compute.shader);
BITSET_DECLARE(dirty_sysvals, MAX_SYSVAL_FAUS) = {0};
/* In indirect case, some sysvals are read from the indirect dispatch
* buffer.
*/
if (info->indirect.buffer_dev_addr == 0) {
set_compute_sysval(cmdbuf, dirty_sysvals, num_work_groups.x,
info->direct.wg_count.x);
set_compute_sysval(cmdbuf, dirty_sysvals, num_work_groups.y,
info->direct.wg_count.y);
set_compute_sysval(cmdbuf, dirty_sysvals, num_work_groups.z,
info->direct.wg_count.z);
} else {
BITSET_SET_RANGE(dirty_sysvals,
sysval_fau_start(compute, num_work_groups),
sysval_fau_end(compute, num_work_groups));
}
set_compute_sysval(cmdbuf, dirty_sysvals, base.x, info->wg_base.x);
set_compute_sysval(cmdbuf, dirty_sysvals, base.y, info->wg_base.y);
set_compute_sysval(cmdbuf, dirty_sysvals, base.z, info->wg_base.z);
set_compute_sysval(cmdbuf, dirty_sysvals, local_group_size.x,
cs->cs.local_size.x);
set_compute_sysval(cmdbuf, dirty_sysvals, local_group_size.y,
cs->cs.local_size.y);
set_compute_sysval(cmdbuf, dirty_sysvals, local_group_size.z,
cs->cs.local_size.z);
#if PAN_ARCH < 9
struct panvk_descriptor_state *desc_state =
&cmdbuf->state.compute.desc_state;
struct panvk_shader_desc_state *cs_desc_state =
&cmdbuf->state.compute.cs.desc;
if (compute_state_dirty(cmdbuf, CS) ||
compute_state_dirty(cmdbuf, DESC_STATE)) {
set_compute_sysval(cmdbuf, dirty_sysvals,
desc.sets[PANVK_DESC_TABLE_CS_DYN_SSBOS],
cs_desc_state->dyn_ssbos);
}
for (uint32_t i = 0; i < MAX_SETS; i++) {
if (cs->desc_info.used_set_mask & BITFIELD_BIT(i)) {
set_compute_sysval(cmdbuf, dirty_sysvals, desc.sets[i],
desc_state->sets[i]->descs.dev);
}
}
#endif
/* Dirty push_uniforms if the used_sysvals/dirty_sysvals overlap. */
BITSET_AND(dirty_sysvals, dirty_sysvals, cs->fau.used_sysvals);
if (!BITSET_IS_EMPTY(dirty_sysvals))
compute_state_set_dirty(cmdbuf, PUSH_UNIFORMS);
}