diff --git a/.pick_status.json b/.pick_status.json index f98afc3805c..b2c46534db3 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -22,7 +22,7 @@ "description": "zink: use general-layout when blitting to/from same resource", "nominated": true, "nomination_type": 1, - "resolution": 0, + "resolution": 1, "master_sha": null, "because_sha": "d2bb63c8d4cdc02b1c33afadea5becd58fb7286c" }, diff --git a/src/gallium/drivers/zink/zink_blit.c b/src/gallium/drivers/zink/zink_blit.c index 2fa0c359cc0..efce46d52d6 100644 --- a/src/gallium/drivers/zink/zink_blit.c +++ b/src/gallium/drivers/zink/zink_blit.c @@ -89,13 +89,35 @@ blit_native(struct zink_context *ctx, const struct pipe_blit_info *info) zink_batch_reference_resoure(batch, src); zink_batch_reference_resoure(batch, dst); - if (src->layout != VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) - zink_resource_barrier(batch->cmdbuf, src, src->aspect, - VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + if (src == dst) { + /* The Vulkan 1.1 specification says the following about valid usage + * of vkCmdBlitImage: + * + * "srcImageLayout must be VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR, + * VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL" + * + * and: + * + * "dstImageLayout must be VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR, + * VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL" + * + * Since we cant have the same image in two states at the same time, + * we're effectively left with VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR or + * VK_IMAGE_LAYOUT_GENERAL. And since this isn't a present-related + * operation, VK_IMAGE_LAYOUT_GENERAL seems most appropriate. + */ + if (src->layout != VK_IMAGE_LAYOUT_GENERAL) + zink_resource_barrier(batch->cmdbuf, src, src->aspect, + VK_IMAGE_LAYOUT_GENERAL); + } else { + if (src->layout != VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) + zink_resource_barrier(batch->cmdbuf, src, src->aspect, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); - if (dst->layout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) - zink_resource_barrier(batch->cmdbuf, dst, dst->aspect, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + if (dst->layout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) + zink_resource_barrier(batch->cmdbuf, dst, dst->aspect, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + } VkImageBlit region = {}; region.srcSubresource.aspectMask = src->aspect;