diff --git a/src/nouveau/vulkan/nvk_buffer_view.c b/src/nouveau/vulkan/nvk_buffer_view.c index 5bc1c9b600d..132587b4a87 100644 --- a/src/nouveau/vulkan/nvk_buffer_view.c +++ b/src/nouveau/vulkan/nvk_buffer_view.c @@ -2,6 +2,13 @@ #include "nvk_device.h" +VkFormatFeatureFlags2 +nvk_get_buffer_format_features(struct nvk_physical_device *pdevice, + VkFormat format) +{ + return 0; +} + VKAPI_ATTR VkResult VKAPI_CALL nvk_CreateBufferView(VkDevice _device, const VkBufferViewCreateInfo *pCreateInfo, diff --git a/src/nouveau/vulkan/nvk_buffer_view.h b/src/nouveau/vulkan/nvk_buffer_view.h index 64dd210b1b7..b2d5206aad2 100644 --- a/src/nouveau/vulkan/nvk_buffer_view.h +++ b/src/nouveau/vulkan/nvk_buffer_view.h @@ -5,6 +5,12 @@ #include "vulkan/runtime/vk_buffer_view.h" +struct nvk_physical_device; + +VkFormatFeatureFlags2 +nvk_get_buffer_format_features(struct nvk_physical_device *pdevice, + VkFormat format); + struct nvk_buffer_view { struct vk_buffer_view vk; diff --git a/src/nouveau/vulkan/nvk_format.c b/src/nouveau/vulkan/nvk_format.c index 7db0ab453e0..8d17a2d2728 100644 --- a/src/nouveau/vulkan/nvk_format.c +++ b/src/nouveau/vulkan/nvk_format.c @@ -1,8 +1,13 @@ #include "nvk_format.h" +#include "nvk_buffer_view.h" +#include "nvk_image.h" +#include "nvk_physical_device.h" + #include "nvtypes.h" #include "classes/cl902d.h" #include "classes/cl90c0.h" +#include "vulkan/util/vk_enum_defines.h" #include "vulkan/util/vk_format.h" /* @@ -181,3 +186,40 @@ nvk_get_format(VkFormat vk_format) return NULL; } + +VKAPI_ATTR void VKAPI_CALL +nvk_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice, + VkFormat format, + VkFormatProperties2 *pFormatProperties) +{ + VK_FROM_HANDLE(nvk_physical_device, pdevice, physicalDevice); + + VkFormatFeatureFlags2 linear2, optimal2, buffer2; + linear2 = nvk_get_image_format_features(pdevice, format, + VK_IMAGE_TILING_LINEAR); + optimal2 = nvk_get_image_format_features(pdevice, format, + VK_IMAGE_TILING_OPTIMAL); + buffer2 = nvk_get_buffer_format_features(pdevice, format); + + pFormatProperties->formatProperties = (VkFormatProperties) { + .linearTilingFeatures = vk_format_features2_to_features(linear2), + .optimalTilingFeatures = vk_format_features2_to_features(optimal2), + .bufferFeatures = vk_format_features2_to_features(buffer2), + }; + + vk_foreach_struct(ext, pFormatProperties->pNext) { + switch (ext->sType) { + case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR: { + VkFormatProperties3KHR *props = (VkFormatProperties3KHR *)ext; + props->linearTilingFeatures = linear2; + props->optimalTilingFeatures = optimal2; + props->bufferFeatures = buffer2; + break; + } + + default: + nvk_debug_ignored_stype(ext->sType); + break; + } + } +} diff --git a/src/nouveau/vulkan/nvk_image.c b/src/nouveau/vulkan/nvk_image.c index 5423aa2c7c7..20cbe7c56ea 100644 --- a/src/nouveau/vulkan/nvk_image.c +++ b/src/nouveau/vulkan/nvk_image.c @@ -1,12 +1,108 @@ #include "nvk_image.h" -#include "vulkan/util/vk_format.h" - #include "nvk_device.h" #include "nvk_device_memory.h" #include "nvk_format.h" #include "nvk_physical_device.h" +#include "nil_format.h" +#include "vulkan/util/vk_format.h" + +static bool +is_storage_image_format(enum pipe_format p_format) +{ + /* TODO: This shouldn't be a fixed list */ + + switch (p_format) { + case PIPE_FORMAT_R32G32B32A32_UINT: + case PIPE_FORMAT_R32G32B32A32_SINT: + case PIPE_FORMAT_R32G32B32A32_FLOAT: + case PIPE_FORMAT_R32_UINT: + case PIPE_FORMAT_R32_SINT: + case PIPE_FORMAT_R32_FLOAT: + case PIPE_FORMAT_R16G16B16A16_UINT: + case PIPE_FORMAT_R16G16B16A16_SINT: + case PIPE_FORMAT_R16G16B16A16_FLOAT: + case PIPE_FORMAT_R32G32_UINT: + case PIPE_FORMAT_R32G32_SINT: + case PIPE_FORMAT_R32G32_FLOAT: + case PIPE_FORMAT_R8G8B8A8_UINT: + case PIPE_FORMAT_R8G8B8A8_SINT: + case PIPE_FORMAT_R16G16_UINT: + case PIPE_FORMAT_R16G16_SINT: + case PIPE_FORMAT_R16G16_FLOAT: + case PIPE_FORMAT_R8G8_UINT: + case PIPE_FORMAT_R8G8_SINT: + case PIPE_FORMAT_R16_UINT: + case PIPE_FORMAT_R16_FLOAT: + case PIPE_FORMAT_R16_SINT: + case PIPE_FORMAT_R8_UINT: + case PIPE_FORMAT_R8_SINT: + case PIPE_FORMAT_R10G10B10A2_UINT: + case PIPE_FORMAT_R10G10B10A2_UNORM: + case PIPE_FORMAT_R11G11B10_FLOAT: + case PIPE_FORMAT_R16G16B16A16_UNORM: + case PIPE_FORMAT_R16G16B16A16_SNORM: + case PIPE_FORMAT_R8G8B8A8_UNORM: + case PIPE_FORMAT_R8G8B8A8_SNORM: + case PIPE_FORMAT_R16G16_UNORM: + case PIPE_FORMAT_R16G16_SNORM: + case PIPE_FORMAT_R8G8_UNORM: + case PIPE_FORMAT_R8G8_SNORM: + case PIPE_FORMAT_R16_UNORM: + case PIPE_FORMAT_R16_SNORM: + case PIPE_FORMAT_R8_UNORM: + case PIPE_FORMAT_R8_SNORM: + return true; + default: + return false; + } +} + +VkFormatFeatureFlags2 +nvk_get_image_format_features(struct nvk_physical_device *pdevice, + VkFormat vk_format, VkImageTiling tiling) +{ + VkFormatFeatureFlags2 features = 0; + + if (tiling != VK_IMAGE_TILING_OPTIMAL) + return 0; + + enum pipe_format p_format = vk_format_to_pipe_format(vk_format); + if (p_format == PIPE_FORMAT_NONE) + return 0; + + const struct nil_tic_format *tic_format = nil_tic_format_for_pipe(p_format); + if (tic_format == NULL) + return 0; + + features |= VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT; + features |= VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT; + features |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT; + + if (util_format_is_float(p_format) || + util_format_is_unorm(p_format) || + util_format_is_snorm(p_format)) + features |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT; + + if (is_storage_image_format(p_format)) { + features |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT | + VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT | + VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT; + } + + if (p_format == PIPE_FORMAT_R32_UINT) + features |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT; + + const struct nvk_format *nvk_format = nvk_get_format(vk_format); + if (nvk_format && nvk_format->supports_2d_blit) { + features |= VK_FORMAT_FEATURE_2_BLIT_SRC_BIT | + VK_FORMAT_FEATURE_2_BLIT_DST_BIT; + } + + return features; +} + static enum nil_image_dim vk_image_type_to_nil_dim(VkImageType type) { diff --git a/src/nouveau/vulkan/nvk_image.h b/src/nouveau/vulkan/nvk_image.h index 5230234d015..4667ac800aa 100644 --- a/src/nouveau/vulkan/nvk_image.h +++ b/src/nouveau/vulkan/nvk_image.h @@ -9,6 +9,12 @@ #include "nouveau_push.h" #include "vulkan/runtime/vk_image.h" +struct nvk_physical_device; + +VkFormatFeatureFlags2 +nvk_get_image_format_features(struct nvk_physical_device *pdevice, + VkFormat format, VkImageTiling tiling); + struct nvk_image { struct vk_image vk; struct nvk_device_memory *mem; diff --git a/src/nouveau/vulkan/nvk_physical_device.c b/src/nouveau/vulkan/nvk_physical_device.c index 8ec5220a8ba..14d7dc8c199 100644 --- a/src/nouveau/vulkan/nvk_physical_device.c +++ b/src/nouveau/vulkan/nvk_physical_device.c @@ -9,11 +9,8 @@ #include "nvk_wsi.h" #include "vulkan/runtime/vk_device.h" -#include "vulkan/util/vk_enum_defines.h" #include "vulkan/wsi/wsi_common.h" -#include "vulkan/util/vk_enum_defines.h" - #include "cl90c0.h" #include "cl91c0.h" #include "cla0c0.h" @@ -148,6 +145,7 @@ nvk_get_device_extensions(const struct nvk_physical_device *device, { *ext = (struct vk_device_extension_table) { .KHR_copy_commands2 = true, + .KHR_format_feature_flags2 = true, #ifdef NVK_USE_WSI_PLATFORM .KHR_swapchain = true, .KHR_swapchain_mutable_format = true, @@ -412,51 +410,6 @@ nvk_GetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice, } } -static void -nvk_physical_device_get_format_properties(struct nvk_physical_device *physical_device, - VkFormat format, VkFormatProperties3 *out_properties) -{ - VkFormatFeatureFlags2 linear = 0, tiled = 0, buffer = 0; - - linear = VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT; - tiled = VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT; - if (format == VK_FORMAT_B8G8R8A8_UNORM) { - buffer |= VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT | - VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT | - VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT; - } - - out_properties->linearTilingFeatures = linear; - out_properties->optimalTilingFeatures = tiled; - out_properties->bufferFeatures = buffer; -} - -VKAPI_ATTR void VKAPI_CALL -nvk_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice, - VkFormat format, - VkFormatProperties2 *pFormatProperties) -{ - VK_FROM_HANDLE(nvk_physical_device, physical_device, physicalDevice); - VkFormatProperties3 format_props; - - nvk_physical_device_get_format_properties(physical_device, format, &format_props); - pFormatProperties->formatProperties.linearTilingFeatures = - vk_format_features2_to_features(format_props.linearTilingFeatures); - pFormatProperties->formatProperties.optimalTilingFeatures = - vk_format_features2_to_features(format_props.optimalTilingFeatures); - pFormatProperties->formatProperties.bufferFeatures = - vk_format_features2_to_features(format_props.bufferFeatures); - vk_foreach_struct(ext, pFormatProperties->pNext) - { - /* Use unsigned since some cases are not in the VkStructureType enum. */ - switch ((unsigned)ext->sType) { - default: - nvk_debug_ignored_stype(ext->sType); - break; - } - } -} - VKAPI_ATTR VkResult VKAPI_CALL nvk_GetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2 *base_info,