Spec-Zone.ru › Qt 6.1

Справочник QSB

qsb — это утилита командной строки, предоставляемая модулем Qt Shader Tools. Она интегрирует сторонние библиотеки, такие как glslang и SPIRV-Cross, по желанию вызывает внешние инструменты, такие как fxc или spirv-opt, и генерирует файлы .qsb. Кроме того, она может использоваться для проверки содержимого пакета .qsb.

Usage: qsb [options] file
Qt Shader Baker (using QShader from Qt 6.0.0)

Options:
  -?, -h, --help               Displays help on commandline options.
  --help-all                   Displays help including Qt specific options.
  -v, --version                Displays version information.
  -b, --batchable              Also generates rewritten vertex shader for Qt
                               Quick scene graph batching.
  --zorder-loc <location>      The extra vertex input location when rewriting
                               for batching. Defaults to 7.
  --glsl <versions>            Comma separated list of GLSL versions to
                               generate. (for example, "100 es,120,330")
  --hlsl <versions>            Comma separated list of HLSL (Shader Model)
                               versions to generate. F.ex. 50 is 5.0, 51 is 5.1.
  --msl <versions>             Comma separated list of Metal Shading Language
                               versions to generate. F.ex. 12 is 1.2, 20 is 2.0.
  -g                           Generate full debug info for SPIR-V and DXBC
  -O                           Invoke spirv-opt to optimize SPIR-V for
                               performance
  -o, --output <filename>      Output file for the shader pack.
  -c, --fxc                    In combination with --hlsl invokes fxc to store
                               DXBC instead of HLSL.
  -t, --metallib               In combination with --msl builds a Metal library
                               with xcrun metal(lib) and stores that instead of
                               the source.
  -D, --define <name[=value]>  Define macro
  -p, --per-target             Enable per-target compilation. (instead of
                               source->SPIRV->targets, do source->SPIRV->target
                               separately for each target)
  -d, --dump                   Switches to dump mode. Input file is expected to
                               be a shader pack.
  -x, --extract <what>         Switches to extract mode. Input file is expected
                               to be a shader pack. Result is written to the
                               output specified by -o. Pass -b to choose the
                               batchable variant.
                               <what>=reflect|spirv.<version>|glsl.<version>|...

Arguments:
  file                         Vulkan GLSL source file to compile

Режимы работы

Существует три основных режима работы:

  • .qsb генерация файлов.
  • .qsb проверка файлов. Например, qsb -d myshader.frag.qsb выведет метаданные рефлексии (в формате JSON) и включённые шейдеры.
  • Режим извлечения. Это позволяет записать заданный шейдер из существующего файла .qsb в отдельный файл. Например, qsb -x spirv.100 -o myshader.spv myshader.frag.qsb записывает двоичный код SPIR-V в myshader.spv.

Пример

Рассмотрим следующий фрагмент шейдера:

#version 440

layout(location = 0) in vec2 v_texcoord;
layout(location = 0) out vec4 fragColor;
layout(binding = 1) uniform sampler2D tex;

layout(std140, binding = 0) uniform buf {
    float uAlpha;
};

void main()
{
    vec4 c = texture(tex, v_texcoord);
    fragColor = vec4(c.rgb, uAlpha);
}

Выполнение qsb -o shader.frag.qsb shader.frag приводит к генерации shader.frag.qsb. Проверка этого файла с помощью qsb -d shader.frag.qsb даёт:

Stage: Fragment
QSB_VERSION: 5
Has 1 shaders: (unordered list)
  Shader 0: SPIR-V 100 [Standard]

Reflection info: {
    "combinedImageSamplers": [
        {
            "binding": 1,
            "name": "tex",
            "set": 0,
            "type": "sampler2D"
        }
    ],
    "inputs": [
        {
            "location": 0,
            "name": "v_texcoord",
            "type": "vec2"
        }
    ],
    "localSize": [
        0,
        0,
        0
    ],
    "outputs": [
        {
            "location": 0,
            "name": "fragColor",
            "type": "vec4"
        }
    ],
    "uniformBlocks": [
        {
            "binding": 0,
            "blockName": "buf",
            "members": [
                {
                    "name": "uAlpha",
                    "offset": 0,
                    "size": 4,
                    "type": "float"
                }
            ],
            "set": 0,
            "size": 4,
            "structName": "_27"
        }
    ]
}


Shader 0: SPIR-V 100 [Standard]
Entry point: main
Contents:
Binary of 864 bytes

По умолчанию генерируется только SPIR-V, поэтому приложение, использующее этот пакет шейдеров, будет функциональным только с Vulkan. Давайте сделаем его более универсальным:

qsb --glsl "100 es,120,150" --hlsl 50 --msl 12 -o shader.frag.qsb shader.frag

Это приводит к генерации пакета шейдеров, подходящего для OpenGL, Direct 3D и Metal. Функционал, использованный в этом шейдере, базовый, и даже GLSL ES 100 (язык шейдинга OpenGL ES 2.0) подходит.

