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: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20598>
This commit is contained in:
Mike Blumenkrantz
2023-01-06 10:38:22 -05:00
committed by Marge Bot
parent c46fb43473
commit b6518f3ba5
4 changed files with 29 additions and 3 deletions

View File

@@ -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 */

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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;
};