Module: Mesa Branch: main Commit: 1bc9db68790645825682dc7a7a41850d8f4512da URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=1bc9db68790645825682dc7a7a41850d8f4512da
Author: Mike Blumenkrantz <[email protected]> Date: Fri Jul 15 09:47:26 2022 -0400 zink: split out rp_changed to be more granular for dynamic render sometimes a state change MAY require a renderpass change, but this change will not require splitting the current renderpass Reviewed-by: Dave Airlie <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17640> --- src/gallium/drivers/zink/zink_batch.c | 2 +- src/gallium/drivers/zink/zink_clear.c | 2 +- src/gallium/drivers/zink/zink_context.c | 22 ++++++++++++++++++++-- src/gallium/drivers/zink/zink_context.h | 4 +++- src/gallium/drivers/zink/zink_render_pass.c | 4 +++- src/gallium/drivers/zink/zink_resource.c | 4 ++-- src/gallium/drivers/zink/zink_state.c | 2 +- 7 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/gallium/drivers/zink/zink_batch.c b/src/gallium/drivers/zink/zink_batch.c index faa64385deb..f041e091c85 100644 --- a/src/gallium/drivers/zink/zink_batch.c +++ b/src/gallium/drivers/zink/zink_batch.c @@ -498,7 +498,7 @@ zink_batch_resource_usage_set(struct zink_batch *batch, struct zink_resource *re } if (write && !res->obj->is_buffer) { if (!res->valid && res->fb_binds) - batch->state->ctx->rp_changed = true; + batch->state->ctx->rp_loadop_changed = true; res->valid = true; } zink_resource_usage_set(res, batch->state, write); diff --git a/src/gallium/drivers/zink/zink_clear.c b/src/gallium/drivers/zink/zink_clear.c index 9eec1b37e3d..25725bbf2cd 100644 --- a/src/gallium/drivers/zink/zink_clear.c +++ b/src/gallium/drivers/zink/zink_clear.c @@ -607,7 +607,7 @@ zink_fb_clear_reset(struct zink_context *ctx, unsigned i) ctx->rp_clears_enabled &= ~(PIPE_CLEAR_COLOR0 << i); } if (ctx->rp_clears_enabled != rp_clears_enabled) - ctx->rp_changed = true; + ctx->rp_loadop_changed = true; } void diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index 9aa34fba9ca..aae88c6b1f0 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -2160,7 +2160,9 @@ begin_rendering(struct zink_context *ctx) zink_render_update_swapchain(ctx); bool has_depth = false; bool has_stencil = false; - if (ctx->rp_changed) { + bool changed_layout = false; + bool changed_size = false; + if (ctx->rp_changed || ctx->rp_layout_changed || ctx->rp_loadop_changed) { /* init imageviews, base loadOp, formats */ for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) { struct zink_surface *surf = zink_csurface(ctx->fb_state.cbufs[i]); @@ -2177,11 +2179,17 @@ begin_rendering(struct zink_context *ctx) /* use dummy fb size of 1024 if no surf exists */ unsigned width = surf ? surf->base.texture->width0 : 1024; unsigned height = surf ? surf->base.texture->height0 : 1024; + unsigned prev_width = ctx->dynamic_fb.info.renderArea.extent.width; + unsigned prev_height = ctx->dynamic_fb.info.renderArea.extent.height; ctx->dynamic_fb.info.renderArea.extent.width = MIN2(ctx->dynamic_fb.info.renderArea.extent.width, width); ctx->dynamic_fb.info.renderArea.extent.height = MIN2(ctx->dynamic_fb.info.renderArea.extent.height, height); + changed_size |= ctx->dynamic_fb.info.renderArea.extent.width != prev_width; + changed_size |= ctx->dynamic_fb.info.renderArea.extent.height != prev_height; } /* unset depth and stencil info: reset below */ + VkImageLayout zlayout = ctx->dynamic_fb.info.pDepthAttachment ? ctx->dynamic_fb.info.pDepthAttachment->imageLayout : VK_IMAGE_LAYOUT_UNDEFINED; + VkImageLayout slayout = ctx->dynamic_fb.info.pStencilAttachment ? ctx->dynamic_fb.info.pStencilAttachment->imageLayout : VK_IMAGE_LAYOUT_UNDEFINED; ctx->dynamic_fb.info.pDepthAttachment = NULL; ctx->gfx_pipeline_state.rendering_info.depthAttachmentFormat = VK_FORMAT_UNDEFINED; ctx->dynamic_fb.info.pStencilAttachment = NULL; @@ -2220,6 +2228,10 @@ begin_rendering(struct zink_context *ctx) ctx->dynamic_fb.info.pDepthAttachment = NULL; ctx->gfx_pipeline_state.rendering_info.depthAttachmentFormat = VK_FORMAT_UNDEFINED; } + if (zlayout != (ctx->dynamic_fb.info.pDepthAttachment ? ctx->dynamic_fb.info.pDepthAttachment->imageLayout : VK_IMAGE_LAYOUT_UNDEFINED)) + changed_layout = true; + if (slayout != (ctx->dynamic_fb.info.pStencilAttachment ? ctx->dynamic_fb.info.pStencilAttachment->imageLayout : VK_IMAGE_LAYOUT_UNDEFINED)) + changed_layout = true; /* similar to begin_render_pass(), but just filling in VkRenderingInfo */ for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) { @@ -2262,12 +2274,18 @@ begin_rendering(struct zink_context *ctx) clear_buffers |= zink_fb_clear_element(fb_clear, j)->zs.bits; } } - ctx->rp_changed = false; + if (changed_size || changed_layout) + ctx->rp_changed = true; + ctx->rp_loadop_changed = false; + ctx->rp_layout_changed = false; } /* validate zs VUs: attachment must be null or format must be valid */ assert(!ctx->dynamic_fb.info.pDepthAttachment || ctx->gfx_pipeline_state.rendering_info.depthAttachmentFormat); assert(!ctx->dynamic_fb.info.pStencilAttachment || ctx->gfx_pipeline_state.rendering_info.stencilAttachmentFormat); + if (!ctx->rp_changed && ctx->batch.in_rp) + return 0; + ctx->rp_changed = false; /* update pipeline info id for compatibility VUs */ unsigned rp_state = find_rp_state(ctx); ctx->gfx_pipeline_state.dirty |= ctx->gfx_pipeline_state.rp_state != rp_state; diff --git a/src/gallium/drivers/zink/zink_context.h b/src/gallium/drivers/zink/zink_context.h index 3a409439607..7238db1c074 100644 --- a/src/gallium/drivers/zink/zink_context.h +++ b/src/gallium/drivers/zink/zink_context.h @@ -274,7 +274,9 @@ struct zink_context { bool new_swapchain; VkExtent2D swapchain_size; bool fb_changed; - bool rp_changed; + bool rp_changed; //force renderpass restart + bool rp_layout_changed; //renderpass changed, maybe restart + bool rp_loadop_changed; //renderpass changed, don't restart struct zink_framebuffer *framebuffer; struct zink_framebuffer_clear fb_clears[PIPE_MAX_COLOR_BUFS + 1]; diff --git a/src/gallium/drivers/zink/zink_render_pass.c b/src/gallium/drivers/zink/zink_render_pass.c index de786bfe44a..b7cec650bce 100644 --- a/src/gallium/drivers/zink/zink_render_pass.c +++ b/src/gallium/drivers/zink/zink_render_pass.c @@ -443,7 +443,7 @@ setup_framebuffer(struct zink_context *ctx) zink_update_vk_sample_locations(ctx); - if (ctx->rp_changed) + if (ctx->rp_changed || ctx->rp_layout_changed) rp = get_render_pass(ctx); ctx->fb_changed |= rp != ctx->gfx_pipeline_state.render_pass; @@ -452,6 +452,7 @@ setup_framebuffer(struct zink_context *ctx) ctx->gfx_pipeline_state.dirty = true; } + ctx->rp_layout_changed = false; ctx->rp_changed = false; zink_render_update_swapchain(ctx); @@ -636,6 +637,7 @@ zink_begin_render_pass(struct zink_context *ctx) pipe_sampler_view_reference(&src_view, NULL); csurf->transient_init = true; } + ctx->rp_layout_changed = ctx->rp_loadop_changed = false; ctx->fb_changed = ctx->rp_changed = false; ctx->gfx_pipeline_state.rp_state = rp_state; ctx->gfx_pipeline_state.render_pass = rp; diff --git a/src/gallium/drivers/zink/zink_resource.c b/src/gallium/drivers/zink/zink_resource.c index 39976742b5b..fa9673b61d3 100644 --- a/src/gallium/drivers/zink/zink_resource.c +++ b/src/gallium/drivers/zink/zink_resource.c @@ -1562,7 +1562,7 @@ zink_resource_invalidate(struct pipe_context *pctx, struct pipe_resource *pres) else { struct zink_resource *res = zink_resource(pres); if (res->valid && res->fb_binds) - zink_context(pctx)->rp_changed = true; + zink_context(pctx)->rp_loadop_changed = true; res->valid = false; } } @@ -1957,7 +1957,7 @@ zink_image_map(struct pipe_context *pctx, goto fail; if (usage & PIPE_MAP_WRITE) { if (!res->valid && res->fb_binds) - ctx->rp_changed = true; + ctx->rp_loadop_changed = true; res->valid = true; } diff --git a/src/gallium/drivers/zink/zink_state.c b/src/gallium/drivers/zink/zink_state.c index 11f45761925..1d6f5a5f2bd 100644 --- a/src/gallium/drivers/zink/zink_state.c +++ b/src/gallium/drivers/zink/zink_state.c @@ -534,7 +534,7 @@ zink_bind_depth_stencil_alpha_state(struct pipe_context *pctx, void *cso) } if (prev_zwrite != (ctx->dsa_state ? ctx->dsa_state->hw_state.depth_write : false)) { /* flag renderpass for re-check on next draw */ - ctx->rp_changed = true; + ctx->rp_layout_changed = true; } }
