Mesa (main): dzn: Provide a helper to check if 2 formats are compatible

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Jul 6 06:29:45 UTC 2022


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

Author: Boris Brezillon <boris.brezillon at collabora.com>
Date:   Thu Jun 30 04:12:45 2022 -0700

dzn: Provide a helper to check if 2 formats are compatible

D3D12 supports fomat casting through optional features. Let's
add a helper to query whether 2 formats are compatible or not.
The compatibility depends on the formats+usage pair
(CopyTextureRegion() is less strict than the texture sampling
logic).

Reviewed-by: Jesse Natalie <jenatali at microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17368>

---

 src/microsoft/vulkan/dzn_image.c   | 47 +++++++++++++++++++++++++++++++++
 src/microsoft/vulkan/dzn_private.h |  7 +++++
 src/microsoft/vulkan/dzn_util.c    | 53 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 107 insertions(+)

diff --git a/src/microsoft/vulkan/dzn_image.c b/src/microsoft/vulkan/dzn_image.c
index b907f513d90..16d6f785841 100644
--- a/src/microsoft/vulkan/dzn_image.c
+++ b/src/microsoft/vulkan/dzn_image.c
@@ -587,6 +587,53 @@ dzn_image_layout_to_state(const struct dzn_image *image,
    }
 }
 
+bool
+dzn_image_formats_are_compatible(const struct dzn_device *device,
+                                 VkFormat orig_fmt, VkFormat new_fmt,
+                                 VkImageUsageFlags usage,
+                                 VkImageAspectFlagBits aspect)
+{
+   const struct dzn_physical_device *pdev =
+      container_of(device->vk.physical, struct dzn_physical_device, vk);
+   DXGI_FORMAT orig_dxgi = dzn_image_get_dxgi_format(orig_fmt, usage, aspect);
+   DXGI_FORMAT new_dxgi = dzn_image_get_dxgi_format(new_fmt, usage, aspect);
+
+   if (orig_dxgi == new_dxgi)
+      return true;
+
+   DXGI_FORMAT typeless_orig = dzn_get_typeless_dxgi_format(orig_dxgi);
+   DXGI_FORMAT typeless_new = dzn_get_typeless_dxgi_format(new_dxgi);
+
+   if (!(usage & VK_IMAGE_USAGE_SAMPLED_BIT))
+      return typeless_orig == typeless_new;
+
+   if (pdev->options3.CastingFullyTypedFormatSupported) {
+      enum pipe_format orig_pfmt = vk_format_to_pipe_format(orig_fmt);
+      enum pipe_format new_pfmt = vk_format_to_pipe_format(new_fmt);
+
+      /* Types don't belong to the same group, they're incompatible. */
+      if (typeless_orig != typeless_new)
+         return false;
+
+      /* FLOAT <-> non-FLOAT casting is disallowed. */
+      if (util_format_is_float(orig_pfmt) != util_format_is_float(new_pfmt))
+         return false;
+
+      /* UNORM <-> SNORM casting is disallowed. */
+      bool orig_is_norm =
+         util_format_is_unorm(orig_pfmt) || util_format_is_snorm(orig_pfmt);
+      bool new_is_norm =
+         util_format_is_unorm(new_pfmt) || util_format_is_snorm(new_pfmt);
+      if (orig_is_norm && new_is_norm &&
+          util_format_is_unorm(orig_pfmt) != util_format_is_unorm(new_pfmt))
+         return false;
+
+      return true;
+   }
+
+   return false;
+}
+
 VKAPI_ATTR VkResult VKAPI_CALL
 dzn_CreateImage(VkDevice device,
                 const VkImageCreateInfo *pCreateInfo,
diff --git a/src/microsoft/vulkan/dzn_private.h b/src/microsoft/vulkan/dzn_private.h
index 8d3b9b9ee8e..4c063ec001e 100644
--- a/src/microsoft/vulkan/dzn_private.h
+++ b/src/microsoft/vulkan/dzn_private.h
@@ -878,6 +878,12 @@ struct dzn_image {
    VkDeviceSize mem_offset;
 };
 
+bool
+dzn_image_formats_are_compatible(const struct dzn_device *device,
+                                 VkFormat orig_fmt, VkFormat new_fmt,
+                                 VkImageUsageFlags usage,
+                                 VkImageAspectFlagBits aspect);
+
 void
 dzn_image_align_extent(const struct dzn_image *image,
                        VkExtent3D *extent);
@@ -998,6 +1004,7 @@ struct dzn_sampler {
     (_image)->vk.mip_levels - (_range)->baseMipLevel : (_range)->levelCount)
 
 DXGI_FORMAT dzn_pipe_to_dxgi_format(enum pipe_format in);
+DXGI_FORMAT dzn_get_typeless_dxgi_format(DXGI_FORMAT in);
 D3D12_FILTER dzn_translate_sampler_filter(const VkSamplerCreateInfo *create_info);
 D3D12_COMPARISON_FUNC dzn_translate_compare_op(VkCompareOp in);
 void dzn_translate_viewport(D3D12_VIEWPORT *out, const VkViewport *in);
diff --git a/src/microsoft/vulkan/dzn_util.c b/src/microsoft/vulkan/dzn_util.c
index ba75301c109..753e664234b 100644
--- a/src/microsoft/vulkan/dzn_util.c
+++ b/src/microsoft/vulkan/dzn_util.c
@@ -155,6 +155,59 @@ dzn_pipe_to_dxgi_format(enum pipe_format in)
    return formats[in];
 }
 
