Image to Image copy command

Implemented Image to Image copy, Image to Buffer copy and
Buffer to Image copy commands which are required in order
to run the dEQP-VK.api.copy_and_blit.core.image_to_image.*
tests.

Passes over 99.7% of the 10907 tests in:
dEQP-VK.api.copy_and_blit.core.image_to_image.*

Bug b/118619338 b/119620767

Change-Id: Id4d3aa5186bed84d0925e4424399716efbd241ee
Reviewed-on: https://swiftshader-review.googlesource.com/c/23071
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Chris Forbes <chrisforbes@google.com>
Reviewed-by: Corentin Wallez <cwallez@google.com>
diff --git a/src/Vulkan/VkCommandBuffer.cpp b/src/Vulkan/VkCommandBuffer.cpp
index 62c6ccf..1b74365 100644
--- a/src/Vulkan/VkCommandBuffer.cpp
+++ b/src/Vulkan/VkCommandBuffer.cpp
@@ -13,6 +13,7 @@
 // limitations under the License.
 
 #include "VkCommandBuffer.hpp"
+#include "VkImage.hpp"
 
 #include <cstring>
 
@@ -125,6 +126,24 @@
 	uint32_t vertexCount;
 };
 
+struct ImageToImageCopy : public CommandBuffer::Command
+{
+	ImageToImageCopy(VkImage pSrcImage, VkImage pDstImage, const VkImageCopy& pRegion) :
+		srcImage(pSrcImage), dstImage(pDstImage), region(pRegion)
+	{
+	}
+
+	void play(CommandBuffer* commandBuffer)
+	{
+		Cast(srcImage)->copyTo(dstImage, region);
+	}
+
+private:
+	VkImage srcImage;
+	VkImage dstImage;
+	const VkImageCopy region;
+};
+
 struct ImageToBufferCopy : public CommandBuffer::Command
 {
 	ImageToBufferCopy(VkImage pSrcImage, VkBuffer pDstBuffer, const VkBufferImageCopy& pRegion) :
@@ -134,7 +153,7 @@
 
 	void play(CommandBuffer* commandBuffer)
 	{
-		UNIMPLEMENTED();
+		Cast(srcImage)->copyTo(dstBuffer, region);
 	}
 
 private:
@@ -143,6 +162,24 @@
 	const VkBufferImageCopy region;
 };
 
+struct BufferToImageCopy : public CommandBuffer::Command
+{
+	BufferToImageCopy(VkBuffer pSrcBuffer, VkImage pDstImage, const VkBufferImageCopy& pRegion) :
+		srcBuffer(pSrcBuffer), dstImage(pDstImage), region(pRegion)
+	{
+	}
+
+	void play(CommandBuffer* commandBuffer)
+	{
+		Cast(dstImage)->copyFrom(srcBuffer, region);
+	}
+
+private:
+	VkBuffer srcBuffer;
+	VkImage dstImage;
+	const VkBufferImageCopy region;
+};
+
 struct PipelineBarrier : public CommandBuffer::Command
 {
 	PipelineBarrier()
@@ -436,7 +473,16 @@
 void CommandBuffer::copyImage(VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout,
 	uint32_t regionCount, const VkImageCopy* pRegions)
 {
-	UNIMPLEMENTED();
+	ASSERT(state == RECORDING);
+	ASSERT(srcImageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL ||
+	       srcImageLayout == VK_IMAGE_LAYOUT_GENERAL);
+	ASSERT(dstImageLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL ||
+	       dstImageLayout == VK_IMAGE_LAYOUT_GENERAL);
+
+	for(uint32_t i = 0; i < regionCount; i++)
+	{
+		commands->push_back(std::make_unique<ImageToImageCopy>(srcImage, dstImage, pRegions[i]));
+	}
 }
 
 void CommandBuffer::blitImage(VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout,
@@ -448,12 +494,18 @@
 void CommandBuffer::copyBufferToImage(VkBuffer srcBuffer, VkImage dstImage, VkImageLayout dstImageLayout,
 	uint32_t regionCount, const VkBufferImageCopy* pRegions)
 {
-	UNIMPLEMENTED();
+	ASSERT(state == RECORDING);
+
+	for(uint32_t i = 0; i < regionCount; i++)
+	{
+		commands->push_back(std::make_unique<BufferToImageCopy>(srcBuffer, dstImage, pRegions[i]));
+	}
 }
 
 void CommandBuffer::copyImageToBuffer(VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer dstBuffer,
 	uint32_t regionCount, const VkBufferImageCopy* pRegions)
 {
+	ASSERT(state == RECORDING);
 	ASSERT(srcImageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
 
 	for(uint32_t i = 0; i < regionCount; i++)