zink: rework xfb counter resource barriers

using the new helper functions, we can now more accurately determine
exactly which barriers we need/want and avoid setting unnecessary barriers
or ending a renderpass early

Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8945>
This commit is contained in:
Mike Blumenkrantz 2020-08-19 10:40:58 -04:00 committed by Marge Bot
parent dd858be011
commit fb14793ebb
2 changed files with 24 additions and 24 deletions

View file

@ -1602,15 +1602,25 @@ zink_set_stream_output_targets(struct pipe_context *pctx,
pipe_so_target_reference(&ctx->so_targets[i], NULL);
ctx->num_so_targets = 0;
} else {
for (unsigned i = 0; i < num_targets; i++)
for (unsigned i = 0; i < num_targets; i++) {
struct zink_so_target *t = zink_so_target(targets[i]);
pipe_so_target_reference(&ctx->so_targets[i], targets[i]);
if (!t)
continue;
struct zink_resource *res = zink_resource(t->counter_buffer);
if (offsets[0] == (unsigned)-1)
ctx->xfb_barrier |= zink_resource_buffer_needs_barrier(res,
VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT,
VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT);
else
ctx->xfb_barrier |= zink_resource_buffer_needs_barrier(res,
VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT,
VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT);
}
for (unsigned i = num_targets; i < ctx->num_so_targets; i++)
pipe_so_target_reference(&ctx->so_targets[i], NULL);
ctx->num_so_targets = num_targets;
/* emit memory barrier on next draw for synchronization */
if (offsets[0] == (unsigned)-1)
ctx->xfb_barrier = true;
/* TODO: possibly avoid rebinding on resume if resuming from same buffers? */
ctx->dirty_so_targets = true;
}

View file

@ -52,29 +52,19 @@ zink_emit_xfb_counter_barrier(struct zink_context *ctx)
*
* - from VK_EXT_transform_feedback spec
*/
VkBufferMemoryBarrier barriers[PIPE_MAX_SO_OUTPUTS] = {};
unsigned barrier_count = 0;
struct zink_batch *batch = zink_batch_no_rp(ctx);
for (unsigned i = 0; i < ctx->num_so_targets; i++) {
struct zink_so_target *t = zink_so_target(ctx->so_targets[i]);
if (t && t->counter_buffer_valid) {
barriers[i].sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
barriers[i].srcAccessMask = VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT;
barriers[i].dstAccessMask = VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT;
barriers[i].buffer = zink_resource(t->counter_buffer)->buffer;
barriers[i].size = VK_WHOLE_SIZE;
barrier_count++;
}
if (!t)
continue;
struct zink_resource *res = zink_resource(t->counter_buffer);
if (t->counter_buffer_valid)
zink_resource_buffer_barrier(batch->cmdbuf, res, VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT,
VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT);
else
zink_resource_buffer_barrier(batch->cmdbuf, res, VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT,
VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT);
}
struct zink_batch *batch = zink_batch_no_rp(ctx);
vkCmdPipelineBarrier(batch->cmdbuf,
VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT,
VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT,
0,
0, NULL,
barrier_count, barriers,
0, NULL
);
ctx->xfb_barrier = false;
}