金属渲染产生奇怪的比赛条件

时间:2018-10-03 05:22:44

标签: grand-central-dispatch metal metalkit

我在Xcode 9.4.1中打开了线程清理器,现在我的旋转缓冲区(大小最大为2)收到了奇怪的竞争情况警告。我以为在这里正确使用信号灯可以消除此问题。我应该提到,该缓冲区来自另一个渲染编码的输出,该输出位于单独的“第一” MTKView中。我在第二个下游视图中通过dispatch_semaphore_create(1)初始化了一个信号灯。

在我提交的第一个MTKView中,我按如下方式抓取渲染的纹理,然后使用该下游视图的信号量将其排队到下游缓冲区中:

[commandBuffer presentDrawable:self.currentDrawable];
[commandBuffer commit];
//[commandBuffer waitUntilCompleted]; // (doesn't matter if this is in or out)
...
id obj = [self.renderedQueue firstObject];
for (MonitorMTKView *v in self.downstreamOutputs) {
   dispatch_semaphore_wait(v.bufferSemaphore,DISPATCH_TIME_FOREVER);
   [v.textureQueue addObject:inputTexture];
   if ([v.textureQueue count]>2)
      [v.textureQueue removeObjectAtIndex:0];
   dispatch_semaphore_signal(v.bufferSemaphore);
}

现在进入我的下游MTKView中的渲染循环。我提交了命令缓冲区,并有以下完成处理程序:

__block __weak __typeof__(self) weakSelf = self;
[commandBuffer addCompletedHandler:^(id<MTLCommandBuffer> buffer) {
   dispatch_semaphore_wait(weakSelf.bufferSemaphore, DISPATCH_TIME_FOREVER);
   id obj = [weakSelf.textureQueue firstObject];

**// thread sanitizer issue on this next line of code "Race on a library object detected" **
   [weakSelf.textureQueue removeObject:obj];

   dispatch_semaphore_signal(weakSelf.bufferSemaphore);
}


为什么围绕信号量保护的种族状况? 我在做错什么吗?。缓冲区本身不是基于GPU的,因此那里不会有干扰。

一种思路是对它进行三倍缓冲,但这并不能缓解问题,因此我不认为它会对GPU造成干扰。

1 个答案:

答案 0 :(得分:0)

Apple Metal文档指示您应该使用3个缓冲区,以避免填充缓冲区和传递给GPU之间的争用情况。