Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to deallocate a MTLBuffer and MTLTexture

I know how to create a MTLBuffer and or MTLTexture but how do I free the GPU memory for these resources when they are no longer needed?

like image 201
gloo Avatar asked Aug 26 '16 04:08

gloo


2 Answers

MTLBuffer and MTLTexture are Objective-C objects and thus reference counted. If you are using automatic reference counting in an Objective-C project or using Metal via Swift, simply ensuring you no longer hold references to the buffer or texture will release any associated hardware resources.

let texture: MTLTexture? = device.newTexture(with: descriptor)
texture = nil // <- resources will be released

One can confirm this by stepping through the associated assembly when assigning nil to texture, which first leads us to [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    

...and through [MTLToolsObject dealloc]

MetalTools`-[MTLToolsObject dealloc]:
    0x100ac6c7a <+0>:   push   rbp
    0x100ac6c7b <+1>:   mov    rbp, rsp
    0x100ac6c7e <+4>:   push   r14
    ...

...and through the GeForceMTLDriver

GeForceMTLDriver`___lldb_unnamed_symbol1095$$GeForceMTLDriver:
->  0x7fffd2e57b14 <+0>:  push   rbp
    0x7fffd2e57b15 <+1>:  mov    rbp, rsp

All the way, releasing any resources through the various dealloc methods.

like image 52
Stuart Carnie Avatar answered Oct 31 '22 20:10

Stuart Carnie


If you are using automatic reference counting, as the accepted answer said, just set nil.

But if you are using manual reference counting, Metal has two kinds of dynamically allocated resources(MTLBuffer && MTLTexture) and you can release them in below way.

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];

About setPurgeableState, you can refer to the link(https://developer.apple.com/documentation/metal/mtlresource/1515898-setpurgeablestate)

like image 37
冯剑龙 Avatar answered Oct 31 '22 19:10

冯剑龙