zink: workaround undefined swizzle 1 for z/s textures
authorSoroushIMG <soroush.kashani@imgtec.com>
Sat, 25 Feb 2023 22:24:00 +0000 (22:24 +0000)
committerMarge Bot <emma+marge@anholt.net>
Tue, 14 Mar 2023 17:03:30 +0000 (17:03 +0000)
using swizzle 1 with z/s textures returns undefined data
on some Imagination hardware.
Work around this by using the same shader swizzling used for
shadow samplers.

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

src/gallium/drivers/zink/zink_context.c
src/gallium/drivers/zink/zink_program.c
src/gallium/drivers/zink/zink_program.h

index ce1bdbc..4473337 100644 (file)
@@ -529,11 +529,15 @@ get_imageview_for_binding(struct zink_context *ctx, gl_shader_stage stage, enum
       if (!sampler_view || !sampler_view->base.texture)
          return NULL;
       /* if this is a non-seamless cube sampler, return the cube array view */
-      return (ctx->di.emulate_nonseamless[stage] & ctx->di.cubes[stage] & BITFIELD_BIT(idx)) ?
-             sampler_view->cube_array :
-             sampler_view->shadow && stage == MESA_SHADER_FRAGMENT && ctx->gfx_stages[MESA_SHADER_FRAGMENT] &&
-             (ctx->di.shadow[MESA_SHADER_FRAGMENT].mask & ctx->gfx_stages[MESA_SHADER_FRAGMENT]->fs.legacy_shadow_mask & BITFIELD_BIT(idx)) ? sampler_view->shadow :
-             sampler_view->image_view;
+      if (ctx->di.emulate_nonseamless[stage] & ctx->di.cubes[stage] & BITFIELD_BIT(idx))
+         return sampler_view->cube_array;
+      bool needs_zs_shader_swizzle = (ctx->di.shadow[stage].mask & BITFIELD_BIT(idx)) &&
+                                     zink_screen(ctx->base.screen)->driver_workarounds.needs_zs_shader_swizzle;
+      bool needs_shadow_shader_swizzle = (stage == MESA_SHADER_FRAGMENT) && ctx->gfx_stages[MESA_SHADER_FRAGMENT] &&
+                                         (ctx->di.shadow[MESA_SHADER_FRAGMENT].mask & ctx->gfx_stages[MESA_SHADER_FRAGMENT]->fs.legacy_shadow_mask & BITFIELD_BIT(idx));
+      if (sampler_view->shadow && (needs_zs_shader_swizzle || needs_shadow_shader_swizzle))
+         return sampler_view->shadow;
+      return sampler_view->image_view;
    }
    case ZINK_DESCRIPTOR_TYPE_IMAGE: {
       struct zink_image_view *image_view = &ctx->image_views[stage][idx];
@@ -1026,11 +1030,13 @@ zink_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *pres,
          ivci.components.g = zink_component_mapping(clamp_zs_swizzle(sampler_view->base.swizzle_g));
          ivci.components.b = zink_component_mapping(clamp_zs_swizzle(sampler_view->base.swizzle_b));
          ivci.components.a = zink_component_mapping(clamp_zs_swizzle(sampler_view->base.swizzle_a));
-         if (ivci.subresourceRange.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT) {
+         if (ivci.subresourceRange.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT ||
+             zink_screen(ctx->base.screen)->driver_workarounds.needs_zs_shader_swizzle) {
             VkComponentSwizzle *swizzle = (VkComponentSwizzle*)&ivci.components;
             for (unsigned i = 0; i < 4; i++) {
                /* these require shader rewrites to correctly emulate */
-               if (swizzle[i] == VK_COMPONENT_SWIZZLE_ONE || swizzle[i] == VK_COMPONENT_SWIZZLE_ZERO)
+               if (swizzle[i] == VK_COMPONENT_SWIZZLE_ONE ||
+                   (swizzle[i] == VK_COMPONENT_SWIZZLE_ZERO && ivci.subresourceRange.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT))
                   shadow_needs_shader_swizzle = true;
             }
             /* this is the data that will be used in shader rewrites */
@@ -2051,8 +2057,8 @@ zink_set_sampler_views(struct pipe_context *pctx,
       zink_context_invalidate_descriptor_state(ctx, shader_type, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, start_slot, num_views);
       if (!screen->info.have_EXT_non_seamless_cube_map)
          update_nonseamless_shader_key(ctx, shader_type);
-         shadow_update |= shadow_mask != ctx->di.shadow[shader_type].mask;
-      zink_set_fs_shadow_needs_shader_swizzle_key(ctx, shadow_update);
+      shadow_update |= shadow_mask != ctx->di.shadow[shader_type].mask;
+      zink_set_zs_needs_shader_swizzle_key(ctx, shader_type, shadow_update);
    }
 }
 
index ecffad4..26c6942 100644 (file)
@@ -1762,8 +1762,9 @@ zink_bind_fs_state(struct pipe_context *pctx,
             ctx->gfx_pipeline_state.dirty = true;
          ctx->gfx_pipeline_state.rast_attachment_order = nir->info.fs.uses_fbfetch_output;
       }
-      zink_set_fs_shadow_needs_shader_swizzle_key(ctx, false);
-      if (shadow_mask != ctx->gfx_stages[MESA_SHADER_FRAGMENT]->fs.legacy_shadow_mask)
+      zink_set_zs_needs_shader_swizzle_key(ctx, MESA_SHADER_FRAGMENT, false);
+      if (shadow_mask != ctx->gfx_stages[MESA_SHADER_FRAGMENT]->fs.legacy_shadow_mask &&
+          !zink_screen(pctx->screen)->driver_workarounds.needs_zs_shader_swizzle)
          zink_update_shadow_samplerviews(ctx, shadow_mask | ctx->gfx_stages[MESA_SHADER_FRAGMENT]->fs.legacy_shadow_mask);
    }
    zink_update_fbfetch(ctx);
index be48c36..400dcdd 100644 (file)
@@ -360,16 +360,6 @@ zink_set_fs_point_coord_key(struct zink_context *ctx)
    }
 }
 
