From 20d8d1e239be95143fc25886fe28aeb5d82a4d8c Mon Sep 17 00:00:00 2001 From: Faith Ekstrand Date: Mon, 30 Jan 2023 20:11:50 -0600 Subject: [PATCH] nvk: Add a more competent GetPhysicalDeviceImageFormatProperties Part-of: --- src/nouveau/vulkan/nvk_image.c | 111 +++++++++++++++++++++++++++++++ src/nouveau/vulkan/nvk_physical_device.c | 48 ------------- 2 files changed, 111 insertions(+), 48 deletions(-) diff --git a/src/nouveau/vulkan/nvk_image.c b/src/nouveau/vulkan/nvk_image.c index 20cbe7c..a7ca98d 100644 --- a/src/nouveau/vulkan/nvk_image.c +++ b/src/nouveau/vulkan/nvk_image.c @@ -103,6 +103,117 @@ nvk_get_image_format_features(struct nvk_physical_device *pdevice, return features; } +static VkFormatFeatureFlags2KHR +vk_image_usage_to_format_features(VkImageUsageFlagBits usage_flag) +{ + assert(util_bitcount(usage_flag) == 1); + switch (usage_flag) { + case VK_IMAGE_USAGE_TRANSFER_SRC_BIT: + return VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT_KHR | + VK_FORMAT_FEATURE_BLIT_SRC_BIT; + case VK_IMAGE_USAGE_TRANSFER_DST_BIT: + return VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT_KHR | + VK_FORMAT_FEATURE_BLIT_DST_BIT; + case VK_IMAGE_USAGE_SAMPLED_BIT: + return VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT; + case VK_IMAGE_USAGE_STORAGE_BIT: + return VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT; + case VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT: + return VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT; + case VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT: + return VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT; + default: + return 0; + } +} + +VKAPI_ATTR VkResult VKAPI_CALL +nvk_GetPhysicalDeviceImageFormatProperties2( + VkPhysicalDevice physicalDevice, + const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo, + VkImageFormatProperties2 *pImageFormatProperties) +{ + VK_FROM_HANDLE(nvk_physical_device, pdevice, physicalDevice); + + VkFormatFeatureFlags2KHR features = + nvk_get_image_format_features(pdevice, pImageFormatInfo->format, + pImageFormatInfo->tiling); + if (features == 0) + return VK_ERROR_FORMAT_NOT_SUPPORTED; + + if (vk_format_is_compressed(pImageFormatInfo->format) && + pImageFormatInfo->type != VK_IMAGE_TYPE_2D) + return VK_ERROR_FORMAT_NOT_SUPPORTED; + + VkExtent3D maxExtent; + uint32_t maxMipLevels; + uint32_t maxArraySize; + VkSampleCountFlags sampleCounts; + switch (pImageFormatInfo->type) { + case VK_IMAGE_TYPE_1D: + maxExtent = (VkExtent3D) { 16384, 1, 1 }, + maxMipLevels = 15; + maxArraySize = 2048; + sampleCounts = VK_SAMPLE_COUNT_1_BIT; + break; + case VK_IMAGE_TYPE_2D: + maxExtent = (VkExtent3D) { 16384, 16384, 1 }; + maxMipLevels = 15; + maxArraySize = 2048; + sampleCounts = VK_SAMPLE_COUNT_1_BIT; /* TODO: MSAA */ + break; + case VK_IMAGE_TYPE_3D: + maxExtent = (VkExtent3D) { 2048, 2048, 2048 }; + maxMipLevels = 12; + maxArraySize = 1; + sampleCounts = VK_SAMPLE_COUNT_1_BIT; + break; + default: + unreachable("Invalid image type"); + } + + /* From the Vulkan 1.2.199 spec: + * + * "VK_IMAGE_CREATE_EXTENDED_USAGE_BIT specifies that the image can be + * created with usage flags that are not supported for the format the + * image is created with but are supported for at least one format a + * VkImageView created from the image can have." + * + * If VK_IMAGE_CREATE_EXTENDED_USAGE_BIT is set, views can be created with + * different usage than the image so we can't always filter on usage. + * There is one exception to this below for storage. + */ + const VkImageUsageFlags image_usage = pImageFormatInfo->usage; + VkImageUsageFlags view_usage = image_usage; + if (pImageFormatInfo->flags & VK_IMAGE_CREATE_EXTENDED_USAGE_BIT) + view_usage = 0; + + u_foreach_bit(b, view_usage) { + VkFormatFeatureFlags2KHR usage_features = + vk_image_usage_to_format_features(1 << b); + if (usage_features && !(features & usage_features)) + return VK_ERROR_FORMAT_NOT_SUPPORTED; + } + + pImageFormatProperties->imageFormatProperties = (VkImageFormatProperties) { + .maxExtent = maxExtent, + .maxMipLevels = maxMipLevels, + .maxArrayLayers = maxArraySize, + .sampleCounts = sampleCounts, + .maxResourceSize = UINT32_MAX, /* TODO */ + }; + + vk_foreach_struct(s, pImageFormatProperties->pNext) { + switch (s->sType) { + default: + nvk_debug_ignored_stype(s->sType); + break; + } + } + + return VK_SUCCESS; +} + static enum nil_image_dim vk_image_type_to_nil_dim(VkImageType type) { diff --git a/src/nouveau/vulkan/nvk_physical_device.c b/src/nouveau/vulkan/nvk_physical_device.c index 14d7dc8..73e79e8 100644 --- a/src/nouveau/vulkan/nvk_physical_device.c +++ b/src/nouveau/vulkan/nvk_physical_device.c @@ -409,51 +409,3 @@ nvk_GetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice, p->queueFamilyProperties.minImageTransferGranularity = (VkExtent3D){1, 1, 1}; } } - -VKAPI_ATTR VkResult VKAPI_CALL -nvk_GetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice, - const VkPhysicalDeviceImageFormatInfo2 *base_info, - VkImageFormatProperties2 *base_props) -{ - if (base_info->usage & ~(VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT)) - return VK_ERROR_FORMAT_NOT_SUPPORTED; - - const struct nvk_format *format = nvk_get_format(base_info->format); - if (format == NULL) - return VK_ERROR_FORMAT_NOT_SUPPORTED; - - if (!format->supports_2d_blit) - return VK_ERROR_FORMAT_NOT_SUPPORTED; - - if (base_info->type == VK_IMAGE_TYPE_1D) - base_props->imageFormatProperties.maxExtent = (VkExtent3D){32768, 1, 1}; - else if (base_info->type == VK_IMAGE_TYPE_2D) - base_props->imageFormatProperties.maxExtent = (VkExtent3D){32768, 32768, 1}; - else - return VK_ERROR_FORMAT_NOT_SUPPORTED; - - base_props->imageFormatProperties.maxMipLevels = 15; - base_props->imageFormatProperties.maxArrayLayers = 2048; - base_props->imageFormatProperties.sampleCounts = 0; - base_props->imageFormatProperties.maxResourceSize = 0xffffffff; // TODO proper value - - vk_foreach_struct(s, base_props->pNext) { - switch (s->sType) { - default: - nvk_debug_ignored_stype(s->sType); - break; - } - } - - vk_foreach_struct(ext, base_info->pNext) - { - /* Use unsigned since some cases are not in the VkStructureType enum. */ - switch ((unsigned)ext->sType) { - default: - nvk_debug_ignored_stype(ext->sType); - break; - } - } - - return VK_SUCCESS; -} -- 2.7.4