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 panfrost_context *ctx = batch->ctx;
struct pan_ptr T; 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 /* Although individual resources need only 16 byte alignment, the
* resource table as a whole must be 64-byte aligned. * 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 #else
struct pan_ptr T; 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 /* Although individual resources need only 16 byte alignment, the
* resource table as a whole must be 64-byte aligned. * 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="Shader" start="10:0" size="64" type="address"/>
<field name="Thread storage" start="12: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"/> <field name="FAU" start="14:0" size="64" type="address"/>
<value name="Mali resource table size alignment" value="4"/>
</struct> </struct>
<struct name="Compute size workgroup" size="4"> <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="Fragment Shader" start="26:0" size="64" type="address"/>
<field name="Thread storage" start="28: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"/> <field name="Fragment FAU" start="30:0" size="64" type="FAU Pointer"/>
<value name="Mali resource table size alignment" value="4"/>
</struct> </struct>
<struct name="Primitive Size" size="2"> <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="Fragment Shader" start="26:0" size="64" type="address"/>
<field name="Thread storage" start="28: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"/> <field name="Fragment FAU" start="30:0" size="64" type="FAU Pointer"/>
<value name="Mali resource table size alignment" value="4"/>
</struct> </struct>
</panxml> </panxml>

View file

@ -1327,6 +1327,8 @@
<field name="Shader" start="10:0" size="64" type="address"/> <field name="Shader" start="10:0" size="64" type="address"/>
<field name="Thread storage" start="12: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"/> <field name="FAU" start="14:0" size="64" type="address"/>
<value name="Mali resource table size alignment" value="4"/>
</struct> </struct>
<struct name="Compute Payload" size="24"> <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 = uint32_t patch_attribs =
cmdbuf->state.gfx.vi.attribs_changing_on_base_instance; cmdbuf->state.gfx.vi.attribs_changing_on_base_instance;
uint32_t vs_res_table_size = 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) || bool patch_faus = shader_uses_sysval(vs, graphics, vs.first_vertex) ||
shader_uses_sysval(vs, graphics, vs.base_instance); shader_uses_sysval(vs, graphics, vs.base_instance);
struct cs_index draw_params_addr = cs_scratch_reg64(b, 0); struct cs_index draw_params_addr = cs_scratch_reg64(b, 0);

View file

@ -41,6 +41,16 @@ struct panvk_shader_desc_state {
#endif #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_push_set {
struct panvk_cmd_pool_obj base; struct panvk_cmd_pool_obj base;
struct panvk_descriptor_set set; 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 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 = struct pan_ptr ptr =
panvk_cmd_alloc_desc_array(cmdbuf, res_count * repeat_count, RESOURCE); panvk_cmd_alloc_desc_array(cmdbuf, res_count * repeat_count, RESOURCE);
if (!ptr.gpu) 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; 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) if (key->aspects == VK_IMAGE_ASPECT_COLOR_BIT)
fill_bds(fbinfo, key, bds.cpu); 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) if (!res_table.cpu)
return VK_ERROR_OUT_OF_DEVICE_MEMORY; 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) { pan_cast_and_pack(res_table.cpu, RESOURCE, cfg) {
cfg.address = descs.gpu; 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; cfg.flags_0.clean_fragment_write = true;
#if PAN_ARCH >= 12 #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.fragment_shader = panvk_priv_mem_dev_addr(shader->spd);
cfg.thread_storage = cmdbuf->state.gfx.tsd; cfg.thread_storage = cmdbuf->state.gfx.tsd;
#else #else
cfg.maximum_z = 1.0; 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.shader = panvk_priv_mem_dev_addr(shader->spd);
cfg.shader.thread_storage = cmdbuf->state.gfx.tsd; cfg.shader.thread_storage = cmdbuf->state.gfx.tsd;
#endif #endif