QShaderBaker Class
GLSL/VulkanシェーダーをSPIR-Vにコンパイルし、他のシェーディング言語に翻訳し、リフレクションのメタデータを収集します。詳細...
Header: | #include <QShaderBaker> |
Since: | Qt 6.6 |
パブリック型
GeneratedShader | |
flags | SpirvOptions |
パブリック関数
QShaderBaker() | |
~QShaderBaker() | |
QShader | bake() |
QString | errorMessage() const |
void | setBatchableVertexShaderExtraInputLocation(int location) |
void | setBreakOnShaderTranslationError(bool enable) |
void | setGeneratedShaderVariants(const QList<QShader::Variant> &v) |
void | setGeneratedShaders(const QList<QShaderBaker::GeneratedShader> &v) |
(since 6.7) void | setMultiViewCount(int count) |
void | setPerTargetCompilation(bool enable) |
void | setPreamble(const QByteArray &preamble) |
void | setSourceDevice(QIODevice *device, QShader::Stage stage, const QString &fileName = QString()) |
void | setSourceFileName(const QString &fileName) |
void | setSourceFileName(const QString &fileName, QShader::Stage stage) |
void | setSourceString(const QByteArray &sourceString, QShader::Stage stage, const QString &fileName = QString()) |
void | setTessellationMode(QShaderDescription::TessellationMode mode) |
void | setTessellationOutputVertexCount(int count) |
詳細説明
警告 QShaderBaker は、QShader やQShaderDescription を含む Qt GUI モジュールのQRhi クラスファミリーと同様に、限られた互換性しか保証していません。つまり、APIはアプリケーションが開発されたQtバージョンでのみ動作することが保証されています。しかし、ソース互換性のない変更は最小限に抑えることを目的としており、マイナーリリース(6.7、6.8など)でのみ行われます。このクラスをアプリケーションで使用するには、Qt::ShaderToolsPrivate
(CMake を使用している場合) にリンクし、rhi
のプレフィックスを付けてヘッダをインクルードします。例えば、#include <rhi/qshaderbaker.h>
です。
QShaderBaker はグラフィックス(頂点、フラグメントなど)またはコンピュートシェーダを受け取り、その複数の(ソースまたはバイトコードの)バリエーションを、リフレクション情報とともに生成します。結果はQShader インスタンスで表現され、シンプルで高速なシリアライズとデシリアライズも提供します。
注意: アプリケーションやライブラリは、このクラスを直接使用しないことを推奨します。むしろ、すべての Qt ユーザーは、ビルド時に CMake 経由でqsb
コマンドラインツールを呼び出すことで、オフラインコンパイルに依存することが推奨されます。qsb
ツールは QShaderBaker を使用し、生成されたQShader のシリアライズバージョンをファイルに書き込みます。このクラスの使用は、ユーザー提供のシェーダー・ソース文字列や動的に生成されたシェーダー・ソース文字列を扱う場合など、実行時のコンパイルが避けられない場合に限られるべきです。
入力フォーマットは、現時点では常にVulkan風味のGLSLであると仮定されます。概要についてはGL_KHR_vulkan_glsl 仕様を参照してください。QtShader Tools モジュールは Qt Rendering Hardware Interface モジュールのQRhi クラスと組み合わせて使用することを想定しているため、現時点では多くの概念やコンストラクト(プッシュ定数、ストレージバッファ、サブパスなど)は適用できません。将来的には、HLSLからSPIR-Vへのコンパイルが適切と判断された時点で、ソース形式としてHLSLを有効にするなど、追加オプションが導入される可能性があります。
反射メタデータは、QShader::description()を呼び出すことで、結果のQShader から取得できます。これは、シェーダが期待する頂点入力とシェーダリソースのセットと、それらのレイアウトを発見しなければならないときに不可欠です。
典型的なワークフロー
アプリケーションに次のような頂点シェーダとフラグメントシェーダがあると 仮定しましょう:
頂点シェーダ:
#version 440 layout(location = 0) in vec4 position; layout(location = 1) in vec3 color; layout(location = 0) out vec3 v_color; layout(std140, binding = 0) uniform buf { mat4 mvp; float opacity; }; void main() { v_color = color; gl_Position = mvp * position; }
フラグメントシェーダ
#version 440 layout(location = 0) in vec3 v_color; layout(location = 0) out vec4 fragColor; layout(std140, binding = 0) uniform buf { mat4 mvp; float opacity; }; void main() { fragColor = vec4(v_color * opacity, opacity); }
そのままQRhiGraphicsPipeline に渡せるQShader インスタンスを得るには、シェーダパック生成 をオフラインで行うか、実行時に行うかの 2 つのオプションがあります。
前者ではqsb
ツールを実行します:
qsb --glsl "100 es,120" --hlsl 50 --msl 12 color.vert -o color.vert.qsb qsb --glsl "100 es,120" --hlsl 50 --msl 12 color.frag -o color.frag.qsb
この例ではQRhi に適したトランスレーションターゲットを使用しています。つまり、GLSL/ES 100、GLSL 120、HLSL シェーダモデル 5.0、および Metal Shading Language 1.2 です。
コマンドラインオプションがsetGeneratedShaders() で指定できるものとどのように対応しているかに注意してください。出来上がったファイルが利用可能になると、アプリケーションと一緒に出荷することができ(通常は Qt Resource System の実行ファイルに埋め込まれます)、実行時にロードしてQShader::fromSerialized() に渡すことができます。
qsb
fxc
生成された HLSL または Metal シェーダーコードをバイトコードにコンパイルし、コンパイルされたバージョンをQShader に含めます。ベイクされたシェーダーパックがファイルに書き込まれた後、qsb -d
を実行することで、その内容を調べることができます。詳しくは、--help
とともにqsb
を実行してください。
別の方法は、実行時に同じことを行うことです。これには、QShaderBaker のインスタンスを作成し、setSourceFileName() を呼び出し、setGeneratedShaders() でトランスレーションターゲットを設定します:
baker.setGeneratedShaderVariants({ QShader::StandardShader }); QList<QShaderBaker::GeneratedShader> targets; targets.append({ QShader::SpirvShader, QShaderVersion(100) }); targets.append({ QShader::GlslShader, QShaderVersion(100, QShaderVersion::GlslEs) }); targets.append({ QShader::SpirvShader, QShaderVersion(120) }); targets.append({ QShader::HlslShader, QShaderVersion(50) }); targets.append({ QShader::MslShader, QShaderVersion(12) }); baker.setGeneratedShaders(targets); QShader shaders = baker.bake(); if (!shaders.isValid()) qWarning() << baker.errorMessage();
QShaderも参照してください 。
メンバー関数ドキュメント
QShaderBaker::QShaderBaker()
新しい QShaderBaker を構築します。
[noexcept]
QShaderBaker::~QShaderBaker()
破壊者。
QShader QShaderBaker::bake()
コンパイルと翻訳プロセスを実行する。
QShader インスタンスを返す。処理が成功したかどうかを確認するには、QShader::isValid() を呼び出す。その結果、false
が返されたら、errorMessage() を呼び出してログを取得する。
これは高価な操作である。アプリケーションからこの処理を呼び出す場合は、別のスレッドで実行することをお勧めします。
注: QShaderBaker インスタンスは再利用可能である:bake()を呼び出した後、同じインスタンスを異なる入力で再度使用することができる。ただし、QShaderBaker インスタンスは、その存続期間中、単一のスレッドでのみ使用する必要があります。
QString QShaderBaker::errorMessage() const
最後にbake() を実行したときのエラー・メッセージ、またはエラーがない場合は空文字列を返します。
注意: エラーには、ファイルの読み込みエラー、コンパイル、翻訳の失敗が含まれます。ターゲットやバリアントを要求していない場合は、結果のQShader が無効であってもエラーとしてカウントされません。
void QShaderBaker::setBatchableVertexShaderExtraInputLocation(int location)
QShader::BatchableVertexShader バリアントを生成するとき、location は挿入される頂点入力の入力位置を指定します。この値はデフォルトで 7 であり、頂点シェーダがすでに入力位置 7 を使用している場合にのみオーバーライドする必要があります。
void QShaderBaker::setBreakOnShaderTranslationError(bool enable)
SPIR-V から GLSL/HLSL/MSL への)シェーダ変換に失敗したときの動作を制御します。デフォルトではこの設定はtrueで、要求されたシェーダが生成できない場合、bake ()はエラーで返されます。これを望まず、生成できるものは生成するが、残りは黙ってスキップすることを意図する場合は、enable を false に設定します。
複数の GLSL バージョンをターゲットにすると、ある機能があるバージョンに翻訳 できないときにエラーになることがあります。たとえば、textureSize() を使ったシェーダを GLSL ES 100 に変換しようとすると、bake() の呼び出し全体が失敗し、「textureSize は ESSL 100 ではサポートされていません」というエラーメッセージが表示されます。GLSL ES 100 シェーダが要求されたにもかかわらず、結果に GLSL ES 100 シェーダがないことが許容される場合、このフラグを false に設定すると、bake() は成功します。
void QShaderBaker::setGeneratedShaderVariants(const QList<QShader::Variant> &v)
どのシェーダバリアントを生成するかを指定します。各シェーダバージョンは、結果のQShader に複数のバリアントを持つことができます。
ほとんどの場合、v は単一のエントリ、QShader::StandardShader を含んでいます。
注意: variants が設定されていない場合、結果のQShader は空になり、無効です。
void QShaderBaker::setGeneratedShaders(const QList<QShaderBaker::GeneratedShader> &v)
コンパイルまたは変換するシェーダーの種類を指定します。デフォルトでは何も生成されないため、bake() の前にこの関数を呼び出すことが必須です。
注意: この関数が呼び出されなかったり、v が空であったり、無効な項目しか含まれていない場合、結果として生成されるQShader は空となり、無効となります。
例えば、最小限のベーキングターゲットはSPIR-Vであり、他の言語への追加翻訳はない。これを要求するには、次のようにする:
baker.setGeneratedShaders({ QShader::SpirvShader, QShaderVersion(100) });
注: QShaderBaker は、SPIR-Vと人間が読めるソース・ターゲットのみを扱う。QShader::DxbcShader やQShader::MetalLibShader のようなAPI固有の中間フォーマットへのさらなるコンパイルは、qsb
コマンドラインツールによって実装され、QShaderBaker ランタイムAPIの一部ではない。
[since 6.7]
void QShaderBaker::setMultiViewCount(int count)
マルチビューを使用するシェーダをトランスパイルする場合(たとえば、GL_OVR_multiview2、VK_KHR_multiviewなどに依存するレンダラー用にgl_ViewIndexを使用する頂点シェーダ)、一部のターゲットでは、シェーダ内のビュー数を宣言する必要があります。これは Vulkan スタイルの GLSL コードでは行われず、SPIR-V や HLSL などのターゲットには関係ありませんが、OpenGL や GLSL では必要なため、値を追加のメタデータとして提供する必要があります。
デフォルトでは値は0であり、num_views
ステートメントの注入を無効にします。1を設定しても、デフォルトのnum_views
になるので意味がありません。したがって、count を有効にするには >= 2 でなければならない。たとえば 2 に設定すると、生成される GLSL シェーダにはlayout(num_views = 2) in;
ステートメントが含まれます。
count QSHADER_VIEW_COUNT
は に設定されますが、 拡張は自動的に有効になります。例えば、頂点シェーダとフラグメントシェーダの間で均一バッファを共有し、両方のシェーダが のようなものを記述できる必要がある場合などです。count GL_EXT_multiview
count #if QSHADER_VIEW_COUNT >= 2
この関数は Qt 6.7 で導入されました。
void QShaderBaker::setPerTargetCompilation(bool enable)
ターゲットごとのコンパイルをenable に設定します。 デフォルトではこれは無効で、Vulkan/GLSL ソースはバリアントごとに 1 回 SPIR-V にコンパイルされます。(つまり、Vulkan/GLSL ソースは、バリアントごとに 1 回 SPIR-V にコンパイルされます(デフォルトでは 1 回、バーテックスシェーダの場合は 2 回、Batchable バリアントの場合は要求に応じて 2 回)。その結果、SPIR-V はさまざまなターゲット言語(GLSL、HLSL、MSL)に翻訳されます。
ターゲットごとのコンパイルモードでは、各ターゲット、つまりsetGeneratedShaders() を介して要求された GLSL/HLSL/MSL バージョンごとに、別々の GLSL から SPIR-V へのコンパイルステップがあります。入力ソースは同じですが、ターゲット固有のプリプロセッサ定義が挿入されます。これはかなり時間がかかりますが、アプリケーションが単一のシェーダを提供し、#ifdef
ブロックを使用して区別することができます。このモードが無効な場合、同じことを達成する唯一の方法は、複数のバージョンの シェーダファイルを提供し、それぞれを別々に処理し、それぞれに {.qsb} ファイルを出荷し、ランタイムロジックに基づいて正しいファ イルを選択することです。
このモードでは、以下のマクロが自動的に定義されます。マクロはグラフィック API ではなく、常にシェーディング言語に関連付け られていることに注意してください。
QSHADER_SPIRV
- SPIR-Vをターゲットにするときに定義されます(通常、Vulkanによって消費されます)。QSHADER_SPIRV_VERSION
- ターゲットとする SPIR-V のバージョン番号、例えば 。100
QSHADER_GLSL
- GLSLまたはGLSL ES(通常、OpenGLまたはOpenGL ESによって消費される)をターゲットとする場合に定義されます。QSHADER_GLSL_VERSION
- ターゲットとする GLSL または GLSL ES バージョン番号。 、 、 など。100
300
330
QSHADER_GLSL_ES
- GLSL ESをターゲットとする場合のみ定義されます。QSHADER_HLSL
- HLSL をターゲットとする場合に定義されます(通常、Direct 3D によって消費されます)。QSHADER_HLSL_VERSION
- など、対象となる HLSL シェーダモデルのバージョン。50
QSHADER_MSL
- Metal Shading Language をターゲットとするときに定義される(通常、Metal によって消費される)。QSHADER_MSL_VERSION
- ターゲットとする MSL バージョン、たとえば や など。12
20
これにより、次のようなシェーダコードを書くことができます。
#if QSHADER_HLSL || QSHADER_MSL vec2 uv = vec2(uv_coord.x, 1.0 - uv_coord.y); #else vec2 uv = uv_coord; #endif
注意: バージョン番号は GLSL にインスパイアされたQShaderVersion 構文に従っ ているため、常に単一の整数です。
注意 :QShader あたりQShaderDescription は、個々のターゲットがいくつあろうとも 1 つだけです。したがって、ユニフォームブロックのメンバーや頂点入力などは、上記のマクロを使って条件付きにしてはいけません。
警告 グラフィックスAPIとシェーディング言語のコンセプトの違いに注意してください。QShaderBaker と関連ツールは、シェーディング言語のコンセプトで厳密に動作し、その後に結果がどのように消費されるかは無視されます。したがって、ある日Qtグラフィックススタックの上位レイヤーがVulkan以外のAPIでもSPIR-Vを使用し始めた場合、QSHADER_SPIRVがVulkanを意味するという仮定はもはや成り立たなくなります。
void QShaderBaker::setPreamble(const QByteArray &preamble)
通常のシェーダコードの前に処理されるカスタムpreamble を指定します。
これは単にソース文字列の前に追加するだけではありません: GLSL version ディレクティブの有効性は影響を受けません。報告されるエラーメッセージの行番号も、preamble で指定された内容を無視して変更されません。
プリアンブルの1つの使用例は、動的に生成された#define
ステートメントを透過的に挿入することです。
void QShaderBaker::setSourceDevice(QIODevice *device, QShader::Stage stage, const QString &fileName = QString())
ソースdevice を設定します。QIODevice stage はシェーダステージを指定し、オプションのfileName にはエラーメッセージで使用されるファイル名が含まれます。
void QShaderBaker::setSourceFileName(const QString &fileName)
シェーダー・ソース・ファイルの名前をfileName に設定します。 これはbake() を呼び出すときに読み込まれるファイルです。シェーダのステージは、ファイルの拡張子から自動的に推測されます。これが不要な場合や不可能な場合は、代わりに stage 引数を指定してオーバーロードを使用します。
サポートされているファイル拡張子は
.vert
- 頂点シェーダ.frag
- フラグメント(ピクセル)シェーダ.tesc
- テッセレーション制御(ハル)シェーダ.tese
- テッセレーション評価(ドメイン)シェーダ.geom
- ジオメトリ・シェーダ.comp
- 計算シェーダ
void QShaderBaker::setSourceFileName(const QString &fileName, QShader::Stage stage)
シェーダー・ソース・ファイルの名前をfileName に設定します。これは、bake() を呼び出すときに読み込まれるファイルです。シェーダー・ステージはstage で指定します。
void QShaderBaker::setSourceString(const QByteArray &sourceString, QShader::Stage stage, const QString &fileName = QString())
入力シェーダーを設定するsourceString.stage はシェーダーのステージを指定し、オプションのfileName はエラーメッセージで使用されるファイル名を含む。
void QShaderBaker::setTessellationMode(QShaderDescription::TessellationMode mode)
テセレーション・コントロール・シェーダー用にMSLシェーダー・コードを生成する場合、テセレーションmode (三角形または四角形)を前もって知っておく必要があります。GLSLでは、これは通常テッセレーション評価シェーダで宣言されますが、Metalでは、テッセレーション・コントロール・シェーダからコンピュート・シェーダを生成するときにも知らなければなりません。
設定されていない場合、デフォルトは三角形です。
void QShaderBaker::setTessellationOutputVertexCount(int count)
テセレーション評価シェーダ用のMSLシェーダコードを生成するとき、テセレーション制御シェーダの出力頂点count を前もって知っておく必要があります。GLSLでは、これは通常テセレーション制御シェーダで宣言されますが、Metalでは、テセレーション評価シェーダから頂点シェーダを生成するときにも知っておく必要があります。
設定されていない場合、デフォルト値は3です。
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.