diff --git a/src/gallium/drivers/zink/zink_descriptors.c b/src/gallium/drivers/zink/zink_descriptors.c index 2a9c770da96..ec0fe76bb61 100644 --- a/src/gallium/drivers/zink/zink_descriptors.c +++ b/src/gallium/drivers/zink/zink_descriptors.c @@ -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; diff --git a/src/gallium/drivers/zink/zink_descriptors.h b/src/gallium/drivers/zink/zink_descriptors.h index 91fcf3a6d73..af0e5979e96 100644 --- a/src/gallium/drivers/zink/zink_descriptors.h +++ b/src/gallium/drivers/zink/zink_descriptors.h @@ -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 diff --git a/src/gallium/drivers/zink/zink_descriptors_lazy.c b/src/gallium/drivers/zink/zink_descriptors_lazy.c index 72018bdb9ec..fe6578a9d20 100644 --- a/src/gallium/drivers/zink/zink_descriptors_lazy.c +++ b/src/gallium/drivers/zink/zink_descriptors_lazy.c @@ -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) {