Mesa (main): tu: Fix stencil border color with has_z24uint_s8uint

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Jun 29 03:37:28 UTC 2022


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

Author: Connor Abbott <cwabbott0 at gmail.com>
Date:   Wed Jun 22 00:08:49 2022 +0200

tu: Fix stencil border color with has_z24uint_s8uint

On a650+ we use the new Z24UINT_S8UINT format to sample the stencil
aspect of D24S8, which returns stencil in the second component and also
uses the second integer component for the border color. However Vulkan
mandates that the first component is used for the stencil border color.
There's no workaround we know of, so we have to fall back to the old
behavior where there is a workaround. If we know the format, we can
fixup the border color ourselves though.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17177>

---

 src/freedreno/fdl/fd6_view.c      |  6 ++++--
 src/freedreno/vulkan/tu_device.c  | 23 ++++++++++++++++++++++-
 src/freedreno/vulkan/tu_formats.c |  4 ++--
 src/freedreno/vulkan/tu_image.c   | 12 ++++++++----
 src/freedreno/vulkan/tu_private.h |  5 ++++-
 5 files changed, 40 insertions(+), 10 deletions(-)

diff --git a/src/freedreno/fdl/fd6_view.c b/src/freedreno/fdl/fd6_view.c
index 851533de789..34dd9a8d26c 100644
--- a/src/freedreno/fdl/fd6_view.c
+++ b/src/freedreno/fdl/fd6_view.c
@@ -110,8 +110,10 @@ fdl6_format_swiz(enum pipe_format format, bool has_z24uint_s8uint,
          format_swiz[2] = PIPE_SWIZZLE_0;
          format_swiz[3] = PIPE_SWIZZLE_1;
       } else {
-         /* using FMT6_Z24_UINT_S8_UINT, which is (d, s, 0, 1), so need to
-          * swizzle away the d.
+         /* Using FMT6_Z24_UINT_S8_UINT, which is (d, s, 0, 1), so need to
+          * swizzle away the d. We don't use this if
+          * customBorderColorWithoutFormat is enabled, so we can fix up the
+          * border color, and there's a workaround in freedreno.
           */
          format_swiz[0] = PIPE_SWIZZLE_Y;
          format_swiz[1] = PIPE_SWIZZLE_0;
diff --git a/src/freedreno/vulkan/tu_device.c b/src/freedreno/vulkan/tu_device.c
index 7e5e8505754..9c09bbd647d 100644
--- a/src/freedreno/vulkan/tu_device.c
+++ b/src/freedreno/vulkan/tu_device.c
@@ -1734,12 +1734,15 @@ tu_CreateDevice(VkPhysicalDevice physicalDevice,
    bool custom_border_colors = false;
    bool perf_query_pools = false;
    bool robust_buffer_access2 = false;
+   bool border_color_without_format = false;
 
    vk_foreach_struct_const(ext, pCreateInfo->pNext) {
       switch (ext->sType) {
       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT: {
          const VkPhysicalDeviceCustomBorderColorFeaturesEXT *border_color_features = (const void *)ext;
          custom_border_colors = border_color_features->customBorderColors;
+         border_color_without_format =
+            border_color_features->customBorderColorWithoutFormat;
          break;
       }
       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_FEATURES_KHR: {
@@ -1962,6 +1965,10 @@ tu_CreateDevice(VkPhysicalDevice physicalDevice,
 
    mtx_init(&device->mutex, mtx_plain);
 
+   device->use_z24uint_s8uint =
+      physical_device->info->a6xx.has_z24uint_s8uint &&
+      !border_color_without_format;
+
    device->submit_count = 0;
    u_trace_context_init(&device->trace_context, device,
                      tu_trace_create_ts_buffer,
@@ -2638,8 +2645,22 @@ tu_init_sampler(struct tu_device *device,
       assert(border_color < TU_BORDER_COLOR_COUNT);
       BITSET_CLEAR(device->custom_border_color, border_color);
       mtx_unlock(&device->mutex);
+
+      VkClearColorValue color = custom_border_color->customBorderColor;
+      if (custom_border_color->format == VK_FORMAT_D24_UNORM_S8_UINT &&
+          pCreateInfo->borderColor == VK_BORDER_COLOR_INT_CUSTOM_EXT &&
+          device->use_z24uint_s8uint) {
+         /* When sampling stencil using the special Z24UINT_S8UINT format, the
+          * border color is in the second component. Note: if
+          * customBorderColorWithoutFormat is enabled, we may miss doing this
+          * here if the format isn't specified, which is why we don't use that
+          * format.
+          */
+         color.uint32[1] = color.uint32[0];
+      }
+
       tu6_pack_border_color(device->global_bo->map + gb_offset(bcolor[border_color]),
-                            &custom_border_color->customBorderColor,
+                            &color,
                             pCreateInfo->borderColor == VK_BORDER_COLOR_INT_CUSTOM_EXT);
       border_color += TU_BORDER_COLOR_BUILTIN;
    }
diff --git a/src/freedreno/vulkan/tu_formats.c b/src/freedreno/vulkan/tu_formats.c
index 3e4e6d5cd7b..c24648bf3b5 100644
--- a/src/freedreno/vulkan/tu_formats.c
+++ b/src/freedreno/vulkan/tu_formats.c
@@ -348,7 +348,7 @@ tu_GetPhysicalDeviceFormatProperties2(
       /* note: ubwc_possible() argument values to be ignored except for format */
       if (pFormatProperties->formatProperties.optimalTilingFeatures &&
           tiling_possible(format) &&
-          ubwc_possible(format, VK_IMAGE_TYPE_2D, 0, 0, physical_device->info, VK_SAMPLE_COUNT_1_BIT)) {
+          ubwc_possible(format, VK_IMAGE_TYPE_2D, 0, 0, physical_device->info, VK_SAMPLE_COUNT_1_BIT, false)) {
          vk_outarray_append_typed(VkDrmFormatModifierPropertiesEXT, &out, mod_props) {
             mod_props->drmFormatModifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
             mod_props->drmFormatModifierPlaneCount = tu6_plane_count(format);
@@ -399,7 +399,7 @@ tu_get_image_format_properties(
             return VK_ERROR_FORMAT_NOT_SUPPORTED;
 
 
-         if (!ubwc_possible(info->format, info->type, info->usage, info->usage, physical_device->info, sampleCounts))
+         if (!ubwc_possible(info->format, info->type, info->usage, info->usage, physical_device->info, sampleCounts, false))
             return VK_ERROR_FORMAT_NOT_SUPPORTED;
 
          format_feature_flags = format_props.optimalTilingFeatures;
diff --git a/src/freedreno/vulkan/tu_image.c b/src/freedreno/vulkan/tu_image.c
index 5dcc5c1bd71..bf892ccbdf8 100644
--- a/src/freedreno/vulkan/tu_image.c
+++ b/src/freedreno/vulkan/tu_image.c
@@ -286,7 +286,7 @@ tiling_possible(VkFormat format)
 bool
 ubwc_possible(VkFormat format, VkImageType type, VkImageUsageFlags usage,
               VkImageUsageFlags stencil_usage, const struct fd_dev_info *info,
-              VkSampleCountFlagBits samples)
+              VkSampleCountFlagBits samples, bool use_z24uint_s8uint)
 {
    /* no UBWC with compressed formats, E5B9G9R9, S8_UINT
     * (S8_UINT because separate stencil doesn't have UBWC-enable bit)
@@ -336,10 +336,13 @@ ubwc_possible(VkFormat format, VkImageType type, VkImageUsageFlags usage,
     *
     * It must be sampled as FMT6_8_8_8_8_UINT, which is not UBWC-compatible
     *
+    * If we wish to get the border colors correct without knowing the format
+    * when creating the sampler, we also have to use the A630 workaround.
+    *
     * 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 (!info->a6xx.has_z24uint_s8uint &&
+   if (!use_z24uint_s8uint &&
        format == VK_FORMAT_D24_UNORM_S8_UINT &&
        (stencil_usage & (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)))
       return false;
@@ -452,7 +455,8 @@ tu_image_init(struct tu_device *device, struct tu_image *image,
 
    if (!ubwc_possible(image->vk_format, pCreateInfo->imageType, pCreateInfo->usage,
                       stencil_usage_info ? stencil_usage_info->stencilUsage : pCreateInfo->usage,
-                      device->physical_device->info, pCreateInfo->samples))
+                      device->physical_device->info, pCreateInfo->samples,
+                      device->use_z24uint_s8uint))
       ubwc_enabled = false;
 
    /* expect UBWC enabled if we asked for it */
@@ -827,7 +831,7 @@ tu_CreateImageView(VkDevice _device,
    if (view == NULL)
       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
 
-   tu_image_view_init(view, pCreateInfo, device->physical_device->info->a6xx.has_z24uint_s8uint);
+   tu_image_view_init(view, pCreateInfo, device->use_z24uint_s8uint);
 
    *pView = tu_image_view_to_handle(view);
 
diff --git a/src/freedreno/vulkan/tu_private.h b/src/freedreno/vulkan/tu_private.h
index 8b2ccd8b5ec..38735010d83 100644
--- a/src/freedreno/vulkan/tu_private.h
+++ b/src/freedreno/vulkan/tu_private.h
@@ -614,6 +614,8 @@ struct tu_device
    #ifdef HAVE_PERFETTO
    struct tu_perfetto_state perfetto;
    #endif
+
+   bool use_z24uint_s8uint;
 };
 
 void tu_init_clear_blit_shaders(struct tu_device *dev);
@@ -1851,7 +1853,8 @@ tiling_possible(VkFormat format);
 
 bool
 ubwc_possible(VkFormat format, VkImageType type, VkImageUsageFlags usage, VkImageUsageFlags stencil_usage,
-              const struct fd_dev_info *info, VkSampleCountFlagBits samples);
+              const struct fd_dev_info *info, VkSampleCountFlagBits samples,
+              bool use_z24uint_s8uint);
 
 struct tu_buffer_view
 {



More information about the mesa-commit mailing list