diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm b/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm index 6299de78..0022a577 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm @@ -93,6 +93,8 @@ void MVKCmdCopyImage::encode(MVKCommandEncoder* cmdEncoder, MVKCommandUse com VkBufferImageCopy vkDstCopies[copyCnt]; size_t tmpBuffSize = 0; + _srcImage->flushToDevice(0, VK_WHOLE_SIZE); + for (uint32_t copyIdx = 0; copyIdx < copyCnt; copyIdx++) { auto& vkIC = _vkImageCopies[copyIdx]; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDeviceMemory.h b/MoltenVK/MoltenVK/GPUObjects/MVKDeviceMemory.h index 98faa38e..c66ddb32 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDeviceMemory.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDeviceMemory.h @@ -148,6 +148,7 @@ public: protected: friend class MVKBuffer; friend class MVKImageMemoryBinding; + friend class MVKImagePlane; void propagateDebugName() override; VkDeviceSize adjustMemorySize(VkDeviceSize size, VkDeviceSize offset); diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKImage.h b/MoltenVK/MoltenVK/GPUObjects/MVKImage.h index 90d1c765..a4eae12f 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKImage.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKImage.h @@ -257,6 +257,9 @@ public: MVKCommandEncoder* cmdEncoder, MVKCommandUse cmdUse); + /** Flush underlying buffer memory into the image if necessary */ + void flushToDevice(VkDeviceSize offset, VkDeviceSize size); + #pragma mark Metal /** Returns the Metal texture underlying this image. */ diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm index 7413a9c6..0c2087bb 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm @@ -178,7 +178,7 @@ void MVKImagePlane::updateMTLTextureContent(MVKImageSubresource& subresource, VkImageSubresource& imgSubRez = subresource.subresource; VkSubresourceLayout& imgLayout = subresource.layout; - + size = getMemoryBinding()->getDeviceMemory()->adjustMemorySize(size, offset); // Check if subresource overlaps the memory range. if ( !overlaps(imgLayout, offset, size) ) { return; } @@ -514,6 +514,13 @@ void MVKImage::propagateDebugName() { } } +void MVKImage::flushToDevice(VkDeviceSize offset, VkDeviceSize size) { + for (int bindingIndex = 0; bindingIndex < _memoryBindings.size(); bindingIndex++) { + MVKImageMemoryBinding *binding = _memoryBindings[bindingIndex]; + binding->flushToDevice(offset, size); + } +} + VkImageType MVKImage::getImageType() { return mvkVkImageTypeFromMTLTextureType(_mtlTextureType); } bool MVKImage::getIsDepthStencil() { return getPixelFormats()->getFormatType(_vkFormat) == kMVKFormatDepthStencil; }