zink: manually apply barriers whenever zink_context::blitting is set
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>
Tue, 28 Feb 2023 19:37:46 +0000 (14:37 -0500)
committerMarge Bot <emma+marge@anholt.net>
Mon, 20 Mar 2023 02:26:20 +0000 (02:26 +0000)
this simplifies some codepaths at runtime by short-circuiting some
of the more complex operations since it's already known in advance
exactly which images will be used for which purpose

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

src/gallium/drivers/zink/zink_blit.c
src/gallium/drivers/zink/zink_clear.c
src/gallium/drivers/zink/zink_context.c
src/gallium/drivers/zink/zink_draw.cpp
src/gallium/drivers/zink/zink_render_pass.c

index 83a3573..45899d3 100644 (file)
@@ -356,12 +356,36 @@ zink_blit(struct pipe_context *pctx,
     */
    apply_dst_clears(ctx, info, true);
    zink_fb_clears_apply_region(ctx, info->src.resource, zink_rect_from_box(&info->src.box));
+   unsigned rp_clears_enabled = ctx->rp_clears_enabled;
+   unsigned clears_enabled = ctx->clears_enabled;
+   if (!dst->fb_bind_count) {
+      /* avoid applying clears from fb unbind by storing and re-setting them after the blit */
+      ctx->rp_clears_enabled = 0;
+      ctx->clears_enabled = 0;
+   } else {
+      unsigned bit;
+      /* convert to PIPE_CLEAR_XYZ */
+      if (dst->fb_binds & BITFIELD_BIT(PIPE_MAX_COLOR_BUFS))
+         bit = PIPE_CLEAR_DEPTHSTENCIL;
+      else
+         bit = dst->fb_binds << 2;
+      rp_clears_enabled &= ~bit;
+      clears_enabled &= ~bit;
+      ctx->rp_clears_enabled &= bit;
+      ctx->clears_enabled &= bit;
+   }
 
    /* this will draw a full-resource quad, so ignore existing data */
-   if (util_blit_covers_whole_resource(info))
+   bool whole = util_blit_covers_whole_resource(info);
+   if (whole)
       pctx->invalidate_resource(pctx, info->dst.resource);
-   ctx->blitting = true;
    zink_blit_begin(ctx, ZINK_BLIT_SAVE_FB | ZINK_BLIT_SAVE_FS | ZINK_BLIT_SAVE_TEXTURES);
+   if (info->src.format != info->src.resource->format)
+      zink_resource_object_init_mutable(ctx, src);
+   if (info->dst.format != info->dst.resource->format)
+      zink_resource_object_init_mutable(ctx, dst);
+   zink_blit_barriers(ctx, src, dst, whole);
+   ctx->blitting = true;
 
    if (stencil_blit) {
       struct pipe_surface *dst_view, dst_templ;
@@ -386,6 +410,8 @@ zink_blit(struct pipe_context *pctx,
       util_blitter_blit(ctx->blitter, info);
    }
    ctx->blitting = false;
+   ctx->rp_clears_enabled = rp_clears_enabled;
+   ctx->clears_enabled = clears_enabled;
 end:
    if (needs_present_readback)
       zink_kopper_present_readback(ctx, src);
index 4a14e58..19c9a33 100644 (file)
@@ -539,6 +539,7 @@ zink_clear_texture(struct pipe_context *pctx,
       surf = create_clear_surface(pctx, pres, level, box);
       util_blitter_save_framebuffer(ctx->blitter, &ctx->fb_state);
       set_clear_fb(pctx, surf, NULL);
+      zink_blit_barriers(ctx, NULL, res, false);
       ctx->blitting = true;
       ctx->queries_disabled = true;
       pctx->clear(pctx, PIPE_CLEAR_COLOR0, &scissor, &color, 0, 0);
@@ -562,6 +563,7 @@ zink_clear_texture(struct pipe_context *pctx,
          flags |= PIPE_CLEAR_STENCIL;
       surf = create_clear_surface(pctx, pres, level, box);
       util_blitter_save_framebuffer(ctx->blitter, &ctx->fb_state);
+      zink_blit_barriers(ctx, NULL, res, false);
       ctx->blitting = true;
       set_clear_fb(pctx, NULL, surf);
       ctx->queries_disabled = true;
@@ -633,6 +635,7 @@ zink_clear_render_target(struct pipe_context *pctx, struct pipe_surface *dst,
    util_blitter_save_framebuffer(ctx->blitter, &ctx->fb_state);
    set_clear_fb(pctx, dst, NULL);
    struct pipe_scissor_state scissor = {dstx, dsty, dstx + width, dsty + height};
+   zink_blit_barriers(ctx, NULL, zink_resource(dst->texture), false);
    ctx->blitting = true;
    pctx->clear(pctx, PIPE_CLEAR_COLOR0, &scissor, color, 0, 0);
    util_blitter_restore_fb_state(ctx->blitter);
@@ -662,6 +665,7 @@ zink_clear_depth_stencil(struct pipe_context *pctx, struct pipe_surface *dst,
    if (!cur_attachment) {
       util_blitter_save_framebuffer(ctx->blitter, &ctx->fb_state);
       set_clear_fb(pctx, NULL, dst);
+      zink_blit_barriers(ctx, NULL, zink_resource(dst->texture), false);
       ctx->blitting = true;
    }
    struct pipe_scissor_state scissor = {dstx, dsty, dstx + width, dsty + height};
index 552b8ef..13c08f9 100644 (file)
@@ -648,7 +648,7 @@ update_descriptor_state_sampler(struct zink_context *ctx, gl_shader_stage shader
          }
       } else {
          struct zink_surface *surface = get_imageview_for_binding(ctx, shader, type, slot);
-         ctx->di.textures[shader][slot].imageLayout = get_layout_for_binding(ctx, res, type, shader == MESA_SHADER_COMPUTE);
+         ctx->di.textures[shader][slot].imageLayout = ctx->blitting ? res->layout : get_layout_for_binding(ctx, res, type, shader == MESA_SHADER_COMPUTE);
          ctx->di.textures[shader][slot].imageView = surface->image_view;
          if (!screen->have_D24_UNORM_S8_UINT &&
              ctx->sampler_states[shader][slot] && ctx->sampler_states[shader][slot]->sampler_clamped) {
@@ -2862,6 +2862,8 @@ zink_prep_fb_attachment(struct zink_context *ctx, struct zink_surface *surf, uns
       if (!i)
          zink_update_fbfetch(ctx);
    }
+   if (ctx->blitting)
+      return surf->image_view;
    VkImageLayout layout;
    if (ctx->tc && zink_screen(ctx->base.screen)->driver_workarounds.track_renderpasses && !ctx->blitting) {
       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);
@@ -3205,7 +3207,7 @@ unbind_fb_surface(struct zink_context *ctx, struct pipe_surface *surf, unsigned
       check_resource_for_batch_ref(ctx, res);
       if (res->sampler_bind_count[0]) {
          update_res_sampler_layouts(ctx, res);
-         if (res->layout != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
+         if (res->layout != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL && !ctx->blitting)
             _mesa_set_add(ctx->need_barriers[0], res);
       }
    }
@@ -3727,6 +3729,7 @@ static void
 resource_check_defer_image_barrier(struct zink_context *ctx, struct zink_resource *res, VkImageLayout layout, VkPipelineStageFlags pipeline)
 {
    assert(!res->obj->is_buffer);
+   assert(!ctx->blitting);
 
    bool is_compute = pipeline == VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
    /* if this is a non-shader barrier and there are binds, always queue a shader barrier */
@@ -4094,6 +4097,13 @@ zink_flush(struct pipe_context *pctx,
          ctx->fbfetch_outputs = 0;
          ctx->rp_changed = true;
       }
+      if (ctx->fb_state.zsbuf)
+         zink_blit_barriers(ctx, NULL, zink_resource(ctx->fb_state.zsbuf->texture), false);
+
+      for (unsigned i = 0; i < ctx->fb_state.nr_cbufs; i++) {
+         if (ctx->fb_state.cbufs[i])
+            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);
@@ -5034,6 +5044,7 @@ zink_resource_commit(struct pipe_context *pctx, struct pipe_resource *pres, unsi
 static void
 rebind_image(struct zink_context *ctx, struct zink_resource *res)
 {
+   assert(!ctx->blitting);
    if (res->fb_binds)
       zink_rebind_framebuffer(ctx, res);
    if (!zink_resource_has_binds(res))
@@ -5111,6 +5122,7 @@ zink_rebind_all_buffers(struct zink_context *ctx)
 void
 zink_rebind_all_images(struct zink_context *ctx)
 {
+   assert(!ctx->blitting);
    rebind_fb_state(ctx, NULL, false);
     for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
       for (unsigned j = 0; j < ctx->di.num_sampler_views[i]; j++) {
@@ -5628,6 +5640,7 @@ void
 zink_update_barriers(struct zink_context *ctx, bool is_compute,
                      struct pipe_resource *index, struct pipe_resource *indirect, struct pipe_resource *indirect_draw_count)
 {
+   assert(!ctx->blitting);
    if (!ctx->need_barriers[is_compute]->entries)
       return;
    struct set *need_barriers = ctx->need_barriers[is_compute];
index 7431702..c74b3ea 100644 (file)
@@ -364,15 +364,15 @@ zink_draw(struct pipe_context *pctx,
    unsigned work_count = ctx->batch.work_count;
    enum pipe_prim_type mode = (enum pipe_prim_type)dinfo->mode;
 
-   if (ctx->memory_barrier)
+   if (ctx->memory_barrier && !ctx->blitting)
       zink_flush_memory_barrier(ctx, false);
 
-   if (unlikely(ctx->buffer_rebind_counter < screen->buffer_rebind_counter)) {
+   if (unlikely(ctx->buffer_rebind_counter < screen->buffer_rebind_counter && !ctx->blitting)) {
       ctx->buffer_rebind_counter = screen->buffer_rebind_counter;
       zink_rebind_all_buffers(ctx);
    }
 
-   if (unlikely(ctx->image_rebind_counter < screen->image_rebind_counter)) {
+   if (unlikely(ctx->image_rebind_counter < screen->image_rebind_counter && !ctx->blitting)) {
       ctx->image_rebind_counter = screen->image_rebind_counter;
       zink_rebind_all_images(ctx);
    }
@@ -423,7 +423,8 @@ zink_draw(struct pipe_context *pctx,
 
    barrier_draw_buffers(ctx, dinfo, dindirect, index_buffer);
    /* this may re-emit draw buffer barriers, but such synchronization is harmless */
-   zink_update_barriers(ctx, false, index_buffer, dindirect ? dindirect->buffer : NULL, dindirect ? dindirect->indirect_draw_count : NULL);
+   if (!ctx->blitting)
+      zink_update_barriers(ctx, false, index_buffer, dindirect ? dindirect->buffer : NULL, dindirect ? dindirect->indirect_draw_count : NULL);
 
    /* ensure synchronization between doing streamout with counter buffer
     * and using counter buffer for indirect draw
index ed3abc3..f6dbe1e 100644 (file)
@@ -786,6 +786,7 @@ zink_begin_render_pass(struct zink_context *ctx)
          src_view = ctx->base.create_sampler_view(&ctx->base, src, &src_templ);
 
          zink_blit_begin(ctx, ZINK_BLIT_SAVE_FB | ZINK_BLIT_SAVE_FS | ZINK_BLIT_SAVE_TEXTURES);
+         zink_blit_barriers(ctx, zink_resource(src), zink_resource(dst_view->texture), false);
          ctx->blitting = true;
          util_blitter_blit_generic(ctx->blitter, dst_view, &dstbox,
                                    src_view, &dstbox, ctx->fb_state.width, ctx->fb_state.height,