3
\$\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\$
1
  • \$\begingroup\$ thank you! i know its an old question, but your code samples got me over a hump i've been in with compute shaders for hours. i didn't know that compute shaders use GL.BindImageTexture(0, InputImageHandle, 0, false, 0, TextureAccess.ReadWrite, SizedInternalFormat.Rgba16f); instead of GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, InputImageHandle); \$\endgroup\$ Dec 29, 2021 at 0:30

1 Answer 1

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .