nvk: Use different descriptor layouts for storage vs. sampled images

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28159>
This commit is contained in:
Faith Ekstrand 2024-03-12 11:55:56 -05:00 committed by Marge Bot
parent 86a462fb96
commit 357720c5a7
4 changed files with 104 additions and 42 deletions

View file

@ -49,33 +49,23 @@ write_desc(struct nvk_descriptor_set *set, uint32_t binding, uint32_t elem,
}
static void
write_image_view_desc(struct nvk_descriptor_set *set,
const VkDescriptorImageInfo *const info,
uint32_t binding, uint32_t elem,
VkDescriptorType descriptor_type)
write_sampled_image_view_desc(struct nvk_descriptor_set *set,
const VkDescriptorImageInfo *const info,
uint32_t binding, uint32_t elem,
VkDescriptorType descriptor_type)
{
struct nvk_image_descriptor desc[3] = { };
struct nvk_sampled_image_descriptor desc[3] = { };
uint8_t plane_count = 1;
if (descriptor_type != VK_DESCRIPTOR_TYPE_SAMPLER &&
info && info->imageView != VK_NULL_HANDLE) {
VK_FROM_HANDLE(nvk_image_view, view, info->imageView);
plane_count = view->plane_count;
if (descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) {
/* Storage images are always single plane */
assert(plane_count == 1);
uint8_t plane = 0;
assert(view->planes[plane].storage_desc_index > 0);
assert(view->planes[plane].storage_desc_index < (1 << 20));
desc[plane].image_index = view->planes[plane].storage_desc_index;
} else {
for (uint8_t plane = 0; plane < plane_count; plane++) {
assert(view->planes[plane].sampled_desc_index > 0);
assert(view->planes[plane].sampled_desc_index < (1 << 20));
desc[plane].image_index = view->planes[plane].sampled_desc_index;
}
for (uint8_t plane = 0; plane < plane_count; plane++) {
assert(view->planes[plane].sampled_desc_index > 0);
assert(view->planes[plane].sampled_desc_index < (1 << 20));
desc[plane].image_index = view->planes[plane].sampled_desc_index;
}
}
@ -106,6 +96,29 @@ write_image_view_desc(struct nvk_descriptor_set *set,
write_desc(set, binding, elem, desc, sizeof(desc[0]) * plane_count);
}
static void
write_storage_image_view_desc(struct nvk_descriptor_set *set,
const VkDescriptorImageInfo *const info,
uint32_t binding, uint32_t elem)
{
struct nvk_storage_image_descriptor desc = { };
if (info && info->imageView != VK_NULL_HANDLE) {
VK_FROM_HANDLE(nvk_image_view, view, info->imageView);
/* Storage images are always single plane */
assert(view->plane_count == 1);
uint8_t plane = 0;
assert(view->planes[plane].storage_desc_index > 0);
assert(view->planes[plane].storage_desc_index < (1 << 20));
desc.image_index = view->planes[plane].storage_desc_index;
}
write_desc(set, binding, elem, &desc, sizeof(desc));
}
static void
write_buffer_desc(struct nvk_descriptor_set *set,
const VkDescriptorBufferInfo *const info,
@ -150,7 +163,7 @@ write_buffer_view_desc(struct nvk_descriptor_set *set,
const VkBufferView bufferView,
uint32_t binding, uint32_t elem)
{
struct nvk_image_descriptor desc = { };
struct nvk_buffer_view_descriptor desc = { };
if (bufferView != VK_NULL_HANDLE) {
VK_FROM_HANDLE(nvk_buffer_view, view, bufferView);
@ -184,13 +197,20 @@ nvk_UpdateDescriptorSets(VkDevice device,
case VK_DESCRIPTOR_TYPE_SAMPLER:
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
for (uint32_t j = 0; j < write->descriptorCount; j++) {
write_image_view_desc(set, write->pImageInfo + j,
write->dstBinding,
write->dstArrayElement + j,
write->descriptorType);
write_sampled_image_view_desc(set, write->pImageInfo + j,
write->dstBinding,
write->dstArrayElement + j,
write->descriptorType);
}
break;
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
for (uint32_t j = 0; j < write->descriptorCount; j++) {
write_storage_image_view_desc(set, write->pImageInfo + j,
write->dstBinding,
write->dstArrayElement + j);
}
break;
@ -299,13 +319,20 @@ nvk_push_descriptor_set_update(struct nvk_push_descriptor_set *push_set,
case VK_DESCRIPTOR_TYPE_SAMPLER:
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
for (uint32_t j = 0; j < write->descriptorCount; j++) {
write_image_view_desc(&set, write->pImageInfo + j,
write->dstBinding,
write->dstArrayElement + j,
write->descriptorType);
write_sampled_image_view_desc(&set, write->pImageInfo + j,
write->dstBinding,
write->dstArrayElement + j,
write->descriptorType);
}
break;
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
for (uint32_t j = 0; j < write->descriptorCount; j++) {
write_storage_image_view_desc(&set, write->pImageInfo + j,
write->dstBinding,
write->dstArrayElement + j);
}
break;
@ -516,8 +543,10 @@ nvk_descriptor_set_create(struct nvk_device *dev,
VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT)
array_size = variable_count;
for (uint32_t j = 0; j < array_size; j++)
write_image_view_desc(set, NULL, b, j, layout->binding[b].type);
for (uint32_t j = 0; j < array_size; j++) {
write_sampled_image_view_desc(set, NULL, b, j,
layout->binding[b].type);
}
}
*out_set = set;
@ -632,16 +661,26 @@ nvk_descriptor_set_write_template(struct nvk_descriptor_set *set,
case VK_DESCRIPTOR_TYPE_SAMPLER:
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
for (uint32_t j = 0; j < entry->array_count; j++) {
const VkDescriptorImageInfo *info =
data + entry->offset + j * entry->stride;
write_image_view_desc(set, info,
entry->binding,
entry->array_element + j,
entry->type);
write_sampled_image_view_desc(set, info,
entry->binding,
entry->array_element + j,
entry->type);
}
break;
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
for (uint32_t j = 0; j < entry->array_count; j++) {
const VkDescriptorImageInfo *info =
data + entry->offset + j * entry->stride;
write_storage_image_view_desc(set, info,
entry->binding,
entry->array_element + j);
}
break;

View file

@ -17,10 +17,26 @@ struct nvk_descriptor_set_layout;
#define NVK_IMAGE_DESCRIPTOR_IMAGE_INDEX_MASK 0x000fffff
#define NVK_IMAGE_DESCRIPTOR_SAMPLER_INDEX_MASK 0xfff00000
struct nvk_image_descriptor {
struct nvk_sampled_image_descriptor {
unsigned image_index:20;
unsigned sampler_index:12;
};
static_assert(sizeof(struct nvk_sampled_image_descriptor) == 4,
"nvk_sampled_image_descriptor has no holes");
struct nvk_storage_image_descriptor {
unsigned image_index:20;
unsigned pad:12;
};
static_assert(sizeof(struct nvk_storage_image_descriptor) == 4,
"nvk_storage_image_descriptor has no holes");
struct nvk_buffer_view_descriptor {
unsigned image_index:20;
unsigned pad:12;
};
static_assert(sizeof(struct nvk_buffer_view_descriptor) == 4,
"nvk_buffer_view_descriptor has no holes");
/* This has to match nir_address_format_64bit_bounded_global */
struct nvk_buffer_address {

View file

@ -36,11 +36,17 @@ nvk_descriptor_stride_align_for_type(const struct nvk_physical_device *pdev,
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
/* TODO: How do samplers work? */
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
*stride = *alignment = sizeof(struct nvk_sampled_image_descriptor);
break;
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
*stride = *alignment = sizeof(struct nvk_storage_image_descriptor);
break;
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
*stride = *alignment = sizeof(struct nvk_image_descriptor);
*stride = *alignment = sizeof(struct nvk_buffer_view_descriptor);
break;
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:

View file

@ -921,7 +921,8 @@ lower_tex(nir_builder *b, nir_tex_instr *tex,
nir_def *plane_ssa = nir_steal_tex_src(tex, nir_tex_src_plane);
const uint32_t plane =
plane_ssa ? nir_src_as_uint(nir_src_for_ssa(plane_ssa)) : 0;
const uint64_t plane_offset_B = plane * sizeof(struct nvk_image_descriptor);
const uint64_t plane_offset_B =
plane * sizeof(struct nvk_sampled_image_descriptor);
nir_def *combined_handle;
if (texture == sampler) {