Module: Mesa Branch: main Commit: 4311842f83e554f8480b8907c483ffed7b781067 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=4311842f83e554f8480b8907c483ffed7b781067
Author: Mike Blumenkrantz <[email protected]> Date: Fri Sep 17 11:54:09 2021 -0400 zink: force lazy descriptor set rebinds if pipeline compatibility changes if the pipeline layout changes, it's technically illegal to not rebind the descriptor set even if it hasn't changed Reviewed-by: Dave Airlie <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12931> --- src/gallium/drivers/zink/zink_descriptors_lazy.c | 59 +++++++++++++++++------- src/gallium/drivers/zink/zink_program.c | 4 +- src/gallium/drivers/zink/zink_program.h | 3 +- 3 files changed, 47 insertions(+), 19 deletions(-) diff --git a/src/gallium/drivers/zink/zink_descriptors_lazy.c b/src/gallium/drivers/zink/zink_descriptors_lazy.c index 8908a6f1aa6..f82d1fc452f 100644 --- a/src/gallium/drivers/zink/zink_descriptors_lazy.c +++ b/src/gallium/drivers/zink/zink_descriptors_lazy.c @@ -57,7 +57,9 @@ struct zink_batch_descriptor_data_lazy { struct hash_table pools[ZINK_DESCRIPTOR_TYPES]; struct zink_descriptor_pool *push_pool[2]; struct zink_program *pg[2]; //gfx, compute + uint32_t compat_id[2]; VkDescriptorSetLayout dsl[2][ZINK_DESCRIPTOR_TYPES]; + VkDescriptorSet sets[2][ZINK_DESCRIPTOR_TYPES + 1]; unsigned push_usage[2]; bool has_fbfetch; }; @@ -208,7 +210,7 @@ zink_descriptor_program_init_lazy(struct zink_context *ctx, struct zink_program ralloc_free(pg->dd); pg->dd = NULL; - pg->layout = zink_pipeline_layout_create(screen, pg); + pg->layout = zink_pipeline_layout_create(screen, pg, &pg->compat_id); return !!pg->layout; } @@ -232,7 +234,7 @@ zink_descriptor_program_init_lazy(struct zink_context *ctx, struct zink_program pg->dd->sizes[i].descriptorCount *= screen->descriptor_mode == ZINK_DESCRIPTOR_MODE_LAZY ? MAX_LAZY_DESCRIPTORS : ZINK_DEFAULT_MAX_DESCS; } - pg->layout = zink_pipeline_layout_create(screen, pg); + pg->layout = zink_pipeline_layout_create(screen, pg, &pg->compat_id); if (!pg->layout) return false; if (!screen->info.have_KHR_descriptor_update_template || screen->descriptor_mode == ZINK_DESCRIPTOR_MODE_NOTEMPLATES) @@ -444,7 +446,7 @@ zink_descriptor_set_update_lazy(struct zink_context *ctx, struct zink_program *p } void -zink_descriptors_update_lazy_masked(struct zink_context *ctx, bool is_compute, uint8_t changed_sets, bool need_push, bool update_push) +zink_descriptors_update_lazy_masked(struct zink_context *ctx, bool is_compute, uint8_t changed_sets, bool need_push, bool is_lazy) { struct zink_screen *screen = zink_screen(ctx->base.screen); struct zink_batch *batch = &ctx->batch; @@ -459,35 +461,57 @@ zink_descriptors_update_lazy_masked(struct zink_context *ctx, bool is_compute, u /* no flushing allowed */ assert(ctx->batch.state == bs); - if (pg->dd->binding_usage && changed_sets) { + /* + * when binding a pipeline, the pipeline can correctly access any previously bound + * descriptor sets which were bound with compatible pipeline layouts + * VK 14.2.2 + */ + uint8_t bind_sets = !is_lazy || (bdd->pg[is_compute] && bdd->compat_id[is_compute] == pg->compat_id) ? 0 : pg->dd->binding_usage; + if (pg->dd->binding_usage && (changed_sets || bind_sets)) { u_foreach_bit(type, changed_sets) { - if (pg->dd->layout_key[type]) - VKSCR(UpdateDescriptorSetWithTemplate)(screen->dev, desc_sets[type + 1], pg->dd->layouts[type + 1]->desc_template, ctx); assert(type + 1 < pg->num_dsl); + if (pg->dd->layout_key[type]) { + VKSCR(UpdateDescriptorSetWithTemplate)(screen->dev, desc_sets[type + 1], pg->dd->layouts[type + 1]->desc_template, ctx); + VKSCR(CmdBindDescriptorSets)(bs->cmdbuf, + is_compute ? VK_PIPELINE_BIND_POINT_COMPUTE : VK_PIPELINE_BIND_POINT_GRAPHICS, + /* set index incremented by 1 to account for push set */ + pg->layout, type + 1, 1, &desc_sets[type + 1], + 0, NULL); + bdd->sets[is_compute][type + 1] = desc_sets[type + 1]; + } + } + u_foreach_bit(type, bind_sets & ~changed_sets) { + if (!pg->dd->layout_key[type]) + bdd->sets[is_compute][type + 1] = ctx->dd->dummy_set; + assert(bdd->sets[is_compute][type + 1]); VKSCR(CmdBindDescriptorSets)(bs->cmdbuf, is_compute ? VK_PIPELINE_BIND_POINT_COMPUTE : VK_PIPELINE_BIND_POINT_GRAPHICS, /* set index incremented by 1 to account for push set */ - pg->layout, type + 1, 1, &desc_sets[type + 1], + pg->layout, type + 1, 1, &bdd->sets[is_compute][type + 1], 0, NULL); } dd_lazy(ctx)->state_changed[is_compute] = false; } - if (update_push) { - if (pg->dd->push_usage && dd_lazy(ctx)->push_state_changed[is_compute]) { - if (screen->info.have_KHR_push_descriptor) - VKSCR(CmdPushDescriptorSetWithTemplateKHR)(batch->state->cmdbuf, pg->dd->push_template, - pg->layout, 0, ctx); - else { - assert(desc_sets[0]); - VKSCR(UpdateDescriptorSetWithTemplate)(screen->dev, desc_sets[0], pg->dd->push_template, ctx); + if (is_lazy) { + if (pg->dd->push_usage && (dd_lazy(ctx)->push_state_changed[is_compute] || bind_sets)) { + if (screen->info.have_KHR_push_descriptor) { + if (dd_lazy(ctx)->push_state_changed[is_compute]) + VKSCR(CmdPushDescriptorSetWithTemplateKHR)(batch->state->cmdbuf, pg->dd->push_template, + pg->layout, 0, ctx); + } else { + if (dd_lazy(ctx)->push_state_changed[is_compute]) { + VKSCR(UpdateDescriptorSetWithTemplate)(screen->dev, desc_sets[0], pg->dd->push_template, ctx); + bdd->sets[is_compute][0] = desc_sets[0]; + } + assert(desc_sets[0] || bdd->sets[is_compute][0]); VKSCR(CmdBindDescriptorSets)(batch->state->cmdbuf, is_compute ? VK_PIPELINE_BIND_POINT_COMPUTE : VK_PIPELINE_BIND_POINT_GRAPHICS, - pg->layout, 0, 1, &desc_sets[0], + pg->layout, 0, 1, desc_sets[0] ? &desc_sets[0] : &bdd->sets[is_compute][0], 0, NULL); } dd_lazy(ctx)->push_state_changed[is_compute] = false; - } else if (dd_lazy(ctx)->push_state_changed[is_compute]) { + } else if (dd_lazy(ctx)->push_state_changed[is_compute] || bind_sets) { VKSCR(CmdBindDescriptorSets)(bs->cmdbuf, is_compute ? VK_PIPELINE_BIND_POINT_COMPUTE : VK_PIPELINE_BIND_POINT_GRAPHICS, pg->layout, 0, 1, &ctx->dd->dummy_set, @@ -497,6 +521,7 @@ zink_descriptors_update_lazy_masked(struct zink_context *ctx, bool is_compute, u } bdd->pg[is_compute] = pg; ctx->dd->pg[is_compute] = pg; + bdd->compat_id[is_compute] = pg->compat_id; } void diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c index 0aedff77d4e..a735f67a6d6 100644 --- a/src/gallium/drivers/zink/zink_program.c +++ b/src/gallium/drivers/zink/zink_program.c @@ -249,7 +249,7 @@ zink_update_gfx_program(struct zink_context *ctx, struct zink_gfx_program *prog) } VkPipelineLayout -zink_pipeline_layout_create(struct zink_screen *screen, struct zink_program *pg) +zink_pipeline_layout_create(struct zink_screen *screen, struct zink_program *pg, uint32_t *compat) { VkPipelineLayoutCreateInfo plci = {0}; plci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; @@ -282,6 +282,8 @@ zink_pipeline_layout_create(struct zink_screen *screen, struct zink_program *pg) return VK_NULL_HANDLE; } + *compat = _mesa_hash_data(pg->dsl, pg->num_dsl * sizeof(pg->dsl[0])); + return layout; } diff --git a/src/gallium/drivers/zink/zink_program.h b/src/gallium/drivers/zink/zink_program.h index f4c65f6c7e2..d1befbc84a7 100644 --- a/src/gallium/drivers/zink/zink_program.h +++ b/src/gallium/drivers/zink/zink_program.h @@ -84,6 +84,7 @@ struct zink_program { struct zink_program_descriptor_data *dd; + uint32_t compat_id; VkPipelineLayout layout; VkDescriptorSetLayout dsl[ZINK_DESCRIPTOR_TYPES + 1]; // one for each type + push unsigned num_dsl; @@ -267,7 +268,7 @@ zink_compute_program_reference(struct zink_screen *screen, } VkPipelineLayout -zink_pipeline_layout_create(struct zink_screen *screen, struct zink_program *pg); +zink_pipeline_layout_create(struct zink_screen *screen, struct zink_program *pg, uint32_t *compat); void zink_program_update_compute_pipeline_state(struct zink_context *ctx, struct zink_compute_program *comp, const uint block[3]);
