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:
parent
be40886521
commit
b27e729c0d
|
@ -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);
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue