1
$\begingroup$

I am trying to read an input texture, modify it and then write to an output texture from a very simple compute shader.

For some reason I am not able to write to the output image from the compute shader.

The screen is black (even though I have a red clear color).

Here is my application code:

    // Compute shader
    (...Code to setup images)
    glTextureStorage2D(m_color_texture, 1, GL_RGB32F, m_src_fbo_size, m_src_fbo_size); // <- Yikes, wrong format!
    glTextureStorage2D(m_temp_texture, 1, GL_RGB32F, m_src_fbo_size, m_src_fbo_size); // <- Yikes, wrong format!
    m_compute_shader.use();
    glBindImageTexture(0, m_color_texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F);
    glBindImageTexture(1, m_temp_texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);

    glDispatchCompute(m_info.window_width / 32, m_info.window_height / 32, 1);

    // Full screen quad
    glBindImageTexture(0, m_temp_texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F);
    glDisable(GL_DEPTH_TEST);
    m_full_screen_quad_shader.use();
    glViewport(0, 0, m_info.window_width, m_info.window_height);
    glBindVertexArray(m_full_screen_quad_vao);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

And here is the compute shader:

#version 440 core

layout (local_size_x = 32, local_size_y = 32) in;

layout (binding = 0, rgba32f) readonly uniform image2D input_image;
layout (binding = 1, rgba32f) writeonly uniform image2D output_image;

void main()
{
    vec4 texel;
    ivec2 p = ivec2(gl_GlobalInvocationID.xy);

    texel = imageLoad(input_image, p);
    texel = vec4(1.0) - texel;
    imageStore(output_image, p, texel);
}

If I just swap m_temp_texture with m_color_texture (which is the input image ) in the call to glBindImageTexture(0, m_temp_texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F); then I see the image, so I know it is not a problem with the frag shader. (Here is is though anyway):

#version 440 core

layout (binding = 0) uniform sampler2D input_image;

layout (location = 0) out vec4 fragColor;

//uniform float focal_distance = 50.0;
//uniform float focal_depth = 30.0;

void main()
{
    vec4 color = texelFetch(input_image, ivec2(gl_FragCoord.xy), 0).rgba;
    fragColor = color;
}

Is there some reason why my compute shader is not being called? Even if I just write imageStore(output_image, p, vec4(1.0)); in the compute shader, the screen is all black. I do not know what I am missing.

glGetError does not return anything.

EDIT:

I originally failed to include the code for the texture creation (the first two lines). This affects the qustion. Please see the answer below.

$\endgroup$
  • $\begingroup$ I'm not seeing the part where you use a member barrier to ensure visibility. $\endgroup$ – Nicol Bolas Nov 16 '17 at 16:15
  • 1
    $\begingroup$ @Nicol Bolas - Do we still need to use a memory barrier when 1) - We aren't reading/writing from/to a same image. 2) - We aren't overwriting any pixel of a image by subsequent ImageStore So there wouldn't be any need for that since every invocation is writing to a separate pixel? $\endgroup$ – gallickgunner Nov 17 '17 at 7:24
  • 1
    $\begingroup$ I think you only need the barrier on the C/C++ side, after the compute shader has run but before passing the texture to the rendering command. Something like glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); $\endgroup$ – PaulHK Nov 17 '17 at 8:13
  • 2
    $\begingroup$ If you found a solution, post it as an answer below. $\endgroup$ – narthex Nov 17 '17 at 12:42
0
$\begingroup$

Originally mistmatching image formats (GL_RGB32F instead of GL_RGBA32F) were used in the creation of textures and the call to glBindImageTexture.

This error was hard to track down because the format (without alpha) only mattered (in this case) in the compute shader.

Using GL_RGBA32Feverywhere fixed the issue.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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