@@ -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