Mesa (main): v3dv/format: Add support for VK_KHR_format_feature_flags2

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu May 26 21:41:19 UTC 2022


Module: Mesa
Branch: main
Commit: 746287d221874802feb2d51471a9528be96ca42e
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=746287d221874802feb2d51471a9528be96ca42e

Author: Alejandro Piñeiro <apinheiro at igalia.com>
Date:   Tue May 10 22:01:51 2022 +0200

v3dv/format: Add support for VK_KHR_format_feature_flags2

VK_KHR_format_feature_flags2 is mostly about define a new 64-bit
VkFormatFeatureFlagBits2KHR format feature flag type, as 29 bits of
the 32-bit VkFormatFeatureFlagBits are already in use.

So all the bits from VkFormatFeatureFlagBits are being replicated, and
most of the work here consist on switch to the new flags.

>From the new (not replicated from VkFormatFeatureFlagBits) flag bits,
we don't support
VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR or
VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR, as right now
we require the format on the shader for doing the read and stores.

We use now VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR,
but only applying it for depth formats.

Reviewed-by: Iago Toral Quiroga <itoral at igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16718>

---

 docs/features.txt                    |   2 +-
 src/broadcom/vulkan/v3dv_device.c    |   1 +
 src/broadcom/vulkan/v3dv_formats.c   | 112 +++++++++++++++++++++--------------
 src/broadcom/vulkan/v3dv_meta_copy.c |   2 +-
 src/broadcom/vulkan/v3dv_private.h   |   2 +-
 5 files changed, 73 insertions(+), 46 deletions(-)

diff --git a/docs/features.txt b/docs/features.txt
index bbe24a657fc..2ba759af509 100644
--- a/docs/features.txt
+++ b/docs/features.txt
@@ -474,7 +474,7 @@ Vulkan 1.3 -- all DONE: anv, radv, lvp
 
   VK_KHR_copy_commands2                                 DONE (anv, lvp, radv, tu, v3dv)
   VK_KHR_dynamic_rendering                              DONE (anv, lvp, radv)
-  VK_KHR_format_feature_flags2                          DONE (anv, radv, tu)
+  VK_KHR_format_feature_flags2                          DONE (anv, radv, tu, v3dv)
   VK_KHR_maintenance4                                   DONE (anv, radv, tu)
   VK_KHR_shader_non_semantic_info                       DONE (anv, radv, tu, v3dv)
   VK_KHR_shader_terminate_invocation                    DONE (anv, radv, tu)
