KhronosGroup / KhronosGroup/glslang
Invalid `const` buffer reference function parameter allowed (crashes driver)
- Dominant language
- C++
- Stars
- 3.6k
- Forks
- 989
- Avg merge
- 1d 2h
- Merged PRs (30d)
- 31
Description
Hi,
While debugging a driver crash (AMD Windows driver, deep inside `amdvlk64.dll` in the `vkCreateComputePipelines` function), I found that the reason was a `const`-qualified buffer reference type function parameter.
The `GLSL_EXT_buffer_reference` spec explicitly disallows `const`-qualified buffer reference types here: https://github.com/KhronosGroup/GLSL/blob/38037bb58882e014e8270000c5533d890a79fa63/extensions/ext/GLSL_EXT_buffer_reference.txt#L93-L99
`glslang` (as of `16.1.0`) generates different SPIR-V depending on the parameter's `const`-qualification which is presumably what leads to the crash.
Here's an example:
```glsl
#version 460
#extension GL_EXT_buffer_reference : require
#extension GL_EXT_shader_explicit_arithmetic_types : require
layout(buffer_reference, std430, buffer_reference_align = 16) buffer MyBufferRef {
vec4 data;
};
void func(
#ifdef ADD_CONST
const
#endif
MyBufferRef buffer_ref) {
}
void main() {
func(MyBufferRef(0ul));
}
```
Compiler commands:
```shell
glslang --target-env vulkan1.3 const-buf-ref.frag -o buf-ref.frag.spv
glslang --target-env vulkan1.3 const-buf-ref.frag -o buf-ref-const.frag.spv -DADD_CONST
spirv-dis buf-ref.frag.spv > buf-ref.frag.spv.txt
spirv-dis buf-ref-const.frag.spv > buf-ref-const.frag.spv.txt
```
SPIR-V diff (WITHOUT and WITH `const`):
```diff
diff --git "buf-ref.frag.spv.txt" "buf-ref-const.frag.spv.txt"
index 6fc622b..99990cd 100644
--- "a/buf-ref.frag.spv.txt"
+++ "b/buf-ref-const.frag.spv.txt"
@@ -1,49 +1,44 @@
; SPIR-V
; Version: 1.6
; Generator: Khronos Glslang Reference Front End; 11
-; Bound: 20
+; Bound: 18
; Schema: 0
OpCapability Shader
OpCapability Int64
OpCapability PhysicalStorageBufferAddresses
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel PhysicalStorageBuffer64 GLSL450
OpEntryPoint Fragment %main "main"
OpExecutionMode %main OriginUpperLeft
OpSource GLSL 460
OpSourceExtension "GL_EXT_buffer_reference"
OpSourceExtension "GL_EXT_shader_explicit_arithmetic_types"
OpName %main "main"
OpName %MyBufferRef "MyBufferRef"
OpMemberName %MyBufferRef 0 "data"
OpName %func_1_ "func(1;"
OpName %buffer_ref "buffer_ref"
- OpName %param "param"
OpDecorate %MyBufferRef Block
OpMemberDecorate %MyBufferRef 0 Offset 0
- OpDecorate %buffer_ref AliasedPointer
- OpDecorate %param AliasedPointer
+ OpDecorate %buffer_ref Aliased
%void = OpTypeVoid
%3 = OpTypeFunction %void
OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_MyBufferRef PhysicalStorageBuffer
%float = OpTypeFloat 32
%v4float = OpTypeVector %float 4
%MyBufferRef = OpTypeStruct %v4float
%_ptr_PhysicalStorageBuffer_MyBufferRef = OpTypePointer PhysicalStorageBuffer %MyBufferRef
-%_ptr_Function__ptr_PhysicalStorageBuffer_MyBufferRef = OpTypePointer Function %_ptr_PhysicalStorageBuffer_MyBufferRef
- %11 = OpTypeFunction %void %_ptr_Function__ptr_PhysicalStorageBuffer_MyBufferRef
+ %10 = OpTypeFunction %void %_ptr_PhysicalStorageBuffer_MyBufferRef
%ulong = OpTypeInt 64 0
%ulong_0 = OpConstant %ulong 0
%main = OpFunction %void None %3
%5 = OpLabel
- %param = OpVariable %_ptr_Function__ptr_PhysicalStorageBuffer_MyBufferRef Function
- %17 = OpBitcast %_ptr_PhysicalStorageBuffer_MyBufferRef %ulong_0
- OpStore %param %17
- %19 = OpFunctionCall %void %func_1_ %param
+ %16 = OpBitcast %_ptr_PhysicalStorageBuffer_MyBufferRef %ulong_0
+ %17 = OpFunctionCall %void %func_1_ %16
OpReturn
OpFunctionEnd
- %func_1_ = OpFunction %void None %11
- %buffer_ref = OpFunctionParameter %_ptr_Function__ptr_PhysicalStorageBuffer_MyBufferRef
- %14 = OpLabel
+ %func_1_ = OpFunction %void None %10
+ %buffer_ref = OpFunctionParameter %_ptr_PhysicalStorageBuffer_MyBufferRef
+ %13 = OpLabel
OpReturn
OpFunctionEnd
```
Contributor guide
Assessment
This issue has not been assessed yet.