Fix NonWritable check when vertexPipelineStoresAndAtomics not enabled
karl-lunarg opened this issue · 4 comments
Issue by greg-lunarg (MIGRATED)
Wednesday Mar 28, 2018 at 21:29 GMT
Originally opened as KhronosGroup/Vulkan-LoaderAndValidationLayers#2526
The following Vulkan validation layer error starting popping up on code that previously executed without error:
SC(ERROR / SPEC): object: 0x0 type: 0 msgNum: 15 - Shader requires VkPhysicalDeviceFeatures::vertexPipelineStoresAndAtom
ics but is not enabled on the device
SC(ERROR): object: 0x0 type: 0 location: 1167 msg_code: 15: Object: 0x0 | Shader requires VkPhysicalDeviceFeatures::vert
exPipelineStoresAndAtomics but is not enabled on the device
We believe that this error is being reported due to the following recent change to Vulkan validation layers:
KhronosGroup/Vulkan-LoaderAndValidationLayers#2466
From the PR: While walking the shader for used descriptors, also determine whether any used buffers/images/texelbuffers are not decorated with NonWritable.
From the Vulkan spec:
vertexPipelineStoresAndAtomics indicates whether storage buffers and images support stores and atomic operations in the vertex, tessellation, and geometry shader stages. If this feature is not enabled, all storage image, storage texel buffers, and storage buffer variables used by these stages in shader modules must be decorated with the NonWriteable decoration (or the readonly memory qualifier in GLSL).
Here is the shader:
#version 310 es
layout(location = 0) in vec3 in_pos;
layout(location = 1) in vec3 in_normal;
layout(std140, set = 0, binding = 0) readonly buffer param_block {
vec3 light_pos;
vec3 light_color;
mat4 model;
mat4 view_projection;
float alpha;
} params;
layout(location = 0) out vec3 color;
layout(location = 1) out float alpha;
void main()
{
vec3 world_light = vec3(params.model * vec4(params.light_pos, 1.0));
vec3 world_pos = vec3(params.model * vec4(in_pos, 1.0));
vec3 world_normal = mat3(params.model) * in_normal;
vec3 light_dir = world_light - world_pos;
float brightness = dot(light_dir, world_normal) / length(light_dir) / length(world_normal);
brightness = abs(brightness);
gl_Position = params.view_projection * vec4(world_pos, 1.0);
color = params.light_color * brightness;
alpha = params.alpha;
}
and here is the SPIR-V:
// Module Version 10000
// Generated by (magic number): 80005
// Id's are bound by 114
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Vertex 4 "main" 38 67 89 102 109
Source ESSL 310
Name 4 "main"
Name 9 "world_light"
Name 12 "param_block"
MemberName 12(param_block) 0 "light_pos"
MemberName 12(param_block) 1 "light_color"
MemberName 12(param_block) 2 "model"
MemberName 12(param_block) 3 "view_projection"
MemberName 12(param_block) 4 "alpha"
Name 14 "params"
Name 34 "world_pos"
Name 38 "in_pos"
Name 49 "world_normal"
Name 67 "in_normal"
Name 70 "light_dir"
Name 75 "brightness"
Name 87 "gl_PerVertex"
MemberName 87(gl_PerVertex) 0 "gl_Position"
MemberName 87(gl_PerVertex) 1 "gl_PointSize"
Name 89 ""
Name 102 "color"
Name 109 "alpha"
MemberDecorate 12(param_block) 0 NonWritable
MemberDecorate 12(param_block) 0 Offset 0
MemberDecorate 12(param_block) 1 NonWritable
MemberDecorate 12(param_block) 1 Offset 16
MemberDecorate 12(param_block) 2 ColMajor
MemberDecorate 12(param_block) 2 NonWritable
MemberDecorate 12(param_block) 2 Offset 32
MemberDecorate 12(param_block) 2 MatrixStride 16
MemberDecorate 12(param_block) 3 ColMajor
MemberDecorate 12(param_block) 3 NonWritable
MemberDecorate 12(param_block) 3 Offset 96
MemberDecorate 12(param_block) 3 MatrixStride 16
MemberDecorate 12(param_block) 4 NonWritable
MemberDecorate 12(param_block) 4 Offset 160
Decorate 12(param_block) BufferBlock
Decorate 14(params) DescriptorSet 0
Decorate 14(params) Binding 0
Decorate 38(in_pos) Location 0
Decorate 67(in_normal) Location 1
MemberDecorate 87(gl_PerVertex) 0 BuiltIn Position
MemberDecorate 87(gl_PerVertex) 1 BuiltIn PointSize
Decorate 87(gl_PerVertex) Block
Decorate 102(color) Location 0
Decorate 109(alpha) Location 1
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
7: TypeVector 6(float) 3
8: TypePointer Function 7(fvec3)
10: TypeVector 6(float) 4
11: TypeMatrix 10(fvec4) 4
12(param_block): TypeStruct 7(fvec3) 7(fvec3) 11 11 6(float)
13: TypePointer Uniform 12(param_block)
14(params): 13(ptr) Variable Uniform
15: TypeInt 32 1
16: 15(int) Constant 2
17: TypePointer Uniform 11
20: 15(int) Constant 0
21: TypePointer Uniform 7(fvec3)
24: 6(float) Constant 1065353216
37: TypePointer Input 7(fvec3)
38(in_pos): 37(ptr) Variable Input
52: TypeMatrix 7(fvec3) 3
53: 6(float) Constant 0
67(in_normal): 37(ptr) Variable Input
74: TypePointer Function 6(float)
87(gl_PerVertex): TypeStruct 10(fvec4) 6(float)
88: TypePointer Output 87(gl_PerVertex)
89: 88(ptr) Variable Output
90: 15(int) Constant 3
99: TypePointer Output 10(fvec4)
101: TypePointer Output 7(fvec3)
102(color): 101(ptr) Variable Output
103: 15(int) Constant 1
108: TypePointer Output 6(float)
109(alpha): 108(ptr) Variable Output
110: 15(int) Constant 4
111: TypePointer Uniform 6(float)
Each of the buffer variables in this shader (members of the shader storage block param_block) is decorated NonWritable, so no error should be emitted.
=> Mark as I don't have the free cycles to do this.
Would it be possible to bump the priority for this issue?
As far as I understand,
- This happens for any read-only use of shader storage buffer objects with glslang. I just hit this myself on a Vulkan stream in the really basic example.
- The workaround involves enabling features that the application doesn't use - my guess is that people who aren't hitting this issue enable all features supported by the device which isn't a pattern that we should be encouraging.
@zeux, yes, @chrisforbes bumped this and it is on my plate to be addressed in the next 2-4 weeks.