Skip to content

Commit e2375e4

Browse files
committed
fixup! [wgpu-core] Create default ExternalTextureParams buffer
1 parent ec8b51a commit e2375e4

File tree

1 file changed

+87
-46
lines changed

1 file changed

+87
-46
lines changed

wgpu-core/src/device/resource.rs

Lines changed: 87 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,9 @@ pub struct Device {
175175
OnceCellOrLock<crate::timestamp_normalization::TimestampNormalizer>,
176176
/// Uniform buffer containing [`ExternalTextureParams`] with values such
177177
/// 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>>,
180181
// needs to be dropped last
181182
#[cfg(feature = "trace")]
182183
pub(crate) trace: Mutex<Option<trace::Trace>>,
@@ -204,6 +205,10 @@ impl Drop for Device {
204205

205206
// SAFETY: We are in the Drop impl and we don't use self.zero_buffer anymore after this point.
206207
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) };
207212
// SAFETY: We are in the Drop impl and we don't use self.fence anymore after this point.
208213
let fence = unsafe { ManuallyDrop::take(&mut self.fence.write()) };
209214
if let Some(indirect_validation) = self.indirect_validation.take() {
@@ -214,6 +219,8 @@ impl Drop for Device {
214219
}
215220
unsafe {
216221
self.raw.destroy_buffer(zero_buffer);
222+
self.raw
223+
.destroy_buffer(default_external_texture_params_buffer);
217224
self.raw.destroy_fence(fence);
218225
}
219226
}
@@ -293,6 +300,19 @@ impl Device {
293300
}
294301
.map_err(DeviceError::from_hal)?;
295302

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+
296316
let alignments = adapter.raw.capabilities.alignments.clone();
297317
let downlevel = adapter.raw.capabilities.downlevel.clone();
298318

@@ -318,7 +338,9 @@ impl Device {
318338
adapter: adapter.clone(),
319339
queue: OnceCellOrLock::new(),
320340
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+
),
322344
label: desc.label.to_string(),
323345
command_allocator,
324346
command_indices: RwLock::new(
@@ -369,19 +391,12 @@ impl Device {
369391
})
370392
}
371393

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 {
385400
#[rustfmt::skip]
386401
yuv_conversion_matrix: [
387402
1.0, 0.0, 0.0, 0.0,
@@ -398,33 +413,63 @@ impl Device {
398413
],
399414
num_planes: 1,
400415
};
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)
426469
.unwrap_or_else(|_| panic!("Called late_init_resources_with_queue twice"));
427470

471+
self.init_default_external_texture_params_buffer()?;
472+
428473
Ok(())
429474
}
430475

@@ -2669,11 +2714,7 @@ impl Device {
26692714
},
26702715
];
26712716
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(),
26772718
offset: 0,
26782719
size: None,
26792720
};

0 commit comments

Comments
 (0)