zink: reapply resource/surface refs after app flushes

instead of doing this during descriptor update, we can automatically handle
this rollover

Reviewed-by: Dave Airlie <airlied@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10997>
This commit is contained in:
Mike Blumenkrantz
2021-01-26 09:37:17 -05:00
committed by Marge Bot
parent 234e1b7356
commit a64ef1cd12
3 changed files with 129 additions and 24 deletions
+121 -24
View File
@@ -935,7 +935,8 @@ zink_set_constant_buffer(struct pipe_context *pctx,
new_res->bind_stages |= 1 << shader;
new_res->ubo_bind_count[shader == PIPE_SHADER_COMPUTE]++;
new_res->bind_count[shader == PIPE_SHADER_COMPUTE]++;
zink_batch_reference_resource_rw(&ctx->batch, new_res, false);
if (!ctx->descriptor_refs_dirty[shader == PIPE_SHADER_COMPUTE])
zink_batch_reference_resource_rw(&ctx->batch, new_res, false);
zink_resource_buffer_barrier(ctx, NULL, new_res, VK_ACCESS_UNIFORM_READ_BIT,
zink_pipeline_flags_from_stage(zink_shader_stage(shader)));
}
@@ -1013,9 +1014,9 @@ zink_set_shader_buffers(struct pipe_context *pctx,
if (ctx->writable_ssbos[p_stage] & BITFIELD64_BIT(start_slot + i)) {
res->write_bind_count[p_stage == PIPE_SHADER_COMPUTE]++;
access |= VK_ACCESS_SHADER_WRITE_BIT;
zink_batch_reference_resource_rw(&ctx->batch, res, true);
} else
zink_batch_reference_resource_rw(&ctx->batch, res, false);
}
if (!ctx->descriptor_refs_dirty[p_stage == PIPE_SHADER_COMPUTE])
zink_batch_reference_resource_rw(&ctx->batch, res, access & VK_ACCESS_SHADER_WRITE_BIT);
pipe_resource_reference(&ssbo->buffer, &res->base.b);
ssbo->buffer_offset = buffers[i].buffer_offset;
ssbo->buffer_size = MIN2(buffers[i].buffer_size, res->obj->size - ssbo->buffer_offset);
@@ -1130,11 +1131,8 @@ zink_set_shader_images(struct pipe_context *pctx,
if (image_view->base.access & PIPE_IMAGE_ACCESS_WRITE) {
zink_resource(image_view->base.resource)->write_bind_count[p_stage == PIPE_SHADER_COMPUTE]++;
access |= VK_ACCESS_SHADER_WRITE_BIT;
zink_batch_reference_resource_rw(&ctx->batch, zink_resource(image_view->base.resource), true);
}
if (image_view->base.access & PIPE_IMAGE_ACCESS_READ) {
if (!access)
zink_batch_reference_resource_rw(&ctx->batch, zink_resource(image_view->base.resource), false);
access |= VK_ACCESS_SHADER_READ_BIT;
}
if (images[i].resource->target == PIPE_BUFFER) {
@@ -1144,7 +1142,6 @@ zink_set_shader_images(struct pipe_context *pctx,
images[i].u.buf.offset + images[i].u.buf.size);
zink_resource_buffer_barrier(ctx, NULL, res, access,
zink_pipeline_flags_from_stage(zink_shader_stage(p_stage)));
zink_batch_reference_bufferview(&ctx->batch, image_view->buffer_view);
} else {
struct pipe_surface tmpl = {};
tmpl.format = images[i].format;
@@ -1166,7 +1163,11 @@ zink_set_shader_images(struct pipe_context *pctx,
zink_pipeline_flags_from_stage(zink_shader_stage(p_stage)));
else
_mesa_set_add(ctx->need_barriers[0], res);
zink_batch_reference_surface(&ctx->batch, image_view->surface);
}
if (!ctx->descriptor_refs_dirty[p_stage == PIPE_SHADER_COMPUTE]) {
zink_batch_reference_resource_rw(&ctx->batch, zink_resource(image_view->base.resource),
zink_resource_access_is_write(access));
zink_batch_reference_image_view(&ctx->batch, image_view);
}
update = true;
} else if (image_view->base.resource) {
@@ -1226,7 +1227,6 @@ zink_set_sampler_views(struct pipe_context *pctx,
unbind_samplerview(ctx, shader_type, start_slot + i);
if (b && b->base.texture) {
struct zink_resource *res = zink_resource(b->base.texture);
zink_batch_reference_resource_rw(&ctx->batch, res, false);
if (res->base.b.target == PIPE_BUFFER) {
if (res->bind_history & BITFIELD64_BIT(ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW)) {
/* if this resource has been rebound while it wasn't set here,
@@ -1244,8 +1244,8 @@ zink_set_sampler_views(struct pipe_context *pctx,
}
zink_resource_buffer_barrier(ctx, NULL, res, VK_ACCESS_SHADER_READ_BIT,
zink_pipeline_flags_from_stage(zink_shader_stage(shader_type)));
zink_batch_reference_bufferview(&ctx->batch, b->buffer_view);
update |= !a || a->buffer_view->buffer_view != b->buffer_view->buffer_view;
if (!a || a->buffer_view->buffer_view != b->buffer_view->buffer_view)
update = true;
} else if (!res->obj->is_buffer) {
if (res->obj != b->image_view->obj) {
struct pipe_surface *psurf = &b->image_view->base;
@@ -1253,20 +1253,22 @@ zink_set_sampler_views(struct pipe_context *pctx,
zink_rebind_surface(ctx, &psurf);
b->image_view = zink_surface(psurf);
update |= iv != b->image_view->image_view;
} else {
if (a != b)
update = true;
if (shader_type == PIPE_SHADER_COMPUTE)
zink_resource_image_barrier(ctx, NULL, res, get_layout_for_binding(res, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW),
VK_ACCESS_SHADER_READ_BIT,
zink_pipeline_flags_from_stage(zink_shader_stage(shader_type)));
else
_mesa_set_add(ctx->need_barriers[0], res);
}
} else if (a != b)
update = true;
res->sampler_binds[shader_type] |= BITFIELD_BIT(start_slot + i);
zink_batch_reference_surface(&ctx->batch, b->image_view);
update |= !a || a->image_view->image_view != b->image_view->image_view;
if (shader_type == PIPE_SHADER_COMPUTE)
zink_resource_image_barrier(ctx, NULL, res, get_layout_for_binding(res, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW),
VK_ACCESS_SHADER_READ_BIT,
zink_pipeline_flags_from_stage(zink_shader_stage(shader_type)));
else
_mesa_set_add(ctx->need_barriers[0], res);
if (!a)
update = true;
}
if (!ctx->descriptor_refs_dirty[shader_type == PIPE_SHADER_COMPUTE]) {
zink_batch_reference_resource_rw(&ctx->batch, res, false);
zink_batch_reference_sampler_view(&ctx->batch, b);
}
res->bind_count[shader_type == PIPE_SHADER_COMPUTE]++;
res->bind_history |= BITFIELD_BIT(ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW);
@@ -1583,6 +1585,100 @@ sync_flush(struct zink_context *ctx, struct zink_batch_state *bs)
util_queue_fence_wait(&bs->flush_completed);
}
static inline VkAccessFlags
get_access_flags_for_binding(struct zink_context *ctx, enum zink_descriptor_type type, enum pipe_shader_type stage, unsigned idx)
{
VkAccessFlags flags = 0;
switch (type) {
case ZINK_DESCRIPTOR_TYPE_UBO:
return VK_ACCESS_UNIFORM_READ_BIT;
case ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW:
return VK_ACCESS_SHADER_READ_BIT;
case ZINK_DESCRIPTOR_TYPE_SSBO: {
flags = VK_ACCESS_SHADER_READ_BIT;
if (ctx->writable_ssbos[stage] & (1 << idx))
flags |= VK_ACCESS_SHADER_WRITE_BIT;
return flags;
}
case ZINK_DESCRIPTOR_TYPE_IMAGE: {
struct zink_image_view *image_view = &ctx->image_views[stage][idx];
if (image_view->base.access & PIPE_IMAGE_ACCESS_READ)
flags |= VK_ACCESS_SHADER_READ_BIT;
if (image_view->base.access & PIPE_IMAGE_ACCESS_WRITE)
flags |= VK_ACCESS_SHADER_WRITE_BIT;
return flags;
}
default:
break;
}
unreachable("ACK");
return 0;
}
static inline void
add_surface_ref(struct zink_context *ctx, struct zink_resource *res, union zink_descriptor_surface *surface)
{
if (!surface)
return;
if (res->obj->is_buffer) {
if (surface->bufferview)
zink_batch_reference_bufferview(&ctx->batch, surface->bufferview);
} else if (surface->surface)
zink_batch_reference_surface(&ctx->batch, surface->surface);
}
static void
update_resource_refs_for_stage(struct zink_context *ctx, enum pipe_shader_type stage)
{
struct zink_batch *batch = &ctx->batch;
unsigned max_slot[] = {
[ZINK_DESCRIPTOR_TYPE_UBO] = ctx->di.num_ubos[stage],
[ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW] = ctx->di.num_samplers[stage],
[ZINK_DESCRIPTOR_TYPE_SSBO] = ctx->di.num_ssbos[stage],
[ZINK_DESCRIPTOR_TYPE_IMAGE] = ctx->di.num_images[stage]
};
for (unsigned i = 0; i < ZINK_DESCRIPTOR_TYPES; i++) {
for (unsigned j = 0; j < max_slot[i]; j++) {
if (ctx->di.descriptor_res[i][stage][j]) {
struct zink_resource *res = ctx->di.descriptor_res[i][stage][j];
if (!res)
continue;
bool is_write = zink_resource_access_is_write(get_access_flags_for_binding(ctx, i, stage, j));
zink_batch_reference_resource_rw(batch, res, is_write);
struct zink_sampler_view *sv = zink_sampler_view(ctx->sampler_views[stage][j]);
struct zink_sampler_state *sampler_state = ctx->sampler_states[stage][j];
struct zink_image_view *iv = &ctx->image_views[stage][j];
if (sampler_state && i == ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW && j <= ctx->di.num_samplers[stage])
zink_batch_usage_set(&sampler_state->batch_uses, ctx->curr_batch);
if (sv && i == ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW && j <= ctx->di.num_sampler_views[stage])
zink_batch_reference_sampler_view(batch, sv);
else if (i == ZINK_DESCRIPTOR_TYPE_IMAGE && j <= ctx->di.num_images[stage])
zink_batch_reference_image_view(batch, iv);
}
}
}
}
void
zink_update_descriptor_refs(struct zink_context *ctx, bool compute)
{
struct zink_batch *batch = &ctx->batch;
if (compute)
update_resource_refs_for_stage(ctx, PIPE_SHADER_COMPUTE);
else {
for (unsigned i = 0; i < ZINK_SHADER_COUNT; i++)
update_resource_refs_for_stage(ctx, i);
unsigned vertex_buffers_enabled_mask = ctx->gfx_pipeline_state.vertex_buffers_enabled_mask;
unsigned last_vbo = util_last_bit(vertex_buffers_enabled_mask);
for (unsigned i = 0; i < last_vbo + 1; i++) {
if (ctx->vertex_buffers[i].buffer.resource)
zink_batch_reference_resource_rw(batch, zink_resource(ctx->vertex_buffers[i].buffer.resource), false);
}
}
ctx->descriptor_refs_dirty[compute] = false;
}
static void
flush_batch(struct zink_context *ctx, bool sync)
{
@@ -1604,6 +1700,7 @@ flush_batch(struct zink_context *ctx, bool sync)
zink_start_batch(ctx, batch);
if (zink_screen(ctx->base.screen)->info.have_EXT_transform_feedback && ctx->num_so_targets)
ctx->dirty_so_targets = true;
ctx->descriptor_refs_dirty[0] = ctx->descriptor_refs_dirty[1] = true;
}
}
+3
View File
@@ -251,6 +251,7 @@ struct zink_context {
union zink_descriptor_surface sampler_surfaces[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
union zink_descriptor_surface image_surfaces[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_IMAGES];
} di;
bool descriptor_refs_dirty[2];
struct set *need_barriers[2]; //gfx, compute
struct set update_barriers[2][2]; //[gfx, compute][current, next]
uint8_t barrier_set_idx[2];
@@ -397,4 +398,6 @@ zink_buffer_view_reference(struct zink_screen *screen,
if (dst) *dst = src;
}
void
zink_update_descriptor_refs(struct zink_context *ctx, bool compute);
#endif
+5
View File
@@ -524,6 +524,9 @@ zink_draw_vbo(struct pipe_context *pctx,
if (zink_program_has_descriptors(&gfx_program->base))
screen->descriptors_update(ctx, false);
if (ctx->descriptor_refs_dirty[0])
zink_update_descriptor_refs(ctx, false);
struct zink_batch *batch = zink_batch_rp(ctx);
VkViewport viewports[PIPE_MAX_VIEWPORTS];
for (unsigned i = 0; i < ctx->vp_state.num_viewports; i++) {
@@ -778,6 +781,8 @@ zink_launch_grid(struct pipe_context *pctx, const struct pipe_grid_info *info)
if (zink_program_has_descriptors(&comp_program->base))
screen->descriptors_update(ctx, true);
if (ctx->descriptor_refs_dirty[1])
zink_update_descriptor_refs(ctx, true);
vkCmdBindPipeline(batch->state->cmdbuf, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline);