@@ -175,8 +175,9 @@ pub struct Device {
175
175
OnceCellOrLock < crate :: timestamp_normalization:: TimestampNormalizer > ,
176
176
/// Uniform buffer containing [`ExternalTextureParams`] with values such
177
177
/// that a [`TextureView`] bound to a [`wgt::BindingType::ExternalTexture`]
178
- /// binding point will be rendered correctly.
179
- pub ( crate ) default_external_texture_params_buffer : std:: sync:: OnceLock < Arc < Buffer > > ,
178
+ /// binding point will be rendered correctly. Intended to be used as the
179
+ /// [`hal::ExternalTextureBinding::params`] field.
180
+ pub ( crate ) default_external_texture_params_buffer : ManuallyDrop < Box < dyn hal:: DynBuffer > > ,
180
181
// needs to be dropped last
181
182
#[ cfg( feature = "trace" ) ]
182
183
pub ( crate ) trace : Mutex < Option < trace:: Trace > > ,
@@ -204,6 +205,10 @@ impl Drop for Device {
204
205
205
206
// SAFETY: We are in the Drop impl and we don't use self.zero_buffer anymore after this point.
206
207
let zero_buffer = unsafe { ManuallyDrop :: take ( & mut self . zero_buffer ) } ;
208
+ // SAFETY: We are in the Drop impl and we don't use
209
+ // self.default_external_texture_params_buffer anymore after this point.
210
+ let default_external_texture_params_buffer =
211
+ unsafe { ManuallyDrop :: take ( & mut self . default_external_texture_params_buffer ) } ;
207
212
// SAFETY: We are in the Drop impl and we don't use self.fence anymore after this point.
208
213
let fence = unsafe { ManuallyDrop :: take ( & mut self . fence . write ( ) ) } ;
209
214
if let Some ( indirect_validation) = self . indirect_validation . take ( ) {
@@ -214,6 +219,8 @@ impl Drop for Device {
214
219
}
215
220
unsafe {
216
221
self . raw . destroy_buffer ( zero_buffer) ;
222
+ self . raw
223
+ . destroy_buffer ( default_external_texture_params_buffer) ;
217
224
self . raw . destroy_fence ( fence) ;
218
225
}
219
226
}
@@ -293,6 +300,19 @@ impl Device {
293
300
}
294
301
. map_err ( DeviceError :: from_hal) ?;
295
302
303
+ let default_external_texture_params_buffer = unsafe {
304
+ raw_device. create_buffer ( & hal:: BufferDescriptor {
305
+ label : hal_label (
306
+ Some ( "(wgpu internal) default external texture params buffer" ) ,
307
+ instance_flags,
308
+ ) ,
309
+ size : size_of :: < ExternalTextureParams > ( ) as _ ,
310
+ usage : wgt:: BufferUses :: COPY_DST | wgt:: BufferUses :: UNIFORM ,
311
+ memory_flags : hal:: MemoryFlags :: empty ( ) ,
312
+ } )
313
+ }
314
+ . map_err ( DeviceError :: from_hal) ?;
315
+
296
316
let alignments = adapter. raw . capabilities . alignments . clone ( ) ;
297
317
let downlevel = adapter. raw . capabilities . downlevel . clone ( ) ;
298
318
@@ -318,7 +338,9 @@ impl Device {
318
338
adapter : adapter. clone ( ) ,
319
339
queue : OnceCellOrLock :: new ( ) ,
320
340
zero_buffer : ManuallyDrop :: new ( zero_buffer) ,
321
- default_external_texture_params_buffer : std:: sync:: OnceLock :: new ( ) ,
341
+ default_external_texture_params_buffer : ManuallyDrop :: new (
342
+ default_external_texture_params_buffer,
343
+ ) ,
322
344
label : desc. label . to_string ( ) ,
323
345
command_allocator,
324
346
command_indices : RwLock :: new (
@@ -369,19 +391,12 @@ impl Device {
369
391
} )
370
392
}
371
393
372
- pub fn late_init_resources_with_queue ( self : & Arc < Self > ) -> Result < ( ) , RequestDeviceError > {
373
- let queue = self . get_queue ( ) . unwrap ( ) ;
374
-
375
- let timestamp_normalizer = crate :: timestamp_normalization:: TimestampNormalizer :: new (
376
- self ,
377
- queue. get_timestamp_period ( ) ,
378
- ) ?;
379
-
380
- self . timestamp_normalizer
381
- . set ( timestamp_normalizer)
382
- . unwrap_or_else ( |_| panic ! ( "Called late_init_resources_with_queue twice" ) ) ;
383
-
384
- let params_data = ExternalTextureParams {
394
+ /// Initializes [`Device::default_external_texture_params_buffer`] with
395
+ /// required values such that a [`TextureView`] bound to a
396
+ /// [`wgt::BindingType::ExternalTexture`] binding point will be rendered
397
+ /// correctly.
398
+ fn init_default_external_texture_params_buffer ( self : & Arc < Self > ) -> Result < ( ) , DeviceError > {
399
+ let data = ExternalTextureParams {
385
400
#[ rustfmt:: skip]
386
401
yuv_conversion_matrix : [
387
402
1.0 , 0.0 , 0.0 , 0.0 ,
@@ -398,33 +413,63 @@ impl Device {
398
413
] ,
399
414
num_planes : 1 ,
400
415
} ;
401
- let params_buffer = self
402
- . create_buffer ( & resource:: BufferDescriptor {
403
- label : Some ( Cow :: Borrowed (
404
- "(wgpu internal) default external texture params buffer" ,
405
- ) ) ,
406
- size : size_of_val ( & params_data) as wgt:: BufferAddress ,
407
- usage : wgt:: BufferUsages :: UNIFORM | wgt:: BufferUsages :: COPY_DST ,
408
- mapped_at_creation : false ,
409
- } )
410
- . map_err ( |err| match err {
411
- resource:: CreateBufferError :: Device ( device) => RequestDeviceError :: Device ( device) ,
412
- _ => unreachable ! ( "Error creating default external texture params buffer: {err:?}" ) ,
413
- } ) ?;
414
- queue
415
- . write_buffer (
416
- Fallible :: Valid ( params_buffer. clone ( ) ) ,
417
- 0 ,
418
- bytemuck:: bytes_of ( & params_data) ,
419
- )
420
- . map_err ( |err| match err {
421
- super :: queue:: QueueWriteError :: Queue ( device) => RequestDeviceError :: Device ( device) ,
422
- _ => unreachable ! ( "Error writing default external texture params buffer: {err:?}" ) ,
423
- } ) ?;
424
- self . default_external_texture_params_buffer
425
- . set ( params_buffer)
416
+ let mut staging_buffer =
417
+ StagingBuffer :: new ( self , wgt:: BufferSize :: new ( size_of_val ( & data) as _ ) . unwrap ( ) ) ?;
418
+ staging_buffer. write ( bytemuck:: bytes_of ( & data) ) ;
419
+ let staging_buffer = staging_buffer. flush ( ) ;
420
+
421
+ let params_buffer = self . default_external_texture_params_buffer . as_ref ( ) ;
422
+ let queue = self . get_queue ( ) . unwrap ( ) ;
423
+ let mut pending_writes = queue. pending_writes . lock ( ) ;
424
+
425
+ unsafe {
426
+ pending_writes
427
+ . command_encoder
428
+ . transition_buffers ( & [ hal:: BufferBarrier {
429
+ buffer : params_buffer,
430
+ usage : hal:: StateTransition {
431
+ from : wgt:: BufferUses :: MAP_WRITE ,
432
+ to : wgt:: BufferUses :: COPY_SRC ,
433
+ } ,
434
+ } ] ) ;
435
+ pending_writes. command_encoder . copy_buffer_to_buffer (
436
+ staging_buffer. raw ( ) ,
437
+ params_buffer,
438
+ & [ hal:: BufferCopy {
439
+ src_offset : 0 ,
440
+ dst_offset : 0 ,
441
+ size : staging_buffer. size ,
442
+ } ] ,
443
+ ) ;
444
+ pending_writes. consume ( staging_buffer) ;
445
+ pending_writes
446
+ . command_encoder
447
+ . transition_buffers ( & [ hal:: BufferBarrier {
448
+ buffer : params_buffer,
449
+ usage : hal:: StateTransition {
450
+ from : wgt:: BufferUses :: COPY_DST ,
451
+ to : wgt:: BufferUses :: UNIFORM ,
452
+ } ,
453
+ } ] ) ;
454
+ }
455
+
456
+ Ok ( ( ) )
457
+ }
458
+
459
+ pub fn late_init_resources_with_queue ( self : & Arc < Self > ) -> Result < ( ) , RequestDeviceError > {
460
+ let queue = self . get_queue ( ) . unwrap ( ) ;
461
+
462
+ let timestamp_normalizer = crate :: timestamp_normalization:: TimestampNormalizer :: new (
463
+ self ,
464
+ queue. get_timestamp_period ( ) ,
465
+ ) ?;
466
+
467
+ self . timestamp_normalizer
468
+ . set ( timestamp_normalizer)
426
469
. unwrap_or_else ( |_| panic ! ( "Called late_init_resources_with_queue twice" ) ) ;
427
470
471
+ self . init_default_external_texture_params_buffer ( ) ?;
472
+
428
473
Ok ( ( ) )
429
474
}
430
475
@@ -2669,11 +2714,7 @@ impl Device {
2669
2714
} ,
2670
2715
] ;
2671
2716
let params = hal:: BufferBinding {
2672
- buffer : self
2673
- . default_external_texture_params_buffer
2674
- . get ( )
2675
- . expect ( "Default external texture params buffer should have been initialized" )
2676
- . try_raw ( snatch_guard) ?,
2717
+ buffer : self . default_external_texture_params_buffer . as_ref ( ) ,
2677
2718
offset : 0 ,
2678
2719
size : None ,
2679
2720
} ;
0 commit comments