如何释放 MTLBuffer 和 MTLTexture
How to deallocate a MTLBuffer and MTLTexture
我知道如何创建 MTLBuffer 和/或 MTLTexture,但如何在不再需要这些资源时释放 GPU 内存?
MTLBuffer
和 MTLTexture
是 Objective-C 对象,因此引用计数。如果您在 Objective-C 项目中使用自动引用计数或通过 Swift 使用 Metal,只需确保您不再持有对缓冲区或纹理的引用即可释放任何相关的硬件资源。
let texture: MTLTexture? = device.newTexture(with: descriptor)
texture = nil // <- resources will be released
可以通过在将 nil
分配给 texture
时逐步执行相关程序集来确认这一点,这首先会导致我们 [MTLDebugTexture dealloc]
MetalTools`-[MTLDebugTexture dealloc]:
...
-> 0x100af569e <+34>: call 0x100af87ee ; symbol stub for: objc_msgSendSuper2
0x100af56a3 <+39>: add rsp, 0x10
0x100af56a7 <+43>: pop rbp
0x100af56a8 <+44>: ret
...并通过 [MTLToolsObject dealloc]
MetalTools`-[MTLToolsObject dealloc]:
0x100ac6c7a <+0>: push rbp
0x100ac6c7b <+1>: mov rbp, rsp
0x100ac6c7e <+4>: push r14
...
...并通过 GeForceMTLDriver
GeForceMTLDriver`___lldb_unnamed_symbol1095$$GeForceMTLDriver:
-> 0x7fffd2e57b14 <+0>: push rbp
0x7fffd2e57b15 <+1>: mov rbp, rsp
一直以来,通过各种dealloc
方法释放任何资源。
如果您正在使用自动引用计数,正如接受的答案所说,
只需设置为零。
但是如果你使用手动引用计数,Metal有两种动态分配的资源(MTLBuffer && MTLTexture),你可以释放
他们在下面的方式。
id<MTLDevice> m_Device = MTLCreateSystemDefaultDevice();
// allocate Buffer
NSUInteger BufferLength = 100;
id<MTLBuffer> m_Buffer = [m_Device newBufferWithLength:BufferLength options:0];
// allocate Texture
MTLTextureDescriptor *shadowTextureDesc = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat: MTLPixelFormatDepth32Float width: 1024 height: 1024 mipmapped: NO];
id<MTLTexture> m_Texture = [m_Device newTextureWithDescriptor:shadowTextureDesc];
// release Buffer
[m_Buffer setPurgeableState:MTLPurgeableStateEmpty];
[m_Buffer release];
// release Texture
[m_Texture setPurgeableState:MTLPurgeableStateEmpty];
[m_Texture release];
关于setPurgeableState,可以参考link(https://developer.apple.com/documentation/metal/mtlresource/1515898-setpurgeablestate)
我知道如何创建 MTLBuffer 和/或 MTLTexture,但如何在不再需要这些资源时释放 GPU 内存?
MTLBuffer
和 MTLTexture
是 Objective-C 对象,因此引用计数。如果您在 Objective-C 项目中使用自动引用计数或通过 Swift 使用 Metal,只需确保您不再持有对缓冲区或纹理的引用即可释放任何相关的硬件资源。
let texture: MTLTexture? = device.newTexture(with: descriptor)
texture = nil // <- resources will be released
可以通过在将 nil
分配给 texture
时逐步执行相关程序集来确认这一点,这首先会导致我们 [MTLDebugTexture dealloc]
MetalTools`-[MTLDebugTexture dealloc]:
...
-> 0x100af569e <+34>: call 0x100af87ee ; symbol stub for: objc_msgSendSuper2
0x100af56a3 <+39>: add rsp, 0x10
0x100af56a7 <+43>: pop rbp
0x100af56a8 <+44>: ret
...并通过 [MTLToolsObject dealloc]
MetalTools`-[MTLToolsObject dealloc]:
0x100ac6c7a <+0>: push rbp
0x100ac6c7b <+1>: mov rbp, rsp
0x100ac6c7e <+4>: push r14
...
...并通过 GeForceMTLDriver
GeForceMTLDriver`___lldb_unnamed_symbol1095$$GeForceMTLDriver:
-> 0x7fffd2e57b14 <+0>: push rbp
0x7fffd2e57b15 <+1>: mov rbp, rsp
一直以来,通过各种dealloc
方法释放任何资源。
如果您正在使用自动引用计数,正如接受的答案所说, 只需设置为零。
但是如果你使用手动引用计数,Metal有两种动态分配的资源(MTLBuffer && MTLTexture),你可以释放 他们在下面的方式。
id<MTLDevice> m_Device = MTLCreateSystemDefaultDevice();
// allocate Buffer
NSUInteger BufferLength = 100;
id<MTLBuffer> m_Buffer = [m_Device newBufferWithLength:BufferLength options:0];
// allocate Texture
MTLTextureDescriptor *shadowTextureDesc = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat: MTLPixelFormatDepth32Float width: 1024 height: 1024 mipmapped: NO];
id<MTLTexture> m_Texture = [m_Device newTextureWithDescriptor:shadowTextureDesc];
// release Buffer
[m_Buffer setPurgeableState:MTLPurgeableStateEmpty];
[m_Buffer release];
// release Texture
[m_Texture setPurgeableState:MTLPurgeableStateEmpty];
[m_Texture release];
关于setPurgeableState,可以参考link(https://developer.apple.com/documentation/metal/mtlresource/1515898-setpurgeablestate)