From bc2acc87d7285629602d6bfaf0e7b692920b2863 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Fri, 2 Apr 2021 17:39:30 -0400 Subject: [PATCH] zink: add a pipe_context::evaluate_depth_buffer hook this works by flagging the next barrier to use the current sample locations so that everything works as expected during decompression Reviewed-by: Erik Faye-Lund Part-of: --- src/gallium/drivers/zink/zink_context.c | 26 +++++++++++++++++++++++- src/gallium/drivers/zink/zink_resource.h | 3 +++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index 65868d69732..dbc24c2bec8 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -1647,6 +1647,20 @@ zink_init_vk_sample_locations(struct zink_context *ctx, VkSampleLocationsInfoEXT loc->pSampleLocations = ctx->vk_sample_locations; } +static void +zink_evaluate_depth_buffer(struct pipe_context *pctx) +{ + struct zink_context *ctx = zink_context(pctx); + + if (!ctx->fb_state.zsbuf) + return; + + struct zink_resource *res = zink_resource(ctx->fb_state.zsbuf->texture); + res->obj->needs_zs_evaluate = true; + zink_init_vk_sample_locations(ctx, &res->obj->zs_evaluate); + zink_batch_no_rp(ctx); +} + void zink_begin_render_pass(struct zink_context *ctx, struct zink_batch *batch) { @@ -1872,7 +1886,13 @@ zink_set_framebuffer_state(struct pipe_context *pctx, if (ctx->fb_state.zsbuf) { struct pipe_surface *surf = ctx->fb_state.zsbuf; if (surf != state->zsbuf) { + struct zink_resource *res = zink_resource(surf->texture); zink_fb_clears_apply(ctx, ctx->fb_state.zsbuf->texture); + if (unlikely(res->obj->needs_zs_evaluate)) + /* have to flush zs eval while the sample location data still exists, + * so just throw some random barrier */ + zink_resource_image_barrier(ctx, NULL, res, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); ctx->rp_changed = true; } zink_resource(surf->texture)->fb_binds--; @@ -2131,7 +2151,7 @@ zink_resource_image_barrier_init(VkImageMemoryBarrier *imb, struct zink_resource res->obj->image, isr }; - return zink_resource_image_needs_barrier(res, new_layout, flags, pipeline); + return res->obj->needs_zs_evaluate || zink_resource_image_needs_barrier(res, new_layout, flags, pipeline); } static inline bool @@ -2185,6 +2205,9 @@ zink_resource_image_barrier(struct zink_context *ctx, struct zink_batch *batch, /* only barrier if we're changing layout or doing something besides read -> read */ VkCommandBuffer cmdbuf = get_cmdbuf(ctx, res); assert(new_layout); + if (res->obj->needs_zs_evaluate) + imb.pNext = &res->obj->zs_evaluate; + res->obj->needs_zs_evaluate = false; vkCmdPipelineBarrier( cmdbuf, res->access_stage ? res->access_stage : VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, @@ -3371,6 +3394,7 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags) ctx->base.flush = zink_flush; ctx->base.memory_barrier = zink_memory_barrier; ctx->base.texture_barrier = zink_texture_barrier; + ctx->base.evaluate_depth_buffer = zink_evaluate_depth_buffer; ctx->base.resource_commit = zink_resource_commit; ctx->base.resource_copy_region = zink_resource_copy_region; diff --git a/src/gallium/drivers/zink/zink_resource.h b/src/gallium/drivers/zink/zink_resource.h index 8a277a3a10f..6e257299f8c 100644 --- a/src/gallium/drivers/zink/zink_resource.h +++ b/src/gallium/drivers/zink/zink_resource.h @@ -69,6 +69,9 @@ struct zink_resource_object { struct mem_key mkey; VkDeviceSize offset, size; + VkSampleLocationsInfoEXT zs_evaluate; + bool needs_zs_evaluate; + unsigned persistent_maps; //if nonzero, requires vkFlushMappedMemoryRanges during batch use struct zink_descriptor_refs desc_set_refs;