SSBO 可以在同一个着色器中 read/write 吗?

Can SSBO be read/write within the same shader?

我写了一个小的曲面细分程序。我可以写入 SSBO(使用 RenderDoc 检查输出),但在同一个着色器 (TCS) 中立即读回数据似乎不起作用。如果我直接设置曲面细分级别,我可以看到我的代码有效:

在曲面细分控制着色器的主体中:

 gl_TessLevelInner[0] = 1;
 gl_TessLevelOuter[0] = 1;
 gl_TessLevelOuter[1] = 2;
 gl_TessLevelOuter[2] = 4;

但是通过SSBO内存,是行不通的。显示是空白的,就像在 gl_TessLevelInner & gl_TessLevelOuter 输出中放置了 0。

这是 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 class 创建一个包含几千个图块的数组并将数据传输到 SSBO。我使用 RenderDoc 确认正确的数据存储在 SSBO 中。

是否可以在同一个着色器中使用 SSBO 进行写入和回读?

  • I also inserted a barrier(); between the writing and reading of the SSBO data and it did not help either.

这不会对您的用例有用,您真正需要的是 glMemoryBarrierBuffer()

从单个着色器实例写入任何不连贯的内存位置(SSBO 或图像 load/store)然后从同一位置读取在同一阶段工作如果且仅当:

  1. 您正在阅读它的与写作相同的实例
  2. 只有那个实例写入正在读取的内存。

#2 保持 即使 所有实例都写入相同的值。违反 #2 会产生竞争条件(同样,无论写入的值如何),即 UB。