diff options
author | Emma Anholt <emma@anholt.net> | 2023-05-08 16:12:42 -0700 |
---|---|---|
committer | Marge Bot <emma+marge@anholt.net> | 2023-05-10 18:37:36 +0000 |
commit | e9ad9ab3d2d4bd7b5569b325219a660e3720e7fa (patch) | |
tree | 060c8ff0191194432ea6d8e97f7671712c5cd6c3 | |
parent | 0b22b311900a80fa0b9bb7b573c3b4479668b670 (diff) |
zink: Explain some of the current pathway for shadow sampling.
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22912>
-rw-r--r-- | src/gallium/drivers/zink/zink_compiler.c | 12 | ||||
-rw-r--r-- | src/gallium/drivers/zink/zink_context.c | 15 | ||||
-rw-r--r-- | src/gallium/drivers/zink/zink_shader_keys.h | 1 | ||||
-rw-r--r-- | src/gallium/drivers/zink/zink_types.h | 1 |
4 files changed, 25 insertions, 4 deletions
diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c index fdc296ad618..43fba8a689e 100644 --- a/src/gallium/drivers/zink/zink_compiler.c +++ b/src/gallium/drivers/zink/zink_compiler.c @@ -3498,9 +3498,21 @@ lower_zs_swizzle_tex_instr(nir_builder *b, nir_instr *instr, void *data) return true; } +/* Applies in-shader swizzles when necessary for depth/shadow sampling. + * + * SPIRV only has new-style (scalar result) shadow sampling, so to emulate + * !is_new_style_shadow (vec4 result) shadow sampling we lower to a + * new-style-shadow sample, and apply GL_DEPTH_TEXTURE_MODE swizzles in the NIR + * shader to expand out to vec4. Since this depends on sampler state, it's a + * draw-time shader recompile to do so. + * + * We may also need to apply shader swizzles for + * driver_workarounds.needs_zs_shader_swizzle. + */ static bool lower_zs_swizzle_tex(nir_shader *nir, const void *swizzle, bool shadow_only) { + /* We don't use nir_lower_tex to do our swizzling, because of this base_sampler_id. */ unsigned base_sampler_id = gl_shader_stage_is_compute(nir->info.stage) ? 0 : PIPE_MAX_SAMPLERS * nir->info.stage; struct lower_zs_swizzle_state state = {shadow_only, base_sampler_id, swizzle}; return nir_shader_instructions_pass(nir, lower_zs_swizzle_tex_instr, nir_metadata_dominance | nir_metadata_block_index, (void*)&state); diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index 2c24f2e11b9..023ad0a711e 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -1062,21 +1062,28 @@ 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; + bool red_depth_sampler_view = 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)) { ivci.components.r = zink_component_mapping(clamp_zs_swizzle(sampler_view->base.swizzle_r)); 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 we're sampling depth and we might need to do shader rewrites for + * legacy shadow sampling, then set up an extra image view that just + * returns the red (depth) component, so you can always have the shadow + * result available in the red component for the in-shader swizzling. + * (Or if we have PVR's needs_zs_shader_swizzle and are sampling ONE + * value for stencil, which also uses that view). + */ 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 && ivci.subresourceRange.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT)) - shadow_needs_shader_swizzle = true; + red_depth_sampler_view = 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); @@ -1139,7 +1146,7 @@ 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) { + } else if (red_depth_sampler_view) { /* there is only one component, and real swizzling can't be done here, * so ensure the shader gets the sampled data */ diff --git a/src/gallium/drivers/zink/zink_shader_keys.h b/src/gallium/drivers/zink/zink_shader_keys.h index c7e0615d3b9..1dab2447fd8 100644 --- a/src/gallium/drivers/zink/zink_shader_keys.h +++ b/src/gallium/drivers/zink/zink_shader_keys.h @@ -74,6 +74,7 @@ struct zink_zs_swizzle { }; struct zink_zs_swizzle_key { + /* Mask of sampler views with zs_view, i.e. have swizzles other than GL_RED for depth */ uint32_t mask; struct zink_zs_swizzle swizzle[32]; }; diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h index 492374ad1af..c5a5b72e104 100644 --- a/src/gallium/drivers/zink/zink_types.h +++ b/src/gallium/drivers/zink/zink_types.h @@ -1600,6 +1600,7 @@ struct zink_sampler_view { struct zink_buffer_view *buffer_view; }; struct zink_surface *cube_array; + /* Optional sampler view returning red (depth) in all channels, for shader rewrites. */ struct zink_surface *zs_view; struct zink_zs_swizzle swizzle; }; |