zink: use tc renderpass tracking to optimize renderpasses
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>
Fri, 28 Oct 2022 00:49:43 +0000 (20:49 -0400)
committerMarge Bot <emma+marge@anholt.net>
Sat, 29 Oct 2022 20:19:51 +0000 (20:19 +0000)
this massively improves performance on tiling gpus

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19077>

src/gallium/drivers/zink/zink_context.c
src/gallium/drivers/zink/zink_context.h
src/gallium/drivers/zink/zink_framebuffer.c
src/gallium/drivers/zink/zink_render_pass.c
src/gallium/drivers/zink/zink_render_pass.h
src/gallium/drivers/zink/zink_screen.c
src/gallium/drivers/zink/zink_types.h

index 6157b49..57da750 100644 (file)
 #define XXH_INLINE_ALL
 #include "util/xxhash.h"
 
+static void
+update_tc_info(struct zink_context *ctx, bool wait)
+{
+   if (ctx->tc) {
+      const struct tc_renderpass_info *info = threaded_context_get_renderpass_info(ctx->tc, wait);
+      if (info) {
+         ctx->rp_changed |= ctx->dynamic_fb.tc_info.data != info->data;
+         ctx->dynamic_fb.tc_info.data = info->data;
+      }
+   }
+}
+
 void
 debug_describe_zink_buffer_view(char *buf, const struct zink_buffer_view *ptr)
 {
@@ -2291,6 +2303,7 @@ begin_rendering(struct zink_context *ctx)
    bool has_stencil = false;
    bool changed_layout = false;
    bool changed_size = false;
+   bool zsbuf_used = zink_is_zsbuf_used(ctx);
    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++) {
@@ -2300,6 +2313,12 @@ begin_rendering(struct zink_context *ctx)
             ctx->dynamic_fb.attachments[i].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
          else
             ctx->dynamic_fb.attachments[i].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
+         if (ctx->tc && zink_screen(ctx->base.screen)->driver_workarounds.track_renderpasses) {
+            if (ctx->dynamic_fb.tc_info.cbuf_invalidate & BITFIELD_BIT(i))
+               ctx->dynamic_fb.attachments[i].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+            else
+               ctx->dynamic_fb.attachments[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
+         }
          ctx->gfx_pipeline_state.rendering_formats[i] = surf ? surf->info.format[0] : VK_FORMAT_R8G8B8A8_UNORM;
          /* use dummy fb size of 1024 if no surf exists */
          unsigned width = surf ? surf->base.texture->width0 : 1024;
@@ -2320,7 +2339,7 @@ begin_rendering(struct zink_context *ctx)
       ctx->dynamic_fb.info.pStencilAttachment = NULL;
       ctx->gfx_pipeline_state.rendering_info.stencilAttachmentFormat = VK_FORMAT_UNDEFINED;
 
-      if (ctx->fb_state.zsbuf) {
+      if (ctx->fb_state.zsbuf && zsbuf_used) {
          struct zink_surface *surf = zink_csurface(ctx->fb_state.zsbuf);
          has_depth = util_format_has_depth(util_format_description(ctx->fb_state.zsbuf->format));
          has_stencil = util_format_has_stencil(util_format_description(ctx->fb_state.zsbuf->format));
@@ -2331,8 +2350,16 @@ begin_rendering(struct zink_context *ctx)
          else
             ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
 
+         if (ctx->tc && zink_screen(ctx->base.screen)->driver_workarounds.track_renderpasses) {
+            if (ctx->dynamic_fb.tc_info.zsbuf_invalidate)
+               ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+            else
+               ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
+         }
+
          /* stencil may or may not be used but init it anyway */
          ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS+1].loadOp = ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].loadOp;
+         ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS+1].storeOp = ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].storeOp;
 
          if (has_depth) {
             ctx->dynamic_fb.info.pDepthAttachment = &ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS];
