I have a GLSL fragment shader that should render pixels into a texture, and blend the value at each pixel with the one that has been in the texture before.
Instead of using GL blending operations, it needs to have as variables in the shader, both the existing value at that pixel that is in the texture (dst), and the new value that should be blended on top of it (src).
I have a fragment shader that is like this:
#version 460 core
layout(location=0) in float src;
layout(binding=0, r32f) uniform image2D valuesImage;
layout(location=0) out vec4 outputValue;
void main() {
ivec2 pixelCoord = ivec2(gl_FragCoord.xy);
float dst = imageLoad(valuesImage, pixelCoord).r;
float result = f(dst, src); // do some blending operation
outValue = vec4(result, 0.0, 0.0, 0.0);
}
And it is called like:
// bind texture to framebuffer
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0 };
glDrawBuffers(1, &drawBuffers);
// also bind texture to image
glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32F);
//....
for each frame {
glDrawArrays(GL_TRIANGLES, 0, numVertices);
glTextureBarrier();
}
According to https://www.khronos.org/opengl/wiki/Memory_Model "Framebuffer objects", reading from the image that is being rendered into would not work (such reads are incoherent).
However later it says (bottom of "Texture barrier") that since the ARB_texture_barrier extension, it would work, when there is only a single image read operation from the same pixel that is being rendered into (through the framebuffer), and it is followed by a texture barrier call.
Is this correct that it would be well-defined when used as in this example? Also, would it still work, if GL_BLEND options is used on top of this, when OpenGL renders outValue into the texture?
ARB_texture_barrierseems to say that this is allowed (reading image and rendering to framebuffer, within the same draw call):Specifically, the values of rendered fragments are undefined if any shader stage fetches texels and the same texels are written via fragment shader outputs, even if the reads and writes are not in the same Draw call, unless any of the following exceptions apply: ... There is only a single read and write of each texel, and the read is in the fragment shader invocation that writes the same texel (e.g. using "texelFetch2D(sampler, ivec2(gl_FragCoord.xy), 0);").1. Render an object that reads from image, blends in the shader, and writes to image. 2. Call glTextureBarrier, if the next object overlaps with the first.