zink: avoid looping for non-ubo descriptor updates based on set usage
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>
Tue, 13 Oct 2020 17:45:50 +0000 (13:45 -0400)
committerMarge Bot <eric+marge@anholt.net>
Tue, 16 Mar 2021 01:01:57 +0000 (01:01 +0000)
if we know that the descriptor set is cached and already in use by a given
batch, then we also know that all the resources in the set are tracked, which
means that we can skip over some looping  during descriptor updates which would
otherwise be used to add tracking for sampler/image views/states

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

src/gallium/drivers/zink/zink_descriptors.c
src/gallium/drivers/zink/zink_descriptors.h
src/gallium/drivers/zink/zink_draw.c

index 8c84b78..2a1fefc 100644 (file)
@@ -278,7 +278,8 @@ struct zink_descriptor_set *
 zink_descriptor_set_get(struct zink_context *ctx,
                                enum zink_descriptor_type type,
                                bool is_compute,
-                               bool *cache_hit)
+                               bool *cache_hit,
+                               bool *need_resource_refs)
 {
    *cache_hit = false;
    struct zink_descriptor_set *zds;
@@ -352,7 +353,7 @@ zink_descriptor_set_get(struct zink_context *ctx,
       if (pool->num_sets_allocated + pool->key.num_descriptors > ZINK_DEFAULT_MAX_DESCS) {
          batch = zink_flush_batch(ctx, batch);
          zink_batch_reference_program(batch, pg);
-         return zink_descriptor_set_get(ctx, type, is_compute, cache_hit);
+         return zink_descriptor_set_get(ctx, type, is_compute, cache_hit, need_resource_refs);
       }
    } else {
       if (pg->last_set[type] && !pg->last_set[type]->hash) {
@@ -380,8 +381,11 @@ quick_out:
    if (pool->key.num_descriptors && !*cache_hit)
       util_dynarray_clear(&zds->barriers);
    zds->invalid = false;
-   if (zink_batch_add_desc_set(batch, zds))
+   *need_resource_refs = false;
+   if (zink_batch_add_desc_set(batch, zds)) {
       batch->descs_used += pool->key.num_descriptors;
+      *need_resource_refs = true;
+   }
    pg->last_set[type] = zds;
    return zds;
 }
index 5ad1b81..5766a02 100644 (file)
@@ -131,7 +131,8 @@ struct zink_descriptor_set *
 zink_descriptor_set_get(struct zink_context *ctx,
                                enum zink_descriptor_type type,
                                bool is_compute,
-                               bool *cache_hit);
+                               bool *cache_hit,
+                               bool *need_resource_refs);
 void
 zink_descriptor_set_recycle(struct zink_descriptor_set *zds);
 
index b51c941..03b5a0b 100644 (file)
@@ -321,7 +321,7 @@ cmp_dynamic_offset_binding(const void *a, const void *b)
 
 static bool
 write_descriptors(struct zink_context *ctx, struct zink_descriptor_set *zds, unsigned num_wds, VkWriteDescriptorSet *wds,
-                  bool is_compute, bool cache_hit)
+                 bool is_compute, bool cache_hit, bool need_resource_refs)
 {
    bool need_flush = false;
    struct zink_batch *batch = is_compute ? &ctx->compute_batch : zink_curr_batch(ctx);
@@ -333,7 +333,8 @@ write_descriptors(struct zink_context *ctx, struct zink_descriptor_set *zds, uns
 
    for (int i = 0; zds->pool->key.num_descriptors && i < util_dynarray_num_elements(&zds->barriers, struct zink_descriptor_barrier); ++i) {
       struct zink_descriptor_barrier *barrier = util_dynarray_element(&zds->barriers, struct zink_descriptor_barrier, i);
-      need_flush |= zink_batch_reference_resource_rw(batch, barrier->res, zink_resource_access_is_write(barrier->access)) == check_flush_id;
+      if (need_resource_refs || (ctx->curr_compute && ctx->curr_program))
+         need_flush |= zink_batch_reference_resource_rw(batch, barrier->res, zink_resource_access_is_write(barrier->access)) == check_flush_id;
       zink_resource_barrier(ctx, NULL, barrier->res,
                             barrier->layout, barrier->access, barrier->stage);
    }
@@ -356,7 +357,8 @@ init_write_descriptor(struct zink_shader *shader, struct zink_descriptor_set *zd
 
 static bool
 update_ubo_descriptors(struct zink_context *ctx, struct zink_descriptor_set *zds,
-                       bool is_compute, bool cache_hit, uint32_t *dynamic_offsets, unsigned *dynamic_offset_idx)
+                       bool is_compute, bool cache_hit, bool need_resource_refs,
+                       uint32_t *dynamic_offsets, unsigned *dynamic_offset_idx)
 {
    struct zink_program *pg = is_compute ? (struct zink_program *)ctx->curr_compute : (struct zink_program *)ctx->curr_program;
    struct zink_screen *screen = zink_screen(ctx->base.screen);
@@ -436,12 +438,12 @@ update_ubo_descriptors(struct zink_context *ctx, struct zink_descriptor_set *zds
       dynamic_offsets[i] = dynamic_buffers[i].offset;
    *dynamic_offset_idx = dynamic_offset_count;
 
-   return write_descriptors(ctx, zds, num_wds, wds, is_compute, cache_hit);
+   return write_descriptors(ctx, zds, num_wds, wds, is_compute, cache_hit, need_resource_refs);
 }
 
 static bool
 update_ssbo_descriptors(struct zink_context *ctx, struct zink_descriptor_set *zds,
-                        bool is_compute, bool cache_hit)
+                        bool is_compute, bool cache_hit, bool need_resource_refs)
 {
    struct zink_program *pg = is_compute ? (struct zink_program *)ctx->curr_compute : (struct zink_program *)ctx->curr_program;
    ASSERTED struct zink_screen *screen = zink_screen(ctx->base.screen);
@@ -465,7 +467,7 @@ update_ssbo_descriptors(struct zink_context *ctx, struct zink_descriptor_set *zd
    else
       stages = &ctx->gfx_stages[0];
 
-   for (int i = 0; i < num_stages; i++) {
+   for (int i = 0; (!cache_hit || need_resource_refs) && i < num_stages; i++) {
       struct zink_shader *shader = stages[i];
       if (!shader)
          continue;
@@ -502,7 +504,7 @@ update_ssbo_descriptors(struct zink_context *ctx, struct zink_descriptor_set *zd
       }
    }
    _mesa_set_destroy(ht, NULL);
-   return write_descriptors(ctx, zds, num_wds, wds, is_compute, cache_hit);
+   return write_descriptors(ctx, zds, num_wds, wds, is_compute, cache_hit, need_resource_refs);
 }
 
 static void
@@ -556,7 +558,7 @@ handle_image_descriptor(struct zink_screen *screen, struct zink_resource *res, e
 
 static bool
 update_sampler_descriptors(struct zink_context *ctx, struct zink_descriptor_set *zds,
-                           bool is_compute, bool cache_hit)
+                           bool is_compute, bool cache_hit, bool need_resource_refs)
 {
    struct zink_program *pg = is_compute ? (struct zink_program *)ctx->curr_compute : (struct zink_program *)ctx->curr_program;
    struct zink_screen *screen = zink_screen(ctx->base.screen);
@@ -582,7 +584,7 @@ update_sampler_descriptors(struct zink_context *ctx, struct zink_descriptor_set
    else
       stages = &ctx->gfx_stages[0];
 
-   for (int i = 0; i < num_stages; i++) {
+   for (int i = 0; (!cache_hit || need_resource_refs) && i < num_stages; i++) {
       struct zink_shader *shader = stages[i];
       if (!shader)
          continue;
@@ -635,12 +637,12 @@ update_sampler_descriptors(struct zink_context *ctx, struct zink_descriptor_set
       }
    }
    _mesa_set_destroy(ht, NULL);
-   return write_descriptors(ctx, zds, num_wds, wds, is_compute, cache_hit);
+   return write_descriptors(ctx, zds, num_wds, wds, is_compute, cache_hit, need_resource_refs);
 }
 
 static bool
 update_image_descriptors(struct zink_context *ctx, struct zink_descriptor_set *zds,
-                         bool is_compute, bool cache_hit)
+                         bool is_compute, bool cache_hit, bool need_resource_refs)
 {
    struct zink_program *pg = is_compute ? (struct zink_program *)ctx->curr_compute : (struct zink_program *)ctx->curr_program;
    struct zink_screen *screen = zink_screen(ctx->base.screen);
@@ -666,7 +668,7 @@ update_image_descriptors(struct zink_context *ctx, struct zink_descriptor_set *z
    else
       stages = &ctx->gfx_stages[0];
 
-   for (int i = 0; i < num_stages; i++) {
+   for (int i = 0; (!cache_hit || need_resource_refs) && i < num_stages; i++) {
       struct zink_shader *shader = stages[i];
       if (!shader)
          continue;
@@ -720,7 +722,7 @@ update_image_descriptors(struct zink_context *ctx, struct zink_descriptor_set *z
       }
    }
    _mesa_set_destroy(ht, NULL);
-   return write_descriptors(ctx, zds, num_wds, wds, is_compute, cache_hit);
+   return write_descriptors(ctx, zds, num_wds, wds, is_compute, cache_hit, need_resource_refs);
 }
 
 static void
@@ -730,10 +732,11 @@ update_descriptors(struct zink_context *ctx, struct zink_screen *screen, bool is
 
    zink_context_update_descriptor_states(ctx, is_compute);
    bool cache_hit[ZINK_DESCRIPTOR_TYPES];
+   bool need_resource_refs[ZINK_DESCRIPTOR_TYPES];
    struct zink_descriptor_set *zds[ZINK_DESCRIPTOR_TYPES];
    for (int h = 0; h < ZINK_DESCRIPTOR_TYPES; h++) {
       if (pg->pool[h])
-         zds[h] = zink_descriptor_set_get(ctx, h, is_compute, &cache_hit[h]);
+         zds[h] = zink_descriptor_set_get(ctx, h, is_compute, &cache_hit[h], &need_resource_refs[h]);
       else
          zds[h] = NULL;
    }
@@ -746,16 +749,20 @@ update_descriptors(struct zink_context *ctx, struct zink_screen *screen, bool is
    bool need_flush = false;
    if (zds[ZINK_DESCRIPTOR_TYPE_UBO])
       need_flush |= update_ubo_descriptors(ctx, zds[ZINK_DESCRIPTOR_TYPE_UBO],
-                                           is_compute, cache_hit[ZINK_DESCRIPTOR_TYPE_UBO], dynamic_offsets, &dynamic_offset_idx);
+                                           is_compute, cache_hit[ZINK_DESCRIPTOR_TYPE_UBO],
+                                           need_resource_refs[ZINK_DESCRIPTOR_TYPE_UBO], dynamic_offsets, &dynamic_offset_idx);
    if (zds[ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW])
       need_flush |= update_sampler_descriptors(ctx, zds[ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW],
-                                               is_compute, cache_hit[ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW]);
+                                               is_compute, cache_hit[ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW],
+                                               need_resource_refs[ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW]);
    if (zds[ZINK_DESCRIPTOR_TYPE_SSBO])
       need_flush |= update_ssbo_descriptors(ctx, zds[ZINK_DESCRIPTOR_TYPE_SSBO],
-                                               is_compute, cache_hit[ZINK_DESCRIPTOR_TYPE_SSBO]);
+                                               is_compute, cache_hit[ZINK_DESCRIPTOR_TYPE_SSBO],
+                                               need_resource_refs[ZINK_DESCRIPTOR_TYPE_SSBO]);
    if (zds[ZINK_DESCRIPTOR_TYPE_IMAGE])
       need_flush |= update_image_descriptors(ctx, zds[ZINK_DESCRIPTOR_TYPE_IMAGE],
-                                               is_compute, cache_hit[ZINK_DESCRIPTOR_TYPE_IMAGE]);
+                                               is_compute, cache_hit[ZINK_DESCRIPTOR_TYPE_IMAGE],
+                                               need_resource_refs[ZINK_DESCRIPTOR_TYPE_IMAGE]);
 
    for (unsigned h = 0; h < ZINK_DESCRIPTOR_TYPES; h++) {
       if (zds[h]) {