From 73e84c33a2d2f8677d85d7121c09ff4b053ba70a Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Wed, 19 Aug 2020 10:49:58 -0400 Subject: [PATCH] zink: rework xfb barrier transitions when reusing as vertex inputs if we have proper barrier usage to start with, then we don't need to do any kind of weird flushing upon changing vertex inputs and can also remove a flag from zink_resource Reviewed-by: Bas Nieuwenhuizen Part-of: --- src/gallium/drivers/zink/zink_context.c | 14 ------- src/gallium/drivers/zink/zink_draw.c | 52 ++++++++++++++++-------- src/gallium/drivers/zink/zink_resource.h | 1 - 3 files changed, 34 insertions(+), 33 deletions(-) diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index 3f57b8ad0d0..45d8b5b3d4f 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -501,20 +501,6 @@ zink_set_vertex_buffers(struct pipe_context *pctx, { struct zink_context *ctx = zink_context(pctx); - if (buffers) { - for (int i = 0; i < num_buffers; ++i) { - const struct pipe_vertex_buffer *vb = buffers + i; - struct zink_resource *res = zink_resource(vb->buffer.resource); - if (res && res->needs_xfb_barrier) { - /* if we're binding a previously-used xfb buffer, we need cmd buffer synchronization to ensure - * that we use the right buffer data - */ - pctx->flush(pctx, NULL, 0); - res->needs_xfb_barrier = false; - } - } - } - util_set_vertex_buffers_mask(ctx->buffers, &ctx->buffers_enabled_mask, buffers, start_slot, num_buffers, unbind_num_trailing_slots, take_ownership); diff --git a/src/gallium/drivers/zink/zink_draw.c b/src/gallium/drivers/zink/zink_draw.c index 367fa74e097..ab7fa6d0594 100644 --- a/src/gallium/drivers/zink/zink_draw.c +++ b/src/gallium/drivers/zink/zink_draw.c @@ -82,23 +82,9 @@ zink_emit_xfb_vertex_input_barrier(struct zink_context *ctx, struct zink_resourc * * - 20.3.1. Drawing Transform Feedback */ - VkBufferMemoryBarrier barriers[1] = {}; - barriers[0].sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; - barriers[0].srcAccessMask = VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT; - barriers[0].dstAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT; - barriers[0].buffer = res->buffer; - barriers[0].size = VK_WHOLE_SIZE; struct zink_batch *batch = zink_batch_no_rp(ctx); - zink_batch_reference_resource_rw(batch, res, false); - vkCmdPipelineBarrier(batch->cmdbuf, - VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT, - VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, - 0, - 0, NULL, - ARRAY_SIZE(barriers), barriers, - 0, NULL - ); - res->needs_xfb_barrier = false; + zink_resource_buffer_barrier(batch->cmdbuf, res, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, + VK_PIPELINE_STAGE_VERTEX_INPUT_BIT); } static void @@ -121,6 +107,13 @@ zink_emit_stream_output_targets(struct pipe_context *pctx) continue; } buffers[i] = zink_resource(t->base.buffer)->buffer; + if (zink_resource_buffer_needs_barrier(zink_resource(t->base.buffer), + VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT, + VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT)) { + batch = zink_batch_no_rp(ctx); + zink_resource_buffer_barrier(batch->cmdbuf, zink_resource(t->base.buffer), + VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT, VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT); + } zink_batch_reference_resource_rw(batch, zink_resource(t->base.buffer), true); buffer_offsets[i] = t->base.buffer_offset; buffer_sizes[i] = t->base.buffer_size; @@ -132,6 +125,25 @@ zink_emit_stream_output_targets(struct pipe_context *pctx) ctx->dirty_so_targets = false; } +static void +barrier_vertex_buffers(struct zink_context *ctx) +{ + const struct zink_vertex_elements_state *elems = ctx->element_state; + for (unsigned i = 0; i < elems->hw_state.num_bindings; i++) { + struct pipe_vertex_buffer *vb = ctx->buffers + ctx->element_state->binding_map[i]; + assert(vb); + if (vb->buffer.resource) { + struct zink_resource *res = zink_resource(vb->buffer.resource); + if (zink_resource_buffer_needs_barrier(res, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, + VK_PIPELINE_STAGE_VERTEX_INPUT_BIT)) { + struct zink_batch *batch = zink_batch_no_rp(ctx); + zink_resource_buffer_barrier(batch->cmdbuf, res, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, + VK_PIPELINE_STAGE_VERTEX_INPUT_BIT); + } + } + } +} + static void zink_bind_vertex_buffers(struct zink_batch *batch, struct zink_context *ctx) { @@ -658,9 +670,13 @@ zink_draw_vbo(struct pipe_context *pctx, if (ctx->dirty_so_targets && ctx->num_so_targets) zink_emit_stream_output_targets(pctx); - if (so_target && zink_resource(so_target->base.buffer)->needs_xfb_barrier) + if (so_target && zink_resource_buffer_needs_barrier(zink_resource(so_target->base.buffer), + VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, + VK_PIPELINE_STAGE_VERTEX_INPUT_BIT)) zink_emit_xfb_vertex_input_barrier(ctx, zink_resource(so_target->base.buffer)); + barrier_vertex_buffers(ctx); + update_descriptors(ctx, screen, false); struct zink_batch *batch = zink_batch_rp(ctx); @@ -797,6 +813,7 @@ zink_draw_vbo(struct pipe_context *pctx, need_index_buffer_unref ? 0 : draws[0].start, dinfo->index_bias, dinfo->start_instance); } else { if (so_target && screen->info.tf_props.transformFeedbackDraw) { + zink_batch_reference_resource_rw(batch, zink_resource(so_target->base.buffer), false); zink_batch_reference_resource_rw(batch, zink_resource(so_target->counter_buffer), true); screen->vk_CmdDrawIndirectByteCountEXT(batch->cmdbuf, dinfo->instance_count, dinfo->start_instance, zink_resource(so_target->counter_buffer)->buffer, so_target->counter_buffer_offset, 0, @@ -826,7 +843,6 @@ zink_draw_vbo(struct pipe_context *pctx, counter_buffers[i] = zink_resource(t->counter_buffer)->buffer; counter_buffer_offsets[i] = t->counter_buffer_offset; t->counter_buffer_valid = true; - zink_resource(ctx->so_targets[i]->buffer)->needs_xfb_barrier = true; } } screen->vk_CmdEndTransformFeedbackEXT(batch->cmdbuf, 0, ctx->num_so_targets, counter_buffers, counter_buffer_offsets); diff --git a/src/gallium/drivers/zink/zink_resource.h b/src/gallium/drivers/zink/zink_resource.h index 92596beafc9..cd3117b6f9a 100644 --- a/src/gallium/drivers/zink/zink_resource.h +++ b/src/gallium/drivers/zink/zink_resource.h @@ -66,7 +66,6 @@ struct zink_resource { /* this has to be atomic for fence access, so we can't use a bitmask and make everything neat */ uint8_t batch_uses[5]; //ZINK_NUM_BATCHES - bool needs_xfb_barrier; }; struct zink_transfer {