From b6518f3ba5955f254c462f6c48eef64b54083a27 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Fri, 6 Jan 2023 10:38:22 -0500 Subject: [PATCH] zink: create another samplerview for shadow textures when doing legacy depth texture mode sampling, it's necessary to keep another view that has the right (R in component 0) swizzle so that depth values can actually be returned in cases where it would otherwise be a constant value due to swizzling this also allows zink_sampler_view::shadow_needs_shader_swizzle to be removed Part-of: --- src/gallium/drivers/zink/zink_context.c | 24 ++++++++++++++++++++++-- src/gallium/drivers/zink/zink_context.h | 3 +++ src/gallium/drivers/zink/zink_program.c | 3 +++ src/gallium/drivers/zink/zink_types.h | 2 +- 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index fccad04..e4102e3 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -523,6 +523,8 @@ get_imageview_for_binding(struct zink_context *ctx, gl_shader_stage stage, enum /* 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.mask & ctx->gfx_stages[MESA_SHADER_FRAGMENT]->fs.legacy_shadow_mask & BITFIELD_BIT(idx)) ? sampler_view->shadow : sampler_view->image_view; } case ZINK_DESCRIPTOR_TYPE_IMAGE: { @@ -672,6 +674,13 @@ update_descriptor_state_sampler(struct zink_context *ctx, gl_shader_stage shader return res; } +void +zink_update_shadow_samplerviews(struct zink_context *ctx, unsigned mask) +{ + u_foreach_bit(slot, mask) + update_descriptor_state_sampler(ctx, MESA_SHADER_FRAGMENT, slot, ctx->di.descriptor_res[ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW][MESA_SHADER_FRAGMENT][slot]); +} + ALWAYS_INLINE static struct zink_resource * update_descriptor_state_image(struct zink_context *ctx, gl_shader_stage shader, unsigned slot, struct zink_resource *res) { @@ -1002,6 +1011,7 @@ zink_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *pres, ivci = create_ivci(screen, res, &templ, state->target); ivci.subresourceRange.levelCount = state->u.tex.last_level - state->u.tex.first_level + 1; ivci.subresourceRange.aspectMask = sampler_aspect_from_format(state->format); + bool shadow_needs_shader_swizzle = false; /* samplers for stencil aspects of packed formats need to always use stencil swizzle */ if (ivci.subresourceRange.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { if (sampler_view->base.swizzle_r == PIPE_SWIZZLE_0 && @@ -1027,7 +1037,7 @@ zink_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *pres, 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) - sampler_view->shadow_needs_shader_swizzle = true; + shadow_needs_shader_swizzle = true; } /* this is the data that will be used in shader rewrites */ sampler_view->swizzle.s[0] = clamp_zs_swizzle(sampler_view->base.swizzle_r); @@ -1090,6 +1100,15 @@ zink_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *pres, if (!screen->info.have_EXT_non_seamless_cube_map && viewtype_is_cube(&sampler_view->image_view->ivci)) { ivci.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY; sampler_view->cube_array = (struct zink_surface*)zink_get_surface(ctx, pres, &templ, &ivci); + } else if (shadow_needs_shader_swizzle) { + /* there is only one component, and real swizzling can't be done here, + * so ensure the shader gets the sampled data + */ + ivci.components.r = VK_COMPONENT_SWIZZLE_R; + ivci.components.g = VK_COMPONENT_SWIZZLE_R; + ivci.components.b = VK_COMPONENT_SWIZZLE_R; + ivci.components.a = VK_COMPONENT_SWIZZLE_R; + sampler_view->shadow = (struct zink_surface*)zink_get_surface(ctx, pres, &templ, &ivci); } err = !sampler_view->image_view; } else { @@ -1137,6 +1156,7 @@ zink_sampler_view_destroy(struct pipe_context *pctx, else { zink_surface_reference(zink_screen(pctx->screen), &view->image_view, NULL); zink_surface_reference(zink_screen(pctx->screen), &view->cube_array, NULL); + zink_surface_reference(zink_screen(pctx->screen), &view->shadow, NULL); } pipe_resource_reference(&pview->texture, NULL); FREE_CL(view); @@ -1951,7 +1971,7 @@ zink_set_sampler_views(struct pipe_context *pctx, update = true; zink_batch_resource_usage_set(&ctx->batch, res, false, false); res->obj->unordered_write = false; - if (b->shadow_needs_shader_swizzle) { + if (b->shadow) { assert(start_slot + i < 32); //bitfield size ctx->di.shadow.mask |= BITFIELD_BIT(start_slot + i); /* this is already gonna be slow, so don't bother trying to micro-optimize */ diff --git a/src/gallium/drivers/zink/zink_context.h b/src/gallium/drivers/zink/zink_context.h index 3fd64a8..e20980a 100644 --- a/src/gallium/drivers/zink/zink_context.h +++ b/src/gallium/drivers/zink/zink_context.h @@ -211,6 +211,9 @@ zink_component_mapping(enum pipe_swizzle swizzle) } } +void +zink_update_shadow_samplerviews(struct zink_context *ctx, unsigned mask); + enum pipe_swizzle zink_clamp_void_swizzle(const struct util_format_description *desc, enum pipe_swizzle swizzle); diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c index 8a688db..fad06eb 100644 --- a/src/gallium/drivers/zink/zink_program.c +++ b/src/gallium/drivers/zink/zink_program.c @@ -1475,6 +1475,7 @@ zink_bind_fs_state(struct pipe_context *pctx, struct zink_context *ctx = zink_context(pctx); if (!cso && !ctx->gfx_stages[MESA_SHADER_FRAGMENT]) return; + unsigned shadow_mask = ctx->gfx_stages[MESA_SHADER_FRAGMENT] ? ctx->gfx_stages[MESA_SHADER_FRAGMENT]->fs.legacy_shadow_mask : 0; bind_gfx_stage(ctx, MESA_SHADER_FRAGMENT, cso); ctx->fbfetch_outputs = 0; if (cso) { @@ -1492,6 +1493,8 @@ zink_bind_fs_state(struct pipe_context *pctx, 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_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_types.h b/src/gallium/drivers/zink/zink_types.h index 616983b..f51bc1d 100644 --- a/src/gallium/drivers/zink/zink_types.h +++ b/src/gallium/drivers/zink/zink_types.h @@ -1470,7 +1470,7 @@ struct zink_sampler_view { struct zink_buffer_view *buffer_view; }; struct zink_surface *cube_array; - bool shadow_needs_shader_swizzle; + struct zink_surface *shadow; struct zink_fs_shadow_swizzle swizzle; }; -- 2.7.4