Проверка результата показывает:

Stage: Fragment
QSB_VERSION: 5
Has 6 shaders: (unordered list)
  Shader 0: GLSL 120 [Standard]
  Shader 1: HLSL 50 [Standard]
  Shader 2: GLSL 100 es [Standard]
  Shader 3: MSL 12 [Standard]
  Shader 4: SPIR-V 100 [Standard]
  Shader 5: GLSL 150 [Standard]

Reflection info: {
    ... <same as above>
}


Shader 0: GLSL 120 [Standard]
Entry point: main
Contents:
#version 120

struct buf
{
    float uAlpha;
};

uniform buf _27;

uniform sampler2D tex;

varying vec2 v_texcoord;

void main()
{
    vec4 c = texture2D(tex, v_texcoord);
    gl_FragData[0] = vec4(c.xyz, _27.uAlpha);
}

************************************

Shader 1: HLSL 50 [Standard]
Entry point: main
Native resource binding map:
0 -> [0, -1]
1 -> [0, 0]
Contents:
cbuffer buf : register(b0)
{
    float _27_uAlpha : packoffset(c0);
};

Texture2D<float4> tex : register(t0);
SamplerState _tex_sampler : register(s0);

static float2 v_texcoord;
static float4 fragColor;

struct SPIRV_Cross_Input
{
    float2 v_texcoord : TEXCOORD0;
};

struct SPIRV_Cross_Output
{
    float4 fragColor : SV_Target0;
};

void frag_main()
{
    float4 c = tex.Sample(_tex_sampler, v_texcoord);
    fragColor = float4(c.xyz, _27_uAlpha);
}

SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
{
    v_texcoord = stage_input.v_texcoord;
    frag_main();
    SPIRV_Cross_Output stage_output;
    stage_output.fragColor = fragColor;
    return stage_output;
}

************************************

...

Shader 3: MSL 12 [Standard]
Entry point: main0
Native resource binding map:
0 -> [0, -1]
1 -> [0, 0]
Contents:
#include <metal_stdlib>
#include <simd/simd.h>

using namespace metal;

struct buf
{
    float uAlpha;
};

struct main0_out
{
    float4 fragColor [[color(0)]];
};

struct main0_in
{
    float2 v_texcoord [[user(locn0)]];
};

fragment main0_out main0(main0_in in [[stage_in]], constant buf& _27 [[buffer(0)]], texture2d<float> tex [[texture(0)]], sampler texSmplr [[sampler(0)]])
{
    main0_out out = {};
    float4 c = tex.sample(texSmplr, in.v_texcoord);
    out.fragColor = float4(c.xyz, _27.uAlpha);
    return out;
}

************************************

...

Этот пакет теперь можно использовать с Qt Quick со всеми поддерживаемыми графическими API: Vulkan, Direct 3D, Metal, OpenGL и OpenGL ES. В момент выполнения соответствующий шейдер автоматически выбирается Qt Rendering Hardware Interface, расположенным под Qt Quick и Qt Quick 3D.

Помимо перевода байткода SPIR-V обратно в исходный код высокого уровня, система обрабатывает дополнительные проблемы, например, гарантирует правильное отображение номеров связей SPIR-V на родные ресурсы. Например, с HLSL мы видели такой раздел выше:

Native resource binding map:
 0 -> [0, -1]
 1 -> [0, 0]

Внутренне это позволяет сопоставить точку привязки в стиле SPIR-V 0 с регистром HLSL b0 и привязку 1 к t0 и s0. Это помогает сделать различия в привязке ресурсов между различными языками шейдинга прозрачными для пользователей Rendering Hardware Interface и позволяет всему в Qt работать с точками привязки в стиле Vulkan/SPIR-V, как они указаны в исходном коде GLSL в стиле Vulkan.

Типы шейдеров

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

  • .vert - для вершинных шейдеров
  • .frag - для фрагментных (пиксельных) шейдеров
  • .comp - для шейдеров вычислений

Языки и версии шейдинга

Всегда генерируется SPIR-V 1.0. Что ещё генерируется, зависит от аргументов командной строки --glsl, --hlsl, и --msl.

Все эти параметры следуют за перечислением, разделённым запятыми. Список должен включать номера версий в стиле GLSL с необязательным суффиксом (es, обозначающим GLSL ES). Пробел между суффиксом и версией необязателен (отсутствие пробела может помочь избежать необходимости в кавычках).

Например, встроенные материалы Qt Quick (шейдеры, лежащие в основе элементов, таких как Image, Text, Rectangle) готовят свои шейдеры с --glsl "100 es,120,150" --hlsl 50 --msl 12. Это делает их совместимыми с OpenGL ES 2.0 и выше, OpenGL 2.1 и выше, и контекстами OpenGL core profile версии 3.2 и выше.

