@@ -176,6 +176,11 @@ pub struct Device {
176
176
// Optional so that we can late-initialize this after the queue is created.
177
177
pub ( crate ) timestamp_normalizer :
178
178
OnceCellOrLock < crate :: timestamp_normalization:: TimestampNormalizer > ,
179
+ /// Uniform buffer containing [`ExternalTextureParams`] with values such
180
+ /// that a [`TextureView`] bound to a [`wgt::BindingType::ExternalTexture`]
181
+ /// binding point will be rendered correctly. Intended to be used as the
182
+ /// [`hal::ExternalTextureBinding::params`] field.
183
+ pub ( crate ) default_external_texture_params_buffer : ManuallyDrop < Box < dyn hal:: DynBuffer > > ,
179
184
// needs to be dropped last
180
185
#[ cfg( feature = "trace" ) ]
181
186
pub ( crate ) trace : Mutex < Option < trace:: Trace > > ,
@@ -203,6 +208,10 @@ impl Drop for Device {
203
208
204
209
// SAFETY: We are in the Drop impl and we don't use self.zero_buffer anymore after this point.
205
210
let zero_buffer = unsafe { ManuallyDrop :: take ( & mut self . zero_buffer ) } ;
211
+ // SAFETY: We are in the Drop impl and we don't use
212
+ // self.default_external_texture_params_buffer anymore after this point.
213
+ let default_external_texture_params_buffer =
214
+ unsafe { ManuallyDrop :: take ( & mut self . default_external_texture_params_buffer ) } ;
206
215
// SAFETY: We are in the Drop impl and we don't use self.fence anymore after this point.
207
216
let fence = unsafe { ManuallyDrop :: take ( & mut self . fence . write ( ) ) } ;
208
217
if let Some ( indirect_validation) = self . indirect_validation . take ( ) {
@@ -213,6 +222,8 @@ impl Drop for Device {
213
222
}
214
223
unsafe {
215
224
self . raw . destroy_buffer ( zero_buffer) ;
225
+ self . raw
226
+ . destroy_buffer ( default_external_texture_params_buffer) ;
216
227
self . raw . destroy_fence ( fence) ;
217
228
}
218
229
}
@@ -292,6 +303,19 @@ impl Device {
292
303
}
293
304
. map_err ( DeviceError :: from_hal) ?;
294
305
306
+ let default_external_texture_params_buffer = unsafe {
307
+ raw_device. create_buffer ( & hal:: BufferDescriptor {
308
+ label : hal_label (
309
+ Some ( "(wgpu internal) default external texture params buffer" ) ,
310
+ instance_flags,
311
+ ) ,
312
+ size : size_of :: < ExternalTextureParams > ( ) as _ ,
313
+ usage : wgt:: BufferUses :: COPY_DST | wgt:: BufferUses :: UNIFORM ,
314
+ memory_flags : hal:: MemoryFlags :: empty ( ) ,
315
+ } )
316
+ }
317
+ . map_err ( DeviceError :: from_hal) ?;
318
+
295
319
let alignments = adapter. raw . capabilities . alignments . clone ( ) ;
296
320
let downlevel = adapter. raw . capabilities . downlevel . clone ( ) ;
297
321
@@ -317,6 +341,9 @@ impl Device {
317
341
adapter : adapter. clone ( ) ,
318
342
queue : OnceCellOrLock :: new ( ) ,
319
343
zero_buffer : ManuallyDrop :: new ( zero_buffer) ,
344
+ default_external_texture_params_buffer : ManuallyDrop :: new (
345
+ default_external_texture_params_buffer,
346
+ ) ,
320
347
label : desc. label . to_string ( ) ,
321
348
command_allocator,
322
349
command_indices : RwLock :: new (
@@ -367,7 +394,78 @@ impl Device {
367
394
} )
368
395
}
369
396
370
- pub fn late_init_resources_with_queue ( & self ) -> Result < ( ) , RequestDeviceError > {
397
+ /// Initializes [`Device::default_external_texture_params_buffer`] with
398
+ /// required values such that a [`TextureView`] bound to a
399
+ /// [`wgt::BindingType::ExternalTexture`] binding point will be rendered
400
+ /// correctly.
401
+ fn init_default_external_texture_params_buffer ( self : & Arc < Self > ) -> Result < ( ) , DeviceError > {
402
+ let data = ExternalTextureParams {
403
+ #[ rustfmt:: skip]
404
+ yuv_conversion_matrix : [
405
+ 1.0 , 0.0 , 0.0 , 0.0 ,
406
+ 0.0 , 1.0 , 0.0 , 0.0 ,
407
+ 0.0 , 0.0 , 1.0 , 0.0 ,
408
+ 0.0 , 0.0 , 0.0 , 1.0 ,
409
+ ] ,
410
+ size : [ 0 , 0 ] ,
411
+ #[ rustfmt:: skip]
412
+ sample_transform : [
413
+ 1.0 , 0.0 ,
414
+ 0.0 , 1.0 ,
415
+ 0.0 , 0.0
416
+ ] ,
417
+ #[ rustfmt:: skip]
418
+ load_transform : [
419
+ 1.0 , 0.0 ,
420
+ 0.0 , 1.0 ,
421
+ 0.0 , 0.0
422
+ ] ,
423
+ num_planes : 1 ,
424
+ } ;
425
+ let mut staging_buffer =
426
+ StagingBuffer :: new ( self , wgt:: BufferSize :: new ( size_of_val ( & data) as _ ) . unwrap ( ) ) ?;
427
+ staging_buffer. write ( bytemuck:: bytes_of ( & data) ) ;
428
+ let staging_buffer = staging_buffer. flush ( ) ;
429
+
430
+ let params_buffer = self . default_external_texture_params_buffer . as_ref ( ) ;
431
+ let queue = self . get_queue ( ) . unwrap ( ) ;
432
+ let mut pending_writes = queue. pending_writes . lock ( ) ;
433
+
434
+ unsafe {
435
+ pending_writes
436
+ . command_encoder
437
+ . transition_buffers ( & [ hal:: BufferBarrier {
438
+ buffer : params_buffer,
439
+ usage : hal:: StateTransition {
440
+ from : wgt:: BufferUses :: MAP_WRITE ,
441
+ to : wgt:: BufferUses :: COPY_SRC ,
442
+ } ,
443
+ } ] ) ;
444
+ pending_writes. command_encoder . copy_buffer_to_buffer (
445
+ staging_buffer. raw ( ) ,
446
+ params_buffer,
447
+ & [ hal:: BufferCopy {
448
+ src_offset : 0 ,
449
+ dst_offset : 0 ,
450
+ size : staging_buffer. size ,
451
+ } ] ,
452
+ ) ;
453
+ pending_writes. consume ( staging_buffer) ;
454
+ pending_writes
455
+ . command_encoder
456
+ . transition_buffers ( & [ hal:: BufferBarrier {
457
+ buffer : params_buffer,
458
+ usage : hal:: StateTransition {
459
+ from : wgt:: BufferUses :: COPY_DST ,
460
+ to : wgt:: BufferUses :: UNIFORM ,
461
+ } ,
462
+ } ] ) ;
463
+ }
464
+
465
+ Ok ( ( ) )
466
+ }
467
+
468
+ pub fn late_init_resources_with_queue ( self : & Arc < Self > ) -> Result < ( ) , RequestDeviceError > {
371
469
let queue = self . get_queue ( ) . unwrap ( ) ;
372
470
373
471
let timestamp_normalizer = crate :: timestamp_normalization:: TimestampNormalizer :: new (
@@ -379,6 +477,8 @@ impl Device {
379
477
. set ( timestamp_normalizer)
380
478
. unwrap_or_else ( |_| panic ! ( "Called late_init_resources_with_queue twice" ) ) ;
381
479
480
+ self . init_default_external_texture_params_buffer ( ) ?;
481
+
382
482
Ok ( ( ) )
383
483
}
384
484
0 commit comments