summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmma Anholt <emma@anholt.net>2023-05-08 16:12:42 -0700
committerMarge Bot <emma+marge@anholt.net>2023-05-10 18:37:36 +0000
commite9ad9ab3d2d4bd7b5569b325219a660e3720e7fa (patch)
tree060c8ff0191194432ea6d8e97f7671712c5cd6c3
parent0b22b311900a80fa0b9bb7b573c3b4479668b670 (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.c12
-rw-r--r--src/gallium/drivers/zink/zink_context.c15
-rw-r--r--src/gallium/drivers/zink/zink_shader_keys.h1
-rw-r--r--src/gallium/drivers/zink/zink_types.h1
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;
};