我有一个带有以下推送常量块的几何着色器:
layout(push_constant) uniform Instance {
mat4 VP;
vec3 posCam;
float radius;
float curvature;
} u_instance;
推送常量在管道布局中定义如下:
uint32_t offset = 0;
uint32_t size = 21 *sizeof(float);
vk::PushConstantRange range {vk::ShaderStageFlagBits::eGeometry,offset,size};
但是,Vulkan验证图层会抛出此错误:
Push constant range covering variable starting at offset 0 not accessible from stage VK_SHADER_STAGE_GEOMETRY_BIT
“无法访问”是什么意思?他们为什么不能进入?如果我将推动常数移动到不同的阶段(例如片段或顶点着色器),则不会发生错误。
此外,我只在Nvidia GeForce GTX 650 Ti上出现此错误。我也在AMD卡上试过它,效果很好。
几何着色器的推动常量是否存在某种限制?我已经检查了我的Nvidia GPU的限制,总的最大推送常量大小是256字节,并且支持几何着色器。我也无法在Vulkan规范中找到任何内容。
答案 0 :(得分:2)
我认为std430打包规则(或 14.5.4。Vulkan规范的Offset和Stride Assignment )可能会搞乱这些规模。例如。 vec3将被设置为vec4(所以也许 22*sizeof(float)
? - 对不起,我自己也对此毫无信心)。
如果您想自己调查(并且我找到了生成该报告的行),则图层代码已打开:https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/blob/master/layers/core_validation.cpp#L1976
更新:
我不认为我就在上面。什么1.0.17 SDK glslangValidator
给我是 84字节(21 *浮点数;成员偏移量分别为0,64,76和80)。虽然整个区块被填充到16的倍数(整块大小为96 B)。
此外,消息与提供的阶段枚举相关联(它将它与着色器模块的阶段进行比较)。奇怪的是,错误消息在实现之间会有所不同......(确保你已经更新了SDK和驱动程序,并且怀疑vkcpp
包装器或发布的代码是什么)并检查{{1使用的pStages[n].stage
成员和PushRange阶段值(图层比较)。
答案 1 :(得分:2)
您能否添加更多代码(或将其上传到某个地方)?我刚刚在GTX 980上使用推送常量块对此进行了测试,其中验证层是从源代码编译的,并且没有得到任何验证警告。
此外,我只在Nvidia GeForce GTX 650 Ti上出现此错误。我也在AMD卡上试过它,效果很好。
这很奇怪,因为验证消息不是由驱动程序生成的,因此实现之间不应该有所不同(除非它是与设备限制相关的验证)。
几何着色器的推动常量是否存在某种限制?我已经检查了我的Nvidia GPU的限制,总的最大推送常量大小是256字节,并且支持几何着色器。我也无法在Vulkan规范中找到任何内容。
没有特定于几何着色器的推动常量限制。如果超过推送常量大小限制,验证层将引发错误。
我认为std430打包规则(或14.5.4.Vulkan规范的偏移和步幅分配)可能会弄乱大小。例如。 vec3将被设置为vec4(所以也许22 * sizeof(浮动)? - 对不起,我自己也不确定。)
不确定打包是否会成为问题,但基本上这应该没有验证层消息。如果步幅是一个问题,如果以偏移0开始,验证层仍然不应该触发任何内容。