Skip to content

Commit

Permalink
fix crash with metal (#3899)
Browse files Browse the repository at this point in the history
* swapchain texture sync acquire/relase

* mtl swapchain sync & spv null protection

* temp memoryless strategy
  • Loading branch information
hana-alice committed Sep 18, 2021
1 parent b2a6448 commit ad746b1
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 22 deletions.
2 changes: 1 addition & 1 deletion native/cocos/renderer/gfx-base/SPIRVUtils.cpp
Expand Up @@ -197,7 +197,7 @@ void SPIRVUtils::compressInputLocations(gfx::AttributeList& attributes) {
newLocations.assign(attributes.size(), UINT_MAX);

for (auto& id : ids) {
if (id.opcode == SpvOpVariable && id.storageClass == SpvStorageClassInput) {
if (id.opcode == SpvOpVariable && id.storageClass == SpvStorageClassInput && id.pLocation) {
uint32_t oldLocation = *id.pLocation;

// update locations in SPIRV
Expand Down
25 changes: 16 additions & 9 deletions native/cocos/renderer/gfx-metal/MTLDevice.mm
Expand Up @@ -212,23 +212,30 @@ of this software and associated engine source code (the "Software"), a limited,
//hold this pointer before update _currentFrameIndex
_currentBufferPoolId = _currentFrameIndex;
_currentFrameIndex = (_currentFrameIndex + 1) % MAX_FRAMES_IN_FLIGHT;

std::vector<id<CAMetalDrawable>> releaseQ;
for (auto* swapchain: _swapchains) {
auto drawable = swapchain->currentDrawable();
if(drawable) {
releaseQ.push_back([drawable retain]);
}
swapchain->release();
}

// NSWindow-related(: drawable) should be udpated in main thread.
dispatch_async(dispatch_get_main_queue(), ^{
id<MTLCommandBuffer> cmdBuffer = [queue->gpuQueueObj()->mtlCommandQueue commandBufferWithUnretainedReferences];

[cmdBuffer enqueue];

for (CCMTLSwapchain* swapchain: _swapchains) {
if (swapchain->currentDrawable()) {
id<CAMetalDrawable> drawable = swapchain->currentDrawable();
[cmdBuffer presentDrawable:drawable];
swapchain->release();
}
[cmdBuffer addCompletedHandler:^(id<MTLCommandBuffer> commandBuffer) {
onPresentCompleted();
}];
for (auto drawable: releaseQ) {
[cmdBuffer presentDrawable:drawable];
[drawable release];
}

[cmdBuffer addCompletedHandler:^(id<MTLCommandBuffer> commandBuffer) {
onPresentCompleted();
}];

[cmdBuffer commit];
});
Expand Down
17 changes: 15 additions & 2 deletions native/cocos/renderer/gfx-metal/MTLRenderPass.mm
Expand Up @@ -29,6 +29,7 @@ of this software and associated engine source code (the "Software"), a limited,
#include "MTLRenderPass.h"
#include "MTLUtils.h"
#include "MTLTexture.h"
#include "MTLSwapchain.h"

namespace cc {
namespace gfx {
Expand Down Expand Up @@ -77,7 +78,13 @@ of this software and associated engine source code (the "Software"), a limited,
return;
}

id<MTLTexture> texture = cctex->getMTLTexture();
id<MTLTexture> texture = nil;
if(cctex->swapChain()) {
auto* swapchain = static_cast<CCMTLSwapchain*>(cctex->swapChain());
texture = swapchain->colorTexture()->getMTLTexture();
} else {
texture = cctex->getMTLTexture();
}

_mtlRenderPassDescriptor.colorAttachments[slot].texture = texture;
_mtlRenderPassDescriptor.colorAttachments[slot].level = level;
Expand All @@ -90,7 +97,13 @@ of this software and associated engine source code (the "Software"), a limited,
return;
}

id<MTLTexture> texture = cctex->getMTLTexture();
id<MTLTexture> texture = nil;
if(cctex->swapChain()) {
auto* swapchain = static_cast<CCMTLSwapchain*>(cctex->swapChain());
texture = swapchain->depthStencilTexture()->getMTLTexture();
} else {
texture = cctex->getMTLTexture();
}

_mtlRenderPassDescriptor.depthAttachment.texture = texture;
_mtlRenderPassDescriptor.depthAttachment.level = level;
Expand Down
2 changes: 1 addition & 1 deletion native/cocos/renderer/gfx-metal/MTLShader.mm
Expand Up @@ -82,7 +82,7 @@ of this software and associated engine source code (the "Software"), a limited,
CC_SAFE_DELETE(_gpuShader);

std::function<void(void)> destroyFunc = [=]() {
if(specFragFuncs.count > 0) {
if([specFragFuncs count]) {
for (NSString* key in [specFragFuncs allKeys]) {
[[specFragFuncs valueForKey:key] release];
}
Expand Down
10 changes: 3 additions & 7 deletions native/cocos/renderer/gfx-metal/MTLSwapchain.mm
Expand Up @@ -149,23 +149,19 @@ of this software and associated engine source code (the "Software"), a limited,
}

id<CAMetalDrawable> CCMTLSwapchain::currentDrawable() {
if(!_gpuSwapchainObj->currentDrawable) {
_gpuSwapchainObj->currentDrawable = [[_gpuSwapchainObj->mtlLayer nextDrawable] retain];
static_cast<CCMTLTexture*>(_colorTexture)->update();
}
return _gpuSwapchainObj->currentDrawable;
}

void CCMTLSwapchain::release() {
[_gpuSwapchainObj->currentDrawable release];
_gpuSwapchainObj->currentDrawable = nil;
static_cast<CCMTLTexture*>(_colorTexture)->update();
}

void CCMTLSwapchain::acquire() {
// hang on here if next drawable not available
while(!currentDrawable()) {
;
while(!_gpuSwapchainObj->currentDrawable) {
_gpuSwapchainObj->currentDrawable = [_gpuSwapchainObj->mtlLayer nextDrawable] ;
static_cast<CCMTLTexture*>(_colorTexture)->update();
}
}

Expand Down
5 changes: 3 additions & 2 deletions native/cocos/renderer/gfx-metal/MTLTexture.mm
Expand Up @@ -130,7 +130,8 @@ of this software and associated engine source code (the "Software"), a limited,

void CCMTLTexture::update() {
if(_swapchain) {
_mtlTexture = [static_cast<CCMTLSwapchain*>(_swapchain)->gpuSwapChainObj()->currentDrawable texture];
id<CAMetalDrawable> drawable = static_cast<CCMTLSwapchain*>(_swapchain)->currentDrawable();
_mtlTexture = drawable ? [drawable texture] : nil;
}
}

Expand Down Expand Up @@ -174,7 +175,7 @@ of this software and associated engine source code (the "Software"), a limited,
descriptor.mipmapLevelCount = _info.levelCount;
descriptor.arrayLength = _info.type == TextureType::CUBE ? 1 : _info.layerCount;

if(hasAllFlags(TextureUsage::COLOR_ATTACHMENT | TextureUsage::DEPTH_STENCIL_ATTACHMENT | TextureUsage::INPUT_ATTACHMENT, _info.usage) && mu::isImageBlockSupported()) {
if(hasAllFlags(TextureUsage::COLOR_ATTACHMENT | TextureUsage::INPUT_ATTACHMENT, _info.usage) && mu::isImageBlockSupported()) {
//xcode OS version warning
if (@available(macOS 11.0, *)) {
descriptor.storageMode = MTLStorageModeMemoryless;
Expand Down

0 comments on commit ad746b1

Please sign in to comment.