0
$\begingroup$

The typical scenario for using a texture would simply be:

//Create texture
glGenTextures(1, &textureID);
glBindTexture(target, textureID);
glTexImage2D(target, 0, color_format, width, height, 0,
    color_format, GL_UNSIGNED_BYTE, data);

glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

//load to program
glActiveTexture(texture_unit);
glBindTexture(target, textureID);
//Get the uniform location in the program and attach the texture unit
GLuint location = /*get_uniform_location*/;
glUniform1i(location,texture_unit - GL_TEXTURE0);

//Draw
render();

However image load store are somewhat different. First, they don't use texture units but image units. Second you need to manually set memory barriers yourself to ensure completion of writing stage before reading. Amgon other things.

I have read the documentation and attempted to implement things myself but It seems I am doing things wrong. I'd rather just forget about what I have tried and understand properly how this needs to be done step by step.

I want to know what a typical, minimum example use of image load stores qould be.

So creation of the image, writing to the image, reading from the image.

$\endgroup$
2
  • 2
    $\begingroup$ "Say the declaration is:" ... I don't know what you mean by that declaration. It's just a GLuint; the declaration doesn't mean anything. $\endgroup$ Commented May 8, 2018 at 18:46
  • $\begingroup$ that declaration was simply to say that we can assume that there is already a successfully compiled program under that ID. $\endgroup$
    – Makogan
    Commented May 8, 2018 at 19:28

1 Answer 1

3
+50
$\begingroup$

I've used imageStore as part of compute shaders doing surface extraction. I've only ever used it in compute shaders, to store the calculated data in a texture to be consumed by another shader - I know it's possible to do imageStore in a fragment shader as well but I haven't come across a use case for it yet.

I also haven't used imageLoad at all, since apparently texelFetch is often faster (benefits from using the texture cache), and at worst no slower, so I simply bound the same texture to both an image and a texture unit, and used imageStore for writes and texelFetch for reads.

The code to get it all working looked something like this (using OpenGL 4.5 and DSA, and assuming cShdr holds a compute program that does imageStore on channel 0, cShdr2 is a second compute program that samples the generated texture on channel 0, and rShdr is a rendering program that samples the texture on channel 0 - of course, if you don't want to hardcode the texture channel in the shader you can use glGetUniformLocation):

//setting up texture and binding to image unit 0
GLuint tex;
glCreateTextures(GL_TEXTURE_2D, 1, &tex);
glTextureStorage2D(tex, 1, GL_RGBA32F, 256, 256)
glBindImageTexture(0, tex, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);

//Dispatch a compute shader to imageStore to the texture
//wait for completion before allowing sampling
glDispatchCompute(cShdr, numX, numY, numZ);
glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);

//code that samples the texture in render loop
glBindVertexArray(vao);
glBindTextureUnit(0, tex);
glUseProgram(rShdr);
glDrawArrays(GL_TRIANGLES, 0, numVerts);

//or if consuming data in second compute shader using texelFetch
glBindTextureUnit(0, tex); 
glDispatchCompute(cShdr2, numX, numY, numZ); 

The first 3 parameters to glBindImageTexture are image unit, texture, and mip level. The next two deal with binding arrays of textures, and should just be set to GL_FALSE, 0 when binding a single texture. The final two are access and format (for stores).

Note that although I've used the GL 4.5-specific functions for creating textures and binding the texture unit, the glBindImageTexture works with every version that supports load/store - 4.2 and above.

$\endgroup$
1
  • $\begingroup$ Could you edit your answer to clearly distinguish between initilization code and use code? (the difference between initializing the texture vs using it on the render loop) $\endgroup$
    – Makogan
    Commented May 15, 2018 at 0:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.