diff --git a/src/broadcom/vulkan/v3dv_device.c b/src/broadcom/vulkan/v3dv_device.c
index b783a28da92..21ffdbbc07b 100644
--- a/src/broadcom/vulkan/v3dv_device.c
+++ b/src/broadcom/vulkan/v3dv_device.c
@@ -129,6 +129,7 @@ get_device_extensions(const struct v3dv_physical_device *device,
       .KHR_external_memory_fd              = true,
       .KHR_external_semaphore              = true,
       .KHR_external_semaphore_fd           = true,
+      .KHR_format_feature_flags2           = true,
       .KHR_get_memory_requirements2        = true,
       .KHR_image_format_list               = true,
       .KHR_imageless_framebuffer           = true,
diff --git a/src/broadcom/vulkan/v3dv_formats.c b/src/broadcom/vulkan/v3dv_formats.c
index 2e8e266d6be..da497c36408 100644
--- a/src/broadcom/vulkan/v3dv_formats.c
+++ b/src/broadcom/vulkan/v3dv_formats.c
@@ -23,6 +23,7 @@
 
 #include "v3dv_private.h"
 #include "vk_util.h"
+#include "vk_enum_defines.h"
 
 #include "drm-uapi/drm_fourcc.h"
 #include "util/format/u_format.h"
@@ -122,7 +123,7 @@ v3dv_get_compatible_tfu_format(struct v3dv_device *device,
    return format;
 }
 
-static VkFormatFeatureFlags
+static VkFormatFeatureFlags2KHR
 image_format_features(struct v3dv_physical_device *pdevice,
                       VkFormat vk_format,
                       const struct v3dv_format *v3dv_format,
@@ -149,7 +150,7 @@ image_format_features(struct v3dv_physical_device *pdevice,
       return 0;
    }
 
-   VkFormatFeatureFlags flags = 0;
+   VkFormatFeatureFlags2KHR flags = 0;
 
    /* Raster format is only supported for 1D textures, so let's just
     * always require optimal tiling for anything that requires sampling.
@@ -158,22 +159,22 @@ image_format_features(struct v3dv_physical_device *pdevice,
     */
    if (v3dv_format->tex_type != TEXTURE_DATA_FORMAT_NO &&
        tiling == VK_IMAGE_TILING_OPTIMAL) {
-      flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
-               VK_FORMAT_FEATURE_BLIT_SRC_BIT;
+      flags |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT |
+               VK_FORMAT_FEATURE_2_BLIT_SRC_BIT;
 
       if (v3dv_format->supports_filtering)
-         flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
+         flags |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
    }
 
    if (v3dv_format->rt_type != V3D_OUTPUT_IMAGE_FORMAT_NO) {
       if (aspects & VK_IMAGE_ASPECT_COLOR_BIT) {
-         flags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
-                  VK_FORMAT_FEATURE_BLIT_DST_BIT;
+         flags |= VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT |
+                  VK_FORMAT_FEATURE_2_BLIT_DST_BIT;
          if (v3dv_X(pdevice, format_supports_blending)(v3dv_format))
-            flags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT;
+            flags |= VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT;
       } else if (aspects & zs_aspects) {
-         flags |= VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT |
-                  VK_FORMAT_FEATURE_BLIT_DST_BIT;
+         flags |= VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT |
+                  VK_FORMAT_FEATURE_2_BLIT_DST_BIT;
       }
    }
 
@@ -183,26 +184,32 @@ image_format_features(struct v3dv_physical_device *pdevice,
 
    if (tiling != VK_IMAGE_TILING_LINEAR) {
       if (desc->layout == UTIL_FORMAT_LAYOUT_PLAIN && desc->is_array) {
-         flags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
+         flags |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT;
          if (desc->nr_channels == 1 && vk_format_is_int(vk_format))
-            flags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT;
+            flags |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT;
       } else if (vk_format == VK_FORMAT_A2B10G10R10_UNORM_PACK32 ||
                  vk_format == VK_FORMAT_A2B10G10R10_UINT_PACK32 ||
                  vk_format == VK_FORMAT_B10G11R11_UFLOAT_PACK32) {
          /* To comply with shaderStorageImageExtendedFormats */
-         flags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
+         flags |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT;
       }
    }
 
+   /* All our depth formats support shadow comparisons. */
+   if (vk_format_has_depth(vk_format) &&
+       (flags & VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT)) {
+      flags |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT;
+   }
+
    if (flags) {
-      flags |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT |
-               VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
+      flags |= VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT |
+               VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT;
    }
 
    return flags;
 }
 
-static VkFormatFeatureFlags
+static VkFormatFeatureFlags2KHR
 buffer_format_features(VkFormat vk_format, const struct v3dv_format *v3dv_format)
 {
    if (!v3dv_format || !v3dv_format->supported)
@@ -221,30 +228,30 @@ buffer_format_features(VkFormat vk_format, const struct v3dv_format *v3dv_format
       vk_format_description(vk_format);
    assert(desc);
 
-   VkFormatFeatureFlags flags = 0;
+   VkFormatFeatureFlags2KHR flags = 0;
    if (desc->layout == UTIL_FORMAT_LAYOUT_PLAIN &&
        desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB &&
        desc->is_array) {
-      flags |=  VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT;
+      flags |=  VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT;
       if (v3dv_format->tex_type != TEXTURE_DATA_FORMAT_NO) {
-         flags |= VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT |
-                  VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT;
+         flags |= VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT |
+                  VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT;
       }
    } else if (vk_format == VK_FORMAT_A2B10G10R10_UNORM_PACK32) {
-      flags |= VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT |
-               VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT |
-               VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT;
+      flags |= VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT |
+               VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT |
+               VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT;
    } else if (vk_format == VK_FORMAT_A2B10G10R10_UINT_PACK32 ||
               vk_format == VK_FORMAT_B10G11R11_UFLOAT_PACK32) {
-      flags |= VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT |
-               VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT;
+      flags |= VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT |
+               VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT;
    }
 
    if (desc->layout == UTIL_FORMAT_LAYOUT_PLAIN &&
        desc->is_array &&
        desc->nr_channels == 1 &&
        vk_format_is_int(vk_format)) {
-      flags |= VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT;
+      flags |= VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_ATOMIC_BIT;
    }
 
    return flags;
@@ -253,14 +260,23 @@ buffer_format_features(VkFormat vk_format, const struct v3dv_format *v3dv_format
 bool
 v3dv_buffer_format_supports_features(struct v3dv_device *device,
                                      VkFormat vk_format,
-                                     VkFormatFeatureFlags features)
+                                     VkFormatFeatureFlags2KHR features)
 {
    const struct v3dv_format *v3dv_format = v3dv_X(device, get_format)(vk_format);
-   const VkFormatFeatureFlags supported =
+   const VkFormatFeatureFlags2KHR supported =
       buffer_format_features(vk_format, v3dv_format);
    return (supported & features) == features;
 }
 
+/* FIXME: this helper now on anv, radv, lvp, and v3dv. Perhaps common
+ * place?
+ */
+static inline VkFormatFeatureFlags
+features2_to_features(VkFormatFeatureFlags2KHR features2)
+{
+   return features2 & VK_ALL_FORMAT_FEATURE_FLAG_BITS;
+}
+
 VKAPI_ATTR void VKAPI_CALL
 v3dv_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice,
                                         VkFormat format,
@@ -269,13 +285,16 @@ v3dv_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice,
    V3DV_FROM_HANDLE(v3dv_physical_device, pdevice, physicalDevice);
    const struct v3dv_format *v3dv_format = v3dv_X(pdevice, get_format)(format);
 
+   VkFormatFeatureFlags2KHR linear2, optimal2, buffer2;
+   linear2 = image_format_features(pdevice, format, v3dv_format,
+                                   VK_IMAGE_TILING_LINEAR);
+   optimal2 = image_format_features(pdevice, format, v3dv_format,
+                                    VK_IMAGE_TILING_OPTIMAL);
+   buffer2 = buffer_format_features(format, v3dv_format);
    pFormatProperties->formatProperties = (VkFormatProperties) {
-      .linearTilingFeatures =
-         image_format_features(pdevice, format, v3dv_format, VK_IMAGE_TILING_LINEAR),
-      .optimalTilingFeatures =
-         image_format_features(pdevice, format, v3dv_format, VK_IMAGE_TILING_OPTIMAL),
-      .bufferFeatures =
-         buffer_format_features(format, v3dv_format),
+      .linearTilingFeatures = features2_to_features(linear2),
+      .optimalTilingFeatures = features2_to_features(optimal2),
+      .bufferFeatures = features2_to_features(buffer2),
    };
 
    vk_foreach_struct(ext, pFormatProperties->pNext) {
@@ -305,6 +324,13 @@ v3dv_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice,
          }
          break;
       }
+      case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR: {
+         VkFormatProperties3KHR *props = (VkFormatProperties3KHR *)ext;
+         props->linearTilingFeatures = linear2;
+         props->optimalTilingFeatures = optimal2;
+         props->bufferFeatures = buffer2;
+         break;
+      }
       default:
          v3dv_debug_ignored_stype(ext->sType);
          break;
@@ -321,7 +347,7 @@ get_image_format_properties(
    VkSamplerYcbcrConversionImageFormatProperties *pYcbcrImageFormatProperties)
 {
    const struct v3dv_format *v3dv_format = v3dv_X(physical_device, get_format)(info->format);
-   VkFormatFeatureFlags format_feature_flags =
+   VkFormatFeatureFlags2KHR format_feature_flags =
       image_format_features(physical_device, info->format, v3dv_format, tiling);
    if (!format_feature_flags)
       goto unsupported;
@@ -355,7 +381,7 @@ get_image_format_properties(
       info->flags & VK_IMAGE_CREATE_EXTENDED_USAGE_BIT ? 0 : image_usage;
 
    if (image_usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {
-      if (!(format_feature_flags & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT)) {
+      if (!(format_feature_flags & VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT)) {
          goto unsupported;
       }
 
@@ -371,14 +397,14 @@ get_image_format_properties(
    }
 
    if (image_usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {
-      if (!(format_feature_flags & VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) {
+      if (!(format_feature_flags & VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT)) {
          goto unsupported;
       }
    }
 
    if (view_usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
                      VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) {
-      if (!(format_feature_flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
+      if (!(format_feature_flags & VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT)) {
          goto unsupported;
       }
 
@@ -393,20 +419,20 @@ get_image_format_properties(
    }
 
    if (view_usage & VK_IMAGE_USAGE_STORAGE_BIT) {
-      if (!(format_feature_flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) {
+      if (!(format_feature_flags & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT)) {
          goto unsupported;
       }
    }
 
    if (view_usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
-      if (!(format_feature_flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) {
+      if (!(format_feature_flags & VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT)) {
          goto unsupported;
       }
    }
 
    if (view_usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
       if (!(format_feature_flags &
-            VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
+            VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT)) {
          goto unsupported;
       }
    }
@@ -464,8 +490,8 @@ get_image_format_properties(
    if (tiling != VK_IMAGE_TILING_LINEAR &&
        info->type == VK_IMAGE_TYPE_2D &&
        !(info->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) &&
-       (format_feature_flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT ||
-        format_feature_flags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
+       (format_feature_flags & VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT ||
+        format_feature_flags & VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT)) {
       pImageFormatProperties->sampleCounts |= VK_SAMPLE_COUNT_4_BIT;
    }
 
diff --git a/src/broadcom/vulkan/v3dv_meta_copy.c b/src/broadcom/vulkan/v3dv_meta_copy.c
index 67a6e51d280..a1dbbd9fd65 100644
--- a/src/broadcom/vulkan/v3dv_meta_copy.c
+++ b/src/broadcom/vulkan/v3dv_meta_copy.c
@@ -1989,7 +1989,7 @@ texel_buffer_shader_copy(struct v3dv_cmd_buffer *cmd_buffer,
    if (!(buffer->usage & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT)) {
       if (v3dv_buffer_format_supports_features(
              cmd_buffer->device, src_format,
-             VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT)) {
+             VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT)) {
          buffer->usage |= VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT;
       } else {
          return handled;
diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h
index 0e2a375c2ef..48001c6aa77 100644
--- a/src/broadcom/vulkan/v3dv_private.h
+++ b/src/broadcom/vulkan/v3dv_private.h
@@ -2001,7 +2001,7 @@ v3dv_get_compatible_tfu_format(struct v3dv_device *device,
                                uint32_t bpp, VkFormat *out_vk_format);
 bool v3dv_buffer_format_supports_features(struct v3dv_device *device,
                                           VkFormat vk_format,
-                                          VkFormatFeatureFlags features);
+                                          VkFormatFeatureFlags2KHR features);
 
 struct v3dv_cl_reloc v3dv_write_uniforms(struct v3dv_cmd_buffer *cmd_buffer,
                                          struct v3dv_pipeline *pipeline,



More information about the mesa-commit mailing list