Если шейдер использует функции или конструкции, у которых нет эквивалента в указанных целях, qsb завершится ошибкой. В таком случае потребуется корректировка целевых платформ, что также означает неявную корректировку минимальных системных требований приложения. К примеру, рассмотрите функцию GLSL textureLod доступную только с OpenGL ES 3.0 и выше (что означает GLSL ES 300 или выше). При запросе GLSL 300 es вместо 100 es, qsb выполнится успешно, но приложение, использующее этот файл .qsb будет теперь требовать OpenGL ES 3.0 или выше и не будет совместимо с системами OpenGL ES 2.0.

Ещё один очевидный пример — шейдеры вычислений: шейдеры .comp должны указывать --glsl 310es,430, так как шейдеры вычислений доступны только с OpenGL ES 3.1 или новее и OpenGL 4.3 или новее.

Настройка версии модели шейдера для HLSL или версии языка шейдинга Metal, как правило, требуется редко. Достаточно будет Shader Model 5.0 (--hlsl 50) и MSL 1.2 (--msl 12).

Оптимизация отрисовки сцены Qt Quick

Рендеринг Qt Quick Scene Graph поддерживает пакетную обработку геометрии для уменьшения количества вызовов отрисовки. Подробности см. на страницах Scene Graph. Это основано на вставке кода в функцию main() вершинного шейдера. В Qt 5.x это происходило во время выполнения путём модификации предоставленного кода вершинного шейдера GLSL. В Qt 6 это не вариант. Вместо этого, пакетные варианты вершинных шейдеров могут быть построены инструментом qsb. Это запрашивается аргументом -b. Когда вход не является вершинным шейдером с расширением .vert, он не оказывает влияния. Однако для вершинных шейдеров это приведёт к генерации версий для каждой цели. Qt Quick автоматически выберет правильный вариант (стандартный или пакетный) во время выполнения.

Примечание: Приложениям не нужно беспокоиться о деталях пакетной обработки. Достаточно просто убедиться, что -b (или эквивалентный BATCHABLE ключ, если используется интеграция CMake CMake) указан при обработке вершинных шейдеров. Это актуально только для шейдеров Qt Quick, используемых с ShaderEffect или QSGMaterialShader.

Рассмотрим следующий пример вершинного шейдера:

#version 440
layout(location = 0) in vec4 position;
layout(location = 1) in vec2 texcoord;
layout(location = 0) out vec2 v_texcoord;
layout(std140, binding = 0) uniform buf {
    mat4 mvp;
} ubuf;
out gl_PerVertex { vec4 gl_Position; };

void main()
{
    v_texcoord = texcoord;
    gl_Position = ubuf.mvp * position;
}

Выполнение qsb -b --glsl 330 -o example.vert.qsb example.vert приведёт к:

Stage: Vertex
QSB_VERSION: 5
Has 4 shaders: (unordered list)
  Shader 0: GLSL 330 [Standard]
  Shader 1: GLSL 330 [Batchable]
  Shader 2: SPIR-V 100 [Standard]
  Shader 3: SPIR-V 100 [Batchable]

Reflection info: {
  ...

Обратите внимание, как все языки и версии целей теперь существуют в двух вариантах: Стандартный и слегка изменённый Пакетный.

Вызов внешних инструментов

qsb может вызывать определённые внешние инструменты. Они делятся на две категории: инструменты для оптимизации байткода шейдеров (SPIR-V) и платформо-специфические инструменты для выполнения первой фазы компиляции шейдеров из исходного кода в какой-либо промежуточный байткод-формат.

Они активируются следующими опциями командной строки:

  • -O - вызывает spirv-opt в качестве послеобработки двоичного файла SPIR-V. Файл .qsb будет содержать оптимизированную версию. Предполагается, что spirv-opt доступен в системе (например, из Vulkan SDK) и готов к вызову.
  • -c или --fxc - вызывает fxc.exe, компилятор шейдеров Direct 3D. Полученные данные DXBC (DirectX Byte Code) хранятся в файле .qsb вместо HLSL. Qt автоматически подберёт его во время выполнения, поэтому создателю файла .qsb решать, что включать: исходный код HLSL или промежуточный формат. Всякий раз, когда это возможно, предпочтительнее использовать последний, так как он исключает необходимость парсинга и исходного кода HLSL во время выполнения, что может значительно ускорить создание графического конвейера. Недостаток заключается в том, что этот аргумент может быть использован только при выполнении qsb на Windows.
  • -t или --metallib - вызывает соответствующие инструменты XCode Metal для генерации файла .metallib и включает его в пакет .qsb вместо исходного кода MSL. Эта опция доступна только при запуске qsb на macOS.

Другие опции

  • -D - определяет макрос. Это позволяет использовать #ifdef и аналогичные конструкции в исходном коде GLSL.
  • -g - включает генерацию полной отладочной информации для SPIR-V, что позволяет инструментам, таким как RenderDoc, отображать полный исходный код при проверке конвейера или при отладке вершинного или фрагментного шейдера. Также оказывает влияние на Direct 3D, когда указан -c, поскольку fxc получает указание включать отладочную информацию в сгенерированный промежуточный байткод.

© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-6.1/qtshadertools-qsb.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API