我目前正在追踪我的Metal应用程序中的一些视觉弹出,并且相信这是因为我直接绘制到帧缓冲区,而不是后台缓冲区
// this is when I've finished passing commands to the render buffer and issue the draw command. I believe this sends all the images directly to the framebuffer instead of using a backbuffer
[renderEncoder endEncoding];
[mtlCommandBuffer presentDrawable:frameDrawable];
[mtlCommandBuffer commit];
[mtlCommandBuffer release];
//[frameDrawable present]; // This line isn't needed (and I believe is performed by presentDrawable
之后的几个谷歌,我还没有找到金属中的后缓冲器的任何文档。我知道我可以自己滚动,但我不相信金属不支持后缓冲。
以下是我如何设置CAMetalLayer对象的代码片段。
+ (id)layerClass
{
return [CAMetalLayer class];
}
- (void)initCommon
{
self.opaque = YES;
self.backgroundColor = nil;
...
}
-(id <CAMetalDrawable>)getMetalLayer
{
id <CAMetalDrawable> frameDrawable;
while (!frameDrawable && !frameDrawable.texture)
{
frameDrawable = [self->_metalLayer nextDrawable];
}
return frameDrawable;
}
我可以在CAMetalLayer对象上启用后备缓冲区,还是需要自己滚动?
答案 0 :(得分:7)
我假设 back-buffer ,你的意思是渲染的渲染缓冲区,而正在显示相应的前缓冲区?
在Metal中,概念由您从CAMetalLayer
提取的drawable提供。 CAMetalLayer
实例维护一个小的drawables池(通常为3),每次调用nextDrawable
时从池中检索其中一个,并在调用{{1}后将其返回池中并且一旦渲染完成(可能需要一段时间,因为GPU从CPU异步运行)。
实际上,在每个帧循环中,您可以通过调用presentDrawable
来获取后台缓冲区,并通过调用使其有资格成为前台缓冲区 nextDrawable
并提交presentDrawable:
。
由于池中只有3个drawable,因此您必须自己管理此生命周期,方法是在调用MTLCommandBuffer
时添加适当的CPU资源同步,并在渲染时获得回调。完成(根据nextDrawable
回调设置)。
通常,您使用MTLCommandBuffer addCompletedHandler:
:
dispatch_semaphore_t
然后在调用_resource_semaphore = dispatch_semaphore_create(3);
之前添加以下内容:
nextDrawable
这在你的dispatch_semaphore_wait(_resource_semaphore, DISPATCH_TIME_FOREVER);
回调处理程序中:
addCompletedHandler:
查看Apple的一些简单的Metal示例应用程序,了解这一点。 Apple的文档在这方面没有太多。