Le manuel QSB
qsb est un outil de ligne de commande fourni par le module Qt Shader Tools. Il intègre des bibliothèques tierces telles que glslang et SPIRV-Cross, invoque éventuellement des outils externes, tels que fxc ou spirv-opt, et génère des fichiers .qsb. En outre, il peut être utilisé pour inspecter le contenu d'un paquetage .qsb.
Usage: qsb [options] file
Qt Shader Baker (using QShader from Qt 6.10.0)
Options:
-?, -h, --help Displays help on commandline options.
--help-all Displays help, including generic Qt 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.
--qt6 Equivalent to --glsl "100 es,120,150" --hlsl 50
--msl 12. This set is commonly used with shaders
for Qt Quick materials and effects.
--msltess Indicates that a vertex shader is going to be
used in a pipeline with tessellation. Mandatory
for vertex shaders planned to be used with
tessellation when targeting Metal (--msl).
--tess-vertex-count <count> The output vertex count from the tessellation
control stage. Mandatory for tessellation
evaluation shaders planned to be used with Metal.
The default value is 3. If it does not match the
tess.control stage, the generated MSL code will
not function as expected.
--tess-mode <mode> The tessellation mode: triangles or quads.
Mandatory for tessellation control shaders
planned to be used with Metal. The default value
is triangles. Isolines are not supported with
Metal. If it does not match the tess.evaluation
stage, the generated MSL code will not function
as expected.
--view-count <num_views> The number of views the shader is used with.
num_views must be >= 2. Mandatory when multiview
rendering is used (gl_ViewIndex). Set only for
vertex shaders that really do rely on multiview
(as the resulting asset is tied to num_views).
Can be set for fragment shaders too, to get
QSHADER_VIEW_COUNT auto-defined. (useful for
ensuring uniform buffer layouts)
-g Generate full debug info for SPIR-V and DXBC
-O Invoke spirv-opt (external tool) to optimize
SPIR-V for performance.
-o, --output <filename> Output file for the shader pack.
--orig-file <filename> Filename to be be used for dependency tracking
instead of <file>.
--qsbversion <version> QSB version to use for the output file. By
default the latest version is automatically used,
use only to bake compatibility versions. F.ex. 64
is Qt 6.4.
-c, --fxc In combination with --hlsl invokes fxc (SM
5.0/5.1) or dxc (SM 6.0+) to store DXBC or DXIL
instead of HLSL.
-t, --metallib In combination with --msl builds a Metal library
with xcrun metal(lib) and stores that instead of
the source. Suitable only when targeting macOS,
not iOS.
-T, --metallib-ios In combination with --msl builds a Metal library
with xcrun metal(lib) and stores that instead of
the source. Suitable only when targeting iOS, not
macOS.
-D, --define <name[=value]> Define macro. This argument can be specified
multiple times.
-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>|...
-r, --replace <what> Switches to replace mode. Replaces the specified
shader in the shader pack with the contents of a
file. This argument can be specified multiple
times. Pass -b to choose the batchable variant.
Also supports adding a shader for a
target/variant that was not present before.
<what>=<target>,<filename> where
<target>=spirv,<version>|glsl,<version>|...
-e, --erase <what> Switches to erase mode. Removes the specified
shader from the shader pack. Pass -b to choose
the batchable variant.
<what>=spirv,<version>|glsl,<version>|...
-s, --silent Enables silent mode. Only fatal errors will be
printed.
--mediump Default to medium precision for floats in
fragment shaders instead of high. GLSL ES only;
ignored for everything else, including GLSL.
--depfile <depfile> Enables generating the depfile for the input
shaders, using the #include statements.
Arguments:
file Vulkan GLSL source file to compile. The file
extension determines the shader stage, and can be
one of .vert, .tesc, .tese, .geom, .frag, .comp.
Note: Tessellation control/evaluation is not
supported with HLSL, instead use -r to inject
handcrafted hull/domain shaders. Some targets may
need special arguments to be set, e.g. MSL
tessellation will likely need --msltess,
--tess-vertex-count, --tess-mode, depending on
the stage. Geometry shaders are not supported
with Metal.Modes de fonctionnement
Il existe cinq modes de fonctionnement principaux :
.qsbgénération de fichiers.qsbinspection de fichiers. Par exemple,qsb -d myshader.frag.qsbimprimera les métadonnées de réflexion (sous forme JSON) et les shaders inclus.- Mode extraction. Il permet d'écrire un shader donné à partir d'un fichier
.qsbexistant dans un fichier séparé. Par exemple,qsb -x spirv,100 -o myshader.spv myshader.frag.qsbécrit le binaire SPIR-V dansmyshader.spv. - Mode remplacement. Ce mode permet de remplacer le contenu d'un ou de plusieurs shaders dans le fichier
.qsbpar le contenu lu dans les fichiers spécifiés. Il est ainsi possible d'injecter du code shader artisanal dans le paquet.qsb. - Mode effacement. Ce mode supprime la variante de nuanceur spécifiée dans le fichier
.qsb.
Exemple
Prenons le fragment shader suivant :
#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);
}L'exécution de qsb -o shader.frag.qsb shader.frag génère shader.frag.qsb. L'inspection de ce fichier à l'aide de qsb -d shader.frag.qsb nous donne les résultats suivants :
Stage: Fragment
QSB_VERSION: 5
Has 1 shaders:
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 bytesPar défaut, seul SPIR-V est généré, de sorte qu'une application utilisant ce package de shaders ne serait fonctionnelle qu'avec Vulkan. Rendons-le plus utile :
qsb --glsl "100 es,120,150" --hlsl 50 --msl 12 -o shader.frag.qsb shader.frag
Cela conduit à générer un package de shaders qui le rend adapté à OpenGL, Direct 3D et Metal également. Les fonctionnalités utilisées dans ce shader sont basiques, et même GLSL ES 100 (le langage d'ombrage d'OpenGL ES 2.0) convient.
L'inspection du résultat montre :
Stage: Fragment
QSB_VERSION: 5
Has 6 shaders:
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;
}
************************************
...Ce paquet peut maintenant être utilisé par Qt Quick avec toutes les API graphiques prises en charge : Vulkan, Direct 3D, Metal, OpenGL et OpenGL ES. Au moment de l'exécution, le shader approprié est récupéré automatiquement par l'interface matérielle de rendu Qt 3D qui se trouve sous Qt Quick et Qt Quick 3D.
Outre la traduction du bytecode SPIR-V en code source de plus haut niveau, le système prend en charge d'autres problèmes, tels que le mappage correct des numéros de liaison SPIR-V sur les ressources natives. Par exemple, avec HLSL, nous avons vu une section comme celle-ci :
Native resource binding map: 0 -> [0, -1] 1 -> [0, 0]
En interne, cela permet de faire correspondre un point de liaison de style SPIR-V 0 au registre HLSL b0 et de lier 1 à t0 et s0. Cela aide à rendre les différences dans les liaisons de ressources entre les divers langages d'ombrage transparentes pour les utilisateurs de l'interface matérielle de rendu, et permet à tout dans Qt de fonctionner avec des points de liaison de style Vulkan/SPIR-V tels qu'ils sont spécifiés dans le code source GLSL original de style Vulkan.
Types de shaders
Le type de shader est déduit de l'extension du fichier d'entrée. Ainsi, l'extension doit être l'une des suivantes :
.vert- pour les nuanceurs de sommets.tesc- pour les shaders de contrôle de tessellation.tese- pour les nuanceurs d'évaluation de tessellation.geom- pour les nuanceurs de géométrie.frag- pour les nuanceurs de fragments (pixels).comp- pour les shaders de calcul
Remarque : les nuanceurs de contrôle et d'évaluation de la tessellation ne sont actuellement pas pris en charge par Direct 3D (HLSL).
Langages et versions d'ombrage
SPIR-V 1.0 est toujours généré. Ce qui est généré en plus dépend des arguments de la ligne de commande --glsl, --hlsl, et --msl.
Ces paramètres sont tous suivis d'une liste séparée par des virgules. La liste doit inclure des numéros de version de style GLSL, avec un suffixe optionnel (es, indiquant GLSL ES). L'espace entre le suffixe et la version est facultatif (l'absence d'espace peut permettre d'éviter l'utilisation de guillemets).
Par exemple, les matériaux intégrés de Qt Quick(les shaders qui soutiennent les éléments, tels que Image, Text, Rectangle) préparent tous leurs shaders avec --glsl "100 es,120,150" --hlsl 50 --msl 12. Cela les rend compatibles avec OpenGL ES 2.0 et plus, OpenGL 2.1 et plus, et les contextes de profil de base OpenGL de la version 3.2 et plus.
Si le shader utilise des fonctions ou des constructions qui n'ont pas d'équivalent dans les cibles spécifiées, qsb échouera. Si c'est le cas, les cibles devront être ajustées, ce qui signifie également que les exigences minimales du système de l'application sont ajustées implicitement. Prenons l'exemple de la fonction GLSL textureLod qui n'est disponible qu'avec OpenGL ES 3.0 et plus (c'est-à-dire GLSL ES 300 ou plus). Si l'on demande la fonction GLSL 300 es au lieu de 100 es, qsb réussira, mais l'application utilisant ce fichier .qsb nécessitera désormais OpenGL ES 3.0 ou plus et ne sera pas compatible avec les systèmes basés sur OpenGL ES 2.0.
Un autre exemple évident est celui des shaders de calcul : les shaders .comp devront spécifier --glsl 310es,430 car les shaders de calcul ne sont disponibles qu'avec OpenGL ES 3.1 ou plus récent et OpenGL 4.3 ou plus récent.
L'ajustement de la version du modèle de shaders pour HLSL, ou la version du Metal Shading Language devrait être rarement nécessaire. Shader Model 5.0 (--hlsl 50) et MSL 1.2 (--msl 12) seront généralement suffisants.
Qt Quick Mise en lots du graphe de scène
Le moteur de rendu du graphe de scène Qt Quick prend en charge la mise en lots de la géométrie afin de réduire le nombre d'appels de dessin. Voir les pages du Scene Graph pour plus de détails. Cela repose sur l'injection de code dans la fonction main() du vertex shader. Dans Qt 5.x, cela se faisait au moment de l'exécution, en modifiant le code du vertex shader GLSL fourni. Dans Qt 6, ce n'est pas une option. Au lieu de cela, des variantes de vertex shaders pouvant être traitées par lots peuvent être construites par l'outil qsb. Ceci est demandé par l'argument -b. Lorsque l'entrée n'est pas un vertex shader avec l'extension .vert, cela n'a aucun effet. Pour les vertex shaders, cependant, cela conduira à générer deux versions pour chaque cible. Qt Quick choisira alors automatiquement la bonne variante (standard ou batchable) au moment de l'exécution.
Remarque : les applications ne doivent pas se préoccuper des détails de la mise en lots. Elles doivent simplement s'assurer que -b (ou le mot-clé équivalent BATCHABLE si elles utilisent l'intégration CMake) est spécifié lors du traitement des nuanceurs de vertex. Cela ne concerne que les nuanceurs Qt Quick utilisés avec ShaderEffect ou QSGMaterialShader.
Prenons l'exemple suivant de nuanceur de vertex :
#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;
void main()
{
v_texcoord = texcoord;
gl_Position = ubuf.mvp * position;
}L'exécution de qsb -b --glsl 330 -o example.vert.qsb example.vert conduit à :
Stage: Vertex
QSB_VERSION: 5
Has 4 shaders:
Shader 0: GLSL 330 [Standard]
Shader 1: GLSL 330 [Batchable]
Shader 2: SPIR-V 100 [Standard]
Shader 3: SPIR-V 100 [Batchable]
Reflection info: {
...Notez que tous les langages et versions cibles existent désormais en deux variantes : Standard et Batchable légèrement modifié.
Invoquer des outils externes
qsb Le logiciel peut invoquer certains outils externes. Ceux-ci se répartissent en deux catégories : les outils permettant d'effectuer des optimisations sur le bytecode des shaders (SPIR-V), et les outils spécifiques à la plate-forme permettant d'effectuer la première phase de la compilation des shaders, des sources vers un format de bytecode intermédiaire.
Ces outils sont activés par les options de ligne de commande suivantes :
-O- invoquespirv-optcomme étape de post-traitement du binaire SPIR-V. Le fichier.qsbinclura la version optimisée. Cela suppose quespirv-optest disponible sur le système (par exemple, à partir du SDK Vulkan) et prêt à être invoqué.-cou--fxc- invoquefxc.exe, le compilateur de shaders Direct 3D. Les donnéesDXBC(DirectX Byte Code) qui en résultent sont stockées dans le fichier.qsbau lieu de HLSL. Qt Creator les récupère automatiquement au moment de l'exécution, c'est donc au créateur du fichier.qsbde décider ce qu'il veut inclure, la source HLSL ou le format intermédiaire. Dans la mesure du possible, préférez ce dernier car il élimine le besoin d'analyser une source HLSL au moment de l'exécution, ce qui conduit à des gains de performance potentiellement significatifs lors de la création du pipeline graphique. L'inconvénient est que cet argument ne peut être utilisé que lorsqueqsbfonctionne sous Windows.-tor--metallib- invoque les outils XCode Metal appropriés pour générer un fichier .metallib et l'inclut dans le paquet.qsbau lieu du code source MSL. Cette option n'est disponible que lorsqueqsbfonctionne sous macOS.
Autres options
-D- définit une macro. Cela permet d'utiliser #ifdef et autres dans le code source GLSL.-g- permet de générer des informations de débogage complètes pour SPIR-V, permettant ainsi à des outils comme RenderDoc d'afficher la source complète lors de l'inspection d'un pipeline ou lors du débogage des vertex ou des fragments. A également un effet pour Direct 3D lorsque-cest spécifié, carfxcest alors chargé d'inclure des informations de débogage dans le bytecode intermédiaire généré.--mediump- demande une précision moyenne par défaut pour les flottants dans les nuanceurs de fragments GLSL ES. Ignoré pour toutes les autres cibles, y compris GLSL (non ES), et pour les nuanceurs non fragmentés.--orig-file- spécifie le nom de fichier utilisé à la place du fichier source d'entrée lors de la génération des fichiers de dépendance pour CMake (-depfiles). Ceci est utile lorsque le fichier passé à qsb est un fichier source intermédiaire généré pour les shaders. Cependant, pour le suivi des dépendances, c'est souvent le fichier original qui doit être utilisé.
Tessellation
--msltess- Indique que le vertex shader est utilisé dans un pipeline qui comprend des étapes de tessellation. N'a pas d'effet pour les autres types de shaders et lorsque la génération de shaders MSL n'est pas activée. S'il n'est pas spécifié, le nuanceur de sommets ne sera pas fonctionnel sur Metal en combinaison avec la tessellation.--tess-vertex-count <count>- Spécifie le nombre de vertex en sortie de l'étage de contrôle de la tessellation. Cette valeur est obligatoire pour les nuanceurs d'évaluation de tessellation utilisés avec Metal. La valeur par défaut est 3. Si elle ne correspond pas à l'étape de contrôle de la tessellation, le code MSL généré ne fonctionnera pas comme prévu.--tess-mode <mode>- Cette option spécifie le mode de tessellation. Elle peut prendre l'une des deux valeurs suivantes :trianglesouquads. La valeur par défaut esttriangles. Cette option est obligatoire pour les shaders de contrôle de tessellation utilisés avec Metal. La valeur doit correspondre à l'étape d'évaluation de la tessellation, sinon le code MSL généré ne fonctionnera pas comme prévu.
Multiview
Prenons le vertex shader suivant. Il est écrit en GLSL compatible avec Vulkan, ce qui permet à l'extension GL_EXT_multiview de rendre l'utilisation de gl_ViewIndex légale.
#version 440
#extension GL_EXT_multiview : require
layout(location = 0) in vec4 pos;
layout(std140, binding = 0) uniform buf
{
mat4 mvp[2];
};
void main()
{
gl_Position = mvp[gl_ViewIndex] * pos;
}Note : En pratique, la ligne #extension GL_EXT_multiview ne sera pas nécessaire dans le code source passé à qsb, parce que passer l'argument --view-count décrit ci-dessous injecte automatiquement cette ligne dans le code source du shader avant de compiler à SPIR-V.
Pour Vulkan, cela fonctionne tel quel, tant que Vulkan 1.1 est pris en charge au moment de l'exécution. Voir VK_KHR_multiview pour plus de détails.
Pour générer un vertex shader HLSL à partir de ce qui précède pour Direct 3D 12 (voir view instancing pour plus de détails), la version minimale du modèle de shader est 6.1, ce qui signifie que qsb échouera si l'on spécifie par exemple --hlsl 50. Utilisez au moins --hlsl 61 lorsque vous traitez un vertex shader multiview. Le multiview n'est pas pris en charge par Direct 3D 11.
Pour OpenGL, des métadonnées supplémentaires sont nécessaires :
--view-count- Lors de la transposition d'un nuanceur ci-dessus (après compilation en SPIR-V) en code source GLSL compatible OpenGL, il ne suffit pas de faire correspondregl_ViewIndexàgl_ViewID_OVR, mais le nombre de vues doit également être déclaré dans le nuanceur. En passant une valeur de 2 à l'argument--view-count, on injecte une déclarationlayout(num_views = 2) in;dans le code source GLSL généré, ce qui en fait un nuanceur GLSL (OpenGL) valide. Voir GL_OVR_multiview pour plus de détails et noter que les shaders GLSL générés nécessitent également que GL_OVR_multiview2 soit supporté à l'exécution puisque c'est ce qui sera requis par la directive#extensiondans le code source du shader généré.
Lorsque l'on cible OpenGL (ES) avec un tel vertex shader, la version GLSL générée (--glsl) doit être au moins 330 ou 300 es. La première n'est pas imposée par qsb ou QShaderBaker, mais en pratique, les implémentations OpenGL sont connues pour rejeter de tels shaders si la version GLSL est 150 ou plus petite. Il est donc recommandé de passer --glsl 330,300es lors du conditionnement des vertex shaders activant GL_EXT_multiview.
Spécifier --view-count génère et injecte automatiquement une définition de préprocesseur : #define QSHADER_VIEW_COUNT n où n est le nombre de vues. Lorsque le nombre de vues n'est pas fourni, la définition n'est pas définie du tout. Cela permet d'écrire du code comme celui qui suit et d'utiliser le même fichier source pour toutes les variantes du nuanceur spécifiques au nombre de vues.
layout(std140, binding = 0) uniform buf {
#if QSHADER_VIEW_COUNT >= 2
mat4 matrix[QSHADER_VIEW_COUNT];
#else
mat4 matrix;
#endif
float opacity;
};En outre, la ligne #extension GL_EXT_multiview : require est générée automatiquement dans les vertex shaders lorsqu'un nombre de vues de 2 ou plus est défini. Cela réduit le nombre de lignes supplémentaires à ajouter pour la prise en charge des vues multiples dans un nuanceur de sommets.
La définition du nombre de vues peut également s'avérer utile pour d'autres types de nuanceurs. Par exemple, lors du partage d'un tampon uniforme entre le vertex et le fragment shader, et lorsque les deux shaders doivent assurer la même disposition du tampon, il peut être utile de pouvoir écrire #if QSHADER_VIEW_COUNT >= 2 dans les deux fichiers sources. Cela peut être assuré en spécifiant --view-count pour les deux lors de l'invocation de qsb.
Note : S'appuyer directement sur le mot-clé gl_ViewIndex dans une étape non-vertex, par exemple dans un fragment shader, n'est pas portable pour le moment et doit être évité.
Travailler avec des fonctionnalités GLSL spécifiques à OpenGL
Il peut parfois être nécessaire d'utiliser des constructions de langage d'ombrage qui sont spécifiques à OpenGL et GLSL, et qui ne sont pas applicables à d'autres langages d'ombrage, formats intermédiaires, et APIs graphiques.
Les textures externes et les échantillonneurs d'OpenGL ES en sont les meilleurs exemples. L'implémentation de la lecture vidéo ou l'affichage d'un viseur de caméra peut impliquer, selon la plateforme, de travailler avec des objets de texture OpenGL qui ne sont pas destinés à être utilisés comme des textures 2D normales, mais qui sont plutôt utilisables, avec un ensemble limité de fonctionnalités, via le point de liaison GL_TEXTURE_EXTERNAL_OES dans l'API OpenGL et le type d'échantillonneur samplerExternalOES dans les shaders. Ce dernier présente un problème potentiel lors de l'utilisation du pipeline de shaders basé sur SPIR-V de Qt : l'exécution d'un tel shader à travers qsb résultera en un échec dû au fait que samplerExternalOES n'est pas accepté comme un type valide parce qu'il n'est pas mappable à SPIR-V et à d'autres langages d'ombrage cibles.
Pour résoudre ce problème, qsb offre la possibilité de remplacer le contenu d'une variante de shader donnée dans un fichier .qsb par des données fournies par l'utilisateur qui sont lues à partir d'un fichier, remplaçant complètement le code source ou le code byte du shader original généré par qsb.
Prenons l'exemple du fragment shader suivant. Notez le type de tex. Que se passe-t-il si le type doit être samplerExternalOES lors de l'exécution avec OpenGL ES ?
#version 440
layout(location = 0) in vec2 texCoord;
layout(location = 0) out vec4 fragColor;
layout(std140, binding = 0) uniform buf {
float opacity;
} ubuf;
layout(binding = 1) uniform sampler2D tex;
void main()
{
fragColor = texture(tex, texCoord).rgba * ubuf.opacity;
}Changer simplement le type de samplerExternalOES n'est pas faisable. Cela conduit immédiatement à des erreurs de compilation.
Il y a une solution simple, cependant : écrire une version séparée, purement ciblée OpenGL ES du shader, et l'injecter dans le fichier .qsb. Le shader suivant n'est compatible qu'avec GLSL ES et ne peut pas être exécuté par qsb. Cependant, nous savons qu'il peut être traité par OpenGL ES au moment de l'exécution.
precision highp float;
#extension GL_OES_EGL_image_external : require
varying vec2 texCoord;
struct buf
{
float opacity;
};
uniform buf ubuf;
uniform samplerExternalOES tex;
void main()
{
gl_FragColor = texture2D(tex, texCoord).rgba * ubuf.opacity;
}Appelons-le shader_gles.frag. Une fois que qsb --glsl 100es -o shader.frag.qsb shader.frag est terminé, nous donnant un fichier .qsb (à moitié prêt), nous pouvons faire qsb -r glsl,100es,shader_gles.frag shader.frag.qsb pour mettre à jour shader.frag.qsb en remplaçant le shader pour GLSL 100 es avec le contenu du fichier spécifié (shader_gles.frag). Maintenant shader.frag.qsb est prêt à être utilisé au moment de l'exécution avec OpenGL ES.
Note : Veillez à ce que l'interface entre le shader et l'application reste inchangée. Inspectez toujours le code GLSL généré par qsb en premier, soit en imprimant le contenu du fichier .qsb via l'option -d, soit en extrayant le shader GLSL ES 100 en exécutant qsb -x glsl,100es -o gles_shader.frag shader.frag.qsb. Les noms de structures, de membres de structures et d'uniformes ne doivent pas non plus différer dans la version injectée manuellement.
Remarque : la possibilité de placer des données provenant de fichiers arbitraires dans le paquet .qsb peut également être utilisée pour injecter des shaders HLSL de coque et de domaine créés à la main, afin de rendre les pipelines graphiques basés sur la tessellation également fonctionnels avec Direct 3D.
© 2026 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.