imageStore 在 Windows 上使用 ANGLE 导致 GL ES 3.1 计算着色器崩溃

问题描述 投票:0回答:1

我的目标是使用计算着色器生成类似于this的亮度波形。

我的设置是:

  • Cpp窗口应用程序
  • EGL/egl.h
  • GLES3/gl31.h(特别请求 ES 3.1 上下文)
  • 来自 ANGLE 最新版本 (04.01.2024) 的 libGLESv2.dll

计算着色器:

#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);
    }
}

我的渲染循环的一部分:

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);

m_tex_source 中的纹理包含正确的数据,并且可以使用简单的顶点和片段着色器毫无问题地显示。

输出纹理是使用以下方式生成的:

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);

输入/源纹理类似地使用以下方式生成:

... // 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
);

崩溃发生在这里:

glDispatchCompute(numGroupsX, numGroupsY, 1);

glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);

异常显示在 glMemoryBarrier 行中,但可能仍然属于着色器执行。

这是一个例外:

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

当我从计算着色器中删除包含

imageStore
的行时,崩溃消失了。

感谢您提前提供的所有帮助。

opengl-es direct3d compute-shader egl opengl-es-3.1
1个回答
0
投票

在调试模式下从源代码编译 ANGLE 有所帮助,并提供了有用的错误消息,表明我没有使用不可变纹理。

改变

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
);

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

解决了这个问题,因为

glTexStorage2D
创建了一个具有固定大小和格式的不可变纹理,这是渲染循环中
glBindImageTexture
所需要的。

© www.soinside.com 2019 - 2024. All rights reserved.