A certain pattern in SPIRV shaders seems to cause a crash in my AMD vulkan driver on windows. It seems to involve a variable defined using OpVariable with an initializer, loading a value from somewhere else via OpAccessChain and storing it to the variable, and then calling a function with a pointer to that variable.
I originally saw this with spriv from: glsl -> shaderc(unoptimized) -> spirv -> naga(create_shader_module_unchecked) -> spirv
I minimized the glsl shader and then made modifications to the spirv to narrow down the cause and found a combination of several aspects that seem to trigger the crash. Finally I found some wgsl that produces spirv with the same issue.
Not sure if there is anything to do other than reporting this to AMD, but I assume this is valuable to document here. I was actually planning to debug a different issue I saw previously with this combination of shader processing and platform... but was stopped by this crash.
Repro steps
Diff
```diff
diff --git a/examples/src/hello_triangle/mod.rs b/examples/src/hello_triangle/mod.rs
index 7c82d49cf..3cb65f4f5 100644
--- a/examples/src/hello_triangle/mod.rs
+++ b/examples/src/hello_triangle/mod.rs
@@ -10,7 +10,12 @@ async fn run(event_loop: EventLoop<()>, window: Window) {
size.width = size.width.max(1);
size.height = size.height.max(1);
- let instance = wgpu::Instance::default();
+ let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
+ backends: wgpu::Backends::VULKAN,
+ // Debugging OpLine(s) make the issue go away.
+ flags: wgpu::InstanceFlags::empty(),
+ ..Default::default()
+ });
let surface = instance.create_surface(&window).unwrap();
let adapter = instance
diff --git a/examples/src/hello_triangle/shader.wgsl b/examples/src/hello_triangle/shader.wgsl
index f84ccfe94..2f68f3716 100644
--- a/examples/src/hello_triangle/shader.wgsl
+++ b/examples/src/hello_triangle/shader.wgsl
@@ -5,7 +5,14 @@ fn vs_main(@builtin(vertex_index) in_vertex_index: u32) -> @builtin(position) ve
return vec4(x, y, 0.0, 1.0);
}
+fn ptr_function(x: ptr) {}
+
@fragment
-fn fs_main() -> @location(0) vec4 {
+fn fs_main(@builtin(position) pos: vec4) -> @location(0) vec4 {
+ var vector = vec2(1.0);
+ var x: f32;
+ // Combination of x with OpVariable initializer, loading via OpAccessChain and storing to x, and calling a function with a ptr to x.
+ x = vector.x;
+ ptr_function(&x);
return vec4(1.0, 0.0, 0.0, 1.0);
}
```
Apply this diff or checkout amd-windows-vk-crash from my fork
Run cargo r --bin wgpu-examples hello_triangle
Expected vs observed behavior
no crash
Extra materials
No vulkan validation layer errors (made sure they were enabled)
Description
A certain pattern in SPIRV shaders seems to cause a crash in my AMD vulkan driver on windows. It seems to involve a variable defined using
OpVariable
with an initializer, loading a value from somewhere else viaOpAccessChain
and storing it to the variable, and then calling a function with a pointer to that variable.I originally saw this with spriv from: glsl -> shaderc(unoptimized) -> spirv -> naga(create_shader_module_unchecked) -> spirv
I minimized the glsl shader and then made modifications to the spirv to narrow down the cause and found a combination of several aspects that seem to trigger the crash. Finally I found some wgsl that produces spirv with the same issue.
Not sure if there is anything to do other than reporting this to AMD, but I assume this is valuable to document here. I was actually planning to debug a different issue I saw previously with this combination of shader processing and platform... but was stopped by this crash.
Repro steps
Diff
```diff diff --git a/examples/src/hello_triangle/mod.rs b/examples/src/hello_triangle/mod.rs index 7c82d49cf..3cb65f4f5 100644 --- a/examples/src/hello_triangle/mod.rs +++ b/examples/src/hello_triangle/mod.rs @@ -10,7 +10,12 @@ async fn run(event_loop: EventLoop<()>, window: Window) { size.width = size.width.max(1); size.height = size.height.max(1); - let instance = wgpu::Instance::default(); + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { + backends: wgpu::Backends::VULKAN, + // Debugging OpLine(s) make the issue go away. + flags: wgpu::InstanceFlags::empty(), + ..Default::default() + }); let surface = instance.create_surface(&window).unwrap(); let adapter = instance diff --git a/examples/src/hello_triangle/shader.wgsl b/examples/src/hello_triangle/shader.wgsl index f84ccfe94..2f68f3716 100644 --- a/examples/src/hello_triangle/shader.wgsl +++ b/examples/src/hello_triangle/shader.wgsl @@ -5,7 +5,14 @@ fn vs_main(@builtin(vertex_index) in_vertex_index: u32) -> @builtin(position) ve return vec4Apply this diff or checkout
amd-windows-vk-crash
from my fork Runcargo r --bin wgpu-examples hello_triangle
Expected vs observed behavior no crash
Extra materials
No vulkan validation layer errors (made sure they were enabled)
Output spirv
```spirv ; SPIR-V ; Version: 1.0 ; Generator: Khronos; 28 ; Bound: 35 ; Schema: 0 OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %19 "fs_main" %gl_FragCoord %17 OpExecutionMode %19 OriginUpperLeft OpDecorate %gl_FragCoord BuiltIn FragCoord OpDecorate %17 Location 0 %void = OpTypeVoid %uint = OpTypeInt 32 0 %float = OpTypeFloat 32 %v4float = OpTypeVector %float 4 %_ptr_Function_float = OpTypePointer Function %float %v2float = OpTypeVector %float 2 %11 = OpTypeFunction %void %_ptr_Function_float %_ptr_Input_v4float = OpTypePointer Input %v4float %gl_FragCoord = OpVariable %_ptr_Input_v4float Input %_ptr_Output_v4float = OpTypePointer Output %v4float %17 = OpVariable %_ptr_Output_v4float Output %20 = OpTypeFunction %void %float_1 = OpConstant %float 1 %22 = OpConstantComposite %v2float %float_1 %float_1 %float_0 = OpConstant %float 0 %24 = OpConstantComposite %v4float %float_1 %float_0 %float_0 %float_1 %_ptr_Function_v2float = OpTypePointer Function %v2float %28 = OpConstantNull %float %_ptr_Function_float_0 = OpTypePointer Function %float %uint_0 = OpConstant %uint 0 %10 = OpFunction %void None %11 %9 = OpFunctionParameter %_ptr_Function_float %8 = OpLabel OpBranch %12 %12 = OpLabel OpReturn OpFunctionEnd %19 = OpFunction %void None %20 %13 = OpLabel %25 = OpVariable %_ptr_Function_v2float Function %22 %27 = OpVariable %_ptr_Function_float Function %28 %16 = OpLoad %v4float %gl_FragCoord OpBranch %29 %29 = OpLabel %32 = OpAccessChain %_ptr_Function_float_0 %25 %uint_0 %33 = OpLoad %float %32 OpStore %27 %33 %34 = OpFunctionCall %void %10 %27 OpStore %17 %24 OpReturn OpFunctionEnd ```LLDB
Exception 0xc0000005 encountered at address 0x7ff8f85517c9: Access violation reading location 0x00000018 ``` boost::serialization::singletoncppvsdbg
Unhandled exception at 0x00007FF8FD2017C9 (amdvlk64.dll) in wgpu-examples.exe: 0xC0000005: Access violation reading location 0x0000000000000018. ``` amdvlk64.dll!00007ff8fd2017c9() (Unknown Source:0) amdvlk64.dll!00007ff8fd256a8e() (Unknown Source:0) amdvlk64.dll!00007ff8fd25ad69() (Unknown Source:0) amdvlk64.dll!00007ff8fd27724e() (Unknown Source:0) amdvlk64.dll!00007ff8fd262b76() (Unknown Source:0) amdvlk64.dll!00007ff8fd1c1ecb() (Unknown Source:0) amdvlk64.dll!00007ff8fd182876() (Unknown Source:0) amdvlk64.dll!00007ff8fd18255d() (Unknown Source:0) amdvlk64.dll!00007ff8fd16f195() (Unknown Source:0) amdvlk64.dll!00007ff8fb5232c8() (Unknown Source:0) amdvlk64.dll!00007ff8fb44b7b0() (Unknown Source:0) amdvlk64.dll!00007ff8fb44f601() (Unknown Source:0) amdvlk64.dll!00007ff8fb4bd7a7() (Unknown Source:0) amdvlk64.dll!00007ff8fb4bfbd0() (Unknown Source:0) amdvlk64.dll!00007ff8fb45bdce() (Unknown Source:0) amdvlk64.dll!00007ff8fb49db49() (Unknown Source:0) wgpu-examples.exe!ash::device::Device::create_graphics_pipelines(ash::vk::definitions::PipelineCache self, ref$Platform
wgpu fb0cb1eb11663f8de023f6dd64128ed1f5342ec7 Windows Vulkan AMD Radeon RX 6650 XT driver: "24.8.1 (AMD proprietary shader compiler)"