From 24a2530ed8cec3d7998a8d34f567d6e23d83ae45 Mon Sep 17 00:00:00 2001 From: SoroushIMG Date: Sat, 25 Feb 2023 22:24:00 +0000 Subject: [PATCH] zink: workaround undefined swizzle 1 for z/s textures 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: --- src/gallium/drivers/zink/zink_context.c | 24 +++++++++++++++--------- src/gallium/drivers/zink/zink_program.c | 5 +++-- src/gallium/drivers/zink/zink_program.h | 28 ++++++++++++++++++---------- 3 files changed, 36 insertions(+), 21 deletions(-) diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index ce1bdbc..4473337 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -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); } } diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c index ecffad4..26c6942 100644 --- a/src/gallium/drivers/zink/zink_program.c +++ b/src/gallium/drivers/zink/zink_program.c @@ -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); diff --git a/src/gallium/drivers/zink/zink_program.h b/src/gallium/drivers/zink/zink_program.h index be48c36..400dcdd 100644 --- a/src/gallium/drivers/zink/zink_program.h +++ b/src/gallium/drivers/zink/zink_program.h @@ -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) { -- 2.7.4