imageStore causing crash in GL ES 3.1 Compute shader using ANGLE on windows

44 views Asked by At

My goal is to generate a luminance waveform similar to this using a compute shader.

My setup is:

  • Cpp window application
  • EGL/egl.h
  • GLES3/gl31.h (specifically requesting an ES 3.1 context)
  • libGLESv2.dll from ANGLE's most recent build (04.01.2024)

Compute Shader:

#version 310 es
layout(local_size_x = 16, local_size_y = 16) in;
layout(binding = 0, rgba8ui) uniform highp readonly uimage2D u_sourceTexture;
layout(binding = 1, rgba8ui) uniform highp writeonly uimage2D u_waveformTexture;

void main() {
    ivec2 sourceSize = imageSize(u_sourceTexture);
    ivec2 waveformSize = imageSize(u_waveformTexture);
    ivec2 gid = ivec2(gl_GlobalInvocationID.xy);

   if (gid.x < sourceSize.x && gid.y < sourceSize.y) {
        uvec4 color = imageLoad(u_sourceTexture, gid);
        float luminance = dot(vec3(color.rgb) / 255.0, vec3(0.299, 0.587, 0.114));
        
        int waveformY = int(clamp(luminance * float(waveformSize.y-1), 0.0, float(waveformSize.y - 1)));
        int waveformX = int(clamp(float(gid.x) * float(waveformSize.x) / float(sourceSize.x), 0.0, float(waveformSize.x - 1)));

        // Compute the position in the waveform texture
        ivec2 waveformPos = ivec2(waveformX, waveformY);

        // Write the color to the waveform texture

        // this line causes the crash
        imageStore(u_waveformTexture, waveformPos, color);
    }
}

Part of my renderloop:

glUseProgram(m_shaderprog_compute_luma_waveform);

glBindImageTexture(
    0, // image unit (not texture unit)
    m_tex_source, 
    0, 
    GL_FALSE, 
    0, 
    GL_READ_ONLY, 
    GL_RGBA8UI
);

glBindImageTexture(
    1, // image unit (not texture unit)
    m_tex_luma_waveform, 
    0, 
    GL_FALSE, 
    0, 
    GL_WRITE_ONLY, 
    GL_RGBA8UI
);

const int groupSize = 16;
unsigned int sourceWidth = m_source_width();
unsigned int sourceHeight = m_source_height();
GLuint numGroupsX = (sourceWidth + groupSize - 1) / groupSize;
GLuint numGroupsY = (sourceHeight + groupSize - 1) / groupSize;
glDispatchCompute(numGroupsX, numGroupsY, 1);

glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);

glUseProgram(0);

The texture in m_tex_source contains the correct data and can be displayed without a problem using a simple vertex and fragment shader.

The output texture is generated using:

glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &m_tex_luma_waveform);
if (m_tex_luma_waveform == 0) {
    throw std::runtime_error("Failed to create luma waveform texture");
}
glBindTexture(GL_TEXTURE_2D, m_tex_luma_waveform);
// Set our texture parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// 580 x 256 px with RGBA8ui data
glTexImage2D(
    GL_TEXTURE_2D, // target
    0, // level
    GL_RGBA8UI, // internal format 
    m_luma_waveform_width, // width
    m_luma_waveform_height, // height
    0, // border
    GL_RGBA_INTEGER, // format
    GL_UNSIGNED_BYTE, // type
    NULL // data
);

glBindTexture(GL_TEXTURE_2D, 0);

The input/source texture was similarly generated using:

... // generate and bind texture, set filters and wrap

glTexImage2D(
    GL_TEXTURE_2D,
    0,
    GL_RGBA,
    image->width,
    image->height,
    0,
    GL_RGBA, 
    GL_UNSIGNED_BYTE,
    image->pixels
);

The crash occurs here:

glDispatchCompute(numGroupsX, numGroupsY, 1);

glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);

The exception is shown in the glMemoryBarrier line but probably still belongs to the shader execution.

This is the exception: Exception thrown at 0x00007FFA387FBE36 (libGLESv2.dll) in angle_test.exe: 0xC0000005: Access violation reading location 0x00000000000000C8.

When I remove the line containig imageStore from the compute shader, the crash disappears.

Thanks for all the help in advance.

1

There are 1 answers

1
MindStudio On

Compiling ANGLE from source in Debug mode helped and gave helpful error messages that indicated that I wasn't using immutable textures.

changing

glTexImage2D(
    GL_TEXTURE_2D, // target
    0, // level
    GL_RGBA8UI, // internal format 
    m_luma_waveform_width, // width
    m_luma_waveform_height, // height
    0, // border
    GL_RGBA_INTEGER, // format
    GL_UNSIGNED_BYTE, // type
    NULL // data
);

to

glTexStorage2D(
    GL_TEXTURE_2D,      // target
    1,                  // levels of mipmapping
    GL_RGBA8UI,         // internal format
    m_luma_waveform_width,  // width
    m_luma_waveform_height  // height
);

resolved the issue, since glTexStorage2D creates an immutable texture with fixed size and format, that is needed for glBindImageTexture in the renderloop.