【发布时间】:2016-06-17 15:21:59
【问题描述】:
我的问题类似于this one,但部分(有用的)给出的答案与基于 OpenGL ES ESSL 3.10 为 vulkan 编译 GLSL 不兼容。
为了在顶点着色器和片段着色器中使用单独的推送常量内存部分,建议的解决方案是在推送常量结构的第一个成员之前使用 layout(offset = #)。
尝试在 GLSL ES 310 代码中执行此操作会导致错误“'offset on block member': not supported with this profile: 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 中是否有任何选项可以实现相同的目标?
【问题讨论】:
-
"将我所有的 310 ES 着色器代码转换为 430 可以解决我的问题,但这并不理想。" 您的着色器被编写为供 使用Vulkan,而不是 OpenGL ES。那么为什么必须对它们进行更改才能使其正常工作不是“理想的”呢?为什么要使用 ES 版本 3.10 附加到着色器?
-
随着这个问题不断获得偶尔的观点和支持,我想我会跟进。我的目标是移动设备,包括 OpenGLES2 和 Metal 设备,并希望使用 SPIR-V cross 将单个着色器集交叉编译到我的所有目标平台。我坚持使用 310 ES+GL_KHR_vulkan_glsl,并破解了 glslang 和 SPIRV-Cross 以允许布局偏移(对于 Vulkan)和 lowp(对于 GLES2)。 Glslang 和 SPIRV-Cross 都是开源的,并且相对容易修改以满足我的需求 - YMMV。
标签: vulkan