【问题标题】:Performance gain of glColorMask()/glDepthMask() on modern hardware?glColorMask()/glDepthMask() 在现代硬件上的性能提升?
【发布时间】:2017-11-16 10:23:48
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

    标签: opengl depth-buffer


    【解决方案1】:

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

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

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

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

    也许在您的情况下,您的应用程序对 GPU 或 CPU 的压力不足以使这种更改变得重要。但总的来说,更改写掩码比玩 FBO 更好。

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

    您是在同时更改其他状态,还是您唯一感兴趣的状态?

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

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

    同时,如果您真的足够在意性能以使这类事情变得重要,那么您应该进行应用程序测试。这应该发生在您实现此功能之后,并且跨越所有感兴趣的硬件。而且您的代码应该足够灵活,可以根据需要轻松地从一个切换到另一个。

    【讨论】:

    • 能否请您详细说明为什么 FBO 状态更改是“OpenGL 中最重量级的操作之一”?
    • @lisyarus:“为什么”本质上是无关紧要的。这是一个well understood fact of OpenGL performance development。您无法更改其性能特征。您所能做的就是在算法允许的范围内尽量避免 FBO 更改。
    猜你喜欢
    • 2013-08-18
    • 2015-10-24
    • 1970-01-01
    • 1970-01-01
    • 2015-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多