glCompileShader 上的 Mesa 访问冲突

Mesa Access Violation on glCompileShader

我一直在尝试为 windows 交叉编译 mesa。我一直在大致遵循 this 教程,但使用的是 MSYS2 而不是完整的 linux OS。除了一个方面,我已经成功地编译了一个正常运行的opengl32.dll。

当着色器包含任意数量的标准内置函数之一时,我在编译着色器时遇到访问冲突。其中包括:

getType max(genType, getType);
getType min(genType, getType);
float dot(genType x, genType y);
genType normalize(genType v);

这并不详尽。大多数(可能是所有)内置函数都会失败。没有任何这些函数,着色器编译并且 运行 正常。我无法获得编译日志或类似内容,因为访问冲突意味着 glCompileShader 执行后没有代码。这是我的顶点着色器:

#version 130
in vec2 position;
void main()
{
    gl_Position = vec4(position, 0.0, 1.0);

    // Meaningless tests ...
    float a = 3.0, b = 4.0, c;
    c = max(a, b); // <-- COMPILES AND RUNS OK WITHOUT THIS LINE
}

C++ 代码是一个简单的本机 windows 应用程序,紧随 this tutorial。如果人们认为它是相关的,我可以 post 完整的代码,但大部分只是 window 设置和类似的。实际的着色器编译位如下所示:

// Load the shader source code from a file
std::string filePath("Shaders/vertex");
std::ifstream stream(filePath, std::ios::in);
std::string code = "", line = "";
while(getline(stream, line)) code += "\n" + line;
stream.close();
const char* code_c_str = code.c_str();
GLint code_length = code.size();

// Create a shader and compile the loaded source code
GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShaderID, 1, &code_c_str, &code_length);
glCompileShader(vertexShaderID);

程序在链接到硬件库(在我的例子中是 NVIDIA)时运行良好。当链接到我公司前雇员完成的 Mesa 构建时,该程序也可以运行。不幸的是,这个人没有留下任何关于如何构建 Mesa 二进制文件的文档。我尝试过使用和不使用 LLVM 构建 Mesa,每次都得到相同的结果。

有谁知道为什么我构建的 Mesa 可能无法如此惊人地编译简单的内置 glsl 函数?


更新

我按照建议进行了调试构建,问题消失了。这似乎是一个优化器问题。我已经确定发布版本适用于 -O0 或 -O1 优化,但在 -O2 或 -O3 上失败。仍然有点痛苦,因为性能对于这个应用程序很重要,但至少我现在有一个工作的 DLL 和去哪里的想法。

作为参考,我在 msys2 上使用默认的 gcc/g++ 交叉编译器,它似乎是 4.9.2。我一直没能从调试器中得到多少,因为 DLL 是用 mingw 构建的,但测试解决方案在 Visual Studio 中。然而,我确实从 gdb 得到了这个:

#0  0x00000008 in ?? ()
#1  0x630e51a0 in (anonymous namespace)::builtin_builder::new_sig(glsl_type const*, bool (*)(_mesa_glsl_parse_state const*), int, ...) [clone .constprop.166]
    () at src/glsl/list.h:440
#2  0x630e51a0 in (anonymous namespace)::builtin_builder::new_sig(glsl_type const*, bool (*)(_mesa_glsl_parse_state const*), int, ...) [clone .constprop.166]
    () at src/glsl/list.h:440
#3  0x630e51a0 in (anonymous namespace)::builtin_builder::new_sig(glsl_type const*, bool (*)(_mesa_glsl_parse_state const*), int, ...) [clone .constprop.166]
    () at src/glsl/list.h:440
#4  0x630e51a0 in (anonymous namespace)::builtin_builder::new_sig(glsl_type const*, bool (*)(_mesa_glsl_parse_state const*), int, ...) [clone .constprop.166]
    () at src/glsl/list.h:440
#5  0x630e51a0 in (anonymous namespace)::builtin_builder::new_sig(glsl_type const*, bool (*)(_mesa_glsl_parse_state const*), int, ...) [clone .constprop.166]
    () at src/glsl/list.h:440
#6  0x630e51a0 in (anonymous namespace)::builtin_builder::new_sig(glsl_type const*, bool (*)(_mesa_glsl_parse_state const*), int, ...) [clone .constprop.166]
    () at src/glsl/list.h:440
#7  0x630e51a0 in (anonymous namespace)::builtin_builder::new_sig(glsl_type const*, bool (*)(_mesa_glsl_parse_state const*), int, ...) [clone .constprop.166]
    () at src/glsl/list.h:440
#8  0x630e51a0 in (anonymous namespace)::builtin_builder::new_sig(glsl_type const*, bool (*)(_mesa_glsl_parse_state const*), int, ...) [clone .constprop.166]
    () at src/glsl/list.h:440
#9  0x630e51a0 in (anonymous namespace)::builtin_builder::new_sig(glsl_type const*, bool (*)(_mesa_glsl_parse_state const*), int, ...) [clone .constprop.166]
    () at src/glsl/list.h:440
#10 0x630e51a0 in (anonymous namespace)::builtin_builder::new_sig(glsl_type const*, bool (*)(_mesa_glsl_parse_state const*), int, ...) [clone .constprop.166]
    () at src/glsl/list.h:440
#11 0x644395c0 in glsl_type::_struct_gl_DepthRangeParameters_type ()
   from C:\Users\will\Documents\Visual Studio 2012\Projects\OpenGLMinimalTest\Debug\opengl32.dll
#12 0x048c0964 in ?? ()
#13 0x00000002 in ?? ()
#14 0x01040000 in ?? ()
#15 0x00000000 in ?? ()

Mesa 代码之前或之后没有任何信息,因为这些位分别是 Windows DLL 和 Visual Studio 编译的。错误出在内置函数构建器中,这是有道理的,因为它是生成它的内置函数。目前还不清楚(至少对我而言)这个错误的原因是在优化中。

这不是一个完整的答案,但我认为已经足够了...

访问冲突问题只在 MinGW 构建中发生在更高级别的优化中。 O2 及以上不起作用。问题出在着色器内置函数中,但我们从未弄清楚它究竟是什么或如何修复它。

最终,为了在 windows 上生成高效的 Mesa 构建,我放弃了 MinGW 并使用 visual studio 构建。我使用以下 python 脚本作为起点。

https://github.com/florianlink/MesaOnWindows

希望这些信息对遇到相同问题的任何人来说都是足够的。