glColorMask()/glDepthMask() 在现代硬件上的性能增益?

Ser*_*gey 3 opengl depth-buffer

在我的应用程序中,我有一些着色器,它们仅写入深度缓冲区,以便稍后将其用于阴影。另外,我还有一些其他着色器,它们渲染全屏四边形,其深度不会影响所有后续的绘制调用,因此它的深度值可能会被丢弃。

假设应用程序在现代硬件上运行(5 年前至今生产),如果我禁用glColorMask(all to GL_FALSE)阴影贴图着色器的颜色缓冲区写入 ( ) 和全屏四元着色器的深度缓冲区写入 ( 使用glDepthMask()),我是否会获得任何额外的性能?

换句话说,这些函数是否真的禁用了某些内存操作,或者它们只是更改了渲染管道这部分中固定按位操作逻辑中使用的一些掩码位?

关于测试同样的问题。如果我事先知道所有片段都会通过深度测试,禁用深度测试会提高性能吗?

我的 FPS 测量没有显示出任何显着差异,但在另一台机器上结果可能会有所不同。

最后,如果在禁用深度/颜色测试/写入的情况下渲染运行得更快,那么它的运行速度会快多少?这种性能提升不会被 gl 函数调用开销所抵消吗?

Nic*_*las 5

你的问题遗漏了一件非常重要的事情:你必须做点什么

每个片段都有颜色和深度值。即使你的 FS 没有产生值,那里仍然会有值。因此,每个生成的未丢弃的片段都会写入这些值,只要:

  1. 颜色通过 路由到颜色缓冲区glDrawBuffers
  2. FBO 附有适当的颜色/深度缓冲区。
  3. 颜色/深度写入掩码允许对其进行写入。

因此,如果您正在渲染并且不想写入其中一种颜色或写入深度缓冲区,则必须执行其中之一。更改 #1 或 #2 是 FBO 状态更改,这是您可以在 OpenGL 中执行的最重量级操作之一。因此,您的选择是更改 FBO 或更改写入掩码。后者始终是对性能更加友好的操作。

也许在您的情况下,您的应用程序对 GPU 或 CPU 的压力不足以使此类更改发挥作用。但总的来说,改变写掩码比使用 FBO 更好。

如果我事先知道所有片段都会通过深度测试,禁用深度测试会提高性能吗?

您是否同时更改其他状态,或者这是您唯一感兴趣的状态?

查看此类先验性能问题的一种好方法是查看 Vulkan 或 D3D12,看看它在API 中需要什么。改变任何管道状态都是一件大事。但改变两个状态并不比改变一个状态更重要。

因此,如果更改深度测试与更改其他状态(混合模式、着色器等)相关,那么它可能不会再造成任何伤害。

同时,如果您确实非常关心性能,因此这类事情很重要,那么您应该进行应用程序测试。这应该在您实施此操作之后以及所有感兴趣的硬件上发生。而且您的代码应该足够灵活,可以根据需要轻松地从一种代码切换到另一种代码。