@@ -147,37 +147,75 @@ impl Drop for Queue {
147
147
. load ( Ordering :: Acquire ) ;
148
148
149
149
let fence = self . device . fence . read ( ) ;
150
- let wait_res = unsafe {
151
- self . device . raw ( ) . wait (
152
- fence. as_ref ( ) ,
153
- last_successful_submission_index,
154
- #[ cfg( not( target_arch = "wasm32" ) ) ]
155
- crate :: device:: CLEANUP_WAIT_MS ,
156
- #[ cfg( target_arch = "wasm32" ) ]
157
- 0 , // WebKit and Chromium don't support a non-0 timeout
158
- )
159
- } ;
160
- drop ( fence) ;
161
150
162
- match wait_res {
163
- Ok ( true ) => { }
164
- // Note: If we don't panic here we are in UB land (destroying resources while they are still in use by the GPU).
165
- Ok ( false ) => {
166
- // It's fine that we timed out on WebGL; GL objects can be deleted early as they
167
- // will be kept around by the driver if GPU work hasn't finished.
168
- // Moreover, the way we emulate read mappings on WebGL allows us to execute map_buffer earlier than on other
169
- // backends since getBufferSubData is synchronous with respect to the other previously enqueued GL commands.
170
- // TODO: Relying on this behavior breaks the clean abstraction wgpu-hal tries to maintain and
171
- // we should find ways to improve this.
172
- #[ cfg( not( target_arch = "wasm32" ) ) ]
173
- panic ! ( "We timed out while waiting on the last successful submission to complete!" ) ;
174
- }
175
- Err ( e) => {
176
- panic ! (
177
- "We ran into an error while waiting on the last successful submission to complete! - {e}"
178
- ) ;
151
+ // Try waiting on the last submission using the following sequence of timeouts
152
+ let timeouts_in_ms = [ 100 , 200 , 400 , 800 , 1600 , 3200 ] ;
153
+
154
+ for ( i, timeout_ms) in timeouts_in_ms. into_iter ( ) . enumerate ( ) {
155
+ let is_last_iter = i == timeouts_in_ms. len ( ) - 1 ;
156
+
157
+ api_log ! (
158
+ "Waiting on last submission. try: {}/{}. timeout: {}ms" ,
159
+ i + 1 ,
160
+ timeouts_in_ms. len( ) ,
161
+ timeout_ms
162
+ ) ;
163
+
164
+ let wait_res = unsafe {
165
+ self . device . raw ( ) . wait (
166
+ fence. as_ref ( ) ,
167
+ last_successful_submission_index,
168
+ #[ cfg( not( target_arch = "wasm32" ) ) ]
169
+ timeout_ms,
170
+ #[ cfg( target_arch = "wasm32" ) ]
171
+ 0 , // WebKit and Chromium don't support a non-0 timeout
172
+ )
173
+ } ;
174
+ // Note: If we don't panic below we are in UB land (destroying resources while they are still in use by the GPU).
175
+ match wait_res {
176
+ Ok ( true ) => break ,
177
+ Ok ( false ) => {
178
+ // It's fine that we timed out on WebGL; GL objects can be deleted early as they
179
+ // will be kept around by the driver if GPU work hasn't finished.
180
+ // Moreover, the way we emulate read mappings on WebGL allows us to execute map_buffer earlier than on other
181
+ // backends since getBufferSubData is synchronous with respect to the other previously enqueued GL commands.
182
+ // TODO: Relying on this behavior breaks the clean abstraction wgpu-hal tries to maintain and
183
+ // we should find ways to improve this.
184
+ #[ cfg( target_arch = "wasm32" ) ]
185
+ {
186
+ break ;
187
+ }
188
+ #[ cfg( not( target_arch = "wasm32" ) ) ]
189
+ {
190
+ if is_last_iter {
191
+ panic ! (
192
+ "We timed out while waiting on the last successful submission to complete!"
193
+ ) ;
194
+ }
195
+ }
196
+ }
197
+ Err ( e) => match e {
198
+ hal:: DeviceError :: OutOfMemory => {
199
+ if is_last_iter {
200
+ panic ! (
201
+ "We ran into an OOM error while waiting on the last successful submission to complete!"
202
+ ) ;
203
+ }
204
+ }
205
+ hal:: DeviceError :: Lost => {
206
+ self . device . handle_hal_error ( e) ; // will lose the device
207
+ break ;
208
+ }
209
+ hal:: DeviceError :: ResourceCreationFailed => unreachable ! ( ) ,
210
+ hal:: DeviceError :: Unexpected => {
211
+ panic ! (
212
+ "We ran into an unexpected error while waiting on the last successful submission to complete!"
213
+ ) ;
214
+ }
215
+ } ,
179
216
}
180
217
}
218
+ drop ( fence) ;
181
219
182
220
let snatch_guard = self . device . snatchable_lock . read ( ) ;
183
221
let ( submission_closures, mapping_closures, queue_empty) =
0 commit comments