6 votes

Compilant GLSL écrit pour les versions OpenGL ES vers Vulkan

Ma question est similaire à celle-ci mais une partie de la réponse (utile) n'est pas compatible avec la compilation de GLSL pour Vulkan basée sur OpenGL ES ESSL 3.10.

Pour utiliser une section distincte de la mémoire push constant dans le vertex shader et le fragment shader, la solution suggérée est d'utiliser layout(offset = #) avant le premier membre de la structure push constant.

Essayer de le faire dans le code GLSL ES 310 conduit à l'erreur "'offset on block member': not supported with this profile: es".

Existe-t-il un moyen pris en charge pour déclarer un tel décalage qui est compatible avec es?

La seule solution de contournement que j'ai trouvée est de déclarer un tas de variables fictives dans le fragment shader. Lorsque je le fais, j'obtiens des erreurs de couche de validation si je ne déclare pas la plage complète du tampon push constant du fragment shader dans VkPipelineLayoutCreateInfo. Après avoir corrigé cela, j'obtiens des avertissements de la couche de validation sur "l'appel vkCreatePipelineLayout() a des push constants avec des plages qui se chevauchent".

Évidemment je peux ignorer les avertissements, mais s'il y a une solution plus propre, alors ce serait beaucoup plus préférable.

Exemple simple, ceci compile avec succès avec VulkanSDK\1.0.13.0\Bin\glslangValidator.exe:

#version 430
#extension GL_ARB_enhanced_layouts: enable

layout(std140, push_constant) uniform PushConstants
{
        layout(offset=64) mat4 matWorldViewProj;
} ubuf;

layout(location = 0) in vec4 i_Position;

void main() {
    gl_Position = ubuf.matWorldViewProj * i_Position;
}

Alors que ceci ne le fait pas :

#version 310 es
#extension GL_ARB_enhanced_layouts: enable

layout(std140, push_constant) uniform PushConstants
{
        layout(offset=64) mat4 matWorldViewProj;
} ubuf;

layout(location = 0) in vec4 i_Position;

void main() {
    gl_Position = ubuf.matWorldViewProj * i_Position;
}

Convertir tout mon code shader 310 ES en 430 résoudrait mon problème, mais ce ne serait pas idéal. GL_ARB_enhanced_layouts ne s'applique pas au code 310 ES, donc ma question ne concerne pas pourquoi cela ne fonctionne pas, mais plutôt, ai-je des options en ES pour atteindre le même objectif?

3voto

Nicol Bolas Points 133791

Je considérerais cela comme une erreur dans le compilateur GLSL.

Ce qui se passe, c'est ceci. Il y a certaines choses que la compilation du GLSL pour Vulkan ajoute au langage, tel que défini par KHR_vulkan_glsl. Par exemple, la disposition push_constant est explicitement ajoutée à la syntaxe GLSL.

Cependant, il y a certaines choses qu'elle n'ajoute pas au langage. Pour votre cas d'utilisation, il est important de pouvoir appliquer des décalages aux membres des blocs uniformes. Oh oui, KHR_vulkan_glsl utilise cette information lors de la construction de la mise en page du bloc du shader. Mais la grammaire qui vous permet de dire layout(offset=#) est définie par GLSL, et non par KHR_vulkan_glsl.

Et cette grammaire ne fait pas partie de quelque version de GLSL-ES. Elle n'est pas non plus fournie par une extension ES que je connais. Vous ne pouvez donc pas l'utiliser.

Je dirais que le compilateur de référence devrait, lors de la compilation d'un shader pour Vulkan, soit échouer à compiler toute version basée sur GLSL-ES, soit ignorer silencieusement toute version et extension déclarées, et supposer simplement GLSL 4.50 pour desktop.

Quant à ce que vous pouvez faire à ce sujet... rien. À part pirater cette solution dans le compilateur vous-même, votre solution principale est d'écrire votre code contre des versions de OpenGL desktop. Comme 4.50.

1voto

Sascha Willems Points 2084

Si vous compilez du SPIR-V pour Vulkan, il y a une définition "VULKAN" définie dans vos shaders (voir GL_KHR_VULKAN_glsl), vous pourriez donc faire quelque chose comme ceci :

#ifdef VULKAN
    layout(push_constant) uniform pushConstants {
        vec4 (offset = 12) pos;
    } pushConstBlock;
#else
    // Choses GLES
#endif

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X