I'm trying to implement a GLSL spinlock to be able to implement single-pass depth peeling. I'm having trouble because examples of locking texture use are scarce. I have to admit that I don't really know what I'm doing, here, so I describe probably more context than is necessary, just to be safe.
I wrote a fragment program which should do effectively nothing:
#version 420 core
//The lock texture holds either 0 or 1.
//0 means that the texture is available.
//1 means that the texture is locked.
layout(r32ui) coherent uniform uimage2D img2D_0; //locking texture
layout(RGBA32F) coherent uniform image2D img2D_1; //data texture (currently unused)
void main() {
ivec2 coord = ivec2(gl_FragCoord.xy);
//The loop's exchange function swaps out the old value with 1.
//If the locking texture was 0, 0 will be returned, terminating the loop;
//the locking texture will now contain 1, indicating that the locking
//texture is now locked.
//Conversely, if the locking texture contains 1, then the exchange function
//will write a 1 (so the texture is still locked), and return 1, indicating
//that the texture is locked and unavailable.
while (imageAtomicExchange(img2D_0,coord,1u)==1u);
//The locking texture is locked. More code would go here
//This unlocks the texture.
imageAtomicExchange(img2D_0,coord,0);
}
The locking texture is created like so:
//data is an array initialized to all 0.
glTexImage2D(GL_TEXTURE_2D,0,GL_R32UI,size_x,size_y,0,GL_RED_INTEGER,GL_UNSIGNED_INT,data);
To execute the algorithm, I take a FBO, with a color RGBA F32 render attachment and enable it. I bind the above shader, then pass the locking texture to img2D_0 and the color attachment to img2D_1, using this code:
glBindImageTextureEXT(
/* 0, 1, respectively */,
texture_id, 0,GL_FALSE,0, GL_READ_WRITE,
/* GL_R32UI, GL_RGBA32F, respectively */
);
The object is then rendered with a VBO, and some secondary passes show the contents of the data.
The problem is that the fragment program given crashes the video driver (because it never terminates). My question is why? The texture is initialized to 0, and I'm pretty sure my logic for the exchange functions is valid. Is my setup and methodology basically correct?