diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index f92e71fa84d..67106acd6b4 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -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); diff --git a/src/gallium/drivers/zink/zink_draw.c b/src/gallium/drivers/zink/zink_draw.c index 8c5863f9350..efcb90373c2 100644 --- a/src/gallium/drivers/zink/zink_draw.c +++ b/src/gallium/drivers/zink/zink_draw.c @@ -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++) { diff --git a/src/gallium/drivers/zink/zink_resource.h b/src/gallium/drivers/zink/zink_resource.h index 92ac55c3773..821f616c807 100644 --- a/src/gallium/drivers/zink/zink_resource.h +++ b/src/gallium/drivers/zink/zink_resource.h @@ -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 {