我写了一个小的曲面细分程序。我可以写入 SSBO(使用 RenderDoc 检查输出),但在同一个着色器 (TCS) 中立即读取数据似乎不起作用。如果我直接设置镶嵌级别,我可以看到我的代码有效:
在 Tessellation Control 着色器的主要部分:
gl_TessLevelInner[0] = 1;
gl_TessLevelOuter[0] = 1;
gl_TessLevelOuter[1] = 2;
gl_TessLevelOuter[2] = 4;
但是通过 SSBO 内存,它不起作用。显示为空白,就像 0 被放置在 gl_TessLevelInner 和 gl_TessLevelOuter 输出中。
这是 TCS 中的 SSBO:
struct SSBO_Data {
float Inside; // Inside Tessellation factor
float Edges[3]; // Outside Tessellation factor
};
layout(std430, binding=2) volatile buffer Tiling {
SSBO_Data Tiles[];
};
在 Tessellation Control 着色器的主要部分
Tiles[0].Inside = 1;
Tiles[0].Edges[0] = 1;
Tiles[0].Edges[1] = 2;
Tiles[0].Edges[2] = 4;
gl_TessLevelInner[0] = Tiles[0].Inside;
gl_TessLevelOuter[0] = Tiles[0].Edges[0];
gl_TessLevelOuter[1] = Tiles[0].Edges[1];
gl_TessLevelOuter[2] = Tiles[0].Edges[2];
在 C++ 中,我使用 nVidia 的 ShaderBuffer 类来创建一个包含几千个图块的数组并将数据传输到 SSBO。我使用 RenderDoc 确认了正确的数据存储在 SSBO 中。
是否可以使用 SSBO 在同一个着色器中进行写入和读取?
答案 0 :(得分:1)
barrier();
,但也没有帮助。这不会对您的用例有用,您实际需要的是 glMemoryBarrierBuffer()
。
答案 1 :(得分:1)
从单个着色器实例写入任何不连贯的内存位置(SSBO 或图像加载/存储),然后在同一阶段从同一位置读取,如果且仅当:
#2 保持即使所有实例都写入相同的值。违反 #2 会产生竞争条件(同样,无论写入的值如何),即 UB。