zink: split out rp_changed to be more granular for dynamic render
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>
Fri, 15 Jul 2022 13:47:26 +0000 (09:47 -0400)
committerMarge Bot <emma+marge@anholt.net>
Wed, 20 Jul 2022 17:30:19 +0000 (17:30 +0000)
sometimes a state change MAY require a renderpass change, but this change
will not require splitting the current renderpass

Reviewed-by: Dave Airlie <airlied@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17640>

src/gallium/drivers/zink/zink_batch.c
src/gallium/drivers/zink/zink_clear.c
src/gallium/drivers/zink/zink_context.c
src/gallium/drivers/zink/zink_context.h
src/gallium/drivers/zink/zink_render_pass.c
src/gallium/drivers/zink/zink_resource.c
src/gallium/drivers/zink/zink_state.c

index faa6438..f041e09 100644 (file)
@@ -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);
index 9eec1b3..25725bb 100644 (file)
@@ -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
index 9aa34fb..aae88c6 100644 (file)
@@ -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;
index 3a40943..7238db1 100644 (file)
@@ -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];
index de786bf..b7cec65 100644 (file)
@@ -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;
index 3997674..fa9673b 100644 (file)
@@ -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;
    }
 
index 11f4576..1d6f5a5 100644 (file)
@@ -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;
    }
 }