在几何着色器中按常量限制?

时间:2016-06-29 10:51:46

标签: glsl shader geometry-shader vulkan

我有一个带有以下推送常量块的几何着色器:

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规范中找到任何内容。

2 个答案:

答案 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开始,验证层仍然不应该触发任何内容。