[NV305.67] compute shader texture sampling reads zero

Hi there,

I stumbled upon this bug(?) a couple of times by now:

  1. create a texture, make it immutable
  2. upload data from cpu to the texture
  3. bind texture to some texture unit (not image unit - actually, I haven’t tested that)
  4. run compute shader
    -> read some data from that texture
    Result: read is always 0.
    If I use the same texture in some program in an old compute shader fashion (quad; vertex/fragment shader), it works.
    If - between step 2 and 4 - the texture is read by some fragment shader, the compute program IS able to read data from the texture.

Some more hints about my application (although it shouldn’t matter)

  • I have a small OpenGL library, which wraps most of the OpenGL “objects”… so no code here.
  • I use DSA (I just like OOP thinking)
  • Am I correct that the 305.67 is still the only driver supporting OpenGL 4.3? I tried the others and (although the nvidia page partially says differently) they do not give me an 4.3 context (card: 560ti).

Best

Update:
I just tried the new driver 306.63 and it behaves the same :(.
Furthermore I ran into an example, where even the trick with first using the texture in a fragment shader does not help, the compute shader always reads 0. I tried the “same” shader as a fragment shader with framebuffers etc. and it there it works as expected.

I have also noticed this issue. I am sure that this is a driver bug.

I was not able to reproduce a problem with the code pasted below. Could you provide some code that reproduces the issue. Are you sampling the texture with texture() or texelFetch()?


int main(int argc, char const * argv[])
{
    GLuint cs = glCreateShader(GL_COMPUTE_SHADER);
    GLchar const * css[] = {
        "#version 430 core
"
        "
"
        "layout(local_size_x=16, local_size_y=16) in;
"
        "
"
        "uniform usampler2D tex;
"
        "layout(binding = 0) buffer Output {
"
        "    uint output[16][16];
"
        "};
"
        "
"
        "void main()
"
        "{
"
        "    uint x = gl_LocalInvocationID.x;
"
        "    uint y = gl_LocalInvocationID.y;
"
        "    output[y][x] = texelFetch(tex, ivec2(x, y), 0).x;
"
        "}
"
    };
    glShaderSource(cs, PDK_ARRAY_SIZE(css), css, 0);
    glCompileShader(cs);


    GLuint pgm = glCreateProgram();
    glAttachShader(pgm, cs);
    glLinkProgram(pgm);
    glUseProgram(pgm);


    GLuint tex;
    glGenTextures(1, &tex);
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, 16, 16);
    GLuint texels[16][16] = { 0 };
    for (int height = 0; height < 16; ++height) {
        for (int width = 0; width < 16; ++width) {
            texels[height][width] = width + height * 16;
        }
    }
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 16, 16, GL_RED_INTEGER, GL_UNSIGNED_INT, texels);


    GLuint ssbo;
    glGenBuffers(1, &ssbo);
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
    GLuint output[16][16] = { 0 };
    glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof output, output, GL_STREAM_DRAW);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ssbo);


    glDispatchCompute(1, 1, 1);
    glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof output, output);


    if (memcmp(output, texels, sizeof output)) {
        printf("ERROR: texture read failed
");
        return EXIT_FAILURE;
    }


    return EXIT_SUCCESS;
}

I have tried various sampling functions (texture, texelFetch and others). My code is similar but:

  • uses glTexImage2D instead of glTexStorage2D
  • uses GL_RGBA32F as an internalformat

I modified my repro app as pasted below, using GL_RGBA32F and glTexImage2D, but I was still unable to reproduce a problem. Does my app work for you? What GPU are you using?


typedef GLfloat vec4[4];


int main(int argc, char const * argv[])
{
    GLuint cs = glCreateShader(GL_COMPUTE_SHADER);
    GLchar const * css[] = {
        "#version 430 core
"
        "
"
        "layout(local_size_x=16, local_size_y=16) in;
"
        "
"
        "uniform sampler2D tex;
"
        "layout(binding = 0) buffer Output {
"
        "    vec4 output[16][16];
"
        "};
"
        "
"
        "void main()
"
        "{
"
        "    uint x = gl_LocalInvocationID.x;
"
        "    uint y = gl_LocalInvocationID.y;
"
        "    output[y][x] = texelFetch(tex, ivec2(x, y), 0);
"
        "}
"
    };
    glShaderSource(cs, PDK_ARRAY_SIZE(css), css, 0);
    glCompileShader(cs);


    GLuint pgm = glCreateProgram();
    glAttachShader(pgm, cs);
    glLinkProgram(pgm);
    glUseProgram(pgm);


    GLuint tex;
    glGenTextures(1, &tex);
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    vec4 texels[16][16] = { 0 };
    for (int height = 0; height < 16; ++height) {
        for (int width = 0; width < 16; ++width) {
            texels[height][width][0] = float(width + height * 16) / 256.0f;
            texels[height][width][1] = float(width + height * 16) / 256.0f;
            texels[height][width][2] = float(width + height * 16) / 256.0f;
            texels[height][width][3] = float(width + height * 16) / 256.0f;
        }
    }
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 16, 16, 0, GL_RGBA, GL_FLOAT, texels);


    GLuint ssbo;
    glGenBuffers(1, &ssbo);
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
    vec4 output[16][16] = { 0 };
    glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof output, output, GL_STREAM_DRAW);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ssbo);


    glDispatchCompute(1, 1, 1);
    glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof output, output);


    if (memcmp(output, texels, sizeof output)) {
        printf("ERROR: texture read failed
");
        return EXIT_FAILURE;
    }


    return EXIT_SUCCESS;
}

Your code reproduces the problem on my machine.

Driver: 306.63
OS: Windows 7 x64
GPU: GeForce GTS 450

Hey Ambator. If you have a different gpu, you should try that.

The reason is I had a similar issue, but it was dealing with glBindSampler. One time it was nVidia driver issue.

The other is was because I forgot to set one setting resulting in texture sampling returns 0 and textureSize returns 0 even though i uploaded and pulled down the texture to verify it is valid.

You may be facing a similar issue.

Thanks for the information. I failed to reproduce this with my GF108, but I am able to reproduce with a GF104, which matches your GPU. I will investigate the issue.

We have found the bug in our driver that’s causing textures to not work properly with compute shaders. This issue is fixed and will be released soon with a new driver update.

In the mean time you can work around the issue by referencing the texture(s) you intend to use with compute from a non-compute shader (or fixed-function) before dispatching the compute.

For example, with my sample application above you could add the following:


    ...
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 16, 16, 0, GL_RGBA, GL_FLOAT, texels);
    // Work around starts here
    glUseProgram(0); // use fixed-function
    glEnable(GL_TEXTURE_2D); // enable texture sampling
    glDrawArrays(GL_TRIANGLES, 0, 0); // draw nothing
    glDisable(GL_TEXTURE_2D);
    glUseProgram(pgm); // restore the compute program
    // Work around ends here

    GLuint ssbo;
    ...

Thanks for the info. I am glad that you have fixed that. I am waiting for the next driver release.

thank you for coming back to this issue.
I’m using a 560Ti currently.
It is good to hear, that you can confirm and resolve this bug.

However, as mentioned in the original post, I also had an issue, where my workaround of using a dummy fragment shader first (which should be more or less equal to your workaround) did not solve the issue.
Unfortunately, I’m too busy atm to test fully test it again.

Best

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.