3

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

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 规范中也找不到任何东西。

4

2 回答 2

2

我认为 std430 打包规则(或14.5.4. Vulkan 规范的偏移和步幅分配)可能会弄乱大小。例如,vec3 将被布置为 vec4(所以也许22*sizeof(float)?-抱歉,我自己对此并不完全有信心)。

如果您想自己调查,图层代码是开放的(我发现生成该报告的行):https ://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/blob/master/layers/core_validation.cpp#L1976

更新:我不认为我是正确的。1.0.17 SDKglslangValidator给我的是84 字节(21*float;成员偏移量分别为 0、64、76 和 80)。对我来说,整个块被填充到 16 的倍数(整个块大小为 96 B)。

此外,消息与提供的阶段枚举相关联(它将它与着色器模块的阶段进行比较)。很奇怪,错误消息在实现之间会有所不同......(确保您已经更新了 SDK 和驱动程序,并怀疑vkcpp包装器或发布的代码是什么)并检查pStages[n].stageused 的成员VkGraphicsPipelineCreateInfo和 PushRange 阶段值(哪个层比较)

于 2016-06-29T12:32:37.603 回答
2

您能否添加更多代码(或将其上传到某个地方)?我刚刚在 GTX 980 上用你的 push constant 块测试了这个,验证层是从源代码编译的,没有收到任何验证警告。

此外,我只在 Nvidia GeForce GTX 650 Ti 上收到此错误。我也在 AMD 卡上试过,效果很好。

这很奇怪,因为验证消息不是由驱动程序生成的,因此在实现之间不应有所不同(除非它是与设备限制相关的验证)。

几何着色器的推送常量是否有某种限制?我检查了我的 Nvidia GPU 的限制,总最大推送常量大小为 256 字节,并且支持几何着色器。我在 Vulkan 规范中也找不到任何东西。

没有特定于几何着色器的推送常数限制。如果超过推送常量大小限制,验证层将抛出错误。

我认为 std430 打包规则(或 14.5.4. Vulkan 规范的偏移和步幅分配)可能会弄乱大小。例如,vec3 将被布置为 vec4(所以可能是 22*sizeof(float)? - 抱歉,我自己对此并不完全有信心)。

不确定打包在这里是否会成为问题,但基本上这应该在没有验证层消息的情况下工作。如果步幅是一个问题,如果您从偏移量 0 开始,验证层应该仍然不会触发任何东西。

于 2016-06-29T17:55:41.717 回答