zink: always use lazy (non-push) updating for fbfetch descriptors
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>
Wed, 3 Nov 2021 19:03:30 +0000 (15:03 -0400)
committerMarge Bot <emma+marge@anholt.net>
Thu, 4 Nov 2021 02:41:09 +0000 (02:41 +0000)
fbfetch descriptors are uncacheable due to having mixed descriptor types
in the same set, so this needs to always use lazy updating to avoid
exploding the cache and crashing

cc: mesa-stable

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

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

index 2a9c770..ec0fe76 100644 (file)
@@ -1271,8 +1271,9 @@ update_push_ubo_descriptors(struct zink_context *ctx, struct zink_descriptor_set
          wds[i].pBufferInfo = &buffer_infos[i];
       }
    }
-   if (unlikely(!cache_hit && !is_compute && ctx->fbfetch_outputs)) {
-      struct zink_resource *res = zink_resource(ctx->fb_state.cbufs[0]->texture);
+   if (unlikely(!cache_hit && !is_compute && ctx->dd->has_fbfetch)) {
+      assert(!pg->dd->fbfetch);
+      struct zink_resource *res = zink_resource(ctx->dummy_surface[0]->texture);
       init_write_descriptor(NULL, zds, 0, MESA_SHADER_STAGES, &wds[ZINK_SHADER_COUNT], 0);
       desc_set_res_add(zds, res, ZINK_SHADER_COUNT, cache_hit);
       wds[ZINK_SHADER_COUNT].pImageInfo = &ctx->di.fbfetch;
@@ -1414,7 +1415,10 @@ zink_descriptors_update(struct zink_context *ctx, bool is_compute)
    struct zink_batch *batch = &ctx->batch;
    VkPipelineBindPoint bp = is_compute ? VK_PIPELINE_BIND_POINT_COMPUTE : VK_PIPELINE_BIND_POINT_GRAPHICS;
 
-   {
+   if (unlikely(pg->dd->fbfetch)) {
+      /* this is not cacheable */
+      zink_descriptors_update_lazy_push(ctx);
+   } else {
       uint32_t dynamic_offsets[PIPE_MAX_CONSTANT_BUFFERS];
       unsigned dynamic_offset_idx = 0;
 
index 91fcf3a..af0e597 100644 (file)
@@ -143,6 +143,7 @@ struct zink_descriptor_data {
 struct zink_program_descriptor_data {
    uint8_t push_usage;
    bool bindless;
+   bool fbfetch;
    uint8_t binding_usage;
    struct zink_descriptor_pool_key *pool_key[ZINK_DESCRIPTOR_TYPES]; //push set doesn't need one
    struct zink_descriptor_layout *layouts[ZINK_DESCRIPTOR_TYPES + 1];
@@ -299,6 +300,8 @@ void
 zink_descriptor_set_update_lazy(struct zink_context *ctx, struct zink_program *pg, enum zink_descriptor_type type, VkDescriptorSet set);
 void
 zink_descriptors_update_lazy_masked(struct zink_context *ctx, bool is_compute, uint8_t changed_sets, uint8_t bind_sets);
+void
+zink_descriptors_update_lazy_push(struct zink_context *ctx);
 #ifdef __cplusplus
 }
 #endif
index 72018bd..fe6578a 100644 (file)
@@ -166,6 +166,7 @@ zink_descriptor_program_init_lazy(struct zink_context *ctx, struct zink_program
       if (stages[PIPE_SHADER_FRAGMENT]->nir->info.fs.uses_fbfetch_output) {
          zink_descriptor_util_init_fbfetch(ctx);
          push_count = 1;
+         pg->dd->fbfetch = true;
       }
    }
 
@@ -524,6 +525,33 @@ zink_descriptors_update_lazy_masked(struct zink_context *ctx, bool is_compute, u
    }
 }
 
+/* only called by cached manager for fbfetch handling */
+void
+zink_descriptors_update_lazy_push(struct zink_context *ctx)
+{
+   struct zink_batch_state *bs = ctx->batch.state;
+   struct zink_batch_descriptor_data_lazy *bdd = bdd_lazy(bs);
+   struct zink_program *pg = &ctx->curr_program->base;
+   struct zink_screen *screen = zink_screen(ctx->base.screen);
+   VkDescriptorSet push_set = VK_NULL_HANDLE;
+   if (!bdd->push_pool[0]) {
+      bdd->push_pool[0] = create_push_pool(screen, bdd, false, true);
+      bdd->has_fbfetch = true;
+   }
+   struct zink_descriptor_pool *pool = check_push_pool_alloc(ctx, bdd->push_pool[0], bdd, false);
+   push_set = get_descriptor_set_lazy(pool);
+   if (!push_set) {
+      mesa_loge("ZINK: failed to get push descriptor set!");
+      /* just jam something in to avoid a hang */
+      push_set = ctx->dd->dummy_set;
+   }
+   VKCTX(UpdateDescriptorSetWithTemplate)(screen->dev, push_set, pg->dd->push_template, ctx);
+   VKCTX(CmdBindDescriptorSets)(bs->cmdbuf,
+                                VK_PIPELINE_BIND_POINT_GRAPHICS,
+                                pg->layout, 0, 1, push_set ? &push_set : &bdd->sets[0][0],
+                                0, NULL);
+}
+
 void
 zink_descriptors_update_lazy(struct zink_context *ctx, bool is_compute)
 {