Merge pull request #1062 from cdavis5e/layered-resolve

MVKCmdResolveImage: Use layered rendering where possible.
This commit is contained in:
Bill Hollings 2020-09-23 12:36:56 -04:00 committed by GitHub
commit cf3379fea9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 27 additions and 15 deletions

View File

@ -125,8 +125,8 @@ typedef MVKCmdBlitImage<4> MVKCmdBlitImageMulti;
/** Describes Metal texture resolve parameters. */
typedef struct {
VkImageSubresource srcSubresource;
VkImageSubresource dstSubresource;
VkImageSubresourceLayers srcSubresource;
VkImageSubresourceLayers dstSubresource;
} MVKMetalResolveSlice;
/**

View File

@ -541,8 +541,13 @@ void MVKCmdResolveImage<N>::encode(MVKCommandEncoder* cmdEncoder) {
VkImageBlit expansionRegions[vkIRCnt];
VkImageCopy copyRegions[vkIRCnt];
// If we can do layered rendering to a multisample texture, I can resolve all the layers at once.
uint32_t layerCnt = 0;
for (VkImageResolve& vkIR : _vkImageResolves) { layerCnt += vkIR.dstSubresource.layerCount; }
if (cmdEncoder->getDevice()->_pMetalFeatures->multisampleLayeredRendering) {
layerCnt = (uint32_t)_vkImageResolves.size();
} else {
for (VkImageResolve& vkIR : _vkImageResolves) { layerCnt += vkIR.dstSubresource.layerCount; }
}
MVKMetalResolveSlice mtlResolveSlices[layerCnt];
uint32_t expCnt = 0;
@ -589,16 +594,20 @@ void MVKCmdResolveImage<N>::encode(MVKCommandEncoder* cmdEncoder) {
// Adds a resolve slice struct for each destination layer in the resolve region.
// Note that the source subresource for this is that of the SOURCE image if we're doing a
// direct resolve, but that of the DESTINATION if we need a temporary transfer image.
uint32_t layCnt = vkIR.dstSubresource.layerCount;
for (uint32_t layIdx = 0; layIdx < layCnt; layIdx++) {
MVKMetalResolveSlice& rslvSlice = mtlResolveSlices[sliceCnt++];
rslvSlice.dstSubresource.aspectMask = vkIR.dstSubresource.aspectMask;
rslvSlice.dstSubresource.mipLevel = vkIR.dstSubresource.mipLevel;
rslvSlice.dstSubresource.arrayLayer = vkIR.dstSubresource.baseArrayLayer + layIdx;
rslvSlice.srcSubresource.aspectMask = needXfrImage ? vkIR.dstSubresource.aspectMask : vkIR.srcSubresource.aspectMask;
rslvSlice.srcSubresource.mipLevel = needXfrImage ? vkIR.dstSubresource.mipLevel : vkIR.srcSubresource.mipLevel;
rslvSlice.srcSubresource.arrayLayer = needXfrImage ? vkIR.dstSubresource.baseArrayLayer : vkIR.srcSubresource.baseArrayLayer;
rslvSlice.srcSubresource.arrayLayer += layIdx;
mtlResolveSlices[sliceCnt].dstSubresource = vkIR.dstSubresource;
mtlResolveSlices[sliceCnt].srcSubresource = needXfrImage ? vkIR.dstSubresource : vkIR.srcSubresource;
if (cmdEncoder->getDevice()->_pMetalFeatures->multisampleLayeredRendering) {
sliceCnt++;
} else {
uint32_t layCnt = vkIR.dstSubresource.layerCount;
mtlResolveSlices[sliceCnt].dstSubresource.layerCount = 1;
mtlResolveSlices[sliceCnt].srcSubresource.layerCount = 1;
for (uint32_t layIdx = 0; layIdx < layCnt; layIdx++) {
MVKMetalResolveSlice& rslvSlice = mtlResolveSlices[sliceCnt++];
rslvSlice = mtlResolveSlices[sliceCnt - 2];
rslvSlice.dstSubresource.baseArrayLayer++;
rslvSlice.srcSubresource.baseArrayLayer++;
}
}
}
@ -649,9 +658,12 @@ void MVKCmdResolveImage<N>::encode(MVKCommandEncoder* cmdEncoder) {
mtlColorAttDesc.texture = xfrImage->getMTLTexture(srcPlaneIndex);
mtlColorAttDesc.resolveTexture = _dstImage->getMTLTexture(dstPlaneIndex);
mtlColorAttDesc.level = rslvSlice.srcSubresource.mipLevel;
mtlColorAttDesc.slice = rslvSlice.srcSubresource.arrayLayer;
mtlColorAttDesc.slice = rslvSlice.srcSubresource.baseArrayLayer;
mtlColorAttDesc.resolveLevel = rslvSlice.dstSubresource.mipLevel;
mtlColorAttDesc.resolveSlice = rslvSlice.dstSubresource.arrayLayer;
mtlColorAttDesc.resolveSlice = rslvSlice.dstSubresource.baseArrayLayer;
if (rslvSlice.dstSubresource.layerCount > 1) {
mtlRPD.renderTargetArrayLengthMVK = rslvSlice.dstSubresource.layerCount;
}
id<MTLRenderCommandEncoder> mtlRendEnc = [cmdEncoder->_mtlCmdBuffer renderCommandEncoderWithDescriptor: mtlRPD];
setLabelIfNotNil(mtlRendEnc, mvkMTLRenderCommandEncoderLabel(kMVKCommandUseResolveImage));