Flush source image of a transfer

Since on macOS textures cannot be resident in shared (host-coherent) memory,
they need to be flushed before making the copy, to ensure that the modified
data is transferred.
This commit is contained in:
Jan Sikorski 2020-08-05 14:53:13 +02:00
parent 4609416ef2
commit 8f52521b1d
4 changed files with 14 additions and 1 deletions

View File

@ -93,6 +93,8 @@ void MVKCmdCopyImage<N>::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];

View File

@ -148,6 +148,7 @@ public:
protected:
friend class MVKBuffer;
friend class MVKImageMemoryBinding;
friend class MVKImagePlane;
void propagateDebugName() override;
VkDeviceSize adjustMemorySize(VkDeviceSize size, VkDeviceSize offset);

View File

@ -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. */

View File

@ -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; }