zink: add vertex buffer barriers during bind

now we have tracking for vbo binds and can automatically reapply the correct
barrier just before draw if the resource is modified after bind

Reviewed-by: Dave Airlie <airlied@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10849>
This commit is contained in:
Mike Blumenkrantz 2021-01-19 12:05:48 -05:00
parent be40886521
commit b27e729c0d
3 changed files with 47 additions and 22 deletions

View File

@ -812,6 +812,18 @@ zink_set_polygon_stipple(struct pipe_context *pctx,
{
}
static void
update_existing_vbo(struct zink_context *ctx, unsigned slot)
{
if (!ctx->vertex_buffers[slot].buffer.resource)
return;
struct zink_resource *res = zink_resource(ctx->vertex_buffers[slot].buffer.resource);
res->vbo_bind_count--;
res->bind_count[0]--;
if (!res->bind_count[0])
_mesa_set_remove_key(ctx->need_barriers[0], res);
}
static void
zink_set_vertex_buffers(struct pipe_context *pctx,
unsigned start_slot,
@ -822,9 +834,29 @@ zink_set_vertex_buffers(struct pipe_context *pctx,
{
struct zink_context *ctx = zink_context(pctx);
if (!zink_screen(pctx->screen)->info.have_EXT_extended_dynamic_state &&
(num_buffers || (!buffers && ctx->gfx_pipeline_state.vertex_buffers_enabled_mask)))
ctx->gfx_pipeline_state.vertex_state_dirty = true;
if (buffers) {
if (!zink_screen(pctx->screen)->info.have_EXT_extended_dynamic_state)
ctx->gfx_pipeline_state.vertex_state_dirty = true;
for (int i = 0; i < num_buffers; ++i) {
const struct pipe_vertex_buffer *vb = buffers + i;
update_existing_vbo(ctx, start_slot + i);
if (vb->buffer.resource) {
struct zink_resource *res = zink_resource(vb->buffer.resource);
res->vbo_bind_count++;
res->bind_count[0]++;
zink_resource_buffer_barrier(ctx, NULL, res, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT,
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT);
}
}
} else if (ctx->gfx_pipeline_state.vertex_buffers_enabled_mask) {
if (!zink_screen(pctx->screen)->info.have_EXT_extended_dynamic_state)
ctx->gfx_pipeline_state.vertex_state_dirty = true;
unsigned vertex_buffers_enabled_mask = ctx->gfx_pipeline_state.vertex_buffers_enabled_mask;
while (vertex_buffers_enabled_mask) {
unsigned slot = u_bit_scan(&vertex_buffers_enabled_mask);
update_existing_vbo(ctx, slot);
}
}
util_set_vertex_buffers_mask(ctx->vertex_buffers, &ctx->gfx_pipeline_state.vertex_buffers_enabled_mask,
buffers, start_slot, num_buffers,
unbind_num_trailing_slots, take_ownership);
@ -1887,9 +1919,12 @@ is_shader_pipline_stage(VkPipelineStageFlags pipeline)
static void
resource_check_defer_barrier(struct zink_context *ctx, struct zink_resource *res, VkPipelineStageFlags pipeline)
{
if (res->bind_count[0] && !is_shader_pipline_stage(pipeline))
/* gfx rebind */
_mesa_set_add(ctx->need_barriers[0], res);
if (res->bind_count[0]) {
if ((res->obj->is_buffer && res->vbo_bind_count && !(pipeline & VK_PIPELINE_STAGE_VERTEX_INPUT_BIT)) ||
((!res->obj->is_buffer || res->vbo_bind_count != res->bind_count[0]) && !is_shader_pipline_stage(pipeline)))
/* gfx rebind */
_mesa_set_add(ctx->need_barriers[0], res);
}
if (res->bind_count[1] && !(pipeline & VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT))
/* compute rebind */
_mesa_set_add(ctx->need_barriers[1], res);

View File

@ -101,21 +101,6 @@ 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->vertex_buffers + ctx->element_state->binding_map[i];
assert(vb);
if (vb->buffer.resource) {
struct zink_resource *res = zink_resource(vb->buffer.resource);
zink_resource_buffer_barrier(ctx, NULL, res, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT,
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT);
}
}
}
static void
check_buffer_barrier(struct zink_context *ctx, struct pipe_resource *pres, VkAccessFlags flags, VkPipelineStageFlags pipeline)
{
@ -376,6 +361,11 @@ update_barriers(struct zink_context *ctx, bool is_compute)
access |= VK_ACCESS_UNIFORM_READ_BIT;
bind_count -= res->ubo_bind_count[is_compute];
}
if (!is_compute && res->vbo_bind_count) {
access |= VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
pipeline |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
bind_count -= res->vbo_bind_count;
}
}
if (bind_count)
access |= VK_ACCESS_SHADER_READ_BIT;
@ -512,7 +502,6 @@ zink_draw_vbo(struct pipe_context *pctx,
if (so_target)
zink_emit_xfb_vertex_input_barrier(ctx, zink_resource(so_target->base.buffer));
barrier_vertex_buffers(ctx);
barrier_draw_buffers(ctx, dinfo, dindirect, index_buffer);
for (int i = 0; i < ZINK_SHADER_COUNT; i++) {

View File

@ -96,6 +96,7 @@ struct zink_resource {
union {
struct {
struct util_range valid_buffer_range;
uint16_t vbo_bind_count;
uint16_t ubo_bind_count[2];
};
struct {