nvk: Use nil_su_info for image descriptors on Kepler

Reviewed-by: Faith Ekstrand <faith.ekstrand@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34975>
This commit is contained in:
Lorenzo Rossi 2025-04-18 12:23:44 -05:00 committed by Marge Bot
parent e5d4c4934d
commit bb3f4b86bf
8 changed files with 186 additions and 75 deletions

View file

@ -67,22 +67,33 @@ nvk_CreateBufferView(VkDevice _device,
nvk_edb_bview_cache_get_descriptor(dev, &dev->edb_bview_cache,
addr, view->vk.range, format);
} else {
uint32_t desc[8];
nil_buffer_fill_tic(&pdev->info, addr, nil_format(format),
view->vk.elements, &desc);
if (pdev->info.cls_eng3d >= MAXWELL_A ||
(buffer->vk.usage & VK_BUFFER_USAGE_2_UNIFORM_TEXEL_BUFFER_BIT_KHR)) {
uint32_t desc[8];
nil_buffer_fill_tic(&pdev->info, addr, nil_format(format),
view->vk.elements, &desc);
uint32_t desc_index;
result = nvk_descriptor_table_add(dev, &dev->images,
desc, sizeof(desc),
&desc_index);
if (result != VK_SUCCESS) {
vk_buffer_view_destroy(&dev->vk, pAllocator, &view->vk);
return result;
uint32_t desc_index;
result = nvk_descriptor_table_add(dev, &dev->images,
desc, sizeof(desc),
&desc_index);
if (result != VK_SUCCESS) {
vk_buffer_view_destroy(&dev->vk, pAllocator, &view->vk);
return result;
}
view->desc = (struct nvk_buffer_view_descriptor) {
.image_index = desc_index,
};
}
if (pdev->info.cls_eng3d < MAXWELL_A &&
(buffer->vk.usage & VK_BUFFER_USAGE_2_STORAGE_TEXEL_BUFFER_BIT_KHR)) {
// Kepler
view->su_info = nil_buffer_fill_su_info(&pdev->info,
addr,
nil_format(format),
view->vk.elements);
}
view->desc = (struct nvk_buffer_view_descriptor) {
.image_index = desc_index,
};
}
*pBufferView = nvk_buffer_view_to_handle(view);

View file

@ -21,7 +21,12 @@ struct nvk_buffer_view {
struct vk_buffer_view vk;
struct nvk_buffer_view_descriptor desc;
/* Used for uniform texel buffers on Kepler and everything on Maxwell+ */
struct nvk_edb_buffer_view_descriptor edb_desc;
/* Used for storage texel buffers on Kepler */
struct nil_su_info su_info;
};
VK_DEFINE_NONDISP_HANDLE_CASTS(nvk_buffer_view, vk.base, VkBufferView,

View file

@ -17,6 +17,8 @@
#include "util/format/u_format.h"
#include "clb097.h"
static inline uint32_t
align_u32(uint32_t v, uint32_t a)
{
@ -117,53 +119,73 @@ write_sampled_image_view_desc(struct nvk_descriptor_set *set,
}
static void
get_storage_image_view_desc(const VkDescriptorImageInfo *const info,
get_storage_image_view_desc(const struct nvk_physical_device *pdev,
const VkDescriptorImageInfo *const info,
void *dst, size_t dst_size)
{
struct nvk_storage_image_descriptor desc = { };
if (pdev->info.cls_eng3d >= MAXWELL_A) {
struct nvk_storage_image_descriptor desc = { };
if (info && info->imageView != VK_NULL_HANDLE) {
VK_FROM_HANDLE(nvk_image_view, view, info->imageView);
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;
/* 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));
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;
desc.image_index = view->planes[plane].storage_desc_index;
const struct nil_Extent4D_Samples px_extent_sa =
nil_px_extent_sa(view->planes[plane].sample_layout);
desc.sw_log2 = util_logbase2(px_extent_sa.width);
desc.sh_log2 = util_logbase2(px_extent_sa.height);
const struct nil_Extent4D_Samples px_extent_sa =
nil_px_extent_sa(view->planes[plane].sample_layout);
desc.sw_log2 = util_logbase2(px_extent_sa.width);
desc.sh_log2 = util_logbase2(px_extent_sa.height);
const enum nil_sample_layout slayout = view->planes[plane].sample_layout;
if (slayout != NIL_SAMPLE_LAYOUT_1X1) {
uint32_t samples = nil_sample_layout_samples(slayout);
assert(samples <= 16);
for (uint32_t s = 0; s < samples; s++) {
const struct nil_sample_offset off = nil_sample_offset(slayout, s);
assert(off.x < 4 && off.y < 4);
uint32_t s_xy = off.y << 2 | off.x;
desc.sample_map |= s_xy << (s * 4);
const enum nil_sample_layout slayout = view->planes[plane].sample_layout;
if (slayout != NIL_SAMPLE_LAYOUT_1X1) {
uint32_t samples = nil_sample_layout_samples(slayout);
assert(samples <= 16);
for (uint32_t s = 0; s < samples; s++) {
const struct nil_sample_offset off = nil_sample_offset(slayout, s);
assert(off.x < 4 && off.y < 4);
uint32_t s_xy = off.y << 2 | off.x;
desc.sample_map |= s_xy << (s * 4);
}
}
}
}
assert(sizeof(desc) <= dst_size);
memcpy(dst, &desc, sizeof(desc));
assert(sizeof(desc) <= dst_size);
memcpy(dst, &desc, sizeof(desc));
} else {
struct nvk_kepler_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);
desc.su_info = view->su_info;
} else {
desc.su_info = nil_fill_null_su_info(&pdev->info);
}
assert(sizeof(desc) <= dst_size);
memcpy(dst, &desc, sizeof(desc));
}
}
static void
write_storage_image_view_desc(struct nvk_descriptor_set *set,
write_storage_image_view_desc(const struct nvk_physical_device *pdev,
struct nvk_descriptor_set *set,
const VkDescriptorImageInfo *const info,
uint32_t binding, uint32_t elem)
{
uint32_t dst_size;
void *dst = desc_ubo_data(set, binding, elem, &dst_size);
get_storage_image_view_desc(info, dst, dst_size);
get_storage_image_view_desc(pdev, info, dst, dst_size);
}
static union nvk_buffer_descriptor
@ -284,7 +306,8 @@ static void
write_buffer_view_desc(const struct nvk_physical_device *pdev,
struct nvk_descriptor_set *set,
const VkBufferView bufferView,
uint32_t binding, uint32_t elem)
uint32_t binding, uint32_t elem,
VkDescriptorType descType)
{
VK_FROM_HANDLE(nvk_buffer_view, view, bufferView);
@ -293,11 +316,22 @@ write_buffer_view_desc(const struct nvk_physical_device *pdev,
if (view != NULL)
desc = view->edb_desc;
write_desc(set, binding, elem, &desc, sizeof(desc));
} else {
} else if (pdev->info.cls_eng3d >= MAXWELL_A ||
descType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) {
struct nvk_buffer_view_descriptor desc = { };
if (view != NULL)
desc = view->desc;
write_desc(set, binding, elem, &desc, sizeof(desc));
} else {// Kepler
struct nvk_kepler_storage_buffer_view_descriptor desc = { };
assert(descType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER);
if (view != NULL)
desc.su_info = view->su_info;
else
desc.su_info = nil_fill_null_su_info(&pdev->info);
write_desc(set, binding, elem, &desc, sizeof(desc));
}
}
@ -339,7 +373,7 @@ nvk_UpdateDescriptorSets(VkDevice device,
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_storage_image_view_desc(pdev, set, write->pImageInfo + j,
write->dstBinding,
write->dstArrayElement + j);
}
@ -349,7 +383,8 @@ nvk_UpdateDescriptorSets(VkDevice device,
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
for (uint32_t j = 0; j < write->descriptorCount; j++) {
write_buffer_view_desc(pdev, set, write->pTexelBufferView[j],
write->dstBinding, write->dstArrayElement + j);
write->dstBinding, write->dstArrayElement + j,
write->descriptorType);
}
break;
@ -473,7 +508,7 @@ nvk_push_descriptor_set_update(struct nvk_device *dev,
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_storage_image_view_desc(pdev, &set, write->pImageInfo + j,
write->dstBinding,
write->dstArrayElement + j);
}
@ -483,7 +518,8 @@ nvk_push_descriptor_set_update(struct nvk_device *dev,
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
for (uint32_t j = 0; j < write->descriptorCount; j++) {
write_buffer_view_desc(pdev, &set, write->pTexelBufferView[j],
write->dstBinding, write->dstArrayElement + j);
write->dstBinding, write->dstArrayElement + j,
write->descriptorType);
}
break;
@ -888,7 +924,7 @@ nvk_descriptor_set_write_template(struct nvk_device *dev,
const VkDescriptorImageInfo *info =
data + entry->offset + j * entry->stride;
write_storage_image_view_desc(set, info,
write_storage_image_view_desc(pdev, set, info,
entry->binding,
entry->array_element + j);
}
@ -902,7 +938,8 @@ nvk_descriptor_set_write_template(struct nvk_device *dev,
write_buffer_view_desc(pdev, set, *bview,
entry->binding,
entry->array_element + j);
entry->array_element + j,
entry->type);
}
break;
@ -1025,7 +1062,7 @@ nvk_GetDescriptorEXT(VkDevice _device,
break;
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
get_storage_image_view_desc(pDescriptorInfo->data.pStorageImage,
get_storage_image_view_desc(pdev, pDescriptorInfo->data.pStorageImage,
pDescriptor, dataSize);
break;

View file

@ -13,6 +13,8 @@
#include "vk_pipeline_layout.h"
#include "clb097.h"
static bool
binding_has_immutable_samplers(const VkDescriptorSetLayoutBinding *binding)
{
@ -26,6 +28,27 @@ binding_has_immutable_samplers(const VkDescriptorSetLayoutBinding *binding)
}
}
static uint32_t
nvk_max_descriptor_size(const struct nv_device_info *info)
{
// This should be constant-folded.
uint32_t max_desc_size = 0;
max_desc_size = MAX2(max_desc_size, sizeof(struct nvk_sampled_image_descriptor));
max_desc_size = MAX2(max_desc_size, sizeof(struct nvk_edb_buffer_view_descriptor));
max_desc_size = MAX2(max_desc_size, sizeof(union nvk_buffer_descriptor));
if (info->cls_eng3d >= MAXWELL_A) {
max_desc_size = MAX2(max_desc_size, sizeof(struct nvk_storage_image_descriptor));
max_desc_size = MAX2(max_desc_size, sizeof(struct nvk_buffer_view_descriptor));
} else {
max_desc_size = MAX2(max_desc_size, sizeof(struct nvk_kepler_storage_image_descriptor));
max_desc_size = MAX2(max_desc_size, sizeof(struct nvk_kepler_storage_buffer_view_descriptor));
}
return max_desc_size;
}
void
nvk_descriptor_stride_align_for_type(const struct nvk_physical_device *pdev,
VkPipelineLayoutCreateFlags layout_flags,
@ -43,7 +66,12 @@ nvk_descriptor_stride_align_for_type(const struct nvk_physical_device *pdev,
break;
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
*stride = *alignment = sizeof(struct nvk_storage_image_descriptor);
if (pdev->info.cls_eng3d >= MAXWELL_A) {
*stride = *alignment = sizeof(struct nvk_storage_image_descriptor);
} else {
*stride = sizeof(struct nvk_kepler_storage_image_descriptor);
*alignment = 16;
}
break;
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
@ -51,8 +79,12 @@ nvk_descriptor_stride_align_for_type(const struct nvk_physical_device *pdev,
if ((layout_flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT) ||
nvk_use_edb_buffer_views(pdev)) {
*stride = *alignment = sizeof(struct nvk_edb_buffer_view_descriptor);
} else {
} else if (pdev->info.cls_eng3d >= MAXWELL_A ||
type == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) {
*stride = *alignment = sizeof(struct nvk_buffer_view_descriptor);
} else {
*stride = sizeof(struct nvk_kepler_storage_buffer_view_descriptor);
*alignment = 16;
}
break;
@ -74,7 +106,7 @@ nvk_descriptor_stride_align_for_type(const struct nvk_physical_device *pdev,
case VK_DESCRIPTOR_TYPE_MUTABLE_EXT:
*stride = *alignment = 0;
if (type_list == NULL)
*stride = *alignment = NVK_MAX_DESCRIPTOR_SIZE;
*stride = *alignment = nvk_max_descriptor_size(&pdev->info);
for (unsigned i = 0; type_list && i < type_list->descriptorTypeCount; i++) {
/* This shouldn't recurse */
assert(type_list->pDescriptorTypes[i] !=
@ -470,7 +502,7 @@ nvk_GetDescriptorSetLayoutSupport(VkDevice device,
uint32_t max_buffer_size;
if (pCreateInfo->flags &
VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR)
max_buffer_size = NVK_PUSH_DESCRIPTOR_SET_SIZE;
max_buffer_size = NVK_MAX_PUSH_DESCRIPTORS * nvk_max_descriptor_size(&pdev->info);
else
max_buffer_size = NVK_MAX_DESCRIPTOR_SET_SIZE;

View file

@ -9,6 +9,8 @@
#include "nvk_physical_device.h"
#include "nil.h"
#define NVK_IMAGE_DESCRIPTOR_IMAGE_INDEX_MASK 0x000fffff
#define NVK_IMAGE_DESCRIPTOR_SAMPLER_INDEX_MASK 0xfff00000
@ -40,6 +42,14 @@ PRAGMA_DIAGNOSTIC_POP
static_assert(sizeof(struct nvk_storage_image_descriptor) == 8,
"nvk_storage_image_descriptor has no holes");
struct nvk_kepler_storage_image_descriptor {
struct nil_su_info su_info;
};
struct nvk_kepler_storage_buffer_view_descriptor {
struct nil_su_info su_info;
};
PRAGMA_DIAGNOSTIC_PUSH
PRAGMA_DIAGNOSTIC_ERROR(-Wpadded)
struct nvk_buffer_view_descriptor {

View file

@ -12,6 +12,8 @@
#include "vk_format.h"
#include "clb097.h"
static enum nil_view_type
vk_image_view_type_to_nil_view_type(VkImageViewType view_type)
{
@ -230,29 +232,38 @@ nvk_image_view_init(struct nvk_device *dev,
}
}
if (image->vk.samples != VK_SAMPLE_COUNT_1_BIT)
nil_image = nil_msaa_image_as_sa(&nil_image);
if (pdev->info.cls_eng3d >= MAXWELL_A) {
if (image->vk.samples != VK_SAMPLE_COUNT_1_BIT)
nil_image = nil_msaa_image_as_sa(&nil_image);
uint32_t tic[8];
nil_image_fill_tic(&nil_image, &pdev->info, &nil_view,
base_addr, &tic);
uint32_t tic[8];
nil_image_fill_tic(&nil_image, &pdev->info, &nil_view,
base_addr, &tic);
uint32_t desc_index = 0;
if (cap_info != NULL) {
assert(view->plane_count == 1);
desc_index = cap.single_plane.storage_desc_index;
result = nvk_descriptor_table_insert(dev, &dev->images,
desc_index, tic, sizeof(tic));
uint32_t desc_index = 0;
if (cap_info != NULL) {
assert(view->plane_count == 1);
desc_index = cap.single_plane.storage_desc_index;
result = nvk_descriptor_table_insert(dev, &dev->images,
desc_index, tic,
sizeof(tic));
} else {
result = nvk_descriptor_table_add(dev, &dev->images,
tic, sizeof(tic),
&desc_index);
}
if (result != VK_SUCCESS) {
nvk_image_view_finish(dev, view);
return result;
}
view->planes[view_plane].storage_desc_index = desc_index;
} else {
result = nvk_descriptor_table_add(dev, &dev->images,
tic, sizeof(tic), &desc_index);
assert(view_plane == 0);
view->su_info = nil_fill_su_info(&pdev->info,
&nil_image, &nil_view,
base_addr);
}
if (result != VK_SUCCESS) {
nvk_image_view_finish(dev, view);
return result;
}
view->planes[view_plane].storage_desc_index = desc_index;
}
}

View file

@ -28,6 +28,9 @@ struct nvk_image_view {
/** Index in the image descriptor table for the storage image descriptor */
uint32_t storage_desc_index;
} planes[NVK_MAX_IMAGE_PLANES];
/* Surface info for Kepler storage images */
struct nil_su_info su_info;
};
VK_DEFINE_NONDISP_HANDLE_CASTS(nvk_image_view, vk.base, VkImageView,

View file

@ -19,7 +19,9 @@
#define NVK_MIN_TEXEL_BUFFER_ALIGNMENT 16
#define NVK_MIN_UBO_ALIGNMENT 64
#define NVK_MAX_VIEWPORTS 16
#define NVK_MAX_DESCRIPTOR_SIZE 16
// This constant tracks the biggest descriptor size, it must be conservative
// From Maxwell we only use much smaller descriptors.
#define NVK_MAX_DESCRIPTOR_SIZE 32
#define NVK_MAX_PUSH_DESCRIPTORS 32
#define NVK_MAX_DESCRIPTOR_SET_SIZE (1u << 30)
#define NVK_MAX_DESCRIPTORS (1 << 20)