Mesa (main): radv: implement VK_KHR_format_feature_flags2

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Oct 12 10:58:28 UTC 2021


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

Author: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Date:   Tue Aug 17 09:05:09 2021 +0200

radv: implement VK_KHR_format_feature_flags2

Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13194>

---

 docs/relnotes/new_features.txt |  1 +
 src/amd/vulkan/radv_android.c  | 81 +++++++++++++++++++++++++++++++++++++
 src/amd/vulkan/radv_device.c   |  1 +
 src/amd/vulkan/radv_formats.c  | 90 ++++++++++++++++++++++++++++++++++++++++--
 4 files changed, 169 insertions(+), 4 deletions(-)

diff --git a/docs/relnotes/new_features.txt b/docs/relnotes/new_features.txt
index 442cb309fda..840409c0864 100644
--- a/docs/relnotes/new_features.txt
+++ b/docs/relnotes/new_features.txt
@@ -18,3 +18,4 @@ Experimental raytracing support on RADV
 VK_KHR_synchronization2 on Intel
 NGG shader based culling is now enabled by default on GFX10.3 on RADV.
 VK_KHR_maintenance4 on RADV
+VK_KHR_format_feature_flags2 on RADV.
diff --git a/src/amd/vulkan/radv_android.c b/src/amd/vulkan/radv_android.c
index c89719bb0b8..dcfdfe3b80c 100644
--- a/src/amd/vulkan/radv_android.c
+++ b/src/amd/vulkan/radv_android.c
@@ -660,6 +660,82 @@ get_ahb_buffer_format_properties(VkDevice device_h, const struct AHardwareBuffer
    return VK_SUCCESS;
 }
 
