简体   繁体   中英

Memory leak when I use custom compute shaders in Metal

Im trying to apply the live camera filters through metal using the default MPSKernal filters given by apple and custom compute Shaders .

Im applying the custom filters on a collection view in a grid with the combination of default and the custom kernel functions.

It looks like in the app Clips.

在此处输入图片说明

But what I observed is that using the custom filters there is a lot of memory leaks compared to the default kernel functions given by apple.

I don't know what mistakes I made though if any.

Here is my custom compute shader.

kernel void customFunction1(

                       texture2d<float, access::read> inTexture [[texture(0)]],

                       texture2d<float, access::write> outTexture [[texture(1)]],

                       uint2 gid [[thread_position_in_grid]]){

const float4 colorAtPixel = inTexture.read(gid);
const float4 outputColor = float4(colorAtPixel.r, colorAtPixel.g, colorAtPixel.b, 1);

outTexture.write(outputColor, gid);

}

Regarding to my creating my pipeline and the dispatching through thread groups the code goes here

let blur = MPSImageGaussianBlur(device: device, sigma: 0)

    let threadsPerThreadgroup = MTLSizeMake(4, 4, 1)
    let threadgroupsPerGrid = MTLSizeMake(destinationTexture.width / threadsPerThreadgroup.width, destinationTexture.height / threadsPerThreadgroup.height, 1)

    let commandEncoder = commandBuffer.makeComputeCommandEncoder()
    commandEncoder.setComputePipelineState(pipelineState!)
    commandEncoder.setTexture(sourceTexture, at: 0)
    commandEncoder.setTexture(destinationTexture, at: 1)

    commandEncoder.dispatchThreadgroups(threadgroupsPerGrid, threadsPerThreadgroup: threadsPerThreadgroup)

    commandEncoder.endEncoding()

    autoreleasepool {
        let inPlaceTexture = UnsafeMutablePointer<MTLTexture>.allocate(capacity: 1)
        inPlaceTexture.initialize(to: destinationTexture)
        blur.encode(commandBuffer: commandBuffer, inPlaceTexture: inPlaceTexture, fallbackCopyAllocator: nil)
    }

The Pipeline state with the custom Shader is created like this.

        let defaultLibrary = device.newDefaultLibrary()

        let kernelFunction = defaultLibrary!.makeFunction(name: name)

        do {
            pipelineState = try device.makeComputePipelineState(function: kernelFunction!)
        } catch {
            fatalError("Unable to create pipeline state")
        }

And in instrumentation it shows there is a leak in some Malloc 16 bytes and in [Mtkview draw] method.

The screenshot is shown below.

在此处输入图片说明

I want help in finding where and how the issue is occurring from.

Thanks.

There's no reason to explicitly allocate an UnsafeMutablePointer to store the in-place texture parameter. Incidentally, that's the source of your leak: you allocate the pointer and then never deallocate it.

Use a local variable to pass the texture instead:

var inPlaceTexture = destinationTexture
blur.encode(commandBuffer: commandBuffer, inPlaceTexture: &inPlaceTexture, fallbackCopyAllocator: nil)

By the way, you're (eventually) going to have a bad time if you call the in-place encode method without providing a fallback allocator or checking the return value. In-place encoding will fail in certain situations, so you should provide a closure that allocates an appropriate texture in the event of failure.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM