使用金属缓冲区崩溃

时间:2017-10-27 11:31:27

标签: multithreading macos metal

我使用后台线程来创建Metal缓冲区:

var vertices:UnsafeMutablePointer<Float>?=nil
var indexes:UnsafeMutablePointer<UInt32>?=nil
var vertexCount: UInt32=UInt32()
var indexCount: UInt32=UInt32()

triangulatePoints(hull, &vertices, &indexes, &vertexCount, &indexCount)

defer {
    free(vertices)
    free(indexes)
}

if let vertexBuffer=device.makeBuffer(bytes: vertices!,
                                      length: Int(vertexCount)*MemoryLayout<Float>.size*3,
                                      options: .storageModeShared),
   let indexBuffer=device.makeBuffer(bytes: indexes!,
                                     length: Int(indexCount)*MemoryLayout<UInt32>.size,
                                     options: .storageModeShared) 
{
   metalObject=MetalObject(vertices: vertexBuffer, indices: indexBuffer)
}

MetalObject暂时存储在字典中,稍后在数组中累积,并返回数组。这发生在调度队列中(下面的调试堆栈跟踪中的编号#5):

CustomOperationQueue.sharedInstance.addSerialOperation {
    //This calls the device.makeBuffers() and stores them in a dictionary owned by the image
    image.constructMetalBuffers(withPrecision: precision, device: device)
    //The MetalObjects are accumulated in arrays. Sorted by their draw type, such as instanced or not. One array of each type.
    let metalLayer:MetalImageLayer=image.layerWithDelegate(device: device, delegate: self)

    OperationQueue.main.addOperation {
        //The MTKView delegate observes this property and triggers a redraw when it changes 
        self.metalLayer=metalLayer
    }

MetalObject是简单容器,也存储在其他容器中:

class MetalObject: NSObject {
    var vertexBuffer: MTLBuffer
    var indexBuffer: MTLBuffer

    init(vertices: MTLBuffer, indices:MTLBuffer) {
        vertexBuffer=vertices
        indexBuffer=indices
    }
}

class MetalImageLayer: NSObject {
    var layers=[MetalPolarityLayer]()
}

class MetalPolarityLayer: NSObject {
    var elements=[MetalObject]() //For general objects that need to be drawn piece by piece
    var regions=[MetalObject]() //For region objects that can be instanced
}

在调试模式下,我经常在行metalObject=MetalObject(vertices: vertexBuffer, indices: indexBuffer)上遇到EXC_BAD_ACCESS (code=1, address=0x40dedeadbec8)的崩溃。堆栈跟踪看起来像:

#0  0x000000010166a6e2 in swift_unknownRetain ()
#1  0x000000010005bf5f in StrokeLine.constructMetalBuffers(withPrecision:device:) at Image+Metal.swift:445
#2  0x000000010005c8b2 in @objc StrokeLine.constructMetalBuffers(withPrecision:device:) ()
#3  0x0000000100050b4d in Image.constructMetalBuffers(withPrecision:device:) at Image+Metal.swift:40
#4  0x0000000100051082 in @objc Image.constructMetalBuffers(withPrecision:device:) ()
#5  0x0000000100067eef in closure #1 in WindowLayer.observeValue(forKeyPath:of:change:context:) at WindowLayer.swift:181

从调试器中检查vertexBuffer,然后提供:po vertexBuffer error: Execution was interrupted, reason: EXC_BAD_ACCESS (code=1, address=0x2e7466697770).

另一方面,在发布模式下,我有时会崩溃

Crashed Thread:        0  Dispatch queue: com.apple.main-thread

Exception Type:        EXC_CRASH (SIGABRT)
Exception Codes:       0x0000000000000000, 0x0000000000000000
Exception Note:        EXC_CORPSE_NOTIFY

Application Specific Information:
abort() called

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   libsystem_kernel.dylib          0x00007fff60084fce __pthread_kill + 10
1   libsystem_pthread.dylib         0x00007fff601c2150 pthread_kill + 333
2   libsystem_c.dylib               0x00007fff5ffe132a abort + 127
3   com.apple.IOAccelerator         0x00007fff5279a1ea ioAccelResourceListAddNewGroupAndResource + 221
4   com.apple.IOAccelerator         0x00007fff52799d19 IOAccelResourceListAddResource + 304
5   com.apple.driver.AppleIntelKBLGraphicsMTLDriver 0x00007fff32aa02ef IGBufferMemory<31ul>::listId(unsigned int) + 85
6   com.apple.driver.AppleIntelKBLGraphicsMTLDriver 0x00007fff32aa654b ShaderBindingStage::updateUAVTable(unsigned int, unsigned int, bool) + 459
7   com.apple.driver.AppleIntelKBLGraphicsMTLDriver 0x00007fff32a9fe0d ShaderBindingStage::updateBindingTableData() + 1631
8   com.apple.driver.AppleIntelKBLGraphicsMTLDriver 0x00007fff32a9f70b ShaderBindingStage::writeTableIf() + 55
9   com.apple.driver.AppleIntelKBLGraphicsMTLDriver 0x00007fff32a9cc11 IGAccelRenderCommandEncoder::programPipeline(sPrimitiveData const&) + 4685
10  com.apple.driver.AppleIntelKBLGraphicsMTLDriver 0x00007fff32a9b7b4 IGAccelRenderCommandEncoder::drawIndexedPrimitives(MTLPrimitiveType, unsigned int, MTLIndexType, MTLIGAccelBuffer*, unsigned int, unsigned int, unsigned int, unsigned int) + 710
11  com.apple.driver.AppleIntelKBLGraphicsMTLDriver 0x00007fff32a9b40c -[MTLIGAccelRenderCommandEncoder drawIndexedPrimitives:indexCount:indexType:indexBuffer:indexBufferOffset:] + 324

没有关于可能导致崩溃的更多信息。

使用Instruments查找Zombies没有结果。

我该怎样去找出这里出了什么问题?

0 个答案:

没有答案