Почему моя программа GLSL не будет ссылаться, когда один шейдер оптимизирован, а другой нет? - PullRequest
0 голосов
/ 16 октября 2018

Я использую шейдерный набор инструментов, где я начинаю с GLSL, компилирую его в SPIRV, оптимизирую SPIRV, а затем использую spirv-cross для генерации оптимизированного GLSL.Это работает хорошо по большей части.

Однако у меня есть механизм, с помощью которого пользователь может генерировать фрагменты кода, которые могут быть введены в некоторые фрагментные шейдеры путем замены текста.Когда это происходит, используется оригинальный неоптимизированный GLSL, поскольку маркеры для замены текста не могут пережить прохождение через SPIRV.

Однако я обнаружил, что в некоторых случаях оптимизированный вершинный шейдер и настроенныйФрагментный шейдер будет скомпилирован, но программа не установит связь, вместо этого появится следующая ошибка:

WARNING: warning(#276) Symbol "_normal" usage doesn't match between two stages
ERROR: error(#277) Symbol "_16" usage doesn't match between two stages

Оптимизированный вершинный шейдер и ссылка на оптимизированный фрагментный шейдер.Неоптимизированные версии обеих ссылок.Даже неоптимизированный вершинный шейдер и оптимизированный фрагментный шейдер связывают ссылки.

Я сузил проблему до следующего объявления, которое появляется в фрагментном шейдере

struct TransformCamera {
    mat4 _view;
    mat4 _viewInverse;
    mat4 _projectionViewUntranslated;
    mat4 _projection;
    mat4 _projectionInverse;
    vec4 _viewport;
    vec4 _stereoInfo;
};

layout(std140, binding=15) uniform transformCameraBuffer {
    TransformCamera _camera;
};

В оптимизированных версияхшейдеры, где весь UBO не оптимизирован как неиспользуемый, объявление становится

layout(binding = 15, std140) uniform transformCameraBuffer
{
    TransformCamera _camera;
} _16;

Если я вручную изменю неоптимизированный фрагментный шейдер, чтобы использовать аналогичный механизм для именования UBO, ошибка ссылки исчезнет (независимо от того,из того, что я называю UBO), так, например, следующее изменение к фрагментному шейдеру успешно компилируется и связывается.

layout(std140, binding=15) uniform transformCameraBuffer {
    TransformCamera _camera;
} _foo;

Я, очевидно, могу обойти эту проблему, но я не понимаю, как различается синтаксисдля объявления UBO полностью нарушает фазу ссылки моей программы.Может ли кто-нибудь дать некоторое представление?

Кроме того, если что-то в glslangValidator -> spirv-opt -> spirv-cross меняет интерфейс ссылки для моего шейдера, должен ли я считать это ошибкой и сообщать об этом?

1 Ответ

0 голосов
/ 16 октября 2018

Я, очевидно, могу обойти эту проблему, но я не понимаю, как другой синтаксис для объявления UBO полностью нарушает фазу соединения моей программы

Поскольку в спецификации так сказано, GLSL 4.60 спецификация , раздел 4.3.9.Состояния «интерфейсных блоков» (выделено мной):

Соответствующие имена блоков в шейдерном интерфейсе (как определено выше) должны совпадать с точки зрения наличия одинакового количества объявлений с одинаковой последовательностью типов ита же последовательность имен членов, а также соответствующая квалификация макета для каждого члена (см. следующий раздел). Совпадающая униформа или хранилище шейдеров имена блоков (но не имена входных или выходных блоков) должны либо все иметь имя экземпляра, либо все иметь имя экземпляра, помещая свои членына том же уровне охвата.Когда имена экземпляров присутствуют в совпадающих именах блоков, имена экземпляров могут различаться;они не должны совпадать для совпадения блоков. [...].

Так что, если ваш вершинный шейдер использует имя экземпляра, фрагментный шейдер тоже должен использовать его.

Кроме того, если что-то в glslangValidator -> spirv-opt -> spirv-cross меняет интерфейс ссылки для моего шейдера, я должен считать это ошибкой и сообщать об этом?

Я не знаю, какие гарантии они дают на отдельные части программы.Я бы не стал интуитивно ожидать, что ваш рабочий процесс объединения неоптимизированных и оптимизированных частей гарантированно будет работать, по крайней мере.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...