/* 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: {
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)
{
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 &&
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);
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 {
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);
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 */
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) {
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);
}