#1 楼
因为OpenGL的基本基础使得不可能进行多CPU内核提交。OpenGL的核心是同步API。每个OpenGL命令的行为都像“立即执行”并立即完成一样。当然,提供了
glFlush
和glFinish
,因此实现可以具有一些命令的异步执行。但是这些本质上是OpenGL定义为同步的无花果叶。并从中读取。您可以执行所有这些操作,而不必考虑发出了两组命令之间可能有零重叠的事实。这是因为需要OpenGL实现来发布进行此工作所需的任何同步机制。作为用户,您可能完全不了解这一点。1因此,请考虑一下,如果您可以在一个线程中发布该渲染到纹理,而在另一线程中发布该纹理的渲染,将会发生什么情况? 。那到底怎么工作?您将需要某种方式说“在完成写入之前不要执行读取”。但是,由于这两组命令位于不同的线程上,因此您怎么说呢?
OpenGL没有这样做的机制。最接近的是某种形式的隔离同步。甚至那还需要“渲染到纹理”线程已经完成发送这些命令,因为
glFenceSync
发出了围栏实际围栏(您无法创建尚未提交的围栏)。这意味着“渲染到纹理”线程也可以发送“从纹理读取”命令。使OpenGL异步工作意味着需要对其内存模型进行大量调整。您必须添加许多命令,以使其他线程可以看到这些内容。为了允许线程A在线程B完成之前不执行其命令。您需要制作命令缓冲区并将该API的一流构造排队。依此类推。
您必须以与现有内存模型向后兼容的方式来执行此操作。除非您想再次进行另一个核心/兼容性拆分。
NV_command_list显示了尝试将此类内容构建到OpenGL中的挑战。他们迫使您使用ARB_bindless_texture。他们必须发明无绑定缓冲区,以便您可以提供顶点数组,UBO和SSBO。
即使那样,AMD甚至都无法实现。为什么?由于图像布局。 NVIDIA的硬件布局较少,可以自动处理过渡。 AMD的硬件需要显式控制布局。一旦打破了同步内存模型,纹理所在的布局的实现细节就变得非常重要。您必须对其进行控制。您必须在各种API中明确声明它,并且必须知道当以其他方式使用纹理时要对其进行更改。
这几乎也肯定是AMD不实现D3D11延迟上下文的原因。 。
或者您可以做Khronos所做的事情:创建一个自然可以处理所有这些东西的API。最终,干净的休息对每个人都是最好的。它允许我们抛弃OpenGL所具有的其他垃圾,以便我们可以拥有一个漂亮,干净的低级API。
1:虽然您可能会遗忘,但是如果您关心诸如性能之类的事情,显然也不应忽略。如果可能,您应该在渲染到纹理和从该纹理读取之间进行一些工作。这是OpenGL的默认同步API的最大问题之一:它使以慢速方式执行操作变得容易,因为API本身并不强迫您发出该同步。在Vulkan中,您不能不知道该同步。或者至少,并非没有您的代码调用UB。
评论
是的,CPU内核。我刚刚编辑了我的问题。谢谢您能对目前为止尝试或发现的内容更具体些吗?