Merge pull request #1033 from cdavis5e/3d-2d-copies

MVKCmdCopyImage: Support copies between 3D and 2D images.
This commit is contained in:
Bill Hollings 2020-09-15 13:35:44 -04:00 committed by GitHub
commit 7abb9f552a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -77,11 +77,6 @@ VkResult MVKCmdCopyImage<N>::setContent(MVKCommandBuffer* cmdBuff,
_vkImageCopies.push_back(vkIR); _vkImageCopies.push_back(vkIR);
} }
// Validate
if ((_srcImage->getMTLTextureType() == MTLTextureType3D) != (_dstImage->getMTLTextureType() == MTLTextureType3D)) {
return cmdBuff->reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCmdCopyImage(): Metal does not support copying to or from slices of a 3D texture.");
}
return VK_SUCCESS; return VK_SUCCESS;
} }
@ -160,25 +155,62 @@ void MVKCmdCopyImage<N>::encode(MVKCommandEncoder* cmdEncoder, MVKCommandUse com
// If copies can be performed using direct texture-texture copying, do so // If copies can be performed using direct texture-texture copying, do so
uint32_t srcLevel = vkIC.srcSubresource.mipLevel; uint32_t srcLevel = vkIC.srcSubresource.mipLevel;
MTLOrigin srcOrigin = mvkMTLOriginFromVkOffset3D(vkIC.srcOffset); MTLOrigin srcOrigin = mvkMTLOriginFromVkOffset3D(vkIC.srcOffset);
MTLSize srcSize = mvkClampMTLSize(mvkMTLSizeFromVkExtent3D(vkIC.extent), MTLSize srcSize;
srcOrigin, uint32_t layCnt;
mvkMTLSizeFromVkExtent3D(_srcImage->getExtent3D(srcPlaneIndex, srcLevel))); if ((_srcImage->getMTLTextureType() == MTLTextureType3D) != (_dstImage->getMTLTextureType() == MTLTextureType3D)) {
// In the case, the number of layers to copy is in extent.depth. Use that value,
// then clamp the depth so we don't try to copy more than Metal will allow.
layCnt = vkIC.extent.depth;
srcSize = mvkClampMTLSize(mvkMTLSizeFromVkExtent3D(vkIC.extent),
srcOrigin,
mvkMTLSizeFromVkExtent3D(_srcImage->getExtent3D(srcPlaneIndex, srcLevel)));
srcSize.depth = 1;
} else {
layCnt = vkIC.srcSubresource.layerCount;
srcSize = mvkClampMTLSize(mvkMTLSizeFromVkExtent3D(vkIC.extent),
srcOrigin,
mvkMTLSizeFromVkExtent3D(_srcImage->getExtent3D(srcPlaneIndex, srcLevel)));
}
uint32_t dstLevel = vkIC.dstSubresource.mipLevel; uint32_t dstLevel = vkIC.dstSubresource.mipLevel;
MTLOrigin dstOrigin = mvkMTLOriginFromVkOffset3D(vkIC.dstOffset); MTLOrigin dstOrigin = mvkMTLOriginFromVkOffset3D(vkIC.dstOffset);
uint32_t srcBaseLayer = vkIC.srcSubresource.baseArrayLayer; uint32_t srcBaseLayer = vkIC.srcSubresource.baseArrayLayer;
uint32_t dstBaseLayer = vkIC.dstSubresource.baseArrayLayer; uint32_t dstBaseLayer = vkIC.dstSubresource.baseArrayLayer;
uint32_t layCnt = vkIC.srcSubresource.layerCount;
for (uint32_t layIdx = 0; layIdx < layCnt; layIdx++) { for (uint32_t layIdx = 0; layIdx < layCnt; layIdx++) {
[mtlBlitEnc copyFromTexture: srcMTLTex // We can copy between a 3D and a 2D image easily. Just copy between
sourceSlice: srcBaseLayer + layIdx // one slice of the 2D image and one plane of the 3D image at a time.
sourceLevel: srcLevel if ((_srcImage->getMTLTextureType() == MTLTextureType3D) == (_dstImage->getMTLTextureType() == MTLTextureType3D)) {
sourceOrigin: srcOrigin [mtlBlitEnc copyFromTexture: srcMTLTex
sourceSize: srcSize sourceSlice: srcBaseLayer + layIdx
toTexture: dstMTLTex sourceLevel: srcLevel
destinationSlice: dstBaseLayer + layIdx sourceOrigin: srcOrigin
destinationLevel: dstLevel sourceSize: srcSize
destinationOrigin: dstOrigin]; toTexture: dstMTLTex
destinationSlice: dstBaseLayer + layIdx
destinationLevel: dstLevel
destinationOrigin: dstOrigin];
} else if (_srcImage->getMTLTextureType() == MTLTextureType3D) {
[mtlBlitEnc copyFromTexture: srcMTLTex
sourceSlice: srcBaseLayer
sourceLevel: srcLevel
sourceOrigin: MTLOriginMake(srcOrigin.x, srcOrigin.y, srcOrigin.z + layIdx)
sourceSize: srcSize
toTexture: dstMTLTex
destinationSlice: dstBaseLayer + layIdx
destinationLevel: dstLevel
destinationOrigin: dstOrigin];
} else {
assert(_dstImage->getMTLTextureType() == MTLTextureType3D);
[mtlBlitEnc copyFromTexture: srcMTLTex
sourceSlice: srcBaseLayer + layIdx
sourceLevel: srcLevel
sourceOrigin: srcOrigin
sourceSize: srcSize
toTexture: dstMTLTex
destinationSlice: dstBaseLayer
destinationLevel: dstLevel
destinationOrigin: MTLOriginMake(dstOrigin.x, dstOrigin.y, dstOrigin.z + layIdx)];
}
} }
} }
} }