diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index 5a8380fe2a2..33857a35dda 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -3381,6 +3381,54 @@ zink_batch_no_rp(struct zink_context *ctx) zink_batch_no_rp_safe(ctx); } +static void +zink_flush_clears(struct zink_context *ctx) +{ + struct zink_screen *screen = zink_screen(ctx->base.screen); + bool general_layout = screen->driver_workarounds.general_layout; + bool queries_disabled = ctx->queries_disabled; + bool blitting = ctx->blitting; + struct pipe_framebuffer_state fb = ctx->fb_state; + if (!blitting) { + for (unsigned i = 0; i < ctx->fb_state.nr_cbufs; i++) { + if (!ctx->fb_state.cbufs[i].texture || !zink_fb_clear_enabled(ctx, i)) { + ctx->fb_state.cbufs[i].texture = NULL; + continue; + } + struct zink_resource *res = zink_resource(ctx->fb_state.cbufs[i].texture); + if (zink_is_swapchain(res)) { + if (!zink_kopper_acquire(ctx, res, UINT64_MAX)) + /* technically this is a failure condition, but there's no safe way out */ + return; + } + screen->image_barrier(ctx, res, + general_layout ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT); + res->obj->unordered_read = res->obj->unordered_write = false; + assert(res->layout != VK_IMAGE_LAYOUT_UNDEFINED); + } + if (ctx->fb_state.zsbuf.texture && zink_fb_clear_enabled(ctx, PIPE_MAX_COLOR_BUFS)) { + struct zink_resource *res = zink_resource(ctx->fb_state.zsbuf.texture); + screen->image_barrier(ctx, res, + general_layout ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, + VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT); + res->obj->unordered_read = res->obj->unordered_write = false; + assert(res->layout != VK_IMAGE_LAYOUT_UNDEFINED); + } else { + ctx->fb_state.zsbuf.texture = NULL; + } + } + ctx->blitting = true; + ctx->queries_disabled = true; + zink_batch_rp(ctx); + ctx->queries_disabled = queries_disabled; + ctx->blitting = blitting; + if (!blitting) + ctx->fb_state = fb; +} + static uint32_t hash_rendering_state(const void *key) { @@ -3608,7 +3656,7 @@ flush_batch(struct zink_context *ctx, bool sync) assert(!ctx->unordered_blitting); if (ctx->clears_enabled) /* start rp to do all the clears */ - zink_batch_rp(ctx); + zink_flush_clears(ctx); zink_batch_no_rp_safe(ctx); util_queue_fence_wait(&ctx->unsync_fence); @@ -3822,12 +3870,8 @@ zink_set_framebuffer_state(struct pipe_context *pctx, bool zsbuf_changed = !pipe_surface_equal(&ctx->fb_state.zsbuf, &state->zsbuf); if (zsbuf_changed) flush_clears |= zink_fb_clear_enabled(ctx, PIPE_MAX_COLOR_BUFS); - if (flush_clears) { - bool queries_disabled = ctx->queries_disabled; - ctx->queries_disabled = true; - zink_batch_rp(ctx); - ctx->queries_disabled = queries_disabled; - } + if (flush_clears) + zink_flush_clears(ctx); /* need to ensure we start a new rp on next draw */ zink_batch_no_rp_safe(ctx); for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) { @@ -4029,10 +4073,8 @@ zink_flush(struct pipe_context *pctx, if (ctx->fb_state.cbufs[i].texture) zink_blit_barriers(ctx, NULL, zink_resource(ctx->fb_state.cbufs[i].texture), false); } - ctx->blitting = true; /* start rp to do all the clears */ - zink_batch_rp(ctx); - ctx->blitting = false; + zink_flush_clears(ctx); ctx->fbfetch_outputs = fbfetch_outputs; ctx->rp_changed |= fbfetch_outputs > 0; } @@ -4191,7 +4233,7 @@ zink_texture_barrier(struct pipe_context *pctx, unsigned flags) /* if this is a fb barrier, flush all pending clears */ if (ctx->rp_clears_enabled && dst == VK_ACCESS_INPUT_ATTACHMENT_READ_BIT) - zink_batch_rp(ctx); + zink_flush_clears(ctx); /* this is not an in-renderpass barrier */ if (!ctx->fbfetch_outputs)