@@ -2420,7 +2447,7 @@ begin_rendering(struct zink_context *ctx)
          return 0;
       ctx->dynamic_fb.attachments[i].imageView = iv;
    }
-   if (ctx->fb_state.zsbuf) {
+   if (ctx->fb_state.zsbuf && zsbuf_used) {
       struct zink_surface *surf = zink_csurface(ctx->fb_state.zsbuf);
       VkImageView iv = zink_prep_fb_attachment(ctx, surf, ctx->fb_state.nr_cbufs);
       ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].imageView = iv;
@@ -2464,6 +2491,8 @@ zink_batch_rp(struct zink_context *ctx)
       ctx->base.clear(&ctx->base, ctx->void_clears, NULL, &color, 0, 0);
       ctx->void_clears = 0;
    }
+   update_tc_info(ctx, ctx->rp_tc_info_updated);
+   ctx->rp_tc_info_updated = false;
    unsigned clear_buffers;
    /* use renderpass for multisample-to-singlesample or fbfetch:
     * - msrtss is TODO
@@ -2534,16 +2563,24 @@ zink_prep_fb_attachment(struct zink_context *ctx, struct zink_surface *surf, uns
          zink_update_fbfetch(ctx);
    }
    VkImageLayout layout;
-   if (ctx->gfx_pipeline_state.render_pass) {
-      layout = zink_render_pass_attachment_get_barrier_info(&ctx->gfx_pipeline_state.render_pass->state.rts[i],
-                                                            i < ctx->fb_state.nr_cbufs, &pipeline, &access);
+   if (ctx->tc && zink_screen(ctx->base.screen)->driver_workarounds.track_renderpasses && !ctx->blitting) {
+      assert(threaded_context_get_renderpass_info(ctx->tc, false)->data == ctx->dynamic_fb.tc_info.data);
+      layout = zink_tc_renderpass_info_parse(ctx, &ctx->dynamic_fb.tc_info, i < ctx->fb_state.nr_cbufs ? i : PIPE_MAX_COLOR_BUFS, &pipeline, &access);
+      assert(i < ctx->fb_state.nr_cbufs || layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL || !zink_fb_clear_enabled(ctx, PIPE_MAX_COLOR_BUFS));
+      if (i == ctx->fb_state.nr_cbufs && zink_fb_clear_enabled(ctx, PIPE_MAX_COLOR_BUFS))
+         assert(ctx->dynamic_fb.tc_info.zsbuf_clear || ctx->dynamic_fb.tc_info.zsbuf_clear_partial || ctx->dynamic_fb.tc_info.zsbuf_load);
    } else {
-      struct zink_rt_attrib rt;
-      if (i < ctx->fb_state.nr_cbufs)
-         zink_init_color_attachment(ctx, i, &rt);
-      else
-         zink_init_zs_attachment(ctx, &rt);
-      layout = zink_render_pass_attachment_get_barrier_info(&rt, i < ctx->fb_state.nr_cbufs, &pipeline, &access);
+      if (ctx->gfx_pipeline_state.render_pass) {
+         layout = zink_render_pass_attachment_get_barrier_info(&ctx->gfx_pipeline_state.render_pass->state.rts[i],
+                                                               i < ctx->fb_state.nr_cbufs, &pipeline, &access);
+      } else {
+         struct zink_rt_attrib rt;
+         if (i < ctx->fb_state.nr_cbufs)
+            zink_init_color_attachment(ctx, i, &rt);
+         else
+            zink_init_zs_attachment(ctx, &rt);
+         layout = zink_render_pass_attachment_get_barrier_info(&rt, i < ctx->fb_state.nr_cbufs, &pipeline, &access);
+      }
    }
    if (!zink_screen(ctx->base.screen)->info.have_EXT_attachment_feedback_loop_layout &&
        layout == VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT)
@@ -3051,6 +3088,8 @@ zink_set_framebuffer_state(struct pipe_context *pctx,
       flush_batch(ctx, false);
    else
       update_layered_rendering_state(ctx);
+
+   ctx->rp_tc_info_updated = !ctx->blitting;
 }
 
 static void
@@ -3706,6 +3745,7 @@ zink_flush(struct pipe_context *pctx,
       if (!(flags & (PIPE_FLUSH_DEFERRED | PIPE_FLUSH_ASYNC)))
          sync_flush(ctx, zink_batch_state(fence));
    }
+   update_tc_info(ctx, false);
 }
 
 void
@@ -4654,6 +4694,25 @@ struct zink_surface *
 zink_get_dummy_surface(struct zink_context *ctx, int samples_index)
 {
    return zink_csurface(zink_get_dummy_pipe_surface(ctx, samples_index));
+
+}
+
+static void
+zink_tc_parse_dsa(void *state, struct tc_renderpass_info *info)
+{
+   struct zink_depth_stencil_alpha_state *cso = state;
+   info->zsbuf_write_dsa |= (cso->hw_state.depth_write || cso->base.stencil[0].writemask || cso->base.stencil[1].writemask);
+   info->zsbuf_read_dsa |= (cso->hw_state.depth_test || cso->hw_state.stencil_test);
+   /* TODO: if zsbuf fbfetch is ever supported */
+}
+
+static void
+zink_tc_parse_fs(void *state, struct tc_renderpass_info *info)
+{
+   struct zink_shader *zs = state;
+   info->zsbuf_write_fs |= zs->nir->info.outputs_written & (BITFIELD64_BIT(FRAG_RESULT_DEPTH) | BITFIELD64_BIT(FRAG_RESULT_STENCIL));
+   /* TODO: if >1 fbfetch attachment is ever supported */
+   info->cbuf_fbfetch |= zs->nir->info.fs.uses_fbfetch_output ? BITFIELD_BIT(0) : 0;
 }
 
 struct pipe_context *
