Skip to content

Commit d2eb777

Browse files
authored
Make timestamping dependent on support (#38)
1 parent 6193c0f commit d2eb777

File tree

1 file changed

+106
-47
lines changed

1 file changed

+106
-47
lines changed

examples/runners/wgpu/src/compute.rs

Lines changed: 106 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,22 @@ async fn start_internal(options: &Options, compiled_shader_modules: CompiledShad
2222
.await
2323
.expect("Failed to find an appropriate adapter");
2424

25-
let mut required_features =
26-
wgpu::Features::TIMESTAMP_QUERY | wgpu::Features::TIMESTAMP_QUERY_INSIDE_PASSES;
25+
// Timestamping may not be supported
26+
let timestamping = adapter.features().contains(wgpu::Features::TIMESTAMP_QUERY)
27+
&& adapter
28+
.features()
29+
.contains(wgpu::Features::TIMESTAMP_QUERY_INSIDE_PASSES);
30+
31+
let mut required_features = if timestamping {
32+
wgpu::Features::TIMESTAMP_QUERY | wgpu::Features::TIMESTAMP_QUERY_INSIDE_PASSES
33+
} else {
34+
wgpu::Features::empty()
35+
};
36+
if !timestamping {
37+
eprintln!(
38+
"Adapter reports that timestamping is not supported - no timing information will be available"
39+
);
40+
}
2741
if options.force_spirv_passthru {
2842
required_features |= wgpu::Features::SPIRV_SHADER_PASSTHROUGH;
2943
}
@@ -43,8 +57,11 @@ async fn start_internal(options: &Options, compiled_shader_modules: CompiledShad
4357
drop(instance);
4458
drop(adapter);
4559

46-
let timestamp_period = queue.get_timestamp_period();
47-
60+
let timestamp_period: Option<f32> = if timestamping {
61+
Some(queue.get_timestamp_period())
62+
} else {
63+
None
64+
};
4865
let entry_point = "main_cs";
4966

5067
// FIXME(eddyb) automate this decision by default.
@@ -112,20 +129,26 @@ async fn start_internal(options: &Options, compiled_shader_modules: CompiledShad
112129
| wgpu::BufferUsages::COPY_SRC,
113130
});
114131

115-
let timestamp_buffer = device.create_buffer(&wgpu::BufferDescriptor {
116-
label: Some("Timestamps buffer"),
117-
size: 16,
118-
usage: wgpu::BufferUsages::QUERY_RESOLVE | wgpu::BufferUsages::COPY_SRC,
119-
mapped_at_creation: false,
120-
});
132+
let (timestamp_buffer, timestamp_readback_buffer) = if timestamping {
133+
let timestamp_buffer = device.create_buffer(&wgpu::BufferDescriptor {
134+
label: Some("Timestamps buffer"),
135+
size: 16,
136+
usage: wgpu::BufferUsages::QUERY_RESOLVE | wgpu::BufferUsages::COPY_SRC,
137+
mapped_at_creation: false,
138+
});
121139

122-
let timestamp_readback_buffer = device.create_buffer(&wgpu::BufferDescriptor {
123-
label: None,
124-
size: 16,
125-
usage: wgpu::BufferUsages::MAP_READ | wgpu::BufferUsages::COPY_DST,
126-
mapped_at_creation: true,
127-
});
128-
timestamp_readback_buffer.unmap();
140+
let timestamp_readback_buffer = device.create_buffer(&wgpu::BufferDescriptor {
141+
label: None,
142+
size: 16,
143+
usage: wgpu::BufferUsages::MAP_READ | wgpu::BufferUsages::COPY_DST,
144+
mapped_at_creation: true,
145+
});
146+
timestamp_readback_buffer.unmap();
147+
148+
(Some(timestamp_buffer), Some(timestamp_readback_buffer))
149+
} else {
150+
(None, None)
151+
};
129152

130153
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
131154
label: None,
@@ -136,11 +159,15 @@ async fn start_internal(options: &Options, compiled_shader_modules: CompiledShad
136159
}],
137160
});
138161

139-
let queries = device.create_query_set(&wgpu::QuerySetDescriptor {
140-
label: None,
141-
count: 2,
142-
ty: wgpu::QueryType::Timestamp,
143-
});
162+
let queries = if timestamping {
163+
Some(device.create_query_set(&wgpu::QuerySetDescriptor {
164+
label: None,
165+
count: 2,
166+
ty: wgpu::QueryType::Timestamp,
167+
}))
168+
} else {
169+
None
170+
};
144171

