Mesa (master): turnip: enable VK_EXT_image_drm_format_modifier

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Nov 5 18:25:16 UTC 2020


Module: Mesa
Branch: master
Commit: b2c719308c5d691b84d3ac7dfca9f9704b5f74bd
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=b2c719308c5d691b84d3ac7dfca9f9704b5f74bd

Author: Jonathan Marek <jonathan at marek.ca>
Date:   Wed Sep 30 11:33:46 2020 -0400

turnip: enable VK_EXT_image_drm_format_modifier

Add missing GetPhysicalDeviceImageFormatProperties2 logic for the extension
and enable it.

Also stop exposing optimal tiling for formats which are linear only, to
simplify dealing with those.

Passes dEQP-VK.drm_format_modifiers.*

Signed-off-by: Jonathan Marek <jonathan at marek.ca>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6940>

---

 src/freedreno/vulkan/tu_extensions.py |   2 +-
 src/freedreno/vulkan/tu_formats.c     |  70 ++++++++++++++++-------
 src/freedreno/vulkan/tu_image.c       | 105 +++++++++++++++++-----------------
 src/freedreno/vulkan/tu_private.h     |   3 +
 4 files changed, 105 insertions(+), 75 deletions(-)

diff --git a/src/freedreno/vulkan/tu_extensions.py b/src/freedreno/vulkan/tu_extensions.py
index 1bbb107c430..4c34bdc8c4f 100644
--- a/src/freedreno/vulkan/tu_extensions.py
+++ b/src/freedreno/vulkan/tu_extensions.py
@@ -70,7 +70,7 @@ EXTENSIONS = [
     Extension('VK_KHR_external_memory',                   1, True),
     Extension('VK_KHR_external_memory_fd',                1, True),
     Extension('VK_EXT_external_memory_dma_buf',           1, True),
-    Extension('VK_EXT_image_drm_format_modifier',         1, False),
+    Extension('VK_EXT_image_drm_format_modifier',         1, True),
     Extension('VK_EXT_sample_locations',                  1, 'device->gpu_id == 650'),
     Extension('VK_EXT_sampler_filter_minmax',             1, True),
     Extension('VK_EXT_transform_feedback',                1, True),
diff --git a/src/freedreno/vulkan/tu_formats.c b/src/freedreno/vulkan/tu_formats.c
index 1b3597f6802..f3208780fe2 100644
--- a/src/freedreno/vulkan/tu_formats.c
+++ b/src/freedreno/vulkan/tu_formats.c
@@ -451,6 +451,17 @@ tu_physical_device_get_format_properties(
    if (tu6_pipe2depth(format) != (enum a6xx_depth_format)~0)
       optimal |= VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT;
 
+   /* no tiling for special UBWC formats
+    * TODO: NV12 can be UBWC but has a special UBWC format for accessing the Y plane aspect
+    * for 3plane, tiling/UBWC might be supported, but the blob doesn't use tiling
+    */
+   if (format == VK_FORMAT_G8B8G8R8_422_UNORM ||
+       format == VK_FORMAT_B8G8R8G8_422_UNORM ||
+       format == VK_FORMAT_G8_B8R8_2PLANE_420_UNORM ||
+       format == VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM) {
+      optimal = 0;
+   }
+
    /* D32_SFLOAT_S8_UINT is tiled as two images, so no linear format
     * blob enables some linear features, but its not useful, so don't bother.
     */
@@ -480,15 +491,20 @@ tu_GetPhysicalDeviceFormatProperties2(
       VK_OUTARRAY_MAKE(out, list->pDrmFormatModifierProperties,
                        &list->drmFormatModifierCount);
 
-      vk_outarray_append(&out, mod_props) {
-         mod_props->drmFormatModifier = DRM_FORMAT_MOD_LINEAR;
-         mod_props->drmFormatModifierPlaneCount = 1;
+      if (pFormatProperties->formatProperties.linearTilingFeatures) {
+         vk_outarray_append(&out, mod_props) {
+            mod_props->drmFormatModifier = DRM_FORMAT_MOD_LINEAR;
+            mod_props->drmFormatModifierPlaneCount = 1;
+         }
       }
 
-      /* TODO: any cases where this should be disabled? */
-      vk_outarray_append(&out, mod_props) {
-         mod_props->drmFormatModifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
-         mod_props->drmFormatModifierPlaneCount = 1;
+      /* note: ubwc_possible() argument values to be ignored except for format */
+      if (pFormatProperties->formatProperties.optimalTilingFeatures &&
+          ubwc_possible(format, VK_IMAGE_TYPE_2D, 0, false)) {
+         vk_outarray_append(&out, mod_props) {
+            mod_props->drmFormatModifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
+            mod_props->drmFormatModifierPlaneCount = 1;
+         }
       }
    }
 }
@@ -515,20 +531,34 @@ tu_get_image_format_properties(
       format_feature_flags = format_props.linearTilingFeatures;
       break;
 
-   case VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT:
-      /* The only difference between optimal and linear is currently whether
-       * depth/stencil attachments are allowed on depth/stencil formats.
-       * There's no reason to allow importing depth/stencil textures, so just
-       * disallow it and then this annoying edge case goes away.
-       *
-       * TODO: If anyone cares, we could enable this by looking at the
-       * modifier and checking if it's LINEAR or not.
-       */
-      if (vk_format_is_depth_or_stencil(info->format))
-         goto unsupported;
+   case VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT: {
+      const VkPhysicalDeviceImageDrmFormatModifierInfoEXT *drm_info =
+         vk_find_struct_const(info->pNext, PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT);
+
+      switch (drm_info->drmFormatModifier) {
+      case DRM_FORMAT_MOD_QCOM_COMPRESSED:
+         /* falling back to linear/non-UBWC isn't possible with explicit modifier */
 
-      assert(format_props.optimalTilingFeatures == format_props.linearTilingFeatures);
-      /* fallthrough */
+         /* formats which don't support tiling */
+         if (!format_props.optimalTilingFeatures)
+            return VK_ERROR_FORMAT_NOT_SUPPORTED;
+
+         /* for mutable formats, its very unlikely to be possible to use UBWC */
+         if (info->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT)
+            return VK_ERROR_FORMAT_NOT_SUPPORTED;
+
+         if (!ubwc_possible(info->format, info->type, info->usage, physical_device->limited_z24s8))
+            return VK_ERROR_FORMAT_NOT_SUPPORTED;
+
+         format_feature_flags = format_props.optimalTilingFeatures;
+         break;
+      case DRM_FORMAT_MOD_LINEAR:
+         format_feature_flags = format_props.linearTilingFeatures;
+         break;
+      default:
+         return VK_ERROR_FORMAT_NOT_SUPPORTED;
+      }
+   } break;
    case VK_IMAGE_TILING_OPTIMAL:
       format_feature_flags = format_props.optimalTilingFeatures;
       break;
diff --git a/src/freedreno/vulkan/tu_image.c b/src/freedreno/vulkan/tu_image.c
index 0db7fec18e4..4679c8be929 100644
--- a/src/freedreno/vulkan/tu_image.c
+++ b/src/freedreno/vulkan/tu_image.c
@@ -446,6 +446,53 @@ tu_image_view_init(struct tu_image_view *iview,
    }
 }
 
+bool
+ubwc_possible(VkFormat format, VkImageType type, VkImageUsageFlags usage, bool limited_z24s8)
+{
+   /* no UBWC with compressed formats, E5B9G9R9, S8_UINT
+    * (S8_UINT because separate stencil doesn't have UBWC-enable bit)
+    */
+   if (vk_format_is_compressed(format) ||
+       format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 ||
+       format == VK_FORMAT_S8_UINT)
+      return false;
+
+   if (type == VK_IMAGE_TYPE_3D) {
+      tu_finishme("UBWC with 3D textures");
+      return false;
+   }
+
+   /* Disable UBWC for storage images.
+    *
+    * The closed GL driver skips UBWC for storage images (and additionally
+    * uses linear for writeonly images).  We seem to have image tiling working
+    * in freedreno in general, so turnip matches that.  freedreno also enables
+    * UBWC on images, but it's not really tested due to the lack of
+    * UBWC-enabled mipmaps in freedreno currently.  Just match the closed GL
+    * behavior of no UBWC.
+   */
+   if (usage & VK_IMAGE_USAGE_STORAGE_BIT)
+      return false;
+
+   /* Disable UBWC for D24S8 on A630 in some cases
+    *
+    * VK_IMAGE_ASPECT_STENCIL_BIT image view requires to be able to sample
+    * from the stencil component as UINT, however no format allows this
+    * on a630 (the special FMT6_Z24_UINT_S8_UINT format is missing)
+    *
+    * It must be sampled as FMT6_8_8_8_8_UINT, which is not UBWC-compatible
+    *
+    * Additionally, the special AS_R8G8B8A8 format is broken without UBWC,
+    * so we have to fallback to 8_8_8_8_UNORM when UBWC is disabled
+    */
+   if (limited_z24s8 &&
+       format == VK_FORMAT_D24_UNORM_S8_UINT &&
+       (usage & (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)))
+      return false;
+
+   return true;
+}
+
 VkResult
 tu_CreateImage(VkDevice _device,
                const VkImageCreateInfo *pCreateInfo,
@@ -510,16 +557,8 @@ tu_CreateImage(VkDevice _device,
    bool ubwc_enabled =
       !(device->physical_device->instance->debug_flags & TU_DEBUG_NOUBWC);
 
-   /* use linear tiling if requested and for special ycbcr formats
-    * TODO: NV12 can be UBWC but has a special UBWC format for accessing the Y plane aspect
-    * for 3plane, tiling/UBWC might be supported, but the blob doesn't use tiling
-    */
-   if (pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR ||
-       modifier == DRM_FORMAT_MOD_LINEAR ||
-       image->vk_format == VK_FORMAT_G8B8G8R8_422_UNORM ||
-       image->vk_format == VK_FORMAT_B8G8R8G8_422_UNORM ||
-       image->vk_format == VK_FORMAT_G8_B8R8_2PLANE_420_UNORM ||
-       image->vk_format == VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM) {
+   /* use linear tiling if requested */
+   if (pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR || modifier == DRM_FORMAT_MOD_LINEAR) {
       tile_mode = TILE6_LINEAR;
       ubwc_enabled = false;
    }
@@ -555,51 +594,9 @@ tu_CreateImage(VkDevice _device,
       ubwc_enabled = false;
    }
 
-   /* don't use UBWC with compressed formats */
-   if (vk_format_is_compressed(image->vk_format))
-      ubwc_enabled = false;
-
-   /* UBWC can't be used with E5B9G9R9 */
-   if (image->vk_format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32)
-      ubwc_enabled = false;
-
-   /* separate stencil doesn't have a UBWC enable bit */
-   if (image->vk_format == VK_FORMAT_S8_UINT)
-      ubwc_enabled = false;
-
-   if (pCreateInfo->extent.depth > 1) {
-      tu_finishme("UBWC with 3D textures");
-      ubwc_enabled = false;
-   }
-
-   /* Disable UBWC for storage images.
-    *
-    * The closed GL driver skips UBWC for storage images (and additionally
-    * uses linear for writeonly images).  We seem to have image tiling working
-    * in freedreno in general, so turnip matches that.  freedreno also enables
-    * UBWC on images, but it's not really tested due to the lack of
-    * UBWC-enabled mipmaps in freedreno currently.  Just match the closed GL
-    * behavior of no UBWC.
-   */
-   if (pCreateInfo->usage & VK_IMAGE_USAGE_STORAGE_BIT)
-      ubwc_enabled = false;
-
-   /* Disable UBWC for D24S8 on A630 in some cases
-    *
-    * VK_IMAGE_ASPECT_STENCIL_BIT image view requires to be able to sample
-    * from the stencil component as UINT, however no format allows this
-    * on a630 (the special FMT6_Z24_UINT_S8_UINT format is missing)
-    *
-    * It must be sampled as FMT6_8_8_8_8_UINT, which is not UBWC-compatible
-    *
-    * Additionally, the special AS_R8G8B8A8 format is broken without UBWC,
-    * so we have to fallback to 8_8_8_8_UNORM when UBWC is disabled
-    */
-   if (device->physical_device->limited_z24s8 &&
-       image->vk_format == VK_FORMAT_D24_UNORM_S8_UINT &&
-       (pCreateInfo->usage & (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))) {
+   if (!ubwc_possible(image->vk_format, pCreateInfo->imageType, pCreateInfo->usage,
+                      device->physical_device->limited_z24s8))
       ubwc_enabled = false;
-   }
 
    /* expect UBWC enabled if we asked for it */
    assert(modifier != DRM_FORMAT_MOD_QCOM_COMPRESSED || ubwc_enabled);
diff --git a/src/freedreno/vulkan/tu_private.h b/src/freedreno/vulkan/tu_private.h
index 12e317337dd..6fbd4857216 100644
--- a/src/freedreno/vulkan/tu_private.h
+++ b/src/freedreno/vulkan/tu_private.h
@@ -1380,6 +1380,9 @@ tu_image_view_init(struct tu_image_view *iview,
                    const VkImageViewCreateInfo *pCreateInfo,
                    bool limited_z24s8);
 
+bool
+ubwc_possible(VkFormat format, VkImageType type, VkImageUsageFlags usage, bool limited_z24s8);
+
 struct tu_buffer_view
 {
    struct vk_object_base base;



More information about the mesa-commit mailing list