-static inline void
-zink_set_fs_shadow_needs_shader_swizzle_key(struct zink_context *ctx, bool swizzle_update)
-{
-   const struct zink_fs_key_base *fs = zink_get_fs_base_key(ctx);
-   bool enable = ctx->gfx_stages[MESA_SHADER_FRAGMENT] &&
-                 (ctx->gfx_stages[MESA_SHADER_FRAGMENT]->fs.legacy_shadow_mask & ctx->di.shadow[MESA_SHADER_FRAGMENT].mask) > 0;
-   if (enable != fs->shadow_needs_shader_swizzle || (enable && swizzle_update))
-      zink_set_fs_base_key(ctx)->shadow_needs_shader_swizzle = enable;
-}
-
 void
 zink_set_primitive_emulation_keys(struct zink_context *ctx);
 
@@ -388,6 +378,24 @@ zink_set_shader_key_base(struct zink_context *ctx, gl_shader_stage pstage)
    return &ctx->gfx_pipeline_state.shader_keys.key[pstage].base;
 }
 
+static inline void
+zink_set_zs_needs_shader_swizzle_key(struct zink_context *ctx, gl_shader_stage pstage, bool swizzle_update)
+{
+   if (!zink_screen(ctx->base.screen)->driver_workarounds.needs_zs_shader_swizzle) {
+      if (pstage != MESA_SHADER_FRAGMENT)
+         return;
+      const struct zink_fs_key_base *fs = zink_get_fs_base_key(ctx);
+      bool enable = ctx->gfx_stages[MESA_SHADER_FRAGMENT] && (ctx->gfx_stages[MESA_SHADER_FRAGMENT]->fs.legacy_shadow_mask & ctx->di.shadow[pstage].mask) > 0;
+      if (enable != fs->shadow_needs_shader_swizzle || (enable && swizzle_update))
+         zink_set_fs_base_key(ctx)->shadow_needs_shader_swizzle = enable;
+      return;
+   }
+   bool enable = !!ctx->di.shadow[pstage].mask;
+   const struct zink_shader_key_base *key = zink_get_shader_key_base(ctx, pstage);
+   if (enable != key->needs_zs_shader_swizzle || (enable && swizzle_update))
+      zink_set_shader_key_base(ctx, pstage)->needs_zs_shader_swizzle = enable;
+}
+
 ALWAYS_INLINE static bool
 zink_can_use_pipeline_libs(const struct zink_context *ctx)
 {