openglgraphics3dglslssbo

Can SSBO be read/write within the same shader?


I wrote a small tessellation program. I can write to a SSBO (checked output using RenderDoc) but reading the data back right away in the same shader (TCS) does not seem to work. If I set the tessellation levels directly, I can see that my code works:

In the main of the Tessellation Control shader:

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

But going through the SSBO memory, it does not work. The display is blank like 0 were placed in the gl_TessLevelInner & gl_TessLevelOuter output.

Here is the SSBO in the TCS:

   struct SSBO_Data {
      float Inside;   // Inside Tessellation factor
      float Edges[3]; // Outside Tessellation factor
   };

   layout(std430, binding=2) volatile buffer Tiling {
      SSBO_Data Tiles[];
   };

In the main of the Tessellation Control shader

   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];

In C++, I use the ShaderBuffer class from nVidia to create an array of a few thousand tiles and transfer data to the SSBO. I confirmed that the correct data is stored in the SSBO using RenderDoc.

Is it possible to use SSBO for writing and reading back within the same shader?


Solution

  • Writing to any incoherent memory location (SSBO or image load/store)from a single shader instance and then reading from the same location works in the same stage if and only if:

    1. You are reading it in the same instance that did the writing.
    2. Only that instance wrote to the memory being read.

    #2 holds even if all instances are writing the same value. Violating #2 creates a race condition (again, regardless of the value written), which is UB.