mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-25 08:13:27 +00:00
make StagingBuffer
creation a method
This commit is contained in:
parent
a8b0f2f6a6
commit
9a7f44bf09
@ -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");
|
||||
|
@ -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,
|
||||
|
@ -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> {
|
||||
|
Loading…
Reference in New Issue
Block a user