@@ -4906,6 +4965,9 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
                                                         .is_resource_busy = zink_context_is_resource_busy,
                                                         .driver_calls_flush_notify = true,
                                                         .unsynchronized_get_device_reset_status = true,
+                                                        .parse_renderpass_info = screen->driver_workarounds.track_renderpasses,
+                                                        .dsa_parse = zink_tc_parse_dsa,
+                                                        .fs_parse = zink_tc_parse_fs,
                                                      },
                                                      &ctx->tc);
 
index 111603e..3fd64a8 100644 (file)
@@ -72,6 +72,14 @@ zink_program_cache_stages(uint32_t stages_present)
                              (1 << MESA_SHADER_GEOMETRY))) >> 1;
 }
 
+static inline bool
+zink_is_zsbuf_used(const struct zink_context *ctx)
+{
+   return !ctx->tc || ctx->blitting ||
+         !zink_screen(ctx->base.screen)->driver_workarounds.track_renderpasses ||
+         tc_renderpass_info_is_zsbuf_used(&ctx->dynamic_fb.tc_info);
+}
+
 void
 zink_fence_wait(struct pipe_context *ctx);
 
index d96097e..aa1a4ca 100644 (file)
@@ -147,11 +147,12 @@ struct zink_framebuffer *
 zink_get_framebuffer(struct zink_context *ctx)
 {
    assert(zink_screen(ctx->base.screen)->info.have_KHR_imageless_framebuffer);
+   bool have_zsbuf = ctx->fb_state.zsbuf && zink_is_zsbuf_used(ctx);
 
    struct zink_framebuffer_state state;
    state.num_attachments = ctx->fb_state.nr_cbufs;
 
-   const unsigned cresolve_offset = ctx->fb_state.nr_cbufs + !!ctx->fb_state.zsbuf;
+   const unsigned cresolve_offset = ctx->fb_state.nr_cbufs + !!have_zsbuf;
    unsigned num_resolves = 0;
    for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) {
       struct pipe_surface *psurf = ctx->fb_state.cbufs[i];
@@ -170,7 +171,7 @@ zink_get_framebuffer(struct zink_context *ctx)
    }
 
    const unsigned zsresolve_offset = cresolve_offset + num_resolves;