+static VkResult
+get_ahb_buffer_format_properties2(VkDevice device_h, const struct AHardwareBuffer *buffer,
+                                  VkAndroidHardwareBufferFormatPropertiesANDROID2 *pProperties)
+{
+   RADV_FROM_HANDLE(radv_device, device, device_h);
+
+   /* Get a description of buffer contents . */
+   AHardwareBuffer_Desc desc;
+   AHardwareBuffer_describe(buffer, &desc);
+
+   /* Verify description. */
+   const uint64_t gpu_usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
+                              AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT |
+                              AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER;
+
+   /* "Buffer must be a valid Android hardware buffer object with at least
+    * one of the AHARDWAREBUFFER_USAGE_GPU_* usage flags."
+    */
+   if (!(desc.usage & (gpu_usage)))
+      return VK_ERROR_INVALID_EXTERNAL_HANDLE;
+
+   /* Fill properties fields based on description. */
+   VkAndroidHardwareBufferFormatPropertiesANDROID *p = pProperties;
+
+   p->format = vk_format_from_android(desc.format, desc.usage);
+   p->externalFormat = (uint64_t)(uintptr_t)p->format;
+
+   VkFormatProperties2 format_properties = {
+      .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2
+   };
+
+   radv_GetPhysicalDeviceFormatProperties2(radv_physical_device_to_handle(device->physical_device),
+                                               p->format, &format_properties);
+
+   if (desc.usage & AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER)
+      p->formatFeatures = format_properties.formatProperties.linearTilingFeatures;
+   else
+      p->formatFeatures = format_properties.formatProperties.optimalTilingFeatures;
+
+   /* "Images can be created with an external format even if the Android hardware
+    *  buffer has a format which has an equivalent Vulkan format to enable
+    *  consistent handling of images from sources that might use either category
+    *  of format. However, all images created with an external format are subject
+    *  to the valid usage requirements associated with external formats, even if
+    *  the Android hardware buffer’s format has a Vulkan equivalent."
+    *
+    * "The formatFeatures member *must* include
+    *  VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR and at least one of
+    *  VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT_KHR or
+    *  VK_FORMAT_FEATURE_2_COSITED_CHROMA_SAMPLES_BIT_KHR"
+    */
+   assert(p->formatFeatures & VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR);
+
+   p->formatFeatures |= VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT_KHR;
+
+   /* "Implementations may not always be able to determine the color model,
+    *  numerical range, or chroma offsets of the image contents, so the values
+    *  in VkAndroidHardwareBufferFormatPropertiesANDROID are only suggestions.
+    *  Applications should treat these values as sensible defaults to use in
+    *  the absence of more reliable information obtained through some other
+    *  means."
+    */
+   p->samplerYcbcrConversionComponents.r = VK_COMPONENT_SWIZZLE_IDENTITY;
+   p->samplerYcbcrConversionComponents.g = VK_COMPONENT_SWIZZLE_IDENTITY;
+   p->samplerYcbcrConversionComponents.b = VK_COMPONENT_SWIZZLE_IDENTITY;
+   p->samplerYcbcrConversionComponents.a = VK_COMPONENT_SWIZZLE_IDENTITY;
+
+   p->suggestedYcbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601;
+   p->suggestedYcbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
+
+   p->suggestedXChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
+   p->suggestedYChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
+
+   return VK_SUCCESS;
+}
+
 VkResult
 radv_GetAndroidHardwareBufferPropertiesANDROID(VkDevice device_h,
                                                const struct AHardwareBuffer *buffer,
@@ -675,6 +751,11 @@ radv_GetAndroidHardwareBufferPropertiesANDROID(VkDevice device_h,
    if (format_prop)
       get_ahb_buffer_format_properties(device_h, buffer, format_prop);
 
+   VkAndroidHardwareBufferFormatProperties2ANDROID *format_prop2 =
+      vk_find_struct(pProperties->pNext, ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_2_ANDROID);
+   if (format_prop2)
+      get_ahb_buffer_format_properties2(device_h, buffer, format_prop2);
+
    /* NOTE - We support buffers with only one handle but do not error on
     * multiple handle case. Reason is that we want to support YUV formats
     * where we have many logical planes but they all point to the same
diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c
index 7985cd93218..e30e308d3fc 100644
--- a/src/amd/vulkan/radv_device.c
+++ b/src/amd/vulkan/radv_device.c
@@ -424,6 +424,7 @@ radv_physical_device_get_supported_extensions(const struct radv_physical_device
       .KHR_external_memory_fd = true,
       .KHR_external_semaphore = true,
       .KHR_external_semaphore_fd = true,
+      .KHR_format_feature_flags2 = true,
       .KHR_fragment_shading_rate = device->rad_info.chip_class >= GFX10_3,
       .KHR_get_memory_requirements2 = true,
       .KHR_image_format_list = true,
diff --git a/src/amd/vulkan/radv_formats.c b/src/amd/vulkan/radv_formats.c
index 429f462cfdd..6ec05aa17fd 100644
--- a/src/amd/vulkan/radv_formats.c
+++ b/src/amd/vulkan/radv_formats.c
@@ -684,8 +684,12 @@ radv_physical_device_get_format_properties(struct radv_physical_device *physical
    }
 
    if (radv_is_storage_image_format_supported(physical_device, format)) {
-      tiled |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR;
-      linear |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR;
+      tiled |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR |
+               VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR |
+               VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR;
+      linear |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR |
+                VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR |
+                VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR;
    }
 
    if (radv_is_buffer_format_supported(format, &scaled)) {
@@ -707,8 +711,10 @@ radv_physical_device_get_format_properties(struct radv_physical_device *physical
          if (radv_is_filter_minmax_format_supported(format))
             tiled |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT_KHR;
 
-         if (vk_format_has_depth(format))
-            tiled |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT_KHR;
+         if (vk_format_has_depth(format)) {
+            tiled |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT_KHR |
+                     VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR;
+         }
 
          /* Don't support blitting surfaces with depth/stencil. */
          if (vk_format_has_depth(format) && vk_format_has_stencil(format))
@@ -1229,6 +1235,73 @@ radv_list_drm_format_modifiers(struct radv_physical_device *dev, VkFormat format
    free(mods);
 }
 
+static void
+radv_list_drm_format_modifiers_2(struct radv_physical_device *dev, VkFormat format,
+                                 VkFormatProperties2 *pFormatProperties)
+{
+   VkDrmFormatModifierPropertiesList2EXT *mod_list =
+      vk_find_struct(pFormatProperties, DRM_FORMAT_MODIFIER_PROPERTIES_LIST_2_EXT);
+   unsigned mod_count;
+
+   if (!mod_list)
+      return;
+
+   if (vk_format_is_compressed(format) || vk_format_is_depth_or_stencil(format)) {
+      mod_list->drmFormatModifierCount = 0;
+      return;
+   }
+
+   ac_get_supported_modifiers(&dev->rad_info, &radv_modifier_options,
+                              vk_format_to_pipe_format(format), &mod_count, NULL);
+   if (!mod_list->pDrmFormatModifierProperties) {
+      mod_list->drmFormatModifierCount = mod_count;
+      return;
+   }
+
+   mod_count = MIN2(mod_count, mod_list->drmFormatModifierCount);
+
+   uint64_t *mods = malloc(mod_count * sizeof(uint64_t));
+   if (!mods) {
+      /* We can't return an error here ... */
+      mod_list->drmFormatModifierCount = 0;
+      return;
+   }
+   ac_get_supported_modifiers(&dev->rad_info, &radv_modifier_options,
+                              vk_format_to_pipe_format(format), &mod_count, mods);
+
+   mod_list->drmFormatModifierCount = 0;
+   for (unsigned i = 0; i < mod_count; ++i) {
+      VkFormatProperties3KHR format_props;
+      VkFormatFeatureFlags2KHR features =
+         radv_get_modifier_flags(dev, format, mods[i], &format_props);
+      unsigned planes = vk_format_get_plane_count(format);
+      if (planes == 1) {
+         if (ac_modifier_has_dcc_retile(mods[i]))
+            planes = 3;
+         else if (ac_modifier_has_dcc(mods[i]))
+            planes = 2;
+      }
+
+      pFormatProperties->formatProperties.linearTilingFeatures = format_props.linearTilingFeatures;
+      pFormatProperties->formatProperties.optimalTilingFeatures = format_props.optimalTilingFeatures;
+      pFormatProperties->formatProperties.bufferFeatures = format_props.bufferFeatures;
+
+      if (!features)
+         continue;
+
+      mod_list->pDrmFormatModifierProperties[mod_list->drmFormatModifierCount].drmFormatModifier =
+         mods[i];
+      mod_list->pDrmFormatModifierProperties[mod_list->drmFormatModifierCount]
+         .drmFormatModifierPlaneCount = planes;
+      mod_list->pDrmFormatModifierProperties[mod_list->drmFormatModifierCount]
+         .drmFormatModifierTilingFeatures = features;
+
+      ++mod_list->drmFormatModifierCount;
+   }
+
+   free(mods);
+}
+
 static VkResult
 radv_check_modifier_support(struct radv_physical_device *dev,
                             const VkPhysicalDeviceImageFormatInfo2 *info,
@@ -1322,7 +1395,16 @@ radv_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice, VkForma
    pFormatProperties->formatProperties.bufferFeatures =
       features2_to_features(format_props.bufferFeatures);
 
+   VkFormatProperties3KHR *format_props_extended =
+      vk_find_struct(pFormatProperties, FORMAT_PROPERTIES_3_KHR);
+   if (format_props_extended) {
+      format_props_extended->linearTilingFeatures = format_props.linearTilingFeatures;
+      format_props_extended->optimalTilingFeatures = format_props.optimalTilingFeatures;
+      format_props_extended->bufferFeatures = format_props.bufferFeatures;
+   }
+
    radv_list_drm_format_modifiers(physical_device, format, pFormatProperties);
+   radv_list_drm_format_modifiers_2(physical_device, format, pFormatProperties);
 }
 
 static VkResult



More information about the mesa-commit mailing list