Mesa (main): zink: optimize buffer rebinds

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Jul 7 01:42:35 UTC 2021


Module: Mesa
Branch: main
Commit: 59cc9c8df15c3624ecd712613e59393f7e1dbfe8
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=59cc9c8df15c3624ecd712613e59393f7e1dbfe8

Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date:   Tue May 11 11:08:03 2021 -0400

zink: optimize buffer rebinds

this leverages all the slot masks to more optimally run through all
the rebinds, also enabling some code consolidation

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

---

 src/gallium/drivers/zink/zink_context.c | 172 ++++++++++++--------------------
 1 file changed, 63 insertions(+), 109 deletions(-)

diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c
index 4110cd7adb2..c728a2816e9 100644
--- a/src/gallium/drivers/zink/zink_context.c
+++ b/src/gallium/drivers/zink/zink_context.c
@@ -3127,127 +3127,81 @@ zink_rebind_framebuffer(struct zink_context *ctx, struct zink_resource *res)
       zink_batch_no_rp(ctx);
 }
 
-static bool
-check_and_rebind_buffer(struct zink_context *ctx, struct zink_resource *res, unsigned shader, enum zink_descriptor_type type, unsigned i)
-{
-   bool is_write = false;
-   bool is_read = true;
-   struct zink_resource *cres = zink_get_resource_for_descriptor(ctx, type, shader, i);
-   if (res != cres)
-      return false;
-
-   switch (type) {
-   case ZINK_DESCRIPTOR_TYPE_UBO:
-      update_descriptor_state_ubo(ctx, shader, i);
-      break;
-   case ZINK_DESCRIPTOR_TYPE_SSBO: {
-      struct pipe_shader_buffer *ssbo = &ctx->ssbos[shader][i];
-      is_write = ctx->writable_ssbos[shader] & BITFIELD64_BIT(i);
-      util_range_add(&res->base.b, &res->valid_buffer_range, ssbo->buffer_offset,
-                     ssbo->buffer_offset + ssbo->buffer_size);
-      update_descriptor_state_ssbo(ctx, shader, i);
-      break;
-   }
-   case ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW: {
-      struct zink_sampler_view *sampler_view = zink_sampler_view(ctx->sampler_views[shader][i]);
-      if (zink_batch_usage_exists(sampler_view->buffer_view->batch_uses))
-         zink_batch_reference_bufferview(&ctx->batch, sampler_view->buffer_view);
-      zink_buffer_view_reference(zink_screen(ctx->base.screen), &sampler_view->buffer_view, NULL);
-      sampler_view->buffer_view = get_buffer_view(ctx, res, sampler_view->base.format,
-                                                  sampler_view->base.u.buf.offset, sampler_view->base.u.buf.size);
-      update_descriptor_state_sampler(ctx, shader, i);
-      break;
-   }
-   case ZINK_DESCRIPTOR_TYPE_IMAGE: {
-      struct zink_image_view *image_view = &ctx->image_views[shader][i];
-      zink_descriptor_set_refs_clear(&image_view->buffer_view->desc_set_refs, image_view->buffer_view);
-      if (zink_batch_usage_exists(image_view->buffer_view->batch_uses))
-         zink_batch_reference_bufferview(&ctx->batch, image_view->buffer_view);
-      zink_buffer_view_reference(zink_screen(ctx->base.screen), &image_view->buffer_view, NULL);
-      if (!zink_resource_object_init_storage(ctx, res)) {
-         debug_printf("couldn't create storage image!");
-         return false;
-      }
-      is_write = image_view->base.access & PIPE_IMAGE_ACCESS_WRITE;
-      is_read = image_view->base.access & PIPE_IMAGE_ACCESS_READ;
-      image_view->buffer_view = get_buffer_view(ctx, res, image_view->base.format,
-                                                image_view->base.u.buf.offset, image_view->base.u.buf.size);
-      assert(image_view->buffer_view);
-      util_range_add(&res->base.b, &res->valid_buffer_range, image_view->base.u.buf.offset,
-                     image_view->base.u.buf.offset + image_view->base.u.buf.size);
-      update_descriptor_state_image(ctx, shader, i);
-      break;
-   }
-   default:
-      break;
-   }
-
-   zink_screen(ctx->base.screen)->context_invalidate_descriptor_state(ctx, shader, type, i, 1);
-   zink_batch_resource_usage_set(&ctx->batch, res, is_write);
-   return true;
-}
-
 static void
 rebind_buffer(struct zink_context *ctx, struct zink_resource *res)
 {
-   unsigned num_rebinds = 0;
+   const unsigned total_rebinds = res->bind_count[0] + res->bind_count[1];
+   unsigned num_rebinds = 0, num_image_rebinds_remaining[2] = {res->image_bind_count[0], res->image_bind_count[1]};
+   bool has_write = false;
 
-   for (unsigned shader = 0; shader < PIPE_SHADER_TYPES; shader++) {
-      if (!(res->bind_stages & (1 << shader)))
-         continue;
-      for (enum zink_descriptor_type type = 0; type < ZINK_DESCRIPTOR_TYPES; type++) {
-         if (!(res->bind_history & BITFIELD64_BIT(type)))
-            continue;
+   if (res->vbo_bind_count) {
+      ctx->vertex_buffers_dirty = true;
+      num_rebinds += res->vbo_bind_count;
+   }
+   for (unsigned shader = 0; num_rebinds < total_rebinds && shader < PIPE_SHADER_TYPES; shader++) {
+      u_foreach_bit(slot, res->ubo_bind_mask[shader]) {
+         if (&res->base.b != ctx->ubos[shader][slot].buffer) //wrong context
+            return;
 
-         uint32_t usage = zink_program_get_descriptor_usage(ctx, shader, type);
-         u_foreach_bit(i, usage) {
-            if (check_and_rebind_buffer(ctx, res, shader, type, i))
-               num_rebinds++;
-         }
+         update_descriptor_state_ubo(ctx, shader, slot);
+         zink_screen(ctx->base.screen)->context_invalidate_descriptor_state(ctx, shader, ZINK_DESCRIPTOR_TYPE_UBO, slot, 1);
+         num_rebinds++;
       }
-   }
-   unsigned total_binds = res->bind_count[0] + res->bind_count[1] - res->vbo_bind_count;
-   /* we've missed some rebinds, so we have to go back for them */
-   if (total_binds != num_rebinds) {
-      for (unsigned shader = 0; shader < PIPE_SHADER_TYPES; shader++) {
-         if (!(res->bind_stages & (1 << shader)))
-            continue;
-         for (enum zink_descriptor_type type = 0; type < ZINK_DESCRIPTOR_TYPES; type++) {
-            if (!(res->bind_history & BITFIELD64_BIT(type)))
+      u_foreach_bit(slot, res->ssbo_bind_mask[shader]) {
+         struct pipe_shader_buffer *ssbo = &ctx->ssbos[shader][slot];
+         if (&res->base.b != ssbo->buffer) //wrong context
+            return;
+
+         has_write |= ctx->writable_ssbos[shader] & BITFIELD64_BIT(slot);
+         util_range_add(&res->base.b, &res->valid_buffer_range, ssbo->buffer_offset,
+                        ssbo->buffer_offset + ssbo->buffer_size);
+         update_descriptor_state_ssbo(ctx, shader, slot);
+         zink_screen(ctx->base.screen)->context_invalidate_descriptor_state(ctx, shader, ZINK_DESCRIPTOR_TYPE_SSBO, slot, 1);
+         num_rebinds++;
+      }
+      u_foreach_bit(slot, res->sampler_binds[shader]) {
+         struct zink_sampler_view *sampler_view = zink_sampler_view(ctx->sampler_views[shader][slot]);
+         if (&res->base.b != sampler_view->base.texture) //wrong context
+            return;
+
+         if (zink_batch_usage_exists(sampler_view->buffer_view->batch_uses))
+            zink_batch_reference_bufferview(&ctx->batch, sampler_view->buffer_view);
+         zink_buffer_view_reference(zink_screen(ctx->base.screen), &sampler_view->buffer_view, NULL);
+         sampler_view->buffer_view = get_buffer_view(ctx, res, sampler_view->base.format,
+                                                     sampler_view->base.u.buf.offset, sampler_view->base.u.buf.size);
+         update_descriptor_state_sampler(ctx, shader, slot);
+         zink_screen(ctx->base.screen)->context_invalidate_descriptor_state(ctx, shader, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, slot, 1);
+         num_rebinds++;
+      }
+      if (unlikely(num_image_rebinds_remaining[shader == PIPE_SHADER_COMPUTE])) {
+         for (unsigned slot = 0; num_image_rebinds_remaining[shader == PIPE_SHADER_COMPUTE] &&
+                                 slot < ctx->di.num_images[shader]; slot++) {
+            struct zink_resource *cres = zink_get_resource_for_descriptor(ctx, ZINK_DESCRIPTOR_TYPE_IMAGE, shader, slot);
+            if (res != cres)
                continue;
 
-            unsigned num_descriptors = 0;
-            switch (type) {
-            case ZINK_DESCRIPTOR_TYPE_UBO:
-               num_descriptors = ctx->di.num_ubos[shader];
-               break;
-            case ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW:
-               num_descriptors = ctx->di.num_sampler_views[shader];
-               break;
-            case ZINK_DESCRIPTOR_TYPE_SSBO:
-               num_descriptors = ctx->di.num_ssbos[shader];
-               break;
-            case ZINK_DESCRIPTOR_TYPE_IMAGE:
-               num_descriptors = ctx->di.num_images[shader];
-               break;
-            default:
-               unreachable("ack");
-            }
-            for (unsigned i = 0; i < num_descriptors; i++) {
-               if (check_and_rebind_buffer(ctx, res, shader, type, i))
-                  num_rebinds++;
-               if (total_binds == num_rebinds)
-                  goto out;
+            struct zink_image_view *image_view = &ctx->image_views[shader][slot];
+            zink_descriptor_set_refs_clear(&image_view->buffer_view->desc_set_refs, image_view->buffer_view);
+            if (zink_batch_usage_exists(image_view->buffer_view->batch_uses))
+               zink_batch_reference_bufferview(&ctx->batch, image_view->buffer_view);
+            zink_buffer_view_reference(zink_screen(ctx->base.screen), &image_view->buffer_view, NULL);
+            if (!zink_resource_object_init_storage(ctx, res)) {
+               debug_printf("couldn't create storage image!");
+               continue;
             }
+            has_write |= image_view->base.access & PIPE_IMAGE_ACCESS_WRITE;
+            image_view->buffer_view = get_buffer_view(ctx, res, image_view->base.format,
+                                                      image_view->base.u.buf.offset, image_view->base.u.buf.size);
+            assert(image_view->buffer_view);
+            util_range_add(&res->base.b, &res->valid_buffer_range, image_view->base.u.buf.offset,
+                           image_view->base.u.buf.offset + image_view->base.u.buf.size);
+            update_descriptor_state_image(ctx, shader, slot);
+            zink_screen(ctx->base.screen)->context_invalidate_descriptor_state(ctx, shader, ZINK_DESCRIPTOR_TYPE_IMAGE, slot, 1);
+            num_image_rebinds_remaining[shader == PIPE_SHADER_COMPUTE]--;
          }
       }
    }
-out:
-   assert(total_binds == num_rebinds);
-   if (!res->vbo_bind_count)
-      return;
-   zink_batch_resource_usage_set(&ctx->batch, res, false);
-   ctx->vertex_buffers_dirty = true;
+   zink_batch_resource_usage_set(&ctx->batch, res, has_write);
 }
 
 static inline struct zink_screen **



More information about the mesa-commit mailing list