Fix non-MSAA resolve operations for Metal

This commit is contained in:
Jack Andersen 2018-01-11 15:28:33 -10:00
parent 1a48dd9c42
commit cc6c872747
1 changed files with 89 additions and 26 deletions

View File

@ -525,6 +525,8 @@ class MetalTextureR : public GraphicsDataNode<ITextureR>
for (int i=0 ; i<m_colorBindCount ; ++i) for (int i=0 ; i<m_colorBindCount ; ++i)
{ {
m_colorBindTex[i] = [ctx->m_dev newTextureWithDescriptor:desc]; m_colorBindTex[i] = [ctx->m_dev newTextureWithDescriptor:desc];
if (m_samples > 1)
{
m_blitColor[i] = [MTLRenderPassDescriptor renderPassDescriptor]; m_blitColor[i] = [MTLRenderPassDescriptor renderPassDescriptor];
m_blitColor[i].colorAttachments[0].texture = m_colorTex; m_blitColor[i].colorAttachments[0].texture = m_colorTex;
m_blitColor[i].colorAttachments[0].loadAction = MTLLoadActionLoad; m_blitColor[i].colorAttachments[0].loadAction = MTLLoadActionLoad;
@ -532,6 +534,7 @@ class MetalTextureR : public GraphicsDataNode<ITextureR>
m_blitColor[i].colorAttachments[0].resolveTexture = m_colorBindTex[i]; m_blitColor[i].colorAttachments[0].resolveTexture = m_colorBindTex[i];
} }
} }
}
if (m_depthBindCount) if (m_depthBindCount)
{ {
@ -539,6 +542,8 @@ class MetalTextureR : public GraphicsDataNode<ITextureR>
for (int i=0 ; i<m_depthBindCount ; ++i) for (int i=0 ; i<m_depthBindCount ; ++i)
{ {
m_depthBindTex[i] = [ctx->m_dev newTextureWithDescriptor:desc]; m_depthBindTex[i] = [ctx->m_dev newTextureWithDescriptor:desc];
if (m_samples > 1)
{
m_blitDepth[i] = [MTLRenderPassDescriptor renderPassDescriptor]; m_blitDepth[i] = [MTLRenderPassDescriptor renderPassDescriptor];
m_blitDepth[i].depthAttachment.texture = m_colorTex; m_blitDepth[i].depthAttachment.texture = m_colorTex;
m_blitDepth[i].depthAttachment.loadAction = MTLLoadActionLoad; m_blitDepth[i].depthAttachment.loadAction = MTLLoadActionLoad;
@ -546,6 +551,7 @@ class MetalTextureR : public GraphicsDataNode<ITextureR>
m_blitDepth[i].depthAttachment.resolveTexture = m_depthBindTex[i]; m_blitDepth[i].depthAttachment.resolveTexture = m_depthBindTex[i];
} }
} }
}
{ {
m_passDesc = [MTLRenderPassDescriptor renderPassDescriptor]; m_passDesc = [MTLRenderPassDescriptor renderPassDescriptor];
@ -1213,10 +1219,50 @@ struct MetalCommandQueue : IGraphicsCommandQueue
@autoreleasepool @autoreleasepool
{ {
[m_enc endEncoding]; [m_enc endEncoding];
if (tex->samples() > 1)
{
if (color && tex->m_colorBindTex[bindIdx]) if (color && tex->m_colorBindTex[bindIdx])
[[m_cmdBuf renderCommandEncoderWithDescriptor:tex->m_blitColor[bindIdx]] endEncoding]; [[m_cmdBuf renderCommandEncoderWithDescriptor:tex->m_blitColor[bindIdx]] endEncoding];
if (depth && tex->m_depthBindTex[bindIdx]) if (depth && tex->m_depthBindTex[bindIdx])
[[m_cmdBuf renderCommandEncoderWithDescriptor:tex->m_blitDepth[bindIdx]] endEncoding]; [[m_cmdBuf renderCommandEncoderWithDescriptor:tex->m_blitDepth[bindIdx]] endEncoding];
}
else
{
SWindowRect intersectRect = rect.intersect(SWindowRect(0, 0, tex->m_width, tex->m_height));
NSUInteger y = tlOrigin ? intersectRect.location[1] : int(tex->m_height) -
intersectRect.location[1] - intersectRect.size[1];
MTLOrigin origin = {NSUInteger(intersectRect.location[0]), y, 0};
id<MTLBlitCommandEncoder> blitEnc = [m_cmdBuf blitCommandEncoder];
if (color && tex->m_colorBindTex[bindIdx])
{
[blitEnc copyFromTexture:tex->m_colorTex
sourceSlice:0
sourceLevel:0
sourceOrigin:origin
sourceSize:MTLSizeMake(intersectRect.size[0], intersectRect.size[1], 1)
toTexture:tex->m_colorBindTex[bindIdx]
destinationSlice:0
destinationLevel:0
destinationOrigin:origin];
}
if (depth && tex->m_depthBindTex[bindIdx])
{
[blitEnc copyFromTexture:tex->m_depthTex
sourceSlice:0
sourceLevel:0
sourceOrigin:origin
sourceSize:MTLSizeMake(intersectRect.size[0], intersectRect.size[1], 1)
toTexture:tex->m_depthBindTex[bindIdx]
destinationSlice:0
destinationLevel:0
destinationOrigin:origin];
}
[blitEnc endEncoding];
}
m_enc = [m_cmdBuf renderCommandEncoderWithDescriptor:clearDepth ? tex->m_clearDepthPassDesc : tex->m_passDesc]; m_enc = [m_cmdBuf renderCommandEncoderWithDescriptor:clearDepth ? tex->m_clearDepthPassDesc : tex->m_passDesc];
[m_enc setFrontFacingWinding:MTLWindingCounterClockwise]; [m_enc setFrontFacingWinding:MTLWindingCounterClockwise];
@ -1308,6 +1354,11 @@ struct MetalCommandQueue : IGraphicsCommandQueue
{ {
MetalTextureR* src = m_needsDisplay.cast<MetalTextureR>(); MetalTextureR* src = m_needsDisplay.cast<MetalTextureR>();
id<MTLTexture> dest = drawable.texture; id<MTLTexture> dest = drawable.texture;
if (src->m_colorTex.width == dest.width &&
src->m_colorTex.height == dest.height)
{
if (src->samples() > 1)
{
uintptr_t key = uintptr_t(src->m_colorTex) ^ uintptr_t(dest); uintptr_t key = uintptr_t(src->m_colorTex) ^ uintptr_t(dest);
auto passSearch = m_resolvePasses.find(key); auto passSearch = m_resolvePasses.find(key);
if (passSearch == m_resolvePasses.end()) if (passSearch == m_resolvePasses.end())
@ -1319,10 +1370,22 @@ struct MetalCommandQueue : IGraphicsCommandQueue
desc.colorAttachments[0].resolveTexture = dest; desc.colorAttachments[0].resolveTexture = dest;
passSearch = m_resolvePasses.insert(std::make_pair(key, desc)).first; passSearch = m_resolvePasses.insert(std::make_pair(key, desc)).first;
} }
if (src->m_colorTex.width == dest.width &&
src->m_colorTex.height == dest.height)
{
[[m_cmdBuf renderCommandEncoderWithDescriptor:passSearch->second] endEncoding]; [[m_cmdBuf renderCommandEncoderWithDescriptor:passSearch->second] endEncoding];
}
else
{
id<MTLBlitCommandEncoder> blitEnc = [m_cmdBuf blitCommandEncoder];
[blitEnc copyFromTexture:src->m_colorTex
sourceSlice:0
sourceLevel:0
sourceOrigin:MTLOriginMake(0, 0, 0)
sourceSize:MTLSizeMake(dest.width, dest.height, 1)
toTexture:dest
destinationSlice:0
destinationLevel:0
destinationOrigin:MTLOriginMake(0, 0, 0)];
[blitEnc endEncoding];
}
[m_cmdBuf presentDrawable:drawable]; [m_cmdBuf presentDrawable:drawable];
} }
} }