zink: manually apply barriers whenever zink_context::blitting is set

this simplifies some codepaths at runtime by short-circuiting some
of the more complex operations since it's already known in advance
exactly which images will be used for which purpose

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21906>
This commit is contained in:
Mike Blumenkrantz 2023-02-28 14:37:46 -05:00 committed by Marge Bot
parent 07a5ede65a
commit 9746e7253e
5 changed files with 53 additions and 8 deletions

View file

@ -356,12 +356,36 @@ zink_blit(struct pipe_context *pctx,
*/
apply_dst_clears(ctx, info, true);
zink_fb_clears_apply_region(ctx, info->src.resource, zink_rect_from_box(&info->src.box));
unsigned rp_clears_enabled = ctx->rp_clears_enabled;
unsigned clears_enabled = ctx->clears_enabled;
if (!dst->fb_bind_count) {
/* avoid applying clears from fb unbind by storing and re-setting them after the blit */
ctx->rp_clears_enabled = 0;
ctx->clears_enabled = 0;
} else {
unsigned bit;
/* convert to PIPE_CLEAR_XYZ */
if (dst->fb_binds & BITFIELD_BIT(PIPE_MAX_COLOR_BUFS))
bit = PIPE_CLEAR_DEPTHSTENCIL;
else
bit = dst->fb_binds << 2;
rp_clears_enabled &= ~bit;
clears_enabled &= ~bit;
ctx->rp_clears_enabled &= bit;
ctx->clears_enabled &= bit;
}
/* this will draw a full-resource quad, so ignore existing data */
if (util_blit_covers_whole_resource(info))
bool whole = util_blit_covers_whole_resource(info);
if (whole)
pctx->invalidate_resource(pctx, info->dst.resource);
ctx->blitting = true;
zink_blit_begin(ctx, ZINK_BLIT_SAVE_FB | ZINK_BLIT_SAVE_FS | ZINK_BLIT_SAVE_TEXTURES);
if (info->src.format != info->src.resource->format)
zink_resource_object_init_mutable(ctx, src);
if (info->dst.format != info->dst.resource->format)
zink_resource_object_init_mutable(ctx, dst);
zink_blit_barriers(ctx, src, dst, whole);
ctx->blitting = true;
if (stencil_blit) {
struct pipe_surface *dst_view, dst_templ;
@ -386,6 +410,8 @@ zink_blit(struct pipe_context *pctx,
util_blitter_blit(ctx->blitter, info);
}
ctx->blitting = false;
ctx->rp_clears_enabled = rp_clears_enabled;
ctx->clears_enabled = clears_enabled;
end:
if (needs_present_readback)
zink_kopper_present_readback(ctx, src);

View file

@ -539,6 +539,7 @@ zink_clear_texture(struct pipe_context *pctx,
surf = create_clear_surface(pctx, pres, level, box);
util_blitter_save_framebuffer(ctx->blitter, &ctx->fb_state);
set_clear_fb(pctx, surf, NULL);
zink_blit_barriers(ctx, NULL, res, false);
ctx->blitting = true;
ctx->queries_disabled = true;
pctx->clear(pctx, PIPE_CLEAR_COLOR0, &scissor, &color, 0, 0);
@ -562,6 +563,7 @@ zink_clear_texture(struct pipe_context *pctx,
flags |= PIPE_CLEAR_STENCIL;
surf = create_clear_surface(pctx, pres, level, box);
util_blitter_save_framebuffer(ctx->blitter, &ctx->fb_state);
zink_blit_barriers(ctx, NULL, res, false);
ctx->blitting = true;
set_clear_fb(pctx, NULL, surf);
ctx->queries_disabled = true;
@ -633,6 +635,7 @@ zink_clear_render_target(struct pipe_context *pctx, struct pipe_surface *dst,
util_blitter_save_framebuffer(ctx->blitter, &ctx->fb_state);
set_clear_fb(pctx, dst, NULL);
struct pipe_scissor_state scissor = {dstx, dsty, dstx + width, dsty + height};
zink_blit_barriers(ctx, NULL, zink_resource(dst->texture), false);
ctx->blitting = true;
pctx->clear(pctx, PIPE_CLEAR_COLOR0, &scissor, color, 0, 0);
util_blitter_restore_fb_state(ctx->blitter);
@ -662,6 +665,7 @@ zink_clear_depth_stencil(struct pipe_context *pctx, struct pipe_surface *dst,
if (!cur_attachment) {
util_blitter_save_framebuffer(ctx->blitter, &ctx->fb_state);
set_clear_fb(pctx, NULL, dst);
zink_blit_barriers(ctx, NULL, zink_resource(dst->texture), false);
ctx->blitting = true;
}
struct pipe_scissor_state scissor = {dstx, dsty, dstx + width, dsty + height};

View file

@ -648,7 +648,7 @@ update_descriptor_state_sampler(struct zink_context *ctx, gl_shader_stage shader
}
} else {
struct zink_surface *surface = get_imageview_for_binding(ctx, shader, type, slot);
ctx->di.textures[shader][slot].imageLayout = get_layout_for_binding(ctx, res, type, shader == MESA_SHADER_COMPUTE);
ctx->di.textures[shader][slot].imageLayout = ctx->blitting ? res->layout : get_layout_for_binding(ctx, res, type, shader == MESA_SHADER_COMPUTE);
ctx->di.textures[shader][slot].imageView = surface->image_view;
if (!screen->have_D24_UNORM_S8_UINT &&
ctx->sampler_states[shader][slot] && ctx->sampler_states[shader][slot]->sampler_clamped) {
@ -2862,6 +2862,8 @@ zink_prep_fb_attachment(struct zink_context *ctx, struct zink_surface *surf, uns
if (!i)
zink_update_fbfetch(ctx);
}
if (ctx->blitting)
return surf->image_view;
VkImageLayout layout;
if (ctx->tc && zink_screen(ctx->base.screen)->driver_workarounds.track_renderpasses && !ctx->blitting) {
layout = zink_tc_renderpass_info_parse(ctx, &ctx->dynamic_fb.tc_info, i < ctx->fb_state.nr_cbufs ? i : PIPE_MAX_COLOR_BUFS, &pipeline, &access);
@ -3205,7 +3207,7 @@ unbind_fb_surface(struct zink_context *ctx, struct pipe_surface *surf, unsigned
check_resource_for_batch_ref(ctx, res);
if (res->sampler_bind_count[0]) {
update_res_sampler_layouts(ctx, res);
if (res->layout != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
if (res->layout != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL && !ctx->blitting)
_mesa_set_add(ctx->need_barriers[0], res);
}
}
@ -3727,6 +3729,7 @@ static void
resource_check_defer_image_barrier(struct zink_context *ctx, struct zink_resource *res, VkImageLayout layout, VkPipelineStageFlags pipeline)
{
assert(!res->obj->is_buffer);
assert(!ctx->blitting);
bool is_compute = pipeline == VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
/* if this is a non-shader barrier and there are binds, always queue a shader barrier */
@ -4094,6 +4097,13 @@ zink_flush(struct pipe_context *pctx,
ctx->fbfetch_outputs = 0;
ctx->rp_changed = true;
}
if (ctx->fb_state.zsbuf)
zink_blit_barriers(ctx, NULL, zink_resource(ctx->fb_state.zsbuf->texture), false);
for (unsigned i = 0; i < ctx->fb_state.nr_cbufs; i++) {
if (ctx->fb_state.cbufs[i])
zink_blit_barriers(ctx, NULL, zink_resource(ctx->fb_state.cbufs[i]->texture), false);
}
ctx->blitting = true;
/* start rp to do all the clears */
zink_batch_rp(ctx);
@ -5034,6 +5044,7 @@ zink_resource_commit(struct pipe_context *pctx, struct pipe_resource *pres, unsi
static void
rebind_image(struct zink_context *ctx, struct zink_resource *res)
{
assert(!ctx->blitting);
if (res->fb_binds)
zink_rebind_framebuffer(ctx, res);
if (!zink_resource_has_binds(res))
@ -5111,6 +5122,7 @@ zink_rebind_all_buffers(struct zink_context *ctx)
void
zink_rebind_all_images(struct zink_context *ctx)
{
assert(!ctx->blitting);
rebind_fb_state(ctx, NULL, false);
for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
for (unsigned j = 0; j < ctx->di.num_sampler_views[i]; j++) {
@ -5628,6 +5640,7 @@ void
zink_update_barriers(struct zink_context *ctx, bool is_compute,
struct pipe_resource *index, struct pipe_resource *indirect, struct pipe_resource *indirect_draw_count)
{
assert(!ctx->blitting);
if (!ctx->need_barriers[is_compute]->entries)
return;
struct set *need_barriers = ctx->need_barriers[is_compute];

View file

@ -364,15 +364,15 @@ zink_draw(struct pipe_context *pctx,
unsigned work_count = ctx->batch.work_count;
enum pipe_prim_type mode = (enum pipe_prim_type)dinfo->mode;
if (ctx->memory_barrier)
if (ctx->memory_barrier && !ctx->blitting)
zink_flush_memory_barrier(ctx, false);
if (unlikely(ctx->buffer_rebind_counter < screen->buffer_rebind_counter)) {
if (unlikely(ctx->buffer_rebind_counter < screen->buffer_rebind_counter && !ctx->blitting)) {
ctx->buffer_rebind_counter = screen->buffer_rebind_counter;
zink_rebind_all_buffers(ctx);
}
if (unlikely(ctx->image_rebind_counter < screen->image_rebind_counter)) {
if (unlikely(ctx->image_rebind_counter < screen->image_rebind_counter && !ctx->blitting)) {
ctx->image_rebind_counter = screen->image_rebind_counter;
zink_rebind_all_images(ctx);
}
@ -423,7 +423,8 @@ zink_draw(struct pipe_context *pctx,
barrier_draw_buffers(ctx, dinfo, dindirect, index_buffer);
/* this may re-emit draw buffer barriers, but such synchronization is harmless */
zink_update_barriers(ctx, false, index_buffer, dindirect ? dindirect->buffer : NULL, dindirect ? dindirect->indirect_draw_count : NULL);
if (!ctx->blitting)
zink_update_barriers(ctx, false, index_buffer, dindirect ? dindirect->buffer : NULL, dindirect ? dindirect->indirect_draw_count : NULL);
/* ensure synchronization between doing streamout with counter buffer
* and using counter buffer for indirect draw

View file

@ -786,6 +786,7 @@ zink_begin_render_pass(struct zink_context *ctx)
src_view = ctx->base.create_sampler_view(&ctx->base, src, &src_templ);
zink_blit_begin(ctx, ZINK_BLIT_SAVE_FB | ZINK_BLIT_SAVE_FS | ZINK_BLIT_SAVE_TEXTURES);
zink_blit_barriers(ctx, zink_resource(src), zink_resource(dst_view->texture), false);
ctx->blitting = true;
util_blitter_blit_generic(ctx->blitter, dst_view, &dstbox,
src_view, &dstbox, ctx->fb_state.width, ctx->fb_state.height,