panvk/bifrost: Fix YCbCr texture/sampler array indexing

When the number of planes per descriptor is greater than one, the layout
used on Bifrost doesn't work. Fix that by making sure all plane
descriptors are contiguous in the texture/sampler table.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Eric R. Smith <eric.smith@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38145>
This commit is contained in:
Boris Brezillon
2025-11-25 20:10:27 +01:00
committed by Marge Bot
parent e1a0f2260b
commit 3f021404eb
2 changed files with 40 additions and 23 deletions

View File

@@ -60,7 +60,7 @@ panvk_image_view_plane_index(struct panvk_image_view *view)
* stencil, and if it's not the stencil component the caller wants, it
* has to be the depth.
*/
if (vk_format_get_blocksize(view->vk.view_format))
if (vk_format_get_blocksize(view->vk.view_format) == 1)
return panvk_plane_index(image, VK_IMAGE_ASPECT_STENCIL_BIT);
else
return panvk_plane_index(image, VK_IMAGE_ASPECT_DEPTH_BIT);

View File

@@ -113,8 +113,8 @@ struct desc_id {
struct {
uint32_t binding;
uint32_t set : 4;
uint32_t subdesc : 3;
uint32_t pad : 25;
uint32_t sampler_subdesc : 1;
uint32_t pad : 27;
};
uint64_t ht_key;
};
@@ -124,13 +124,12 @@ struct desc_id {
static enum panvk_bifrost_desc_table_type
desc_type_to_table_type(
const struct panvk_descriptor_set_binding_layout *binding_layout,
unsigned subdesc_idx)
bool sampler_subdesc)
{
switch (binding_layout->type) {
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
return subdesc_idx >= MAX2(1, binding_layout->textures_per_desc)
? PANVK_BIFROST_DESC_TABLE_SAMPLER
: PANVK_BIFROST_DESC_TABLE_TEXTURE;
return sampler_subdesc ? PANVK_BIFROST_DESC_TABLE_SAMPLER
: PANVK_BIFROST_DESC_TABLE_TEXTURE;
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
@@ -172,7 +171,7 @@ shader_desc_idx(uint32_t set, uint32_t binding,
struct desc_id src = {
.set = set,
.subdesc = subdesc_idx,
.sampler_subdesc = subdesc.type == VK_DESCRIPTOR_TYPE_SAMPLER,
.binding = binding,
};
uint32_t *entry =
@@ -188,7 +187,7 @@ shader_desc_idx(uint32_t set, uint32_t binding,
} else if (bind_layout->type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) {
map = &ctx->desc_info.dyn_ssbos;
} else {
uint32_t table = desc_type_to_table_type(bind_layout, src.subdesc);
uint32_t table = desc_type_to_table_type(bind_layout, src.sampler_subdesc);
assert(table < PANVK_BIFROST_DESC_TABLE_COUNT);
map = &ctx->desc_info.others[table];
@@ -204,8 +203,16 @@ shader_desc_idx(uint32_t set, uint32_t binding,
#if PAN_ARCH < 9
/* Adjust the destination index for all dynamic UBOs, which are laid out
* just after the regular UBOs in the UBO table. */
if (bind_layout->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC)
if (bind_layout->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) {
idx += ctx->desc_info.others[PANVK_BIFROST_DESC_TABLE_UBO].count;
} else if (subdesc.type == VK_DESCRIPTOR_TYPE_SAMPLER) {
/* the Cb/Cr planes share the same sampler, so in a 3 plane arrangement
* the number of planes can exceed the number of samplers */
idx += MIN2(subdesc.plane, bind_layout->samplers_per_desc - 1);
} else if (subdesc.type == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) {
assert(subdesc.plane < bind_layout->textures_per_desc);
idx += subdesc.plane;
}
#else
/* Dynamic buffers are pushed directly in the resource tables, after all
* sets. */
@@ -731,22 +738,25 @@ load_img_samples(nir_builder *b, nir_deref_instr *deref,
static uint32_t
get_desc_array_stride(const struct panvk_descriptor_set_binding_layout *layout,
VkDescriptorType type)
VkDescriptorType subtype)
{
if (PAN_ARCH >= 9)
return panvk_get_desc_stride(layout);
if (layout->type != VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
return 1;
/* On Bifrost, descriptors are copied from the sets to the final
* descriptor tables which are per-type. For combined image-sampler,
* the stride is {textures/samplers}_per_desc in this context;
* otherwise the stride is one. */
switch(type) {
switch(subtype) {
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
return layout->textures_per_desc;
case VK_DESCRIPTOR_TYPE_SAMPLER:
return layout->samplers_per_desc;
default:
return 1;
UNREACHABLE("Invalid subtype");
}
}
@@ -840,7 +850,7 @@ lower_tex(nir_builder *b, nir_tex_instr *tex, const struct lower_desc_ctx *ctx)
const struct panvk_descriptor_set_binding_layout *bind_layout =
&set_layout->bindings[binding];
struct panvk_subdesc_info subdesc =
get_tex_subdesc_info(bind_layout->type, plane);
get_tex_subdesc_info(bind_layout->type, plane);
uint32_t desc_stride = get_desc_array_stride(bind_layout, subdesc.type);
uint32_t texture_index = shader_desc_idx(set, binding, subdesc, ctx) + index_imm * desc_stride;
@@ -1200,7 +1210,7 @@ record_binding(struct lower_desc_ctx *ctx, unsigned set, unsigned binding,
struct desc_id src = {
.set = set,
.subdesc = subdesc_idx,
.sampler_subdesc = subdesc.type == VK_DESCRIPTOR_TYPE_SAMPLER,
.binding = binding,
};
uint32_t *entry = _mesa_hash_table_u64_search(ctx->ht, src.ht_key);
@@ -1226,10 +1236,11 @@ record_binding(struct lower_desc_ctx *ctx, unsigned set, unsigned binding,
ctx->desc_info.dyn_ssbos.count += desc_count_diff;
} else {
uint32_t table =
desc_type_to_table_type(binding_layout, subdesc_idx);
desc_type_to_table_type(binding_layout, src.sampler_subdesc);
assert(table < PANVK_BIFROST_DESC_TABLE_COUNT);
ctx->desc_info.others[table].count += desc_count_diff;
ctx->desc_info.others[table].count +=
desc_count_diff * get_desc_array_stride(binding_layout, subdesc.type);
}
#else
ctx->desc_info.dyn_bufs.count += desc_count_diff;
@@ -1238,7 +1249,7 @@ record_binding(struct lower_desc_ctx *ctx, unsigned set, unsigned binding,
static uint32_t *
fill_copy_descs_for_binding(struct lower_desc_ctx *ctx, unsigned set,
unsigned binding, uint32_t subdesc_idx,
unsigned binding, bool sampler_subdesc,
uint32_t desc_count)
{
assert(desc_count);
@@ -1247,13 +1258,14 @@ fill_copy_descs_for_binding(struct lower_desc_ctx *ctx, unsigned set,
const struct panvk_descriptor_set_binding_layout *binding_layout =
&set_layout->bindings[binding];
uint32_t desc_stride = panvk_get_desc_stride(binding_layout);
uint32_t subdesc_offset = sampler_subdesc ? binding_layout->textures_per_desc : 0;
uint32_t *first_entry = NULL;
assert(desc_count <= binding_layout->desc_count);
for (uint32_t i = 0; i < desc_count; i++) {
uint32_t src_idx =
binding_layout->desc_idx + (i * desc_stride) + subdesc_idx;
binding_layout->desc_idx + (i * desc_stride) + subdesc_offset;
struct panvk_shader_desc_map *map;
#if PAN_ARCH < 9
@@ -1264,7 +1276,7 @@ fill_copy_descs_for_binding(struct lower_desc_ctx *ctx, unsigned set,
map = &ctx->desc_info.dyn_ssbos;
} else {
uint32_t dst_table =
desc_type_to_table_type(binding_layout, subdesc_idx);
desc_type_to_table_type(binding_layout, sampler_subdesc);
assert(dst_table < PANVK_BIFROST_DESC_TABLE_COUNT);
map = &ctx->desc_info.others[dst_table];
@@ -1276,7 +1288,12 @@ fill_copy_descs_for_binding(struct lower_desc_ctx *ctx, unsigned set,
if (!first_entry)
first_entry = &map->map[map->count];
map->map[map->count++] = COPY_DESC_HANDLE(set, src_idx);
uint32_t desc_array_stride = get_desc_array_stride(
binding_layout, sampler_subdesc ? VK_DESCRIPTOR_TYPE_SAMPLER
: VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
for (uint32_t j = 0; j < desc_array_stride; j++)
map->map[map->count++] = COPY_DESC_HANDLE(set, src_idx + j);
}
return first_entry;
@@ -1352,8 +1369,8 @@ create_copy_table(nir_shader *nir, struct lower_desc_ctx *ctx)
/* Until now, we were just using the hash table to track descriptors
* count, but after that point, it's a <set,binding> -> <table_index>
* map. */
void *new_data = fill_copy_descs_for_binding(ctx, src.set, src.binding,
src.subdesc, desc_count);
void *new_data = fill_copy_descs_for_binding(
ctx, src.set, src.binding, src.sampler_subdesc, desc_count);
_mesa_hash_table_u64_replace(ctx->ht, &he, new_data);
}
}