【问题标题】:How to properly set the hint of an SSBO to read and write from both shaders and cpu?如何正确设置 SSBO 的提示以从着色器和 cpu 读取和写入?
【发布时间】:2018-11-04 09:34:43
【问题描述】:

我有一个特殊的 SSBO,只有一个 int,我需要从着色器和 cpu 读取和写入。

我创建的SSBO如下:

glGenBuffers(1, &ssbo);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
glObjectLabel(GL_BUFFER, ssbo, -1, ("\"SSBO\""));
GLint zero = 0;
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GLint), &zero, GL_STATIC_COPY);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, ssbo);

当我渲染时,glDbeugMessage 返回:

OpenGL Event Notification:
Source: GL_DEBUG_SOURCE_API
Type: GL_DEBUG_TYPE_PERFORMANCE
ID: Unkown error code: 131186
Severity: GL_DEBUG_SEVERITY_MEDIUM
Message:
Buffer performance warning: Buffer object "SSBO" (bound to
GL_SHADER_STORAGE_BUFFER, and GL_SHADER_STORAGE_BUFFER (3), usage hint is
GL_DYNAMIC_DRAW) is being copied/moved from VIDEO memory to HOST memory. 

此警告中最重要的是它表示 SSBO 有提示:GL_DYNAMIC_DRAW 尽管我尝试将提示设置为:GL_STATIC_COPY

所以我的问题是,我应该使用什么提示来防止 OpenGL 警告,以及如何实际强制使用该提示?

【问题讨论】:

    标签: c++ opengl runtime-error buffer gpu


    【解决方案1】:

    我有一个特殊的 SSBO,只有一个 int,我需要从着色器和 cpu 读取和写入。

    GL_STATIC_COPY 不是这个意思。这意味着您只会分配它并写入一次(静态部分)。这意味着它只能通过 GPU 操作读取/写入; CPU 永远不会直接操作数据(COPY 部分)。

    所以你使用了错误的提示。

    我应该使用什么提示来防止 OpenGL 警告

    如果你关心这类事情,那么你需要使用immutable buffer allocation,而不是旧式的glBufferData 东西。 “提示”不是绑定;这就是为什么它们是“提示”而不是“要求”。

    glBufferStorage 提出要求。具体来说,它对您使用内存提出了要求。如果您没有声明可以映射缓冲区以供读取,那么您不能将其映射以供读取。如果您不声明可以通过glBufferSubData 写信,那么您不能。永远。

    选择您需要的最低使用要求,并在这些限制范围内工作。

    【讨论】:

    • 是否有已知的特定方法可以更快/更好地从 CPU 和 GPU 读取和写入缓冲区?
    • 图形性能通常基于对确切您正在做什么的深入了解。一般规则可以在这里和那里使用,但真正的性能改进需要了解的不仅仅是本地问题。您如何读取 CPU 上的缓冲区?你怎么写?涉及多长时间和多少数据?相对于 GPU 修改,这些读/写何时发生?等等。没有这些细节,就无话可说。
    • 我每帧都在读写它(不能少)。我正在通过片段着色器上的原子添加写入 SSBO 中的单个 int(我正在计算当前调用中的片段数量)我不确定你所说的 GPU 修改是什么意思,并且需要尽快读取缓冲区因为最后一个片段结束了片段着色器上的计算(在调用 glMemoryBarrier() 之后)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-22
    • 1970-01-01
    • 1970-01-01
    • 2017-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多