diff options
-rw-r--r-- | src/gallium/drivers/zink/zink_blit.c | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/src/gallium/drivers/zink/zink_blit.c b/src/gallium/drivers/zink/zink_blit.c index 8accc0c7286..2aeb2247833 100644 --- a/src/gallium/drivers/zink/zink_blit.c +++ b/src/gallium/drivers/zink/zink_blit.c @@ -91,13 +91,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; |