*/
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;
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);
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);
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;
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);
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};
}
} 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) {
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);
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);
}
}
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 */
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);
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))
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++) {
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];
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);
}
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
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,