+DXGI_FORMAT
+dzn_get_typeless_dxgi_format(DXGI_FORMAT in)
+{
+   if (in >= DXGI_FORMAT_R32G32B32A32_TYPELESS && in <= DXGI_FORMAT_R32G32B32A32_SINT)
+      return DXGI_FORMAT_R32G32B32A32_TYPELESS;
+   if (in >= DXGI_FORMAT_R32G32B32_TYPELESS && in <= DXGI_FORMAT_R32G32B32_SINT)
+      return DXGI_FORMAT_R32G32B32_TYPELESS;
+   if (in >= DXGI_FORMAT_R16G16B16A16_TYPELESS && in <= DXGI_FORMAT_R16G16B16A16_SINT)
+      return DXGI_FORMAT_R16G16B16A16_TYPELESS;
+   if (in <= DXGI_FORMAT_R32G32_TYPELESS && in >= DXGI_FORMAT_R32G32_SINT)
+      return DXGI_FORMAT_R32G32_TYPELESS;
+   if (in <= DXGI_FORMAT_R32G8X24_TYPELESS && in >= DXGI_FORMAT_X32_TYPELESS_G8X24_UINT)
+      return DXGI_FORMAT_R32G8X24_TYPELESS;
+   if (in <= DXGI_FORMAT_R10G10B10A2_TYPELESS && in >= DXGI_FORMAT_R10G10B10A2_UINT)
+      return DXGI_FORMAT_R10G10B10A2_TYPELESS;
+   if (in <= DXGI_FORMAT_R8G8B8A8_TYPELESS && in >= DXGI_FORMAT_R8G8B8A8_SINT)
+      return DXGI_FORMAT_R8G8B8A8_TYPELESS;
+   if (in <= DXGI_FORMAT_R16G16_TYPELESS && in >= DXGI_FORMAT_R16G16_SINT)
+      return DXGI_FORMAT_R16G16_TYPELESS;
+   if (in <= DXGI_FORMAT_R32_TYPELESS && in >= DXGI_FORMAT_R32_SINT)
+      return DXGI_FORMAT_R32_TYPELESS;
+   if (in <= DXGI_FORMAT_R24G8_TYPELESS && in >= DXGI_FORMAT_X24_TYPELESS_G8_UINT)
+      return DXGI_FORMAT_R24G8_TYPELESS;
+   if (in <= DXGI_FORMAT_R8G8_TYPELESS && in >= DXGI_FORMAT_R8G8_SINT)
+      return DXGI_FORMAT_R8G8_TYPELESS;
+   if (in <= DXGI_FORMAT_R16_TYPELESS && in >= DXGI_FORMAT_R16_SINT)
+      return DXGI_FORMAT_R16_TYPELESS;
+   if (in <= DXGI_FORMAT_R8_TYPELESS && in >= DXGI_FORMAT_R8_SINT)
+      return DXGI_FORMAT_R8_TYPELESS;
+   if (in <= DXGI_FORMAT_BC1_TYPELESS && in >= DXGI_FORMAT_BC1_UNORM_SRGB)
+      return DXGI_FORMAT_BC1_TYPELESS;
+   if (in <= DXGI_FORMAT_BC2_TYPELESS && in >= DXGI_FORMAT_BC2_UNORM_SRGB)
+      return DXGI_FORMAT_BC2_TYPELESS;
+   if (in <= DXGI_FORMAT_BC3_TYPELESS && in >= DXGI_FORMAT_BC3_UNORM_SRGB)
+      return DXGI_FORMAT_BC3_TYPELESS;
+   if (in <= DXGI_FORMAT_BC4_TYPELESS && in >= DXGI_FORMAT_BC4_SNORM)
+      return DXGI_FORMAT_BC4_TYPELESS;
+   if (in <= DXGI_FORMAT_BC5_TYPELESS && in >= DXGI_FORMAT_BC5_SNORM)
+      return DXGI_FORMAT_BC5_TYPELESS;
+   if (in == DXGI_FORMAT_B8G8R8A8_UNORM ||
+       (in <= DXGI_FORMAT_B8G8R8A8_TYPELESS && in >= DXGI_FORMAT_B8G8R8A8_UNORM_SRGB))
+      return DXGI_FORMAT_B8G8R8A8_TYPELESS;
+   if (in == DXGI_FORMAT_B8G8R8X8_UNORM ||
+       (in <= DXGI_FORMAT_B8G8R8X8_TYPELESS && in >= DXGI_FORMAT_B8G8R8X8_UNORM_SRGB))
+      return DXGI_FORMAT_B8G8R8X8_TYPELESS;
+   if (in <= DXGI_FORMAT_BC6H_TYPELESS && in >= DXGI_FORMAT_BC6H_SF16)
+      return DXGI_FORMAT_BC6H_TYPELESS;
+   if (in <= DXGI_FORMAT_BC7_TYPELESS && in >= DXGI_FORMAT_BC7_UNORM_SRGB)
+      return DXGI_FORMAT_BC7_TYPELESS;
+
+   return in;
+}
+
 struct dzn_sampler_filter_info {
    VkFilter min, mag;
    VkSamplerMipmapMode mipmap;



More information about the mesa-commit mailing list