diff options
Diffstat (limited to 'src/gallium/drivers/zink/zink_blit.c')
-rw-r--r-- | src/gallium/drivers/zink/zink_blit.c | 437 |
1 files changed, 350 insertions, 87 deletions
diff --git a/src/gallium/drivers/zink/zink_blit.c b/src/gallium/drivers/zink/zink_blit.c index 7085c8e033c..f74921a2a1a 100644 --- a/src/gallium/drivers/zink/zink_blit.c +++ b/src/gallium/drivers/zink/zink_blit.c @@ -1,4 +1,8 @@ +#include "zink_clear.h" #include "zink_context.h" +#include "zink_format.h" +#include "zink_inlines.h" +#include "zink_kopper.h" #include "zink_helpers.h" #include "zink_query.h" #include "zink_resource.h" @@ -21,7 +25,7 @@ apply_dst_clears(struct zink_context *ctx, const struct pipe_blit_info *info, bo } static bool -blit_resolve(struct zink_context *ctx, const struct pipe_blit_info *info) +blit_resolve(struct zink_context *ctx, const struct pipe_blit_info *info, bool *needs_present_readback) { if (util_format_get_mask(info->dst.format) != info->mask || util_format_get_mask(info->src.format) != info->mask || @@ -30,9 +34,17 @@ blit_resolve(struct zink_context *ctx, const struct pipe_blit_info *info) info->alpha_blend) return false; - if (info->src.box.width != info->dst.box.width || - info->src.box.height != info->dst.box.height || - info->src.box.depth != info->dst.box.depth) + if (info->src.box.width < 0 || + info->dst.box.width < 0 || + info->src.box.height < 0 || + info->dst.box.height < 0 || + info->src.box.depth < 0 || + info->dst.box.depth < 0) + return false; + /* vulkan resolves can't downscale */ + if (info->src.box.width > info->dst.box.width || + info->src.box.height > info->dst.box.height || + info->src.box.depth > info->dst.box.depth) return false; if (info->render_condition_enable && @@ -40,26 +52,39 @@ blit_resolve(struct zink_context *ctx, const struct pipe_blit_info *info) return false; struct zink_resource *src = zink_resource(info->src.resource); + struct zink_resource *use_src = src; struct zink_resource *dst = zink_resource(info->dst.resource); struct zink_screen *screen = zink_screen(ctx->base.screen); + /* aliased/swizzled formats need u_blitter */ if (src->format != zink_get_format(screen, info->src.format) || dst->format != zink_get_format(screen, info->dst.format)) return false; - if (info->dst.resource->target == PIPE_BUFFER) - util_range_add(info->dst.resource, &dst->valid_buffer_range, - info->dst.box.x, info->dst.box.x + info->dst.box.width); + if (src->format != dst->format) + return false; + apply_dst_clears(ctx, info, false); zink_fb_clears_apply_region(ctx, info->src.resource, zink_rect_from_box(&info->src.box)); + if (src->obj->dt) + *needs_present_readback = zink_kopper_acquire_readback(ctx, src, &use_src); + struct zink_batch *batch = &ctx->batch; - zink_batch_no_rp(ctx); - zink_batch_reference_resource_rw(batch, src, false); + zink_resource_setup_transfer_layouts(ctx, use_src, dst); + VkCommandBuffer cmdbuf = *needs_present_readback ? + ctx->batch.state->cmdbuf : + zink_get_cmdbuf(ctx, src, dst); + if (cmdbuf == ctx->batch.state->cmdbuf) + zink_flush_dgc_if_enabled(ctx); + zink_batch_reference_resource_rw(batch, use_src, false); zink_batch_reference_resource_rw(batch, dst, true); - zink_resource_setup_transfer_layouts(ctx, src, dst); - + bool marker = zink_cmd_debug_marker_begin(ctx, cmdbuf, "blit_resolve(%s->%s, %dx%d->%dx%d)", + util_format_short_name(info->src.format), + util_format_short_name(info->src.format), + info->src.box.width, info->src.box.height, + info->dst.box.width, info->dst.box.height); VkImageResolve region = {0}; region.srcSubresource.aspectMask = src->aspect; @@ -97,23 +122,28 @@ blit_resolve(struct zink_context *ctx, const struct pipe_blit_info *info) region.extent.width = info->dst.box.width; region.extent.height = info->dst.box.height; region.extent.depth = info->dst.box.depth; - VKCTX(CmdResolveImage)(batch->state->cmdbuf, src->obj->image, src->layout, + if (region.srcOffset.x + region.extent.width >= u_minify(src->base.b.width0, region.srcSubresource.mipLevel)) + region.extent.width = u_minify(src->base.b.width0, region.srcSubresource.mipLevel) - region.srcOffset.x; + if (region.dstOffset.x + region.extent.width >= u_minify(dst->base.b.width0, region.dstSubresource.mipLevel)) + region.extent.width = u_minify(dst->base.b.width0, region.dstSubresource.mipLevel) - region.dstOffset.x; + if (region.srcOffset.y + region.extent.height >= u_minify(src->base.b.height0, region.srcSubresource.mipLevel)) + region.extent.height = u_minify(src->base.b.height0, region.srcSubresource.mipLevel) - region.srcOffset.y; + if (region.dstOffset.y + region.extent.height >= u_minify(dst->base.b.height0, region.dstSubresource.mipLevel)) + region.extent.height = u_minify(dst->base.b.height0, region.dstSubresource.mipLevel) - region.dstOffset.y; + if (region.srcOffset.z + region.extent.depth >= u_minify(src->base.b.depth0, region.srcSubresource.mipLevel)) + region.extent.depth = u_minify(src->base.b.depth0, region.srcSubresource.mipLevel) - region.srcOffset.z; + if (region.dstOffset.z + region.extent.depth >= u_minify(dst->base.b.depth0, region.dstSubresource.mipLevel)) + region.extent.depth = u_minify(dst->base.b.depth0, region.dstSubresource.mipLevel) - region.dstOffset.z; + VKCTX(CmdResolveImage)(cmdbuf, use_src->obj->image, src->layout, dst->obj->image, dst->layout, 1, ®ion); + zink_cmd_debug_marker_end(ctx, cmdbuf, marker); return true; } -static VkFormatFeatureFlags -get_resource_features(struct zink_screen *screen, struct zink_resource *res) -{ - VkFormatProperties props = screen->format_props[res->base.b.format]; - return res->optimal_tiling ? props.optimalTilingFeatures : - props.linearTilingFeatures; -} - static bool -blit_native(struct zink_context *ctx, const struct pipe_blit_info *info) +blit_native(struct zink_context *ctx, const struct pipe_blit_info *info, bool *needs_present_readback) { if (util_format_get_mask(info->dst.format) != info->mask || util_format_get_mask(info->src.format) != info->mask || @@ -126,7 +156,7 @@ blit_native(struct zink_context *ctx, const struct pipe_blit_info *info) return false; if (util_format_is_depth_or_stencil(info->dst.format) && - info->dst.format != info->src.format) + (info->dst.format != info->src.format || info->filter == PIPE_TEX_FILTER_LINEAR)) return false; /* vkCmdBlitImage must not be used for multisampled source or destination images. */ @@ -134,15 +164,18 @@ blit_native(struct zink_context *ctx, const struct pipe_blit_info *info) return false; struct zink_resource *src = zink_resource(info->src.resource); + struct zink_resource *use_src = src; struct zink_resource *dst = zink_resource(info->dst.resource); struct zink_screen *screen = zink_screen(ctx->base.screen); if (src->format != zink_get_format(screen, info->src.format) || dst->format != zink_get_format(screen, info->dst.format)) return false; + if (src->format != VK_FORMAT_A8_UNORM_KHR && zink_format_is_emulated_alpha(info->src.format)) + return false; - if (!(get_resource_features(screen, src) & VK_FORMAT_FEATURE_BLIT_SRC_BIT) || - !(get_resource_features(screen, dst) & VK_FORMAT_FEATURE_BLIT_DST_BIT)) + if (!(src->obj->vkfeats & VK_FORMAT_FEATURE_BLIT_SRC_BIT) || + !(dst->obj->vkfeats & VK_FORMAT_FEATURE_BLIT_DST_BIT)) return false; if ((util_format_is_pure_sint(info->src.format) != @@ -152,22 +185,10 @@ blit_native(struct zink_context *ctx, const struct pipe_blit_info *info) return false; if (info->filter == PIPE_TEX_FILTER_LINEAR && - !(get_resource_features(screen, src) & - VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT)) + !(src->obj->vkfeats & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT)) return false; - apply_dst_clears(ctx, info, false); - zink_fb_clears_apply_region(ctx, info->src.resource, zink_rect_from_box(&info->src.box)); - struct zink_batch *batch = &ctx->batch; - zink_batch_no_rp(ctx); - zink_batch_reference_resource_rw(batch, src, false); - zink_batch_reference_resource_rw(batch, dst, true); - - zink_resource_setup_transfer_layouts(ctx, src, dst); - if (info->dst.resource->target == PIPE_BUFFER) - util_range_add(info->dst.resource, &dst->valid_buffer_range, - info->dst.box.x, info->dst.box.x + info->dst.box.width); VkImageBlit region = {0}; region.srcSubresource.aspectMask = src->aspect; region.srcSubresource.mipLevel = info->src.level; @@ -176,13 +197,19 @@ blit_native(struct zink_context *ctx, const struct pipe_blit_info *info) region.srcOffsets[1].x = info->src.box.x + info->src.box.width; region.srcOffsets[1].y = info->src.box.y + info->src.box.height; - switch (src->base.b.target) { + enum pipe_texture_target src_target = src->base.b.target; + if (src->need_2D) + src_target = src_target == PIPE_TEXTURE_1D ? PIPE_TEXTURE_2D : PIPE_TEXTURE_2D_ARRAY; + switch (src_target) { case PIPE_TEXTURE_CUBE: case PIPE_TEXTURE_CUBE_ARRAY: case PIPE_TEXTURE_2D_ARRAY: case PIPE_TEXTURE_1D_ARRAY: /* these use layer */ region.srcSubresource.baseArrayLayer = info->src.box.z; + /* VUID-vkCmdBlitImage-srcImage-00240 */ + if (region.srcSubresource.baseArrayLayer && dst->base.b.target == PIPE_TEXTURE_3D) + return false; region.srcSubresource.layerCount = info->src.box.depth; region.srcOffsets[0].z = 0; region.srcOffsets[1].z = 1; @@ -211,13 +238,19 @@ blit_native(struct zink_context *ctx, const struct pipe_blit_info *info) assert(region.dstOffsets[0].x != region.dstOffsets[1].x); assert(region.dstOffsets[0].y != region.dstOffsets[1].y); - switch (dst->base.b.target) { + enum pipe_texture_target dst_target = dst->base.b.target; + if (dst->need_2D) + dst_target = dst_target == PIPE_TEXTURE_1D ? PIPE_TEXTURE_2D : PIPE_TEXTURE_2D_ARRAY; + switch (dst_target) { case PIPE_TEXTURE_CUBE: case PIPE_TEXTURE_CUBE_ARRAY: case PIPE_TEXTURE_2D_ARRAY: case PIPE_TEXTURE_1D_ARRAY: /* these use layer */ region.dstSubresource.baseArrayLayer = info->dst.box.z; + /* VUID-vkCmdBlitImage-srcImage-00240 */ + if (region.dstSubresource.baseArrayLayer && src->base.b.target == PIPE_TEXTURE_3D) + return false; region.dstSubresource.layerCount = info->dst.box.depth; region.dstOffsets[0].z = 0; region.dstOffsets[1].z = 1; @@ -238,14 +271,57 @@ blit_native(struct zink_context *ctx, const struct pipe_blit_info *info) } assert(region.dstOffsets[0].z != region.dstOffsets[1].z); - VKCTX(CmdBlitImage)(batch->state->cmdbuf, src->obj->image, src->layout, + apply_dst_clears(ctx, info, false); + zink_fb_clears_apply_region(ctx, info->src.resource, zink_rect_from_box(&info->src.box)); + + if (src->obj->dt) + *needs_present_readback = zink_kopper_acquire_readback(ctx, src, &use_src); + + struct zink_batch *batch = &ctx->batch; + zink_resource_setup_transfer_layouts(ctx, use_src, dst); + VkCommandBuffer cmdbuf = *needs_present_readback ? + ctx->batch.state->cmdbuf : + zink_get_cmdbuf(ctx, src, dst); + if (cmdbuf == ctx->batch.state->cmdbuf) + zink_flush_dgc_if_enabled(ctx); + zink_batch_reference_resource_rw(batch, use_src, false); + zink_batch_reference_resource_rw(batch, dst, true); + + bool marker = zink_cmd_debug_marker_begin(ctx, cmdbuf, "blit_native(%s->%s, %dx%d->%dx%d)", + util_format_short_name(info->src.format), + util_format_short_name(info->src.format), + info->src.box.width, info->src.box.height, + info->dst.box.width, info->dst.box.height); + + VKCTX(CmdBlitImage)(cmdbuf, use_src->obj->image, src->layout, dst->obj->image, dst->layout, 1, ®ion, zink_filter(info->filter)); + zink_cmd_debug_marker_end(ctx, cmdbuf, marker); + return true; } +static bool +try_copy_region(struct pipe_context *pctx, const struct pipe_blit_info *info) +{ + struct zink_context *ctx = zink_context(pctx); + struct zink_resource *src = zink_resource(info->src.resource); + struct zink_resource *dst = zink_resource(info->dst.resource); + /* if we're copying between resources with matching aspects then we can probably just copy_region */ + if (src->aspect != dst->aspect) + return false; + struct pipe_blit_info new_info = *info; + + if (src->aspect & VK_IMAGE_ASPECT_STENCIL_BIT && + new_info.render_condition_enable && + !ctx->render_condition_active) + new_info.render_condition_enable = false; + + return util_try_blit_via_copy_region(pctx, &new_info, ctx->render_condition_active); +} + void zink_blit(struct pipe_context *pctx, const struct pipe_blit_info *info) @@ -254,9 +330,14 @@ zink_blit(struct pipe_context *pctx, const struct util_format_description *src_desc = util_format_description(info->src.format); const struct util_format_description *dst_desc = util_format_description(info->dst.format); - if (info->render_condition_enable && - unlikely(!zink_screen(pctx->screen)->info.have_EXT_conditional_rendering && !zink_check_conditional_render(ctx))) - return; + struct zink_resource *src = zink_resource(info->src.resource); + struct zink_resource *use_src = src; + struct zink_resource *dst = zink_resource(info->dst.resource); + bool needs_present_readback = false; + if (zink_is_swapchain(dst)) { + if (!zink_kopper_acquire(ctx, dst, UINT64_MAX)) + return; + } if (src_desc == dst_desc || src_desc->nr_channels != 4 || src_desc->layout != UTIL_FORMAT_LAYOUT_PLAIN || @@ -266,47 +347,158 @@ zink_blit(struct pipe_context *pctx, */ if (info->src.resource->nr_samples > 1 && info->dst.resource->nr_samples <= 1) { - if (blit_resolve(ctx, info)) - return; + if (blit_resolve(ctx, info, &needs_present_readback)) + goto end; } else { - if (blit_native(ctx, info)) - return; + if (try_copy_region(pctx, info)) + goto end; + if (blit_native(ctx, info, &needs_present_readback)) + goto end; } } - struct zink_resource *src = zink_resource(info->src.resource); - struct zink_resource *dst = zink_resource(info->dst.resource); - /* if we're copying between resources with matching aspects then we can probably just copy_region */ - if (src->aspect == dst->aspect) { - struct pipe_blit_info new_info = *info; - if (src->aspect & VK_IMAGE_ASPECT_STENCIL_BIT && - new_info.render_condition_enable && - !ctx->render_condition_active) - new_info.render_condition_enable = false; - if (util_try_blit_via_copy_region(pctx, &new_info)) - return; + bool stencil_blit = false; + if (!util_blitter_is_blit_supported(ctx->blitter, info)) { + if (util_format_is_depth_or_stencil(info->src.resource->format)) { + if (info->mask & PIPE_MASK_Z) { + struct pipe_blit_info depth_blit = *info; + depth_blit.mask = PIPE_MASK_Z; + if (util_blitter_is_blit_supported(ctx->blitter, &depth_blit)) { + zink_blit_begin(ctx, ZINK_BLIT_SAVE_FB | ZINK_BLIT_SAVE_FS | ZINK_BLIT_SAVE_TEXTURES); + util_blitter_blit(ctx->blitter, &depth_blit); + } else { + mesa_loge("ZINK: depth blit unsupported %s -> %s", + util_format_short_name(info->src.resource->format), + util_format_short_name(info->dst.resource->format)); + } + } + if (info->mask & PIPE_MASK_S) + stencil_blit = true; + } + if (!stencil_blit) { + mesa_loge("ZINK: blit unsupported %s -> %s", + util_format_short_name(info->src.resource->format), + util_format_short_name(info->dst.resource->format)); + goto end; + } } - if (!util_blitter_is_blit_supported(ctx->blitter, info)) { - debug_printf("blit unsupported %s -> %s\n", - util_format_short_name(info->src.resource->format), - util_format_short_name(info->dst.resource->format)); - return; + if (src->obj->dt) { + zink_fb_clears_apply_region(ctx, info->src.resource, zink_rect_from_box(&info->src.box)); + needs_present_readback = zink_kopper_acquire_readback(ctx, src, &use_src); } /* this is discard_only because we're about to start a renderpass that will * flush all pending clears anyway */ 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; + } - if (info->dst.resource->target == PIPE_BUFFER) - util_range_add(info->dst.resource, &dst->valid_buffer_range, - info->dst.box.x, info->dst.box.x + info->dst.box.width); + /* this will draw a full-resource quad, so ignore existing data */ + bool whole = util_blit_covers_whole_resource(info); + if (whole) + pctx->invalidate_resource(pctx, info->dst.resource); + + zink_flush_dgc_if_enabled(ctx); + ctx->unordered_blitting = !(info->render_condition_enable && ctx->render_condition_active) && + zink_screen(ctx->base.screen)->info.have_KHR_dynamic_rendering && + !needs_present_readback && + zink_get_cmdbuf(ctx, src, dst) == ctx->batch.state->reordered_cmdbuf; + VkCommandBuffer cmdbuf = ctx->batch.state->cmdbuf; + VkPipeline pipeline = ctx->gfx_pipeline_state.pipeline; + bool in_rp = ctx->batch.in_rp; + uint64_t tc_data = ctx->dynamic_fb.tc_info.data; + bool queries_disabled = ctx->queries_disabled; + bool rp_changed = ctx->rp_changed || (!ctx->fb_state.zsbuf && util_format_is_depth_or_stencil(info->dst.format)); + unsigned ds3_states = ctx->ds3_states; + bool rp_tc_info_updated = ctx->rp_tc_info_updated; + if (ctx->unordered_blitting) { + /* for unordered blit, swap the unordered cmdbuf for the main one for the whole op to avoid conditional hell */ + ctx->batch.state->cmdbuf = ctx->batch.state->reordered_cmdbuf; + ctx->batch.in_rp = false; + ctx->rp_changed = true; + ctx->queries_disabled = true; + ctx->batch.state->has_barriers = true; + ctx->pipeline_changed[0] = true; + zink_reset_ds3_states(ctx); + zink_select_draw_vbo(ctx); + } zink_blit_begin(ctx, ZINK_BLIT_SAVE_FB | ZINK_BLIT_SAVE_FS | ZINK_BLIT_SAVE_TEXTURES); - - util_blitter_blit(ctx->blitter, info); + if (zink_format_needs_mutable(info->src.format, info->src.resource->format)) + zink_resource_object_init_mutable(ctx, src); + if (zink_format_needs_mutable(info->dst.format, info->dst.resource->format)) + zink_resource_object_init_mutable(ctx, dst); + zink_blit_barriers(ctx, use_src, dst, whole); + ctx->blitting = true; + + if (stencil_blit) { + struct pipe_surface *dst_view, dst_templ; + util_blitter_default_dst_texture(&dst_templ, info->dst.resource, info->dst.level, info->dst.box.z); + dst_view = pctx->create_surface(pctx, info->dst.resource, &dst_templ); + + util_blitter_clear_depth_stencil(ctx->blitter, dst_view, PIPE_CLEAR_STENCIL, + 0, 0, info->dst.box.x, info->dst.box.y, + info->dst.box.width, info->dst.box.height); + zink_blit_begin(ctx, ZINK_BLIT_SAVE_FB | ZINK_BLIT_SAVE_FS | ZINK_BLIT_SAVE_TEXTURES | ZINK_BLIT_SAVE_FS_CONST_BUF); + util_blitter_stencil_fallback(ctx->blitter, + info->dst.resource, + info->dst.level, + &info->dst.box, + info->src.resource, + info->src.level, + &info->src.box, + info->scissor_enable ? &info->scissor : NULL); + + pipe_surface_release(pctx, &dst_view); + } else { + struct pipe_blit_info new_info = *info; + new_info.src.resource = &use_src->base.b; + util_blitter_blit(ctx->blitter, &new_info); + } + ctx->blitting = false; + ctx->rp_clears_enabled = rp_clears_enabled; + ctx->clears_enabled = clears_enabled; + if (ctx->unordered_blitting) { + zink_batch_no_rp(ctx); + ctx->batch.in_rp = in_rp; + ctx->gfx_pipeline_state.rp_state = zink_update_rendering_info(ctx); + ctx->rp_changed = rp_changed; + ctx->rp_tc_info_updated |= rp_tc_info_updated; + ctx->queries_disabled = queries_disabled; + ctx->dynamic_fb.tc_info.data = tc_data; + ctx->batch.state->cmdbuf = cmdbuf; + ctx->gfx_pipeline_state.pipeline = pipeline; + ctx->pipeline_changed[0] = true; + ctx->ds3_states = ds3_states; + zink_select_draw_vbo(ctx); + } + ctx->unordered_blitting = false; +end: + if (needs_present_readback) { + src->obj->unordered_read = false; + dst->obj->unordered_write = false; + zink_kopper_present_readback(ctx, src); + } } /* similar to radeonsi */ @@ -316,24 +508,27 @@ zink_blit_begin(struct zink_context *ctx, enum zink_blit_flags flags) util_blitter_save_vertex_elements(ctx->blitter, ctx->element_state); util_blitter_save_viewport(ctx->blitter, ctx->vp_state.viewport_states); - util_blitter_save_vertex_buffer_slot(ctx->blitter, ctx->vertex_buffers); - util_blitter_save_vertex_shader(ctx->blitter, ctx->gfx_stages[PIPE_SHADER_VERTEX]); - util_blitter_save_tessctrl_shader(ctx->blitter, ctx->gfx_stages[PIPE_SHADER_TESS_CTRL]); - util_blitter_save_tesseval_shader(ctx->blitter, ctx->gfx_stages[PIPE_SHADER_TESS_EVAL]); - util_blitter_save_geometry_shader(ctx->blitter, ctx->gfx_stages[PIPE_SHADER_GEOMETRY]); + util_blitter_save_vertex_buffers(ctx->blitter, ctx->vertex_buffers, + util_last_bit(ctx->gfx_pipeline_state.vertex_buffers_enabled_mask)); + util_blitter_save_vertex_shader(ctx->blitter, ctx->gfx_stages[MESA_SHADER_VERTEX]); + util_blitter_save_tessctrl_shader(ctx->blitter, ctx->gfx_stages[MESA_SHADER_TESS_CTRL]); + util_blitter_save_tesseval_shader(ctx->blitter, ctx->gfx_stages[MESA_SHADER_TESS_EVAL]); + util_blitter_save_geometry_shader(ctx->blitter, ctx->gfx_stages[MESA_SHADER_GEOMETRY]); util_blitter_save_rasterizer(ctx->blitter, ctx->rast_state); util_blitter_save_so_targets(ctx->blitter, ctx->num_so_targets, ctx->so_targets); + if (flags & ZINK_BLIT_SAVE_FS_CONST_BUF) + util_blitter_save_fragment_constant_buffer_slot(ctx->blitter, ctx->ubos[MESA_SHADER_FRAGMENT]); + if (flags & ZINK_BLIT_SAVE_FS) { - util_blitter_save_fragment_constant_buffer_slot(ctx->blitter, ctx->ubos[PIPE_SHADER_FRAGMENT]); util_blitter_save_blend(ctx->blitter, ctx->gfx_pipeline_state.blend_state); util_blitter_save_depth_stencil_alpha(ctx->blitter, ctx->dsa_state); util_blitter_save_stencil_ref(ctx->blitter, &ctx->stencil_ref); - util_blitter_save_sample_mask(ctx->blitter, ctx->gfx_pipeline_state.sample_mask); + util_blitter_save_sample_mask(ctx->blitter, ctx->gfx_pipeline_state.sample_mask, ctx->gfx_pipeline_state.min_samples + 1); util_blitter_save_scissor(ctx->blitter, ctx->vp_state.scissor_states); /* also util_blitter_save_window_rectangles when we have that? */ - util_blitter_save_fragment_shader(ctx->blitter, ctx->gfx_stages[PIPE_SHADER_FRAGMENT]); + util_blitter_save_fragment_shader(ctx->blitter, ctx->gfx_stages[MESA_SHADER_FRAGMENT]); } if (flags & ZINK_BLIT_SAVE_FB) @@ -342,27 +537,83 @@ zink_blit_begin(struct zink_context *ctx, enum zink_blit_flags flags) if (flags & ZINK_BLIT_SAVE_TEXTURES) { util_blitter_save_fragment_sampler_states(ctx->blitter, - ctx->di.num_samplers[PIPE_SHADER_FRAGMENT], - (void**)ctx->sampler_states[PIPE_SHADER_FRAGMENT]); + ctx->di.num_samplers[MESA_SHADER_FRAGMENT], + (void**)ctx->sampler_states[MESA_SHADER_FRAGMENT]); util_blitter_save_fragment_sampler_views(ctx->blitter, - ctx->di.num_sampler_views[PIPE_SHADER_FRAGMENT], - ctx->sampler_views[PIPE_SHADER_FRAGMENT]); + ctx->di.num_sampler_views[MESA_SHADER_FRAGMENT], + ctx->sampler_views[MESA_SHADER_FRAGMENT]); } if (flags & ZINK_BLIT_NO_COND_RENDER && ctx->render_condition_active) zink_stop_conditional_render(ctx); } +void +zink_blit_barriers(struct zink_context *ctx, struct zink_resource *src, struct zink_resource *dst, bool whole_dst) +{ + struct zink_screen *screen = zink_screen(ctx->base.screen); + if (src && zink_is_swapchain(src)) { + if (!zink_kopper_acquire(ctx, src, UINT64_MAX)) + return; + } else if (dst && zink_is_swapchain(dst)) { + if (!zink_kopper_acquire(ctx, dst, UINT64_MAX)) + return; + } + + VkAccessFlagBits flags; + VkPipelineStageFlagBits pipeline; + if (util_format_is_depth_or_stencil(dst->base.b.format)) { + flags = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + if (!whole_dst) + flags |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; + pipeline = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; + } else { + flags = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + if (!whole_dst) + flags |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT; + pipeline = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + } + if (src == dst) { + VkImageLayout layout = zink_screen(ctx->base.screen)->info.have_EXT_attachment_feedback_loop_layout ? + VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT : + VK_IMAGE_LAYOUT_GENERAL; + screen->image_barrier(ctx, src, layout, VK_ACCESS_SHADER_READ_BIT | flags, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | pipeline); + } else { + if (src) { + VkImageLayout layout = util_format_is_depth_or_stencil(src->base.b.format) && + src->obj->vkusage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ? + VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL : + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + screen->image_barrier(ctx, src, layout, + VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); + if (!ctx->unordered_blitting) + src->obj->unordered_read = false; + } + VkImageLayout layout = util_format_is_depth_or_stencil(dst->base.b.format) ? + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + screen->image_barrier(ctx, dst, layout, flags, pipeline); + } + if (!ctx->unordered_blitting) + dst->obj->unordered_read = dst->obj->unordered_write = false; +} + bool zink_blit_region_fills(struct u_rect region, unsigned width, unsigned height) { struct u_rect intersect = {0, width, 0, height}; - - if (!u_rect_test_intersection(®ion, &intersect)) + struct u_rect r = { + MIN2(region.x0, region.x1), + MAX2(region.x0, region.x1), + MIN2(region.y0, region.y1), + MAX2(region.y0, region.y1), + }; + + if (!u_rect_test_intersection(&r, &intersect)) /* is this even a thing? */ return false; - u_rect_find_intersection(®ion, &intersect); + u_rect_find_intersection(&r, &intersect); if (intersect.x0 != 0 || intersect.y0 != 0 || intersect.x1 != width || intersect.y1 != height) return false; @@ -373,11 +624,23 @@ zink_blit_region_fills(struct u_rect region, unsigned width, unsigned height) bool zink_blit_region_covers(struct u_rect region, struct u_rect covers) { + struct u_rect r = { + MIN2(region.x0, region.x1), + MAX2(region.x0, region.x1), + MIN2(region.y0, region.y1), + MAX2(region.y0, region.y1), + }; + struct u_rect c = { + MIN2(covers.x0, covers.x1), + MAX2(covers.x0, covers.x1), + MIN2(covers.y0, covers.y1), + MAX2(covers.y0, covers.y1), + }; struct u_rect intersect; - if (!u_rect_test_intersection(®ion, &covers)) + if (!u_rect_test_intersection(&r, &c)) return false; - u_rect_union(&intersect, ®ion, &covers); - return intersect.x0 == covers.x0 && intersect.y0 == covers.y0 && - intersect.x1 == covers.x1 && intersect.y1 == covers.y1; + u_rect_union(&intersect, &r, &c); + return intersect.x0 == c.x0 && intersect.y0 == c.y0 && + intersect.x1 == c.x1 && intersect.y1 == c.y1; } |