2
\$\begingroup\$

I am trying to use a compute shader to generate some data in a texture. My compute shader looks something like this:

#version 430
//uniform int u_CurrentMipSize;       
const int u_CurrentMipSize = 1024;
layout( r16f ) uniform writeonly image2D u_densityTexture;


bool ContributesSignificantDensity( ivec2 uv )
{
    return uv.x >= ( u_CurrentMipSize / 8 ) && uv.y >= ( u_CurrentMipSize / 8 );
}

//.... in main()
if( ContributesSignificantDensity( targetPosition ) )
{
    imageStore( u_densityTexture, targetPosition, vec4( 1.0 ) );
}
else
{
    imageStore( u_densityTexture, targetPosition, vec4( 0.0 ) );
}

And the calling code looks like this:

glUseProgram( m_DensityGenShader );

glMemoryBarrier( GL_SHADER_IMAGE_ACCESS_BARRIER_BIT );

uniform_loc = glGetUniformLocation( m_DensityGenShader, "u_densityTexture" );
if( uniform_loc != unsigned int( -1 ) )
{
    glBindImageTexture( uniform_loc, m_DensityTexture, 0, false, 0, GL_WRITE_ONLY, GL_R16F );
}
checkOpenGLErrors( "Density Texture Compute Shader" );

uniform_loc = glGetUniformLocation( m_DensityGenShader, "u_CurrentMipSize" );
if( uniform_loc != unsigned int( -1 ) )
{
    glUniform1i( uniform_loc, 1024 );
}
checkOpenGLErrors( "Density Texture Compute Shader" );

int num_to_compute = mip_sizes[ i ] / 16;
glDispatchCompute( num_to_compute, num_to_compute, 1); 
checkOpenGLErrors( "Density Texture Compute Shader" );

glMemoryBarrier( GL_SHADER_ACCESS_BARRIER_BIT );

If I use this code, the program executes correctly on my texture of size 1024. I am just storing this result in an image2D. If I use a const float the program executes correctly, and I get a red square in the upper right 7/8ths of the image. (Just rendering this texture onto a quad in another shader). Texture rendered on quad- yay red!

However, if I change the top of my shader to the following by using a uniform instead of a const float:

uniform int u_CurrentMipSize;       
//const float u_CurrentMipSize = 1024;

Then the output texture is just garbage, random data: Texture rendered on quad- boo noise!

I'm always sending the uniform from the compiled code (if I get a valid uniform location back from opengl) so the only thing that changed is reading the value from a uniform vs a const float.

Should I be doing something differently with this because it's a compute shader? I've never had issues passing uniform data with vert/frag/geometry shaders?

I had a similar issue trying to do imageLoad operations, so I think I'm not setting up stuff with my compute shader correctly, but it works in the constant hard-coded case, so I'm not sure.

This is my first forray into compute shaders- I've worked with CUDA a bit so I'm familiar with the paradigms, but not sure how to debug if the kernel is crashing or abandoning early or corrupting the texture somehow or what?

\$\endgroup\$
3
\$\begingroup\$

I'm not sure why this fixed it, but apparently setting the uniform layout location works:

Compute

    layout( location=1 ) uniform unsigned int u_CurrentMipSize;       

C++:

    glUniform1ui( 1, mip_sizes[ i ] );

I had these other uniforms in my compute shader:

    layout( r16f ) uniform writeonly image2D u_densityTexture;
    layout( r16f ) uniform readonly image2D u_densityTexturePrevLevel;

So maybe mixing uniforms with a layout qualifier and those without caused the issue? I'm not sure.

\$\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.