From b6483f51265fe547ca111c827b1a2b926b72c0f1 Mon Sep 17 00:00:00 2001 From: Faith Ekstrand Date: Mon, 30 Jan 2023 20:11:50 -0600 Subject: [PATCH] nvk: Handle cube storage images properly TIC entries for cubes divide the array size by 6 so we don't want that when using it as a storage image. This means nvk_image_view needs separate TIC entries for storage vs. sampled now. Part-of: --- src/nouveau/vulkan/nvk_descriptor_set.c | 9 +++- src/nouveau/vulkan/nvk_image_view.c | 68 +++++++++++++++++++------ src/nouveau/vulkan/nvk_image_view.h | 7 ++- 3 files changed, 65 insertions(+), 19 deletions(-) diff --git a/src/nouveau/vulkan/nvk_descriptor_set.c b/src/nouveau/vulkan/nvk_descriptor_set.c index b1a5e5a354a..a99180b81cc 100644 --- a/src/nouveau/vulkan/nvk_descriptor_set.c +++ b/src/nouveau/vulkan/nvk_descriptor_set.c @@ -45,8 +45,13 @@ write_image_view_desc(struct nvk_descriptor_set *set, if (descriptor_type != VK_DESCRIPTOR_TYPE_SAMPLER && info->imageView != VK_NULL_HANDLE) { VK_FROM_HANDLE(nvk_image_view, view, info->imageView); - assert(view->desc_index < (1 << 20)); - desc.image_index = view->desc_index; + if (descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) { + assert(view->storage_desc_index < (1 << 20)); + desc.image_index = view->storage_desc_index; + } else { + assert(view->sampled_desc_index < (1 << 20)); + desc.image_index = view->sampled_desc_index; + } } if (descriptor_type == VK_DESCRIPTOR_TYPE_SAMPLER || diff --git a/src/nouveau/vulkan/nvk_image_view.c b/src/nouveau/vulkan/nvk_image_view.c index 4007ebacc05..185dd2b0954 100644 --- a/src/nouveau/vulkan/nvk_image_view.c +++ b/src/nouveau/vulkan/nvk_image_view.c @@ -37,6 +37,24 @@ vk_swizzle_to_pipe(VkComponentSwizzle swizzle) } } +static void +nvk_image_view_destroy(struct nvk_device *device, + const VkAllocationCallbacks *pAllocator, + struct nvk_image_view *view) +{ + if (view->sampled_desc_index) { + nvk_descriptor_table_free(device, &device->images, + view->sampled_desc_index); + } + + if (view->storage_desc_index) { + nvk_descriptor_table_free(device, &device->images, + view->sampled_desc_index); + } + + vk_image_view_destroy(&device->vk, pAllocator, &view->vk); +} + VKAPI_ATTR VkResult VKAPI_CALL nvk_CreateImageView(VkDevice _device, const VkImageViewCreateInfo *pCreateInfo, @@ -52,14 +70,6 @@ nvk_CreateImageView(VkDevice _device, if (view == NULL) return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); - uint32_t *desc_map = nvk_descriptor_table_alloc(device, &device->images, - &view->desc_index); - if (desc_map == NULL) { - vk_image_view_destroy(&device->vk, pAllocator, &view->vk); - return vk_errorf(device, VK_ERROR_OUT_OF_DEVICE_MEMORY, - "Failed to allocate image descriptor"); - } - struct nil_view nil_view = { .type = vk_image_view_type_to_nil_view_type(view->vk.view_type), .format = vk_format_to_pipe_format(view->vk.format), @@ -75,10 +85,40 @@ nvk_CreateImageView(VkDevice _device, }, }; - nil_image_fill_tic(nvk_device_physical(device)->dev, - &image->nil, &nil_view, - nvk_image_base_address(image), - desc_map); + if (view->vk.usage & VK_IMAGE_USAGE_SAMPLED_BIT) { + uint32_t *desc_map = nvk_descriptor_table_alloc(device, &device->images, + &view->sampled_desc_index); + if (desc_map == NULL) { + nvk_image_view_destroy(device, pAllocator, view); + return vk_errorf(device, VK_ERROR_OUT_OF_DEVICE_MEMORY, + "Failed to allocate image descriptor"); + } + + nil_image_fill_tic(nvk_device_physical(device)->dev, + &image->nil, &nil_view, + nvk_image_base_address(image), + desc_map); + } + + if (view->vk.usage & VK_IMAGE_USAGE_STORAGE_BIT) { + uint32_t *desc_map = nvk_descriptor_table_alloc(device, &device->images, + &view->storage_desc_index); + if (desc_map == NULL) { + nvk_image_view_destroy(device, pAllocator, view); + return vk_errorf(device, VK_ERROR_OUT_OF_DEVICE_MEMORY, + "Failed to allocate image descriptor"); + } + + /* For storage images, we can't have any cubes */ + if (view->vk.view_type == VK_IMAGE_VIEW_TYPE_CUBE || + view->vk.view_type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) + nil_view.type = NIL_VIEW_TYPE_2D_ARRAY; + + nil_image_fill_tic(nvk_device_physical(device)->dev, + &image->nil, &nil_view, + nvk_image_base_address(image), + desc_map); + } *pView = nvk_image_view_to_handle(view); @@ -96,7 +136,5 @@ nvk_DestroyImageView(VkDevice _device, if (!view) return; - nvk_descriptor_table_free(device, &device->images, view->desc_index); - - vk_image_view_destroy(&device->vk, pAllocator, &view->vk); + nvk_image_view_destroy(device, pAllocator, view); } diff --git a/src/nouveau/vulkan/nvk_image_view.h b/src/nouveau/vulkan/nvk_image_view.h index 2d977d58ab3..b2d3a195c82 100644 --- a/src/nouveau/vulkan/nvk_image_view.h +++ b/src/nouveau/vulkan/nvk_image_view.h @@ -8,8 +8,11 @@ struct nvk_image_view { struct vk_image_view vk; - /** Index in the image descriptor table */ - uint32_t desc_index; + /** Index in the image descriptor table for the sampled image descriptor */ + uint32_t sampled_desc_index; + + /** Index in the image descriptor table for the storage image descriptor */ + uint32_t storage_desc_index; }; VK_DEFINE_HANDLE_CASTS(nvk_image_view, vk.base, VkImageView,