make StagingBuffer creation a method

This commit is contained in:
teoxoy 2024-07-11 13:51:53 +02:00 committed by Teodor Tanasoaia
parent a8b0f2f6a6
commit 9a7f44bf09
3 changed files with 46 additions and 46 deletions

View File

@ -30,7 +30,7 @@ use smallvec::SmallVec;
use std::{
iter,
mem::{self, ManuallyDrop},
mem::{self},
ptr::{self, NonNull},
sync::{atomic::Ordering, Arc},
};
@ -313,43 +313,6 @@ impl<A: HalApi> PendingWrites<A> {
}
}
pub(crate) fn prepare_staging_buffer<A: HalApi>(
device: &Arc<Device<A>>,
size: wgt::BufferSize,
instance_flags: wgt::InstanceFlags,
) -> Result<(StagingBuffer<A>, NonNull<u8>), DeviceError> {
profiling::scope!("prepare_staging_buffer");
let stage_desc = hal::BufferDescriptor {
label: hal_label(Some("(wgpu internal) Staging"), instance_flags),
size: size.get(),
usage: hal::BufferUses::MAP_WRITE | hal::BufferUses::COPY_SRC,
memory_flags: hal::MemoryFlags::TRANSIENT,
};
let buffer = unsafe { device.raw().create_buffer(&stage_desc)? };
let mapping = unsafe { device.raw().map_buffer(&buffer, 0..size.get()) }?;
let staging_buffer = StagingBuffer {
raw: ManuallyDrop::new(buffer),
device: device.clone(),
size,
is_coherent: mapping.is_coherent,
};
Ok((staging_buffer, mapping.ptr))
}
impl<A: HalApi> StagingBuffer<A> {
unsafe fn flush(&self) -> Result<(), DeviceError> {
let device = self.device.raw();
if !self.is_coherent {
unsafe { device.flush_mapped_ranges(self.raw(), iter::once(0..self.size.get())) };
}
unsafe { device.unmap_buffer(self.raw())? };
Ok(())
}
}
#[derive(Clone, Debug, Error)]
#[error("Queue is invalid")]
pub struct InvalidQueue;
@ -443,7 +406,7 @@ impl Global {
// freed, even if an error occurs. All paths from here must call
// `device.pending_writes.consume`.
let (staging_buffer, staging_buffer_ptr) =
prepare_staging_buffer(device, data_size, device.instance_flags)?;
StagingBuffer::new(device, data_size, device.instance_flags)?;
let mut pending_writes = device.pending_writes.lock();
let pending_writes = pending_writes.as_mut().unwrap();
@ -490,7 +453,7 @@ impl Global {
let device = &queue.device;
let (staging_buffer, staging_buffer_ptr) =
prepare_staging_buffer(device, buffer_size, device.instance_flags)?;
StagingBuffer::new(device, buffer_size, device.instance_flags)?;
let fid = hub.staging_buffers.prepare(id_in);
let id = fid.assign(Arc::new(staging_buffer));
@ -825,7 +788,7 @@ impl Global {
// freed, even if an error occurs. All paths from here must call
// `device.pending_writes.consume`.
let (staging_buffer, staging_buffer_ptr) =
prepare_staging_buffer(device, stage_size, device.instance_flags)?;
StagingBuffer::new(device, stage_size, device.instance_flags)?;
if stage_bytes_per_row == bytes_per_row {
profiling::scope!("copy aligned");

View File

@ -22,8 +22,8 @@ use crate::{
pipeline,
pool::ResourcePool,
resource::{
self, Buffer, Labeled, ParentDevice, QuerySet, Sampler, Texture, TextureView,
TextureViewNotRenderableReason, TrackingData,
self, Buffer, Labeled, ParentDevice, QuerySet, Sampler, StagingBuffer, Texture,
TextureView, TextureViewNotRenderableReason, TrackingData,
},
resource_log,
snatch::{SnatchGuard, SnatchLock, Snatchable},
@ -591,7 +591,7 @@ impl<A: HalApi> Device<A> {
};
hal::BufferUses::MAP_WRITE
} else {
let (staging_buffer, staging_buffer_ptr) = queue::prepare_staging_buffer(
let (staging_buffer, staging_buffer_ptr) = StagingBuffer::new(
self,
wgt::BufferSize::new(aligned_size).unwrap(),
self.instance_flags,

View File

@ -863,16 +863,53 @@ impl<A: HalApi> Drop for DestroyedBuffer<A> {
/// [`Device::pending_writes`]: crate::device::Device
#[derive(Debug)]
pub struct StagingBuffer<A: HalApi> {
pub(crate) raw: ManuallyDrop<A::Buffer>,
pub(crate) device: Arc<Device<A>>,
raw: ManuallyDrop<A::Buffer>,
device: Arc<Device<A>>,
pub(crate) size: wgt::BufferSize,
pub(crate) is_coherent: bool,
}
impl<A: HalApi> StagingBuffer<A> {
pub(crate) fn new(
device: &Arc<Device<A>>,
size: wgt::BufferSize,
instance_flags: wgt::InstanceFlags,
) -> Result<(Self, NonNull<u8>), DeviceError> {
use hal::Device;
profiling::scope!("StagingBuffer::new");
let stage_desc = hal::BufferDescriptor {
label: crate::hal_label(Some("(wgpu internal) Staging"), instance_flags),
size: size.get(),
usage: hal::BufferUses::MAP_WRITE | hal::BufferUses::COPY_SRC,
memory_flags: hal::MemoryFlags::TRANSIENT,
};
let buffer = unsafe { device.raw().create_buffer(&stage_desc)? };
let mapping = unsafe { device.raw().map_buffer(&buffer, 0..size.get()) }?;
let staging_buffer = StagingBuffer {
raw: ManuallyDrop::new(buffer),
device: device.clone(),
size,
is_coherent: mapping.is_coherent,
};
Ok((staging_buffer, mapping.ptr))
}
pub(crate) fn raw(&self) -> &A::Buffer {
&self.raw
}
pub(crate) unsafe fn flush(&self) -> Result<(), DeviceError> {
use hal::Device;
let device = self.device.raw();
if !self.is_coherent {
unsafe { device.flush_mapped_ranges(self.raw(), iter::once(0..self.size.get())) };
}
unsafe { device.unmap_buffer(self.raw())? };
Ok(())
}
}
impl<A: HalApi> Drop for StagingBuffer<A> {