panfrost, panvk: The size of resource tables needs to be a multiple of 4.

The HW specifications require the size of shader resource tables to be a
multiple of 4, otherwise correct behaviour is not guaranteed.

Fixes: 713f5c3600 ("panvk: Prepare the cmd_desc_state logic for Valhall")
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Lars-Ivar Hesselberg Simonsen <lars-ivar.simonsen@arm.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35553>
This commit is contained in:
Christopher Gautier 2025-06-16 15:06:18 +02:00 committed by Marge Bot
parent db4c878e4f
commit 48e8d6d207
10 changed files with 42 additions and 8 deletions

View file

@ -285,7 +285,8 @@ panfrost_emit_resources(struct panfrost_batch *batch,
{
struct panfrost_context *ctx = batch->ctx;
struct pan_ptr T;
unsigned nr_tables = PAN_NUM_RESOURCE_TABLES;
unsigned nr_tables =
ALIGN_POT(PAN_NUM_RESOURCE_TABLES, MALI_RESOURCE_TABLE_SIZE_ALIGNMENT);
/* Although individual resources need only 16 byte alignment, the
* resource table as a whole must be 64-byte aligned.

View file

@ -1090,7 +1090,8 @@ pan_preload_emit_dcd(struct pan_fb_preload_cache *cache, struct pan_pool *pool,
}
#else
struct pan_ptr T;
unsigned nr_tables = PAN_BLIT_NUM_RESOURCE_TABLES;
unsigned nr_tables = ALIGN_POT(PAN_BLIT_NUM_RESOURCE_TABLES,
MALI_RESOURCE_TABLE_SIZE_ALIGNMENT);
/* Although individual resources need only 16 byte alignment, the
* resource table as a whole must be 64-byte aligned.

View file

@ -1813,6 +1813,8 @@
<field name="Shader" start="10:0" size="64" type="address"/>
<field name="Thread storage" start="12:0" size="64" type="address"/>
<field name="FAU" start="14:0" size="64" type="address"/>
<value name="Mali resource table size alignment" value="4"/>
</struct>
<struct name="Compute size workgroup" size="4">

View file

@ -2177,6 +2177,8 @@
<field name="Fragment Shader" start="26:0" size="64" type="address"/>
<field name="Thread storage" start="28:0" size="64" type="address"/>
<field name="Fragment FAU" start="30:0" size="64" type="FAU Pointer"/>
<value name="Mali resource table size alignment" value="4"/>
</struct>
<struct name="Primitive Size" size="2">

View file

@ -2489,6 +2489,8 @@
<field name="Fragment Shader" start="26:0" size="64" type="address"/>
<field name="Thread storage" start="28:0" size="64" type="address"/>
<field name="Fragment FAU" start="30:0" size="64" type="FAU Pointer"/>
<value name="Mali resource table size alignment" value="4"/>
</struct>
</panxml>

View file

@ -1327,6 +1327,8 @@
<field name="Shader" start="10:0" size="64" type="address"/>
<field name="Thread storage" start="12:0" size="64" type="address"/>
<field name="FAU" start="14:0" size="64" type="address"/>
<value name="Mali resource table size alignment" value="4"/>
</struct>
<struct name="Compute Payload" size="24">

View file

@ -2476,7 +2476,7 @@ panvk_cmd_draw_indirect(struct panvk_cmd_buffer *cmdbuf,
uint32_t patch_attribs =
cmdbuf->state.gfx.vi.attribs_changing_on_base_instance;
uint32_t vs_res_table_size =
(util_last_bit(vs->desc_info.used_set_mask) + 1) * pan_size(RESOURCE);
panvk_shader_res_table_count(&cmdbuf->state.gfx.vs.desc);
bool patch_faus = shader_uses_sysval(vs, graphics, vs.first_vertex) ||
shader_uses_sysval(vs, graphics, vs.base_instance);
struct cs_index draw_params_addr = cs_scratch_reg64(b, 0);

View file

@ -41,6 +41,16 @@ struct panvk_shader_desc_state {
#endif
};
#if PAN_ARCH >= 9
static inline uint32_t
panvk_shader_res_table_count(struct panvk_shader_desc_state *shader_desc_state)
{
uint32_t count = (shader_desc_state->res_table & BITFIELD_MASK(6));
assert(count % MALI_RESOURCE_TABLE_SIZE_ALIGNMENT == 0);
return count;
}
#endif
struct panvk_push_set {
struct panvk_cmd_pool_obj base;
struct panvk_descriptor_set set;

View file

@ -282,7 +282,8 @@ panvk_per_arch(cmd_prepare_shader_res_table)(
}
uint32_t first_unused_set = util_last_bit(shader->desc_info.used_set_mask);
uint32_t res_count = 1 + first_unused_set;
uint32_t res_count =
ALIGN_POT(1 + first_unused_set, MALI_RESOURCE_TABLE_SIZE_ALIGNMENT);
struct pan_ptr ptr =
panvk_cmd_alloc_desc_array(cmdbuf, res_count * repeat_count, RESOURCE);
if (!ptr.gpu)
@ -317,8 +318,15 @@ panvk_per_arch(cmd_prepare_shader_res_table)(
}
}
}
for (uint32_t i = first_unused_set + 1; i < res_count; i++) {
pan_pack(&res_table[i], RESOURCE, cfg) {
cfg.address = 0;
cfg.contains_descriptors = false;
cfg.size = 0;
}
}
res_table += first_unused_set + 1;
res_table += res_count;
}
shader_desc_state->res_table = ptr.gpu | res_count;

View file

@ -588,9 +588,15 @@ cmd_emit_dcd(struct panvk_cmd_buffer *cmdbuf, struct pan_fb_info *fbinfo,
if (key->aspects == VK_IMAGE_ASPECT_COLOR_BIT)
fill_bds(fbinfo, key, bds.cpu);
struct pan_ptr res_table = panvk_cmd_alloc_desc(cmdbuf, RESOURCE);
/* Resource table sizes need to be multiples of 4. We use only one
* element here though.
*/
const uint32_t res_table_size = MALI_RESOURCE_TABLE_SIZE_ALIGNMENT;
struct pan_ptr res_table =
panvk_cmd_alloc_desc_array(cmdbuf, res_table_size, RESOURCE);
if (!res_table.cpu)
return VK_ERROR_OUT_OF_DEVICE_MEMORY;
memset(res_table.cpu, 0, pan_size(RESOURCE) * res_table_size);
pan_cast_and_pack(res_table.cpu, RESOURCE, cfg) {
cfg.address = descs.gpu;
@ -668,12 +674,12 @@ cmd_emit_dcd(struct panvk_cmd_buffer *cmdbuf, struct pan_fb_info *fbinfo,
cfg.flags_0.clean_fragment_write = true;
#if PAN_ARCH >= 12
cfg.fragment_resources = res_table.gpu | 1;
cfg.fragment_resources = res_table.gpu | res_table_size;
cfg.fragment_shader = panvk_priv_mem_dev_addr(shader->spd);
cfg.thread_storage = cmdbuf->state.gfx.tsd;
#else
cfg.maximum_z = 1.0;
cfg.shader.resources = res_table.gpu | 1;
cfg.shader.resources = res_table.gpu | res_table_size;
cfg.shader.shader = panvk_priv_mem_dev_addr(shader->spd);
cfg.shader.thread_storage = cmdbuf->state.gfx.tsd;
#endif