将为OpenGL ES版本编写的GLSL编译为Vulkan

时间:2016-06-17 15:22:00

标签: vulkan

我的问题类似于this one但是(有用的)给定答案的一部分与基于OpenGL ES ESSL 3.10的vulkan编译GLSL不兼容。

为了在顶点着色器和片段着色器中使用推送常量存储器的单独部分,建议的解决方案是在推式常量结构的第一个成员之前使用布局(offset =#)。

尝试在GLSL ES 310代码中执行此操作会导致错误“'块成员上的偏移':此配置文件不支持:es”。

是否有一种支持的方式来声明与es?

兼容的偏移量

我发现的唯一解决方法是在片段着色器中声明一堆虚拟变量。当我这样做时,如果我没有在VkPipelineLayoutCreateInfo中声明片段着色器的推送常量缓冲区的全部范围,则会出现验证层错误。修复之后,我得到关于“vkCreatePipelineLayout()调用具有重叠范围的推送常量的验证层警告”。

显然我可以忽略警告,但如果有更整洁的解决方案,那就更好了。

简单的例子,这与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;
}

然而这不是:

#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;
}

将我所有的310 ES着色器代码转换为430可以解决我的问题,但这并不理想。 GL_ARB_enhanced_layouts不适用于310 ES代码,所以我的问题不是为什么它不起作用,而是我在ES中有任何选项来实现相同的目标吗?

2 个答案:

答案 0 :(得分:3)

我认为这是GLSL编译器中的一个错误。

这是怎么回事。有些东西可以将Vulkan 添加的GLSL编译为defined by KHR_vulkan_glsl。例如,push_constant布局显式添加到GLSL语法中。

但是,某些事情没有添加到该语言中。对您的用例重要的是能够将偏移量应用于统一块的成员。哦,是的,KHR_vulkan_glsl 在构建着色器的块布局时使用该信息。但允许你说layout(offset=#)语法是由GLSL定义的,而不是由KHR_vulkan_glsl定义的。

该语法不是任何版本的GLSL-ES的一部分。我所知道的任何ES扩展都没有提供它。所以你不能使用它。

我想说,在为Vulkan编译着色器时,参考编译器应该无法编译任何基于GLSL-ES的版本,或者无声地忽略任何版本和扩展声明,并且只是假设桌面GLSL 4.50。

关于你能做些什么......没什么。如果没有将该解决方案自行解决到编译器中,那么您的主要解决方案是针对桌面OpenGL的版本编写代码。像4.50。

答案 1 :(得分:1)

如果你为Vulkan编译SPIR-V,你的着色器中有一个“VULKAN”定义集(见GL_KHR_VULKAN_glsl),所以你可以这样做:

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