-   if (ctx->fb_state.zsbuf) {
+   if (have_zsbuf) {
       struct pipe_surface *psurf = ctx->fb_state.zsbuf;
       struct zink_surface *surface = zink_csurface(psurf);
       struct zink_surface *transient = zink_transient_surface(psurf);
index 002c878..6a3912f 100644 (file)
@@ -284,6 +284,29 @@ zink_render_pass_attachment_get_barrier_info(const struct zink_rt_attrib *rt, bo
    return get_zs_rt_layout(rt);
 }
 
+VkImageLayout
+zink_tc_renderpass_info_parse(struct zink_context *ctx, const struct tc_renderpass_info *info, unsigned idx, VkPipelineStageFlags *pipeline, VkAccessFlags *access)
+{
+   if (idx < PIPE_MAX_COLOR_BUFS) {
+      *pipeline = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+      *access = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
+      if (info->cbuf_load & BITFIELD_BIT(idx))
+         *access |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
+      return (ctx->feedback_loops & BITFIELD_BIT(idx)) ? VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT :
+             (info->cbuf_fbfetch & BITFIELD_BIT(idx)) ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+   } else {
+      *access = 0;
+      if (info->zsbuf_load || info->zsbuf_read_dsa)
+         *access |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
+      if (info->zsbuf_clear | info->zsbuf_clear_partial | info->zsbuf_write_fs | info->zsbuf_write_dsa)
+         *access |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
+      assert(*access);
+      *pipeline = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
+      if (ctx->feedback_loops & BITFIELD_BIT(PIPE_MAX_COLOR_BUFS))
+         return VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT;
+      return (info->zsbuf_clear | info->zsbuf_clear_partial | info->zsbuf_write_fs | info->zsbuf_write_dsa) ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
+   }
+}
 
 static size_t
 rp_state_size(const struct zink_render_pass_pipeline_state *pstate)
@@ -351,6 +374,26 @@ zink_init_zs_attachment(struct zink_context *ctx, struct zink_rt_attrib *rt)
 }
 
 void
+zink_tc_init_zs_attachment(struct zink_context *ctx, const struct tc_renderpass_info *info, struct zink_rt_attrib *rt)
+{
+   const struct pipe_framebuffer_state *fb = &ctx->fb_state;
+   struct zink_resource *zsbuf = zink_resource(fb->zsbuf->texture);
+   struct zink_framebuffer_clear *fb_clear = &ctx->fb_clears[PIPE_MAX_COLOR_BUFS];
+   struct zink_surface *transient = zink_transient_surface(fb->zsbuf);
+   rt->format = zsbuf->format;
+   rt->samples = MAX3(transient ? transient->base.nr_samples : 0, fb->zsbuf->texture->nr_samples, 1);
+   rt->clear_color = zink_fb_clear_enabled(ctx, PIPE_MAX_COLOR_BUFS) &&
+                                         !zink_fb_clear_first_needs_explicit(fb_clear) &&
+                                         (zink_fb_clear_element(fb_clear, 0)->zs.bits & PIPE_CLEAR_DEPTH);
+   rt->clear_stencil = zink_fb_clear_enabled(ctx, PIPE_MAX_COLOR_BUFS) &&
+                                           !zink_fb_clear_first_needs_explicit(fb_clear) &&
+                                           (zink_fb_clear_element(fb_clear, 0)->zs.bits & PIPE_CLEAR_STENCIL);
+   rt->needs_write = info->zsbuf_clear | info->zsbuf_clear_partial | info->zsbuf_write_fs | info->zsbuf_write_dsa;
+   rt->invalid = !zsbuf->valid;
+   rt->feedback_loop = (ctx->feedback_loops & BITFIELD_BIT(PIPE_MAX_COLOR_BUFS)) > 0;
+}
+
+void
 zink_init_color_attachment(struct zink_context *ctx, unsigned i, struct zink_rt_attrib *rt)
 {
    const struct pipe_framebuffer_state *fb = &ctx->fb_state;
@@ -371,6 +414,27 @@ zink_init_color_attachment(struct zink_context *ctx, unsigned i, struct zink_rt_
    }
 }
 
+void
+zink_tc_init_color_attachment(struct zink_context *ctx, const struct tc_renderpass_info *info, unsigned i, struct zink_rt_attrib *rt)
+{
+   const struct pipe_framebuffer_state *fb = &ctx->fb_state;
+   struct pipe_surface *psurf = fb->cbufs[i];
+   if (psurf && !zink_use_dummy_attachments(ctx)) {
+      struct zink_surface *surf = zink_csurface(psurf);
+      struct zink_surface *transient = zink_transient_surface(psurf);
+      rt->format = surf->info.format[0];
+      rt->samples = MAX3(transient ? transient->base.nr_samples : 0, psurf->texture->nr_samples, 1);
+      rt->clear_color = zink_fb_clear_enabled(ctx, i) && !zink_fb_clear_first_needs_explicit(&ctx->fb_clears[i]);
+      rt->invalid = !zink_resource(psurf->texture)->valid;
+      rt->fbfetch = (info->cbuf_fbfetch & BITFIELD_BIT(i)) > 0;
+      rt->feedback_loop = (ctx->feedback_loops & BITFIELD_BIT(i)) > 0;
+   } else {
+      memset(rt, 0, sizeof(struct zink_rt_attrib));
+      rt->format = VK_FORMAT_R8G8B8A8_UNORM;
+      rt->samples = fb->samples;
+   }
+}
+
 static struct zink_render_pass *
 get_render_pass(struct zink_context *ctx)
 {
@@ -378,10 +442,14 @@ get_render_pass(struct zink_context *ctx)
    const struct pipe_framebuffer_state *fb = &ctx->fb_state;
    struct zink_render_pass_state state = {0};
    uint32_t clears = 0;
+   bool have_zsbuf = fb->zsbuf && zink_is_zsbuf_used(ctx);
    state.samples = fb->samples > 0;
 
    for (int i = 0; i < fb->nr_cbufs; i++) {
-      zink_init_color_attachment(ctx, i, &state.rts[i]);
+      if (ctx->tc && screen->driver_workarounds.track_renderpasses)
+         zink_tc_init_color_attachment(ctx, &ctx->dynamic_fb.tc_info, i, &state.rts[i]);
+      else
+         zink_init_color_attachment(ctx, i, &state.rts[i]);
       struct pipe_surface *surf = fb->cbufs[i];
       if (surf && !zink_use_dummy_attachments(ctx)) {
          clears |= !!state.rts[i].clear_color ? PIPE_CLEAR_COLOR0 << i : 0;
@@ -400,8 +468,11 @@ get_render_pass(struct zink_context *ctx)
    state.num_cbufs = fb->nr_cbufs;
    assert(!state.num_cresolves || state.num_cbufs == state.num_cresolves);
 
-   if (fb->zsbuf) {
-      zink_init_zs_attachment(ctx, &state.rts[fb->nr_cbufs]);
+   if (have_zsbuf) {
+      if (ctx->tc && screen->driver_workarounds.track_renderpasses)
+         zink_tc_init_zs_attachment(ctx, &ctx->dynamic_fb.tc_info, &state.rts[fb->nr_cbufs]);
+      else
+         zink_init_zs_attachment(ctx, &state.rts[fb->nr_cbufs]);
       struct zink_surface *transient = zink_transient_surface(fb->zsbuf);
       if (transient) {
          state.num_zsresolves = 1;
@@ -413,7 +484,7 @@ get_render_pass(struct zink_context *ctx)
          clears |= PIPE_CLEAR_STENCIL;
       state.num_rts++;
    }
-   state.have_zsbuf = fb->zsbuf != NULL;
+   state.have_zsbuf = have_zsbuf;
    if (zink_use_dummy_attachments(ctx))
       assert(clears == (ctx->rp_clears_enabled & PIPE_CLEAR_DEPTHSTENCIL));
    else
@@ -533,7 +604,8 @@ setup_framebuffer(struct zink_context *ctx)
 static bool
 prep_fb_attachments(struct zink_context *ctx, VkImageView *att)
 {
-   const unsigned cresolve_offset = ctx->fb_state.nr_cbufs + !!ctx->fb_state.zsbuf;
+   bool have_zsbuf = ctx->fb_state.zsbuf && zink_is_zsbuf_used(ctx);
+   const unsigned cresolve_offset = ctx->fb_state.nr_cbufs + !!have_zsbuf;
    unsigned num_resolves = 0;
    for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) {
       struct zink_surface *surf = zink_csurface(ctx->fb_state.cbufs[i]);
@@ -549,7 +621,7 @@ prep_fb_attachments(struct zink_context *ctx, VkImageView *att)
             return false;
       }
    }
-   if (ctx->fb_state.zsbuf) {
+   if (have_zsbuf) {
       struct zink_surface *surf = zink_csurface(ctx->fb_state.zsbuf);
       struct zink_surface *transient = zink_transient_surface(ctx->fb_state.zsbuf);
       if (transient) {
@@ -567,6 +639,7 @@ begin_render_pass(struct zink_context *ctx)
 {
    struct zink_batch *batch = &ctx->batch;
    struct pipe_framebuffer_state *fb_state = &ctx->fb_state;
+   bool zsbuf_used = ctx->fb_state.zsbuf && zink_is_zsbuf_used(ctx);
 
    VkRenderPassBeginInfo rpbi = {0};
    rpbi.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
@@ -631,7 +704,7 @@ begin_render_pass(struct zink_context *ctx)
    /* this can be set if fbfetch is activated */
    ctx->rp_changed = false;
 #ifndef NDEBUG
-   const unsigned cresolve_offset = ctx->fb_state.nr_cbufs + !!ctx->fb_state.zsbuf;
+   const unsigned cresolve_offset = ctx->fb_state.nr_cbufs + !!zsbuf_used;
    for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) {
       if (ctx->fb_state.cbufs[i]) {
          struct zink_surface *surf = zink_csurface(ctx->fb_state.cbufs[i]);
@@ -651,7 +724,7 @@ begin_render_pass(struct zink_context *ctx)
          }
       }
    }
-   if (ctx->fb_state.zsbuf) {
+   if (ctx->gfx_pipeline_state.render_pass->state.have_zsbuf) {
       struct zink_surface *surf = zink_csurface(ctx->fb_state.zsbuf);
       struct zink_surface *transient = zink_transient_surface(ctx->fb_state.zsbuf);
       if (transient) {
index 20aaeb1..d3d74e2 100644 (file)
@@ -43,7 +43,8 @@ zink_end_render_pass(struct zink_context *ctx);
 
 VkImageLayout
 zink_render_pass_attachment_get_barrier_info(const struct zink_rt_attrib *rt, bool color, VkPipelineStageFlags *pipeline, VkAccessFlags *access);
-
+VkImageLayout
+zink_tc_renderpass_info_parse(struct zink_context *ctx, const struct tc_renderpass_info *info, unsigned idx, VkPipelineStageFlags *pipeline, VkAccessFlags *access);
 bool
 zink_init_render_pass(struct zink_context *ctx);
 void
@@ -52,4 +53,8 @@ void
 zink_init_zs_attachment(struct zink_context *ctx, struct zink_rt_attrib *rt);
 void
 zink_init_color_attachment(struct zink_context *ctx, unsigned i, struct zink_rt_attrib *rt);
+void
+zink_tc_init_zs_attachment(struct zink_context *ctx, const struct tc_renderpass_info *info, struct zink_rt_attrib *rt);
+void
+zink_tc_init_color_attachment(struct zink_context *ctx, const struct tc_renderpass_info *info, unsigned i, struct zink_rt_attrib *rt);
 #endif
index f7f37f0..71cadcc 100644 (file)
@@ -79,6 +79,7 @@ zink_debug_options[] = {
    { "noreorder", ZINK_DEBUG_NOREORDER, "Do not reorder command streams" },
    { "gpl", ZINK_DEBUG_GPL, "Force using Graphics Pipeline Library for all shaders" },
    { "shaderdb", ZINK_DEBUG_SHADERDB, "Do stuff to make shader-db work" },
+   { "rp", ZINK_DEBUG_RP, "Enable renderpass tracking/optimizations" },
    DEBUG_NAMED_VALUE_END
 };
 
@@ -2340,6 +2341,29 @@ init_driver_workarounds(struct zink_screen *screen)
       screen->driver_workarounds.needs_sanitised_layer = false;
       break;
    }
+
+   /* once more testing has been done, use the #if 0 block */
+   if (zink_debug & ZINK_DEBUG_RP)
+      screen->driver_workarounds.track_renderpasses = true;
+#if 0
+   /* these drivers benefit from renderpass optimization */
+   switch (screen->info.driver_props.driverID) {
+   //* llvmpipe is broken: #7489
+   // case VK_DRIVER_ID_MESA_LLVMPIPE:
+   case VK_DRIVER_ID_MESA_TURNIP:
+   case VK_DRIVER_ID_MESA_PANVK:
+   case VK_DRIVER_ID_MESA_VENUS:
+   case VK_DRIVER_ID_MESA_V3DV:
+   case VK_DRIVER_ID_IMAGINATION_PROPRIETARY:
+   case VK_DRIVER_ID_QUALCOMM_PROPRIETARY:
+   case VK_DRIVER_ID_BROADCOM_PROPRIETARY:
+   case VK_DRIVER_ID_ARM_PROPRIETARY:
+      screen->driver_workarounds.track_renderpasses = true;
+      break;
+   default:
+      break;
+   }
+#endif
 }
 
 static struct zink_screen *
index 8dd4c1f..a9c3aeb 100644 (file)
@@ -206,6 +206,7 @@ enum zink_debug {
    ZINK_DEBUG_NOREORDER = (1<<6),
    ZINK_DEBUG_GPL = (1<<7),
    ZINK_DEBUG_SHADERDB = (1<<8),
+   ZINK_DEBUG_RP = (1<<9),
 };
 
 
@@ -1274,6 +1275,7 @@ struct zink_screen {
       bool always_feedback_loop;
       bool always_feedback_loop_zs;
       bool needs_sanitised_layer;
+      bool track_renderpasses;
       unsigned z16_unscaled_bias;
       unsigned z24_unscaled_bias;
    } driver_workarounds;
@@ -1542,6 +1544,7 @@ struct zink_context {
    struct {
       VkRenderingAttachmentInfo attachments[PIPE_MAX_COLOR_BUFS + 2]; //+depth, +stencil
       VkRenderingInfo info;
+      struct tc_renderpass_info tc_info;
    } dynamic_fb;
    uint32_t fb_layer_mismatch; //bitmask
    unsigned depth_bias_scale_factor;
@@ -1673,6 +1676,7 @@ struct zink_context {
    bool dsa_state_changed : 1;
    bool stencil_ref_changed : 1;
    bool rasterizer_discard_changed : 1;
+   bool rp_tc_info_updated : 1;
 };
 
 static inline struct zink_context *