Reputation: 488
I have been attempting to cross compile mesa for windows. I've been following roughly this tutorial, but using MSYS2 rather than a full linux OS. I have successfully compiled a functioning opengl32.dll in all but one aspect.
I'm getting an access violation on compilation of a shader when it contains one of any number of standard built-in functions. These include the following:
getType max(genType, getType);
getType min(genType, getType);
float dot(genType x, genType y);
genType normalize(genType v);
This isn't exhaustive. Most (possibly all) builtin functions fail. Without any of these functions, the shaders compile and run fine. I can't get a compilation log or anything like that as the access violation means no code after glCompileShader executes. Here is my vertex shader:
#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
}
The C++ code is a simple native windows application which follows this tutorial. I can post the full code if people think it is relevant, but most of it is just window setup and similar. The actual shader compilation bit looks like this:
// 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);
The program functions fine when linked to the hardware library (NVIDIA, in my case). The program also functions when linked to a Mesa build done by an ex-employee of my company. Unfortunately, the individual left no documentation on how that Mesa binary was built. I have tried building Mesa both with and without LLVM, with the same result each time.
Does anyone know why my build of Mesa might be failing to compile simple builtin glsl functions so spectacularly?
Update
I did a debug build, as suggested, and the problem went away. It seems to be an optimiser issue. I've since ascertained that the release build works with -O0 or -O1 optimisation, and fails on -O2 or -O3. Still a bit of a pain, as performance is important for this application, but at least I now have a working DLL and an idea of where to go.
For reference, I'm using the default gcc/g++ cross compiler on msys2, which appears to be 4.9.2. I haven't been able to get much out of the debugger, because the DLL is built with mingw, but the test solution is in Visual Studio. I did get this, however, from 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 ?? ()
There's no information before or after the Mesa code, as those bits are Windows DLLs and Visual Studio compiled respectively. The error is in the builtin function builder, which makes sense, given it's builtin functions that generate it. It's not immediately obvious (to me at least) what the reason for this error is under optimisation.
Upvotes: 0
Views: 376
Reputation: 488
It's not a complete answer, but I think it's enough...
The access violation problem was happening in MinGW builds only at higher levels of optimisation. O2 and above didn't work. The problem is in shader builtin functions, but we never worked out exactly what it was or how to fix it.
Eventually, in order to generate an efficient build of Mesa on windows, I abandoned MinGW and built using visual studio. I used the following python script as a starting point.
https://github.com/florianlink/MesaOnWindows
Hopefully that's sufficient information for anyone encountering the same problems.
Upvotes: 0