|
1 | 1 | use std::{num::NonZeroU64, time::Duration}; |
2 | 2 |
|
3 | 3 | use wgpu::{ |
4 | | - BindGroupDescriptor, BindGroupEntry, BindGroupLayoutDescriptor, BindGroupLayoutEntry, |
| 4 | + Backends, BindGroupDescriptor, BindGroupEntry, BindGroupLayoutDescriptor, BindGroupLayoutEntry, |
5 | 5 | BindingResource, BindingType, BufferBindingType, BufferDescriptor, BufferUsages, CommandBuffer, |
6 | | - CommandEncoderDescriptor, ComputePassDescriptor, PollType, ShaderStages, |
| 6 | + CommandEncoderDescriptor, ComputePassDescriptor, ComputePipelineDescriptor, |
| 7 | + PipelineLayoutDescriptor, PollType, ShaderModuleDescriptor, ShaderSource, ShaderStages, |
7 | 8 | }; |
8 | 9 |
|
9 | 10 | use wgpu_test::{ |
10 | | - gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters, TestingContext, |
| 11 | + gpu_test, FailureCase, GpuTestConfiguration, GpuTestInitializer, TestParameters, TestingContext, |
11 | 12 | }; |
12 | 13 |
|
13 | 14 | pub fn all_tests(vec: &mut Vec<GpuTestInitializer>) { |
14 | 15 | vec.extend([ |
15 | 16 | WAIT, |
| 17 | + WAIT_INDEFINITELY_LONG_RUNNING, |
16 | 18 | WAIT_WITH_TIMEOUT, |
17 | 19 | WAIT_WITH_TIMEOUT_MAX, |
18 | 20 | DOUBLE_WAIT, |
@@ -85,6 +87,95 @@ static WAIT: GpuTestConfiguration = GpuTestConfiguration::new() |
85 | 87 | .unwrap(); |
86 | 88 | }); |
87 | 89 |
|
| 90 | +/// Regression test for <https://github.com/gfx-rs/wgpu/issues/9531>. |
| 91 | +#[gpu_test] |
| 92 | +static WAIT_INDEFINITELY_LONG_RUNNING: GpuTestConfiguration = GpuTestConfiguration::new() |
| 93 | + .parameters( |
| 94 | + TestParameters::default() |
| 95 | + .test_features_limits() |
| 96 | + .skip(FailureCase::backend(!Backends::METAL)), |
| 97 | + ) |
| 98 | + .run_async(|ctx| async move { |
| 99 | + const SHADER: &str = r#" |
| 100 | +@group(0) @binding(0) var<storage, read_write> buf: array<u32>; |
| 101 | +
|
| 102 | +@compute @workgroup_size(64) |
| 103 | +fn main(@builtin(global_invocation_id) gid: vec3<u32>) { |
| 104 | + var x: u32 = gid.x ^ 0xDEADBEEFu; |
| 105 | + for (var i: u32 = 0u; i < 5000000u; i++) { |
| 106 | + x ^= x << 13u; |
| 107 | + x ^= x >> 17u; |
| 108 | + x ^= x << 5u; |
| 109 | + } |
| 110 | + buf[gid.x] = x; |
| 111 | +} |
| 112 | +"#; |
| 113 | + |
| 114 | + const N_THREADS: u32 = 1024 * 64; |
| 115 | + |
| 116 | + let module = ctx.device.create_shader_module(ShaderModuleDescriptor { |
| 117 | + label: None, |
| 118 | + source: ShaderSource::Wgsl(SHADER.into()), |
| 119 | + }); |
| 120 | + let buffer = ctx.device.create_buffer(&BufferDescriptor { |
| 121 | + label: None, |
| 122 | + size: (N_THREADS as u64) * 4, |
| 123 | + usage: BufferUsages::STORAGE, |
| 124 | + mapped_at_creation: false, |
| 125 | + }); |
| 126 | + let bind_group_layout = ctx |
| 127 | + .device |
| 128 | + .create_bind_group_layout(&BindGroupLayoutDescriptor { |
| 129 | + label: None, |
| 130 | + entries: &[BindGroupLayoutEntry { |
| 131 | + binding: 0, |
| 132 | + visibility: ShaderStages::COMPUTE, |
| 133 | + ty: BindingType::Buffer { |
| 134 | + ty: BufferBindingType::Storage { read_only: false }, |
| 135 | + has_dynamic_offset: false, |
| 136 | + min_binding_size: None, |
| 137 | + }, |
| 138 | + count: None, |
| 139 | + }], |
| 140 | + }); |
| 141 | + let pipeline_layout = ctx |
| 142 | + .device |
| 143 | + .create_pipeline_layout(&PipelineLayoutDescriptor { |
| 144 | + label: None, |
| 145 | + bind_group_layouts: &[Some(&bind_group_layout)], |
| 146 | + immediate_size: 0, |
| 147 | + }); |
| 148 | + let pipeline = ctx |
| 149 | + .device |
| 150 | + .create_compute_pipeline(&ComputePipelineDescriptor { |
| 151 | + label: None, |
| 152 | + layout: Some(&pipeline_layout), |
| 153 | + module: &module, |
| 154 | + entry_point: Some("main"), |
| 155 | + compilation_options: Default::default(), |
| 156 | + cache: None, |
| 157 | + }); |
| 158 | + let bind_group = ctx.device.create_bind_group(&BindGroupDescriptor { |
| 159 | + label: None, |
| 160 | + layout: &bind_group_layout, |
| 161 | + entries: &[BindGroupEntry { |
| 162 | + binding: 0, |
| 163 | + resource: buffer.as_entire_binding(), |
| 164 | + }], |
| 165 | + }); |
| 166 | + let mut encoder = ctx |
| 167 | + .device |
| 168 | + .create_command_encoder(&CommandEncoderDescriptor::default()); |
| 169 | + { |
| 170 | + let mut cpass = encoder.begin_compute_pass(&ComputePassDescriptor::default()); |
| 171 | + cpass.set_pipeline(&pipeline); |
| 172 | + cpass.set_bind_group(0, &bind_group, &[]); |
| 173 | + cpass.dispatch_workgroups(N_THREADS / 64, 1, 1); |
| 174 | + } |
| 175 | + ctx.queue.submit(Some(encoder.finish())); |
| 176 | + ctx.async_poll(PollType::wait_indefinitely()).await.unwrap(); |
| 177 | + }); |
| 178 | + |
88 | 179 | #[gpu_test] |
89 | 180 | static WAIT_WITH_TIMEOUT: GpuTestConfiguration = GpuTestConfiguration::new() |
90 | 181 | .parameters(TestParameters::default().enable_noop()) |
|
0 commit comments