OpenGL's two-pass rendering system uses the MRT shader, which is associated with 2 tex1 and tex2 framebuffer textures. The purpose of the mrt pass is to compute the overload in the scene and display it as an assembly. I use framebuffer textures to convey the result.
It also has a working ssbo buffer, which is quite large (and uses a fixed screen resolution), and takes a lot of time to link, but I can use it to create atomicAdds. What I'm trying to accomplish is to replace this with imageAtomicAdd operations with uiimage2D, as with mrt passes.
The problem is that the result of imageAtomicAdd is always zero, and I expect it to grow, just like atomAdd does at this point.
#version 440 core layout(early_fragment_tests) in; // this works fine layout (location = 0) out vec4 tex1; layout (location = 1) out vec4 tex2; // this works fine layout(std430, binding = 3) buffer ssbo_data { uint v[1024*768]; }; // this does not work at all. uniform volatile layout(r32ui) uimage2D imgCounter; out vec4 frag_colour; void main () { ivec2 coords = ivec2(gl_FragCoord.xy); uint addValue = 1u; uint countOverdraw1 = atomicAdd(v[coords.x + coords.y * 1024], 1u); uint countOverdraw2 = imageAtomicAdd(imgCounter, ivec2(0,0), 1u); memoryBarrier(); // supports 256 levels of overdraw.. float overdrawDepth = 256.0; vec3 c1 = vec3(float(countOverdraw1+1)/overdrawDepth ,0,1); vec3 c2 = vec3(float(countOverdraw2+1)/overdrawDepth ,0,1); tex1 = vec4(c1,1); tex2 = vec4(c2,1); frag_colour = vec4(1,1,1,1); }
From the khronos atomic operations website I understand that ..
Atomic operations with any texel that is outside the bounds of the bound image will return 0 and will do nothing.
.. but the ivec2 (0,0) coordinate would be good within the texture size (1024 x 768).
Perhaps the texture is set incorrectly? This is how I create uiimage2D (compiled from a pipeline thread):
EDIT: I am updating the code as suggested by Nicol Bolas: texture parameters are set instead of sampler parameters
char data[1024*768*4]; glGenTextures(1, &m_Handle); m_Target = GL_TEXTURE_2D; glActiveTexture(GL_TEXTURE0+6); glBindTexture(m_Target,m_Handle); // updated : a sampler object was bound to the texture, but is now removed glTexParameteri(m_Target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // updated glTexParameteri(m_Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // updated glTexParameteri(m_Target, GL_TEXTURE_WRAP_R, GL_REPEAT); // updated glTexParameteri(m_Target, GL_TEXTURE_WRAP_S, GL_REPEAT); // updated glTexParameteri(m_Target, GL_TEXTURE_WRAP_T, GL_REPEAT); // updated glTexImage2D(m_Target, 0, R32UI, 1024, 768, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, data);
If I run it through gDEBugger GL, I see that “Texture data is unavailable at this time”, and while the texture parameters of “Texture 4” are filled and fixed, none of the “Texture parameters” and “Texture parameters” are shown level 0 parameters (N / A). The debugger trap at this point throws a number of problems that do not appear outside of gDEBugger. Here are the first few:
GL_INVALID_OPERATION error generated. The required buffer is missing. GL_INVALID_ENUM error generated. <pname> requires feature(s) disabled in the current profile. GL_INVALID_OPERATION error generated. <index> exceeds the maximum number of supported texture units. GL_INVALID_ENUM error generated. or require feature(s) disabled in the current profile. GL_INVALID_OPERATION error generated. Can't mix integer and non-integer data ...
I explicitly force the GL 4.4 or GL4.4 kernel profile, so I'm a little puzzled, which could be a problem with the missing required buffer. Maybe this mistakenly sees imgCounter as part of the MRT configuration for the framebuffer?