Нарушение прав доступа к Mesa в glCompileShader

Я пытался перекрестно скомпилировать mesa для окон. Я примерно следовал этому руководству, но использовал MSYS2, а не полную ОС Linux. Я успешно скомпилировал функционирующую 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, которое соответствует этому руководству. Я могу опубликовать полный код, если люди сочтут его уместным, но в основном это просто установка окна и тому подобное. Фактический бит компиляции шейдера выглядит так:

// 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. Я пытался собрать Mesa как с LLVM, так и без него, каждый раз с одним и тем же результатом.

Кто-нибудь знает, почему моя сборка Mesa может так эффектно не компилировать простые встроенные glsl-функции?


Обновить

Я сделал отладочную сборку, как было предложено, и проблема исчезла. Похоже проблема в оптимизаторе. С тех пор я установил, что релизная сборка работает с оптимизацией -O0 или -O1 и не работает с оптимизацией -O2 или -O3. Все еще немного больно, так как для этого приложения важна производительность, но, по крайней мере, теперь у меня есть работающая DLL и представление о том, куда идти.

Для справки, я использую кросс-компилятор gcc/g++ по умолчанию на msys2, который выглядит как 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, так как эти биты представляют собой библиотеки DLL Windows и Visual Studio, скомпилированные соответственно. Ошибка заключается во встроенном построителе функций, что имеет смысл, учитывая встроенные функции, которые ее генерируют. Не сразу очевидно (по крайней мере, для меня), что причина этой ошибки в оптимизации.


person Bill    schedule 08.12.2015    source источник
comment
Никогда не удавалось собрать Mesa с помощью MinGW в Windows. Visual Studio работает очень хорошо.   -  person genpfault    schedule 08.12.2015
comment
Как насчет того, чтобы создать отладочную сборку (чтобы информация о символах осталась в бинарном файле opengl32.dll) и выполнить ее в отладчике, чтобы увидеть, где именно происходит сбой. Конечно, лучшим инструментом для этой работы будет Valgrind, но он доступен только для *nix-подобных ОС. Также предположительно работает Linux+WINE+Valgrind: wiki.winehq.org/< /а>   -  person datenwolf    schedule 09.12.2015
comment
@genpfault Этот пост почти полностью описывает то, что я делаю. Если я не добавлю параметр toolchain=msvc в команду scons, он компилируется с помощью gcc/g++ (или эквивалента mingw-cross). Компиляторы MS, похоже, недоступны в моей оболочке msys2. Я уверен, что это просто вопрос окружающей среды, но я еще не заставил это работать.   -  person Bill    schedule 09.12.2015


Ответы (1)


Это не полный ответ, но я думаю, что этого достаточно...

Проблема нарушения прав доступа возникала в сборках MinGW только на более высоких уровнях оптимизации. O2 и выше не работали. Проблема во встроенных функциях шейдера, но мы так и не выяснили, что это было и как это исправить.

В конце концов, чтобы создать эффективную сборку Mesa для Windows, я отказался от MinGW и построил с помощью Visual Studio. В качестве отправной точки я использовал следующий скрипт Python.

https://github.com/florianlink/MesaOnWindows

Надеюсь, этой информации достаточно для тех, кто сталкивается с такими же проблемами.

person Bill    schedule 26.12.2015