Mesa (main): zink: workaround depth sampler border color when z24 is z32

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Jun 30 00:40:25 UTC 2022


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

Author: Dave Airlie <airlied at redhat.com>
Date:   Thu Jun 30 07:06:15 2022 +1000

zink: workaround depth sampler border color when z24 is z32

If there is a z24 unorm depth buffer, but it's the hw is using
a z32, the border color needs to be clamped appropriately.

This creates a second sampler with the clamped border color,
and uses it if needed. The checks might need some tightening up.

Fixes: zink on radv
dEQP-GLES31.functional.texture.border_clamp.range_clamp.nearest_unorm_depth
dEQP-GLES31.functional.texture.border_clamp.range_clamp.nearest_unorm_depth_uint_stencil_sample_depth

Reviewed-By: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17305>

---

 src/gallium/drivers/zink/ci/zink-radv-fails.txt |  6 ---
 src/gallium/drivers/zink/zink_context.c         | 57 +++++++++++++++++++++++--
 src/gallium/drivers/zink/zink_context.h         |  1 +
 3 files changed, 55 insertions(+), 9 deletions(-)

diff --git a/src/gallium/drivers/zink/ci/zink-radv-fails.txt b/src/gallium/drivers/zink/ci/zink-radv-fails.txt
index 48945301922..cbb8293d2e1 100644
--- a/src/gallium/drivers/zink/ci/zink-radv-fails.txt
+++ b/src/gallium/drivers/zink/ci/zink-radv-fails.txt
@@ -32,12 +32,6 @@ dEQP-GLES31.functional.primitive_bounding_box.wide_points.tessellation_set_per_p
 dEQP-GLES31.functional.shaders.multisample_interpolation.interpolate_at_sample.non_multisample_buffer.sample_n_default_framebuffer,Fail
 dEQP-GLES31.functional.shaders.multisample_interpolation.interpolate_at_sample.non_multisample_buffer.sample_n_singlesample_rbo,Fail
 dEQP-GLES31.functional.shaders.multisample_interpolation.interpolate_at_sample.non_multisample_buffer.sample_n_singlesample_texture,Fail
-dEQP-GLES31.functional.texture.border_clamp.formats.stencil_index8.nearest_size_npot,Fail
-dEQP-GLES31.functional.texture.border_clamp.formats.stencil_index8.nearest_size_pot,Fail
-dEQP-GLES31.functional.texture.border_clamp.range_clamp.nearest_unorm_depth,Fail
-dEQP-GLES31.functional.texture.border_clamp.range_clamp.nearest_unorm_depth_uint_stencil_sample_depth,Fail
-dEQP-GLES31.functional.texture.border_clamp.sampler.uint_stencil,Fail
-dEQP-GLES31.functional.texture.border_clamp.unused_channels.stencil_index8,Fail
 dEQP-GLES3.functional.clipping.line.wide_line_clip_viewport_center,Fail
 dEQP-GLES3.functional.clipping.line.wide_line_clip_viewport_corner,Fail
 dEQP-GLES3.functional.clipping.point.wide_point_clip,Fail
diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c
index 3fb3664e04c..347bea9f158 100644
--- a/src/gallium/drivers/zink/zink_context.c
+++ b/src/gallium/drivers/zink/zink_context.c
@@ -305,9 +305,10 @@ zink_create_sampler_state(struct pipe_context *pctx,
 {
    struct zink_screen *screen = zink_screen(pctx->screen);
    bool need_custom = false;
-
+   bool need_clamped_border_color = false;
    VkSamplerCreateInfo sci = {0};
    VkSamplerCustomBorderColorCreateInfoEXT cbci = {0};
+   VkSamplerCustomBorderColorCreateInfoEXT cbci_clamped = {0};
    sci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
    if (screen->info.have_EXT_non_seamless_cube_map && !state->seamless_cube_map)
       sci.flags |= VK_SAMPLER_CREATE_NON_SEAMLESS_CUBE_MAP_BIT_EXT;
@@ -381,6 +382,22 @@ zink_create_sampler_state(struct pipe_context *pctx,
             static bool warned = false;
             warn_missing_feature(warned, "VK_EXT_border_color_swizzle");
          }
+
+         if (!is_integer && !screen->have_D24_UNORM_S8_UINT) {
+            union pipe_color_union clamped_border_color;
+            for (unsigned i = 0; i < 4; ++i) {
+               /* Use channel 0 on purpose, so that we can use OPAQUE_WHITE
+                * when the border color is 1.0. */
+               clamped_border_color.f[i] = CLAMP(state->border_color.f[0], 0, 1);
+            }
+            if (memcmp(&state->border_color, &clamped_border_color, sizeof(clamped_border_color)) != 0) {
+               need_clamped_border_color = true;
+               cbci_clamped.sType = VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT;
+               cbci_clamped.format = VK_FORMAT_UNDEFINED;
+               /* these are identical unions */
+               memcpy(&cbci_clamped.customBorderColor, &clamped_border_color, sizeof(union pipe_color_union));
+            }
+         }
          cbci.sType = VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT;
          cbci.format = VK_FORMAT_UNDEFINED;
          /* these are identical unions */
@@ -409,6 +426,15 @@ zink_create_sampler_state(struct pipe_context *pctx,
       FREE(sampler);
       return NULL;
    }
+   if (need_clamped_border_color) {
+      sci.pNext = &cbci_clamped;
+      if (VKSCR(CreateSampler)(screen->dev, &sci, NULL, &sampler->sampler_clamped) != VK_SUCCESS) {
+         mesa_loge("ZINK: vkCreateSampler failed");
+         VKSCR(DestroySampler)(screen->dev, sampler->sampler, NULL);
+         FREE(sampler);
+         return NULL;
+      }
+   }
    util_dynarray_init(&sampler->desc_set_refs.refs, NULL);
    calc_descriptor_hash_sampler_state(sampler);
    sampler->custom_border_color = need_custom;
@@ -539,6 +565,18 @@ update_descriptor_state_sampler(struct zink_context *ctx, enum pipe_shader_type
          struct zink_surface *surface = get_imageview_for_binding(ctx, shader, type, slot);
          ctx->di.textures[shader][slot].imageLayout = get_layout_for_binding(ctx, res, type, shader == PIPE_SHADER_COMPUTE);
          ctx->di.textures[shader][slot].imageView = surface->image_view;
+         if (!screen->have_D24_UNORM_S8_UINT &&
+             ctx->sampler_states[shader][slot] && ctx->sampler_states[shader][slot]->sampler_clamped) {
+            struct zink_sampler_state *state = ctx->sampler_states[shader][slot];
+            VkSampler sampler = (surface->base.format == PIPE_FORMAT_Z24X8_UNORM && surface->ivci.format == VK_FORMAT_D32_SFLOAT) ||
+                                (surface->base.format == PIPE_FORMAT_Z24_UNORM_S8_UINT && surface->ivci.format == VK_FORMAT_D32_SFLOAT_S8_UINT) ?
+                                state->sampler_clamped :
+                                state->sampler;
+            if (ctx->di.textures[shader][slot].sampler != sampler) {
+               screen->context_invalidate_descriptor_state(ctx, shader, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, slot, 1);
+               ctx->di.textures[shader][slot].sampler = sampler;
+            }
+         }
          ctx->di.sampler_surfaces[shader][slot].surface = surface;
          ctx->di.sampler_surfaces[shader][slot].is_buffer = false;
       }
@@ -629,8 +667,15 @@ zink_bind_sampler_states(struct pipe_context *pctx,
       if (ctx->sampler_states[shader][start_slot + i])
          was_nonseamless = ctx->sampler_states[shader][start_slot + i]->emulate_nonseamless;
       ctx->sampler_states[shader][start_slot + i] = state;
-      ctx->di.textures[shader][start_slot + i].sampler = state ? state->sampler : VK_NULL_HANDLE;
       if (state) {
+         ctx->di.textures[shader][start_slot + i].sampler = state->sampler;
+         if (state->sampler_clamped && !screen->have_D24_UNORM_S8_UINT) {
+            struct zink_surface *surface = get_imageview_for_binding(ctx, shader, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, start_slot + i);
+            if (surface &&
+                ((surface->base.format == PIPE_FORMAT_Z24X8_UNORM && surface->ivci.format == VK_FORMAT_D32_SFLOAT) ||
+                 (surface->base.format == PIPE_FORMAT_Z24_UNORM_S8_UINT && surface->ivci.format == VK_FORMAT_D32_SFLOAT_S8_UINT)))
+               ctx->di.textures[shader][start_slot + i].sampler = state->sampler_clamped;
+         }
          zink_batch_usage_set(&state->batch_uses, ctx->batch.state);
          if (screen->info.have_EXT_non_seamless_cube_map)
             continue;
@@ -646,6 +691,8 @@ zink_bind_sampler_states(struct pipe_context *pctx,
                screen->context_invalidate_descriptor_state(ctx, shader, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, start_slot + i, 1);
             }
          }
+      } else {
+         ctx->di.textures[shader][start_slot + i].sampler = VK_NULL_HANDLE;
       }
    }
    ctx->di.num_samplers[shader] = start_slot + num_samplers;
@@ -661,9 +708,13 @@ zink_delete_sampler_state(struct pipe_context *pctx,
    struct zink_batch *batch = &zink_context(pctx)->batch;
    zink_descriptor_set_refs_clear(&sampler->desc_set_refs, sampler_state);
    /* may be called if context_create fails */
-   if (batch->state)
+   if (batch->state) {
       util_dynarray_append(&batch->state->zombie_samplers, VkSampler,
                            sampler->sampler);
+      if (sampler->sampler_clamped)
+         util_dynarray_append(&batch->state->zombie_samplers, VkSampler,
+                              sampler->sampler_clamped);
+   }
    if (sampler->custom_border_color)
       p_atomic_dec(&zink_screen(pctx->screen)->cur_custom_border_color_samplers);
    FREE(sampler);
diff --git a/src/gallium/drivers/zink/zink_context.h b/src/gallium/drivers/zink/zink_context.h
index 24e699302d3..539d6cdc657 100644
--- a/src/gallium/drivers/zink/zink_context.h
+++ b/src/gallium/drivers/zink/zink_context.h
@@ -82,6 +82,7 @@ enum zink_blit_flags {
 
 struct zink_sampler_state {
    VkSampler sampler;
+   VkSampler sampler_clamped;
    uint32_t hash;
    struct zink_descriptor_refs desc_set_refs;
    struct zink_batch_usage *batch_uses;



More information about the mesa-commit mailing list