/// <inheritdoc cref="Copy(GraphicsBuffer, GraphicsBuffer)" />
        public void Copy(VulkanGraphicsBuffer destination, VulkanGraphicsBuffer source)
        {
            ThrowIfNull(destination, nameof(destination));
            ThrowIfNull(source, nameof(source));

            var vulkanBufferCopy = new VkBufferCopy {
                srcOffset = 0,
                dstOffset = 0,
                size      = Math.Min(destination.Size, source.Size),
            };

            vkCmdCopyBuffer(VulkanCommandBuffer, source.VulkanBuffer, destination.VulkanBuffer, 1, &vulkanBufferCopy);
        }
        /// <inheritdoc cref="Copy(GraphicsTexture, GraphicsBuffer)" />
        public void Copy(VulkanGraphicsTexture destination, VulkanGraphicsBuffer source)
        {
            ThrowIfNull(destination, nameof(destination));
            ThrowIfNull(source, nameof(source));

            var vulkanCommandBuffer = VulkanCommandBuffer;
            var vulkanImage         = destination.VulkanImage;

            BeginCopy();

            var vulkanBufferImageCopy = new VkBufferImageCopy {
                imageSubresource = new VkImageSubresourceLayers {
                    aspectMask = (uint)VK_IMAGE_ASPECT_COLOR_BIT,
                    layerCount = 1,
                },
                imageExtent = new VkExtent3D {
                    width  = (uint)destination.Width,
                    height = destination.Height,
                    depth  = destination.Depth,
                },
            };

            vkCmdCopyBufferToImage(vulkanCommandBuffer, source.VulkanBuffer, vulkanImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &vulkanBufferImageCopy);

            EndCopy();

            void BeginCopy()
            {
                var vulkanImageMemoryBarrier = new VkImageMemoryBarrier {
                    sType            = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
                    dstAccessMask    = (uint)VK_ACCESS_TRANSFER_WRITE_BIT,
                    oldLayout        = VK_IMAGE_LAYOUT_UNDEFINED,
                    newLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
                    image            = vulkanImage,
                    subresourceRange = new VkImageSubresourceRange {
                        aspectMask = (uint)VK_IMAGE_ASPECT_COLOR_BIT,
                        levelCount = 1,
                        layerCount = 1,
                    },
                };

                vkCmdPipelineBarrier(vulkanCommandBuffer, (uint)VK_PIPELINE_STAGE_HOST_BIT, (uint)VK_PIPELINE_STAGE_TRANSFER_BIT, dependencyFlags: 0, memoryBarrierCount: 0, pMemoryBarriers: null, bufferMemoryBarrierCount: 0, pBufferMemoryBarriers: null, imageMemoryBarrierCount: 1, &vulkanImageMemoryBarrier);
            }

            void EndCopy()
            {
                var vulkanImageMemoryBarrier = new VkImageMemoryBarrier {
                    sType            = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
                    srcAccessMask    = (uint)VK_ACCESS_TRANSFER_WRITE_BIT,
                    dstAccessMask    = (uint)VK_ACCESS_SHADER_READ_BIT,
                    oldLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
                    newLayout        = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
                    image            = vulkanImage,
                    subresourceRange = new VkImageSubresourceRange {
                        aspectMask = (uint)VK_IMAGE_ASPECT_COLOR_BIT,
                        levelCount = 1,
                        layerCount = 1,
                    },
                };

                vkCmdPipelineBarrier(vulkanCommandBuffer, (uint)VK_PIPELINE_STAGE_TRANSFER_BIT, (uint)VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, dependencyFlags: 0, memoryBarrierCount: 0, pMemoryBarriers: null, bufferMemoryBarrierCount: 0, pBufferMemoryBarriers: null, imageMemoryBarrierCount: 1, &vulkanImageMemoryBarrier);
            }
        }