From 7d6c90826de0ad25e8155bc4e98e0f3d2ab2e1cd Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Mon, 7 Sep 2020 10:35:20 -0400 Subject: [PATCH] zink: add access info for update_descriptor image barriers this forces resources to transition where necessary to ensure that data from previous ops have been made available (e.g., clear -> shader image) we also switch needs_barrier over to a more accurate signature here since we can now do it without breaking update_descriptors() Reviewed-by: Bas Nieuwenhuizen Part-of: --- src/gallium/drivers/zink/zink_context.c | 4 ++-- src/gallium/drivers/zink/zink_context.h | 2 +- src/gallium/drivers/zink/zink_draw.c | 29 ++++++++++++++++--------- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index b5753a5f0c8..c9e6f9967b7 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -1216,10 +1216,10 @@ zink_resource_buffer_barrier(struct zink_batch *batch, struct zink_resource *res } bool -zink_resource_needs_barrier(struct zink_resource *res, unsigned layout, VkAccessFlags flags, VkPipelineStageFlags pipeline) +zink_resource_needs_barrier(struct zink_resource *res, VkImageLayout layout, VkAccessFlags flags, VkPipelineStageFlags pipeline) { if (res->base.target == PIPE_BUFFER) - return zink_resource_buffer_needs_barrier(res, layout, pipeline); + return zink_resource_buffer_needs_barrier(res, flags, pipeline); return zink_resource_image_needs_barrier(res, layout, flags, pipeline); } diff --git a/src/gallium/drivers/zink/zink_context.h b/src/gallium/drivers/zink/zink_context.h index 535f4bc2aef..f3e8aab3152 100644 --- a/src/gallium/drivers/zink/zink_context.h +++ b/src/gallium/drivers/zink/zink_context.h @@ -224,7 +224,7 @@ zink_resource_barrier(struct zink_batch *batch, struct zink_resource *res, VkImageLayout new_layout, VkAccessFlags flags, VkPipelineStageFlags pipeline); bool -zink_resource_needs_barrier(struct zink_resource *res, unsigned layout, VkAccessFlags flags, VkPipelineStageFlags pipeline); +zink_resource_needs_barrier(struct zink_resource *res, VkImageLayout layout, VkAccessFlags flags, VkPipelineStageFlags pipeline); void zink_begin_render_pass(struct zink_context *ctx, diff --git a/src/gallium/drivers/zink/zink_draw.c b/src/gallium/drivers/zink/zink_draw.c index b7206a1b693..4243466b7c0 100644 --- a/src/gallium/drivers/zink/zink_draw.c +++ b/src/gallium/drivers/zink/zink_draw.c @@ -252,7 +252,8 @@ get_gfx_program(struct zink_context *ctx) struct zink_transition { struct zink_resource *res; - unsigned layout; + VkImageLayout layout; + VkAccessFlags access; VkPipelineStageFlagBits stage; }; @@ -264,6 +265,8 @@ transition_equals(const void *a, const void *b) const struct zink_transition *t1 = a, *t2 = b; if (t1->res != t2->res) return false; + if ((t1->access & t2->access) != t2->access) + return false; if (t1->layout != t2->layout) return false; return true; @@ -276,10 +279,10 @@ transition_hash(const void *key) } static inline void -add_transition(struct zink_resource *res, unsigned layout, enum pipe_shader_type stage, struct zink_transition *t, int *num_transitions, struct set *ht) +add_transition(struct zink_resource *res, VkImageLayout layout, VkAccessFlags flags, enum pipe_shader_type stage, struct zink_transition *t, int *num_transitions, struct set *ht) { VkPipelineStageFlags pipeline = zink_pipeline_flags_from_stage(zink_shader_stage(stage)); - struct zink_transition key = {res, layout, 0}; + struct zink_transition key = {res, layout, flags, 0}; uint32_t hash = transition_hash(&key); struct set_entry *entry = _mesa_set_search_pre_hashed(ht, hash, &key); @@ -290,6 +293,7 @@ add_transition(struct zink_resource *res, unsigned layout, enum pipe_shader_type t->stage = 0; t->layout = layout; t->res = res; + t->access = flags; _mesa_set_add_pre_hashed(ht, hash, t); } t->stage |= pipeline; @@ -349,7 +353,7 @@ update_descriptors(struct zink_context *ctx, struct zink_screen *screen, bool is buffer_infos[num_buffer_info].offset = res ? ctx->ubos[stage][index].buffer_offset : 0; buffer_infos[num_buffer_info].range = res ? ctx->ubos[stage][index].buffer_size : VK_WHOLE_SIZE; if (res) - add_transition(res, VK_ACCESS_UNIFORM_READ_BIT, stage, &transitions[num_transitions], &num_transitions, ht); + add_transition(res, 0, VK_ACCESS_UNIFORM_READ_BIT, stage, &transitions[num_transitions], &num_transitions, ht); wds[num_wds].pBufferInfo = buffer_infos + num_buffer_info; ++num_buffer_info; } else if (shader->bindings[j].type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) { @@ -364,7 +368,7 @@ update_descriptors(struct zink_context *ctx, struct zink_screen *screen, bool is } else { read_desc_resources[num_wds] = res; } - add_transition(res, flag, stage, &transitions[num_transitions], &num_transitions, ht); + add_transition(res, 0, flag, stage, &transitions[num_transitions], &num_transitions, ht); buffer_infos[num_buffer_info].buffer = res->buffer; buffer_infos[num_buffer_info].offset = ctx->ssbos[stage][index].buffer_offset; buffer_infos[num_buffer_info].range = ctx->ssbos[stage][index].buffer_size; @@ -397,9 +401,9 @@ update_descriptors(struct zink_context *ctx, struct zink_screen *screen, bool is else { imageview = sampler_view->image_view; layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - add_transition(res, layout, stage, &transitions[num_transitions], &num_transitions, ht); sampler = ctx->samplers[stage][index + k]; } + add_transition(res, layout, VK_ACCESS_SHADER_READ_BIT, stage, &transitions[num_transitions], &num_transitions, ht); read_desc_resources[num_wds] = res; } break; @@ -417,8 +421,13 @@ update_descriptors(struct zink_context *ctx, struct zink_screen *screen, bool is } else { imageview = image_view->surface->image_view; layout = VK_IMAGE_LAYOUT_GENERAL; - add_transition(res, layout, stage, &transitions[num_transitions], &num_transitions, ht); } + VkAccessFlags flags = 0; + if (image_view->base.access & PIPE_IMAGE_ACCESS_READ) + flags |= VK_ACCESS_SHADER_READ_BIT; + if (image_view->base.access & PIPE_IMAGE_ACCESS_WRITE) + flags |= VK_ACCESS_SHADER_WRITE_BIT; + add_transition(res, layout, flags, stage, &transitions[num_transitions], &num_transitions, ht); if (image_view->base.access & PIPE_IMAGE_ACCESS_WRITE) write_desc_resources[num_wds] = res; else @@ -480,7 +489,7 @@ update_descriptors(struct zink_context *ctx, struct zink_screen *screen, bool is for (int i = 0; i < num_transitions; ++i) { if (!zink_resource_needs_barrier(transitions[i].res, transitions[i].layout, - 0, + transitions[i].access, transitions[i].stage)) continue; if (is_compute) @@ -490,10 +499,10 @@ update_descriptors(struct zink_context *ctx, struct zink_screen *screen, bool is if (transitions[i].res->base.target == PIPE_BUFFER) zink_resource_buffer_barrier(batch, transitions[i].res, - transitions[i].layout, transitions[i].stage); + transitions[i].access, transitions[i].stage); else zink_resource_barrier(batch, transitions[i].res, - transitions[i].layout, 0, transitions[i].stage); + transitions[i].layout, transitions[i].access, transitions[i].stage); } }