145172
let mut encoder =
146173
device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
@@ -149,9 +176,17 @@ async fn start_internal(options: &Options, compiled_shader_modules: CompiledShad
149176
let mut cpass = encoder.begin_compute_pass(&Default::default());
150177
cpass.set_bind_group(0, &bind_group, &[]);
151178
cpass.set_pipeline(&compute_pipeline);
152-
cpass.write_timestamp(&queries, 0);
179+
if timestamping {
180+
if let Some(queries) = queries.as_ref() {
181+
cpass.write_timestamp(queries, 0);
182+
}
183+
}
153184
cpass.dispatch_workgroups(src_range.len() as u32 / 64, 1, 1);
154-
cpass.write_timestamp(&queries, 1);
185+
if timestamping {
186+
if let Some(queries) = queries.as_ref() {
187+
cpass.write_timestamp(queries, 1);
188+
}
189+
}
155190
}
156191

157192
encoder.copy_buffer_to_buffer(
@@ -161,38 +196,68 @@ async fn start_internal(options: &Options, compiled_shader_modules: CompiledShad
161196
0,
162197
src.len() as wgpu::BufferAddress,
163198
);
164-
encoder.resolve_query_set(&queries, 0..2, &timestamp_buffer, 0);
165-
encoder.copy_buffer_to_buffer(
166-
&timestamp_buffer,
167-
0,
168-
&timestamp_readback_buffer,
169-
0,
170-
timestamp_buffer.size(),
171-
);
199+
200+
if timestamping {
201+
if let (Some(queries), Some(timestamp_buffer), Some(timestamp_readback_buffer)) = (
202+
queries.as_ref(),
203+
timestamp_buffer.as_ref(),
204+
timestamp_readback_buffer.as_ref(),
205+
) {
206+
encoder.resolve_query_set(queries, 0..2, timestamp_buffer, 0);
207+
encoder.copy_buffer_to_buffer(
208+
timestamp_buffer,
209+
0,
210+
timestamp_readback_buffer,
211+
0,
212+
timestamp_buffer.size(),
213+
);
214+
}
215+
}
172216

173217
queue.submit(Some(encoder.finish()));
174218
let buffer_slice = readback_buffer.slice(..);
175-
let timestamp_slice = timestamp_readback_buffer.slice(..);
176-
timestamp_slice.map_async(wgpu::MapMode::Read, |r| r.unwrap());
219+
if timestamping {
220+
if let Some(timestamp_readback_buffer) = timestamp_readback_buffer.as_ref() {
221+
let timestamp_slice = timestamp_readback_buffer.slice(..);
222+
timestamp_slice.map_async(wgpu::MapMode::Read, |r| r.unwrap());
223+
}
224+
}
177225
buffer_slice.map_async(wgpu::MapMode::Read, |r| r.unwrap());
178226
// NOTE(eddyb) `poll` should return only after the above callbacks fire
179227
// (see also https://github.com/gfx-rs/wgpu/pull/2698 for more details).
180228
device.poll(wgpu::Maintain::Wait);
181229

230+
if timestamping {
231+
if let (Some(timestamp_readback_buffer), Some(timestamp_period)) =
232+
(timestamp_readback_buffer.as_ref(), timestamp_period)
233+
{
234+
{
235+
let timing_data = timestamp_readback_buffer.slice(..).get_mapped_range();
236+
let timings = timing_data
237+
.chunks_exact(8)
238+
.map(|b| u64::from_ne_bytes(b.try_into().unwrap()))
239+
.collect::<Vec<_>>();
240+
241+
println!(
242+
"Took: {:?}",
243+
Duration::from_nanos(
244+
((timings[1] - timings[0]) as f64 * f64::from(timestamp_period)) as u64
245+
)
246+
);
247+
drop(timing_data);
248+
timestamp_readback_buffer.unmap();
249+
}
250+
}
251+
}
252+
182253
let data = buffer_slice.get_mapped_range();
183-
let timing_data = timestamp_slice.get_mapped_range();
184254
let result = data
185255
.chunks_exact(4)
186256
.map(|b| u32::from_ne_bytes(b.try_into().unwrap()))
187257
.collect::<Vec<_>>();
188-
let timings = timing_data
189-
.chunks_exact(8)
190-
.map(|b| u64::from_ne_bytes(b.try_into().unwrap()))
191-
.collect::<Vec<_>>();
192258
drop(data);
193259
readback_buffer.unmap();
194-
drop(timing_data);
195-
timestamp_readback_buffer.unmap();
260+
196261
let mut max = 0;
197262
for (src, out) in src_range.zip(result.iter().copied()) {
198263
if out == u32::MAX {
@@ -204,10 +269,4 @@ async fn start_internal(options: &Options, compiled_shader_modules: CompiledShad
204269
println!("{src}: {out}");
205270
}
206271
}
207-
println!(
208-
"Took: {:?}",
209-
Duration::from_nanos(
210-
((timings[1] - timings[0]) as f64 * f64::from(timestamp_period)) as u64
211-
)
212-
);
213272
}

0 commit comments

Comments
 (0)