Metal: Added swap chain support. Manual merge from PR #1563.

This commit is contained in:
Branimir Karadžić 2018-11-28 15:19:45 -08:00
parent 610d503d97
commit 2b919c1ec4
2 changed files with 264 additions and 172 deletions

View File

@ -888,6 +888,35 @@ namespace bgfx { namespace mtl
uint8_t m_numMips;
};
struct FrameBufferMtl;
struct SwapChainMtl
{
SwapChainMtl()
: m_metalLayer(nil)
, m_drawable(nil)
, m_backBufferColorMSAA()
, m_backBufferDepth()
, m_backBufferStencil()
, m_maxAnisotropy(0)
{
}
~SwapChainMtl();
void init(void* _nwh);
void resize(FrameBufferMtl &_frameBuffer, uint32_t _width, uint32_t _height, uint32_t _flags);
id<CAMetalDrawable> currentDrawable();
CAMetalLayer* m_metalLayer;
id <CAMetalDrawable> m_drawable;
Texture m_backBufferColorMSAA;
Texture m_backBufferDepth;
Texture m_backBufferStencil;
uint32_t m_maxAnisotropy;
};
struct FrameBufferMtl
{
FrameBufferMtl()
@ -910,6 +939,7 @@ namespace bgfx { namespace mtl
void postReset();
uint16_t destroy();
SwapChainMtl* m_swapChain;
uint32_t m_width;
uint32_t m_height;
uint16_t m_denseIdx;

View File

@ -46,7 +46,6 @@ Known issues(driver problems??):
- finish savescreenshot with screenshotbegin/end
- support multiple windows: 22-windows
- multithreading with multiple commandbuffer
- compute and drawindirect: 24-nbody (needs compute shaders)
@ -382,18 +381,18 @@ namespace bgfx { namespace mtl
#define SHADER_FUNCTION_NAME ("xlatMtlMain")
#define SHADER_UNIFORM_NAME ("_mtl_u")
struct RendererContextMtl;
static RendererContextMtl* s_renderMtl;
struct RendererContextMtl : public RendererContextI
{
RendererContextMtl()
: m_metalLayer(NULL)
, m_backBufferPixelFormatHash(0)
, m_maxAnisotropy(1)
, m_bufferIndex(0)
, m_numWindows(1)
: m_bufferIndex(0)
, m_numWindows(0)
, m_rtMsaa(false)
, m_capture(NULL)
, m_captureSize(0)
, m_drawable(NULL)
, m_saveScreenshot(false)
{
}
@ -411,67 +410,21 @@ namespace bgfx { namespace mtl
bx::memSet(m_uniforms, 0, sizeof(m_uniforms) );
bx::memSet(&m_resolution, 0, sizeof(m_resolution) );
if (NULL != NSClassFromString(@"MTKView") )
m_device = (id<MTLDevice>)g_platformData.context;
if (NULL == m_device)
{
MTKView *view = (MTKView *)g_platformData.nwh;
if (NULL != view && [view isKindOfClass:NSClassFromString(@"MTKView")])
{
m_metalLayer = (CAMetalLayer *)view.layer;
}
m_device = MTLCreateSystemDefaultDevice();
}
if (NULL != NSClassFromString(@"CAMetalLayer") )
{
if (NULL == m_metalLayer)
#if BX_PLATFORM_IOS
{
CAMetalLayer* metalLayer = (CAMetalLayer*)g_platformData.nwh;
if (NULL == metalLayer
|| ![metalLayer isKindOfClass:NSClassFromString(@"CAMetalLayer")])
{
BX_WARN(NULL != m_device, "Unable to create Metal device. Please set platform data window to a CAMetalLayer");
return false;
}
m_metalLayer = metalLayer;
}
#elif BX_PLATFORM_OSX
{
NSObject* nvh = (NSObject*)g_platformData.nwh;
if ([nvh isKindOfClass:[CAMetalLayer class]])
{
CAMetalLayer* metalLayer = (CAMetalLayer*)g_platformData.nwh;
m_metalLayer = metalLayer;
}
else
{
NSWindow* nsWindow = (NSWindow*)g_platformData.nwh;
[nsWindow.contentView setWantsLayer:YES];
m_metalLayer = [CAMetalLayer layer];
[nsWindow.contentView setLayer:m_metalLayer];
}
}
#endif // BX_PLATFORM_*
m_device = (id<MTLDevice>)g_platformData.context;
if (NULL == m_device)
{
m_device = MTLCreateSystemDefaultDevice();
}
}
if (NULL == m_device
|| NULL == m_metalLayer)
if (NULL == m_device)
{
BX_WARN(NULL != m_device, "Unable to create Metal device.");
return false;
}
retain(m_device);
m_metalLayer.device = m_device;
m_metalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;
m_metalLayer.magnificationFilter = kCAFilterNearest;
createFrameBuffer(m_fbh, g_platformData.nwh, 0, 0, TextureFormat::Unknown, TextureFormat::UnknownDepth);
m_cmd.init(m_device);
BGFX_FATAL(NULL != m_cmd.m_commandQueue, Fatal::UnableToInitialize, "Unable to create Metal device.");
@ -530,7 +483,7 @@ namespace bgfx { namespace mtl
release(lib);
reset(m_renderPipelineDescriptor);
m_renderPipelineDescriptor.colorAttachments[0].pixelFormat = m_metalLayer.pixelFormat;
m_renderPipelineDescriptor.colorAttachments[0].pixelFormat = m_mainFrameBuffer.m_swapChain->m_metalLayer.pixelFormat;
m_renderPipelineDescriptor.vertexFunction = m_screenshotBlitProgram.m_vsh->m_function;
m_renderPipelineDescriptor.fragmentFunction = m_screenshotBlitProgram.m_fsh->m_function;
m_screenshotBlitRenderPipelineState = m_device.newRenderPipelineStateWithDescriptor(m_renderPipelineDescriptor);
@ -550,8 +503,8 @@ namespace bgfx { namespace mtl
| BGFX_CAPS_OCCLUSION_QUERY
| BGFX_CAPS_ALPHA_TO_COVERAGE
| BGFX_CAPS_TEXTURE_2D_ARRAY
| BGFX_CAPS_SWAP_CHAIN
);
if (BX_ENABLED(BX_PLATFORM_IOS) )
{
if (iOSVersionEqualOrGreater("9.0.0") )
@ -730,8 +683,11 @@ namespace bgfx { namespace mtl
MTL_RELEASE(m_textureDescriptor);
MTL_RELEASE(m_samplerDescriptor);
MTL_RELEASE(m_backBufferDepth);
MTL_RELEASE(m_backBufferStencil);
MTL_RELEASE(m_mainFrameBuffer.m_swapChain->m_backBufferDepth);
if (BX_ENABLED(BX_PLATFORM_IOS) )
{
MTL_RELEASE(m_mainFrameBuffer.m_swapChain->m_backBufferStencil);
}
for (uint8_t i=0; i < MTL_MAX_FRAMES_IN_FLIGHT; ++i)
{
@ -927,7 +883,15 @@ namespace bgfx { namespace mtl
{
uint16_t denseIdx = m_numWindows++;
m_windows[denseIdx] = _handle;
m_frameBuffers[_handle.idx].create(denseIdx, _nwh, _width, _height, _format, _depthFormat);
if (!isValid(_handle))
{
m_mainFrameBuffer.create(denseIdx, _nwh, _width, _height, _format, _depthFormat);
}
else
{
m_frameBuffers[_handle.idx].create(denseIdx, _nwh, _width, _height, _format, _depthFormat);
m_frameBuffers[_handle.idx].m_swapChain->resize(m_frameBuffers[_handle.idx], _width, _height, 0);//_resolution.reset);
}
}
void destroyFrameBuffer(FrameBufferHandle _handle) override
@ -1176,10 +1140,15 @@ namespace bgfx { namespace mtl
return;
}
if (NULL != m_drawable)
for (uint32_t ii = 0, num = m_numWindows; ii < num; ++ii)
{
m_commandBuffer.presentDrawable(m_drawable);
MTL_RELEASE(m_drawable);
FrameBufferMtl& frameBuffer = ii == 0 ? m_mainFrameBuffer : m_frameBuffers[m_windows[ii].idx];
if (NULL != frameBuffer.m_swapChain &&
frameBuffer.m_swapChain->m_drawable)
{
m_commandBuffer.presentDrawable(frameBuffer.m_swapChain->m_drawable);
MTL_RELEASE(frameBuffer.m_swapChain->m_drawable);
}
}
m_cmd.kick(true);
@ -1188,7 +1157,7 @@ namespace bgfx { namespace mtl
void updateResolution(const Resolution& _resolution)
{
m_maxAnisotropy = !!(_resolution.reset & BGFX_RESET_MAXANISOTROPY)
m_mainFrameBuffer.m_swapChain->m_maxAnisotropy = !!(_resolution.reset & BGFX_RESET_MAXANISOTROPY)
? 16
: 1
;
@ -1203,90 +1172,12 @@ namespace bgfx { namespace mtl
|| m_resolution.height != _resolution.height
|| (m_resolution.reset&maskFlags) != (_resolution.reset&maskFlags) )
{
int sampleCount = s_msaa[(_resolution.reset&BGFX_RESET_MSAA_MASK)>>BGFX_RESET_MSAA_SHIFT];
MTLPixelFormat prevMetalLayerPixelFormat = m_metalLayer.pixelFormat;
#if BX_PLATFORM_OSX > 101300
m_metalLayer.displaySyncEnabled = 0 != (_resolution.reset&BGFX_RESET_VSYNC);
#endif // BX_PLATFORM_OSX > 101300
m_metalLayer.drawableSize = CGSizeMake(_resolution.width, _resolution.height);
m_metalLayer.pixelFormat = (m_resolution.reset & BGFX_RESET_SRGB_BACKBUFFER)
? MTLPixelFormatBGRA8Unorm_sRGB
: MTLPixelFormatBGRA8Unorm
;
MTLPixelFormat prevMetalLayerPixelFormat = m_mainFrameBuffer.m_swapChain->m_metalLayer.pixelFormat;
m_resolution = _resolution;
m_resolution.reset &= ~BGFX_RESET_INTERNAL_FORCE;
m_textureDescriptor.textureType = sampleCount > 1 ? MTLTextureType2DMultisample : MTLTextureType2D;
if (m_hasPixelFormatDepth32Float_Stencil8)
{
m_textureDescriptor.pixelFormat = MTLPixelFormatDepth32Float_Stencil8;
}
else
{
m_textureDescriptor.pixelFormat = MTLPixelFormatDepth32Float;
}
m_textureDescriptor.width = _resolution.width;
m_textureDescriptor.height = _resolution.height;
m_textureDescriptor.depth = 1;
m_textureDescriptor.mipmapLevelCount = 1;
m_textureDescriptor.sampleCount = sampleCount;
m_textureDescriptor.arrayLength = 1;
if (m_iOS9Runtime
|| m_macOS11Runtime)
{
m_textureDescriptor.cpuCacheMode = MTLCPUCacheModeDefaultCache;
m_textureDescriptor.storageMode = MTLStorageModePrivate;
m_textureDescriptor.usage = MTLTextureUsageRenderTarget;
}
if (NULL != m_backBufferDepth)
{
release(m_backBufferDepth);
}
m_backBufferDepth = m_device.newTextureWithDescriptor(m_textureDescriptor);
if (NULL != m_backBufferStencil)
{
release(m_backBufferStencil);
}
if (m_hasPixelFormatDepth32Float_Stencil8)
{
m_backBufferStencil = m_backBufferDepth;
retain(m_backBufferStencil);
}
else
{
m_textureDescriptor.pixelFormat = MTLPixelFormatStencil8;
m_backBufferStencil = m_device.newTextureWithDescriptor(m_textureDescriptor);
}
if (sampleCount > 1)
{
if (NULL != m_backBufferColorMSAA)
{
release(m_backBufferColorMSAA);
}
m_textureDescriptor.pixelFormat = m_metalLayer.pixelFormat;
m_backBufferColorMSAA = m_device.newTextureWithDescriptor(m_textureDescriptor);
}
bx::HashMurmur2A murmur;
murmur.begin();
murmur.add(1);
murmur.add( (uint32_t)m_metalLayer.pixelFormat);
murmur.add( (uint32_t)m_backBufferDepth.pixelFormat() );
murmur.add( (uint32_t)m_backBufferStencil.pixelFormat() );
murmur.add( (uint32_t)sampleCount);
m_backBufferPixelFormatHash = murmur.end();
m_mainFrameBuffer.m_swapChain->resize(m_mainFrameBuffer, _resolution.width, _resolution.height, _resolution.reset);
for (uint32_t ii = 0; ii < BX_COUNTOF(m_frameBuffers); ++ii)
{
@ -1298,11 +1189,11 @@ namespace bgfx { namespace mtl
m_textVideoMem.resize(false, _resolution.width, _resolution.height);
m_textVideoMem.clear();
if (prevMetalLayerPixelFormat != m_metalLayer.pixelFormat)
if (prevMetalLayerPixelFormat != m_mainFrameBuffer.m_swapChain->m_metalLayer.pixelFormat)
{
MTL_RELEASE(m_screenshotBlitRenderPipelineState)
reset(m_renderPipelineDescriptor);
m_renderPipelineDescriptor.colorAttachments[0].pixelFormat = m_metalLayer.pixelFormat;
m_renderPipelineDescriptor.colorAttachments[0].pixelFormat = m_mainFrameBuffer.m_swapChain->m_metalLayer.pixelFormat;
m_renderPipelineDescriptor.vertexFunction = m_screenshotBlitProgram.m_vsh->m_function;
m_renderPipelineDescriptor.fragmentFunction = m_screenshotBlitProgram.m_fsh->m_function;
m_screenshotBlitRenderPipelineState = m_device.newRenderPipelineStateWithDescriptor(m_renderPipelineDescriptor);
@ -1647,26 +1538,30 @@ namespace bgfx { namespace mtl
void setFrameBuffer(RenderPassDescriptor renderPassDescriptor, FrameBufferHandle _fbh, bool _msaa = true)
{
if (!isValid(_fbh) )
if (!isValid(_fbh) || m_frameBuffers[_fbh.idx].m_swapChain)
{
SwapChainMtl* swapChain =
!isValid(_fbh) ?
m_mainFrameBuffer.m_swapChain :
m_frameBuffers[_fbh.idx].m_swapChain;
if (NULL != m_backBufferColorMSAA)
{
renderPassDescriptor.colorAttachments[0].texture = m_backBufferColorMSAA;
renderPassDescriptor.colorAttachments[0].texture = swapChain->m_backBufferColorMSAA;
renderPassDescriptor.colorAttachments[0].resolveTexture = NULL != m_screenshotTarget
? m_screenshotTarget.m_obj
: currentDrawable().texture
: swapChain->currentDrawable().texture
;
}
else
{
renderPassDescriptor.colorAttachments[0].texture = NULL != m_screenshotTarget
? m_screenshotTarget.m_obj
: currentDrawable().texture
: swapChain->currentDrawable().texture
;
}
renderPassDescriptor.depthAttachment.texture = m_backBufferDepth;
renderPassDescriptor.stencilAttachment.texture = m_backBufferStencil;
renderPassDescriptor.depthAttachment.texture = swapChain->m_backBufferDepth;
renderPassDescriptor.stencilAttachment.texture = swapChain->m_backBufferStencil;
}
else
{
@ -1845,15 +1740,16 @@ namespace bgfx { namespace mtl
uint32_t frameBufferAttachment = 1;
if (!isValid(_fbh) )
if (!isValid(_fbh) || s_renderMtl->m_frameBuffers[_fbh.idx].m_swapChain)
{
pd.sampleCount = NULL != m_backBufferColorMSAA
? m_backBufferColorMSAA.sampleCount()
: 1
;
pd.colorAttachments[0].pixelFormat = currentDrawable().texture.pixelFormat;
pd.depthAttachmentPixelFormat = m_backBufferDepth.m_obj.pixelFormat;
pd.stencilAttachmentPixelFormat = m_backBufferStencil.m_obj.pixelFormat;
SwapChainMtl* swapChain =
!isValid(_fbh) ?
s_renderMtl->m_mainFrameBuffer.m_swapChain :
s_renderMtl->m_frameBuffers[_fbh.idx].m_swapChain;
pd.sampleCount = NULL != swapChain->m_backBufferColorMSAA ? swapChain->m_backBufferColorMSAA.sampleCount() : 1;
pd.colorAttachments[0].pixelFormat = swapChain->currentDrawable().texture.pixelFormat;
pd.depthAttachmentPixelFormat = swapChain->m_backBufferDepth.m_obj.pixelFormat;
pd.stencilAttachmentPixelFormat = swapChain->m_backBufferStencil.m_obj.pixelFormat;
}
else
{
@ -2195,7 +2091,7 @@ namespace bgfx { namespace mtl
m_samplerDescriptor.lodMinClamp = 0;
m_samplerDescriptor.lodMaxClamp = FLT_MAX;
m_samplerDescriptor.normalizedCoordinates = TRUE;
m_samplerDescriptor.maxAnisotropy = (0 != (_flags & (BGFX_SAMPLER_MIN_ANISOTROPIC|BGFX_SAMPLER_MAG_ANISOTROPIC) ) ) ? m_maxAnisotropy : 1;
m_samplerDescriptor.maxAnisotropy = (0 != (_flags & (BGFX_SAMPLER_MIN_ANISOTROPIC|BGFX_SAMPLER_MAG_ANISOTROPIC) ) ) ? m_mainFrameBuffer.m_swapChain->m_maxAnisotropy : 1;
if (m_macOS11Runtime
|| [m_device supportsFeatureSet:(MTLFeatureSet)4 /*MTLFeatureSet_iOS_GPUFamily3_v1*/])
@ -2277,6 +2173,7 @@ namespace bgfx { namespace mtl
ShaderMtl m_shaders[BGFX_CONFIG_MAX_SHADERS];
ProgramMtl m_program[BGFX_CONFIG_MAX_PROGRAMS];
TextureMtl m_textures[BGFX_CONFIG_MAX_TEXTURES];
FrameBufferMtl m_mainFrameBuffer;
FrameBufferMtl m_frameBuffers[BGFX_CONFIG_MAX_FRAME_BUFFERS];
VertexDecl m_vertexDecls[BGFX_CONFIG_MAX_VERTEX_DECLS];
UniformRegistry m_uniformReg;
@ -2320,8 +2217,6 @@ namespace bgfx { namespace mtl
FrameBufferHandle m_renderCommandEncoderFrameBufferHandle;
};
static RendererContextMtl* s_renderMtl;
RendererContextI* rendererCreate(const Init& _init)
{
s_renderMtl = BX_NEW(g_allocator, RendererContextMtl);
@ -2903,8 +2798,163 @@ namespace bgfx { namespace mtl
}
}
SwapChainMtl::~SwapChainMtl()
{
MTL_RELEASE(m_backBufferDepth);
if (BX_ENABLED(BX_PLATFORM_IOS) )
{
MTL_RELEASE(m_backBufferStencil);
}
}
void SwapChainMtl::init(void* _nwh)
{
if (NULL != NSClassFromString(@"MTKView") )
{
MTKView *view = (MTKView *)_nwh;
if (NULL != view && [view isKindOfClass:NSClassFromString(@"MTKView")])
{
m_metalLayer = (CAMetalLayer *)view.layer;
}
}
if (NULL != NSClassFromString(@"CAMetalLayer") )
{
if (NULL == m_metalLayer)
#if BX_PLATFORM_IOS
{
CAMetalLayer* metalLayer = (CAMetalLayer*)_nwh;
if (NULL == metalLayer
|| ![metalLayer isKindOfClass:NSClassFromString(@"CAMetalLayer")])
{
BX_WARN(NULL != metalLayer, "Unable to create Metal device. Please set platform data window to a CAMetalLayer");
return;
}
m_metalLayer = metalLayer;
}
#elif BX_PLATFORM_OSX
{
NSObject* nvh = (NSObject*)_nwh;
if ([nvh isKindOfClass:[CAMetalLayer class]])
{
CAMetalLayer* metalLayer = (CAMetalLayer*)_nwh;
m_metalLayer = metalLayer;
}
else
{
NSWindow* nsWindow = (NSWindow*)_nwh;
[nsWindow.contentView setWantsLayer:YES];
m_metalLayer = [CAMetalLayer layer];
[nsWindow.contentView setLayer:m_metalLayer];
}
}
#endif // BX_PLATFORM_*
}
if (NULL == m_metalLayer)
{
BX_WARN(NULL != s_renderMtl->m_device, "Unable to create Metal device.");
return;
}
m_metalLayer.device = s_renderMtl->m_device;
m_metalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;
m_metalLayer.magnificationFilter = kCAFilterNearest;
}
void SwapChainMtl::resize(FrameBufferMtl &_frameBuffer, uint32_t _width, uint32_t _height, uint32_t _flags)
{
int sampleCount = s_msaa[(_flags&BGFX_RESET_MSAA_MASK)>>BGFX_RESET_MSAA_SHIFT];
#if BX_PLATFORM_OSX > 101300
m_metalLayer.displaySyncEnabled = 0 != (_flags&BGFX_RESET_VSYNC);
#endif // BX_PLATFORM_OSX > 101300
m_metalLayer.drawableSize = CGSizeMake(_width, _height);
m_metalLayer.pixelFormat = (_flags & BGFX_RESET_SRGB_BACKBUFFER)
? MTLPixelFormatBGRA8Unorm_sRGB
: MTLPixelFormatBGRA8Unorm
;
TextureDescriptor desc = s_renderMtl->m_textureDescriptor;
desc.textureType = sampleCount > 1 ? MTLTextureType2DMultisample : MTLTextureType2D;
if (s_renderMtl->m_hasPixelFormatDepth32Float_Stencil8)
desc.pixelFormat = MTLPixelFormatDepth32Float_Stencil8;
else
desc.pixelFormat = MTLPixelFormatDepth32Float;
desc.width = _width;
desc.height = _height;
desc.depth = 1;
desc.mipmapLevelCount = 1;
desc.sampleCount = sampleCount;
desc.arrayLength = 1;
if ( s_renderMtl->m_iOS9Runtime || s_renderMtl->m_macOS11Runtime )
{
desc.cpuCacheMode = MTLCPUCacheModeDefaultCache;
desc.storageMode = MTLStorageModePrivate;
desc.usage = MTLTextureUsageRenderTarget;
}
if (NULL != m_backBufferDepth)
{
release(m_backBufferDepth);
}
m_backBufferDepth = s_renderMtl->m_device.newTextureWithDescriptor(desc);
if (NULL != m_backBufferStencil)
{
release(m_backBufferStencil);
}
if (s_renderMtl->m_hasPixelFormatDepth32Float_Stencil8)
{
m_backBufferStencil = m_backBufferDepth;
retain(m_backBufferStencil);
}
else
{
desc.pixelFormat = MTLPixelFormatStencil8;
m_backBufferStencil = s_renderMtl->m_device.newTextureWithDescriptor(desc);
}
if ( sampleCount > 1 )
{
if (NULL != m_backBufferColorMSAA)
{
release(m_backBufferColorMSAA);
}
desc.pixelFormat = m_metalLayer.pixelFormat;
m_backBufferColorMSAA = s_renderMtl->m_device.newTextureWithDescriptor(desc);
}
bx::HashMurmur2A murmur;
murmur.begin();
murmur.add(1);
murmur.add((uint32_t)m_metalLayer.pixelFormat);
murmur.add((uint32_t)m_backBufferDepth.pixelFormat());
murmur.add((uint32_t)m_backBufferStencil.pixelFormat());
murmur.add((uint32_t)sampleCount);
_frameBuffer.m_pixelFormatHash = murmur.end();
}
id<CAMetalDrawable> SwapChainMtl::currentDrawable()
{
if (m_drawable == nil)
{
m_drawable = m_metalLayer.nextDrawable;
retain(m_drawable); // keep alive to be useable at 'flip'
}
return m_drawable;
}
void FrameBufferMtl::create(uint8_t _num, const Attachment* _attachment)
{
m_swapChain = NULL;
m_denseIdx = UINT16_MAX;
m_num = 0;
m_width = 0;
@ -2968,7 +3018,13 @@ namespace bgfx { namespace mtl
void FrameBufferMtl::create(uint16_t _denseIdx, void* _nwh, uint32_t _width, uint32_t _height, TextureFormat::Enum _format, TextureFormat::Enum _depthFormat)
{
BX_UNUSED(_denseIdx, _nwh, _width, _height, _format, _depthFormat);
BX_UNUSED(_format, _depthFormat);
m_swapChain = BX_NEW(g_allocator, SwapChainMtl);
m_width = _width;
m_height = _height;
m_denseIdx = _denseIdx;
m_swapChain->init(_nwh);
}
void FrameBufferMtl::postReset()
@ -2977,6 +3033,12 @@ namespace bgfx { namespace mtl
uint16_t FrameBufferMtl::destroy()
{
if (NULL != m_swapChain)
{
BX_DELETE(g_allocator, m_swapChain);
m_swapChain = NULL;
}
m_num = 0;
m_depthHandle.idx = kInvalidHandle;
@ -3307,7 +3369,7 @@ namespace bgfx { namespace mtl
if (NULL == m_screenshotTarget)
{
m_textureDescriptor.textureType = MTLTextureType2D;
m_textureDescriptor.pixelFormat = m_metalLayer.pixelFormat;
m_textureDescriptor.pixelFormat = m_mainFrameBuffer.m_swapChain->m_metalLayer.pixelFormat;
m_textureDescriptor.width = m_resolution.width;
m_textureDescriptor.height = m_resolution.height;
m_textureDescriptor.depth = 1;
@ -3556,7 +3618,7 @@ namespace bgfx { namespace mtl
? MTLLoadActionClear
: MTLLoadActionLoad
;
depthAttachment.storeAction = NULL != m_backBufferColorMSAA
depthAttachment.storeAction = NULL != m_mainFrameBuffer.m_swapChain->m_backBufferColorMSAA
? MTLStoreActionDontCare
: MTLStoreActionStore
;
@ -3570,7 +3632,7 @@ namespace bgfx { namespace mtl
? MTLLoadActionClear
: MTLLoadActionLoad
;
stencilAttachment.storeAction = NULL != m_backBufferColorMSAA
stencilAttachment.storeAction = NULL != m_mainFrameBuffer.m_swapChain->m_backBufferColorMSAA
? MTLStoreActionDontCare
: MTLStoreActionStore
;
@ -4212,7 +4274,7 @@ namespace bgfx { namespace mtl
if (m_screenshotTarget)
{
RenderPassDescriptor renderPassDescriptor = newRenderPassDescriptor();
renderPassDescriptor.colorAttachments[0].texture = currentDrawable().texture;
renderPassDescriptor.colorAttachments[0].texture = m_mainFrameBuffer.m_swapChain->currentDrawable().texture;
renderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore;
rce = m_commandBuffer.renderCommandEncoderWithDescriptor(renderPassDescriptor);