mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-25 00:03:29 +00:00
[core] Move CommandAllocator
into its own module.
No intended change in behavior.
This commit is contained in:
parent
c6efbef8a6
commit
b9781ee6e2
62
wgpu-core/src/command/allocator.rs
Normal file
62
wgpu-core/src/command/allocator.rs
Normal file
@ -0,0 +1,62 @@
|
||||
use crate::hal_api::HalApi;
|
||||
use crate::resource_log;
|
||||
use hal::Device as _;
|
||||
|
||||
/// A pool of free [`wgpu_hal::CommandEncoder`]s, owned by a `Device`.
|
||||
///
|
||||
/// Each encoder in this list is in the "closed" state.
|
||||
///
|
||||
/// Since a raw [`CommandEncoder`][ce] is itself a pool for allocating
|
||||
/// raw [`CommandBuffer`][cb]s, this is a pool of pools.
|
||||
///
|
||||
/// [ce]: wgpu_hal::CommandEncoder
|
||||
/// [cb]: wgpu_hal::Api::CommandBuffer
|
||||
pub(crate) struct CommandAllocator<A: HalApi> {
|
||||
free_encoders: Vec<A::CommandEncoder>,
|
||||
}
|
||||
|
||||
impl<A: HalApi> CommandAllocator<A> {
|
||||
pub(crate) fn new() -> Self {
|
||||
Self {
|
||||
free_encoders: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Return a fresh [`wgpu_hal::CommandEncoder`] in the "closed" state.
|
||||
///
|
||||
/// If we have free encoders in the pool, take one of those. Otherwise,
|
||||
/// create a new one on `device`.
|
||||
pub(crate) fn acquire_encoder(
|
||||
&mut self,
|
||||
device: &A::Device,
|
||||
queue: &A::Queue,
|
||||
) -> Result<A::CommandEncoder, hal::DeviceError> {
|
||||
match self.free_encoders.pop() {
|
||||
Some(encoder) => Ok(encoder),
|
||||
None => unsafe {
|
||||
let hal_desc = hal::CommandEncoderDescriptor { label: None, queue };
|
||||
device.create_command_encoder(&hal_desc)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Add `encoder` back to the free pool.
|
||||
pub(crate) fn release_encoder(&mut self, encoder: A::CommandEncoder) {
|
||||
self.free_encoders.push(encoder);
|
||||
}
|
||||
|
||||
/// Free the pool of command encoders.
|
||||
///
|
||||
/// This is only called when the `Device` is dropped.
|
||||
pub(crate) fn dispose(self, device: &A::Device) {
|
||||
resource_log!(
|
||||
"CommandAllocator::dispose encoders {}",
|
||||
self.free_encoders.len()
|
||||
);
|
||||
for cmd_encoder in self.free_encoders {
|
||||
unsafe {
|
||||
device.destroy_command_encoder(cmd_encoder);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
mod allocator;
|
||||
mod bind;
|
||||
mod bundle;
|
||||
mod clear;
|
||||
@ -15,6 +16,7 @@ pub(crate) use self::clear::clear_texture;
|
||||
pub use self::{
|
||||
bundle::*, clear::ClearError, compute::*, draw::*, query::*, render::*, transfer::*,
|
||||
};
|
||||
pub(crate) use allocator::CommandAllocator;
|
||||
|
||||
use self::memory_init::CommandBufferTextureMemoryActions;
|
||||
|
||||
|
@ -361,7 +361,7 @@ impl<A: HalApi> LifetimeTracker<A> {
|
||||
pub fn triage_submissions(
|
||||
&mut self,
|
||||
last_done: SubmissionIndex,
|
||||
command_allocator: &mut super::CommandAllocator<A>,
|
||||
command_allocator: &mut crate::command::CommandAllocator<A>,
|
||||
) -> SmallVec<[SubmittedWorkDoneClosure; 1]> {
|
||||
profiling::scope!("triage_submissions");
|
||||
|
||||
|
@ -4,7 +4,6 @@ use crate::{
|
||||
hub::Hub,
|
||||
id::{BindGroupLayoutId, PipelineLayoutId},
|
||||
resource::{Buffer, BufferAccessError, BufferAccessResult, BufferMapOperation},
|
||||
resource_log,
|
||||
snatch::SnatchGuard,
|
||||
Label, DOWNLEVEL_ERROR_MESSAGE,
|
||||
};
|
||||
@ -377,59 +376,6 @@ fn map_buffer<A: HalApi>(
|
||||
Ok(mapping.ptr)
|
||||
}
|
||||
|
||||
/// A pool of free [`wgpu_hal::CommandEncoder`]s, owned by a `Device`.
|
||||
///
|
||||
/// Each encoder in this list is in the "closed" state.
|
||||
///
|
||||
/// Since a raw [`CommandEncoder`][ce] is itself a pool for allocating
|
||||
/// raw [`CommandBuffer`][cb]s, this is a pool of pools.
|
||||
///
|
||||
/// [ce]: wgpu_hal::CommandEncoder
|
||||
/// [cb]: wgpu_hal::Api::CommandBuffer
|
||||
pub(crate) struct CommandAllocator<A: HalApi> {
|
||||
free_encoders: Vec<A::CommandEncoder>,
|
||||
}
|
||||
|
||||
impl<A: HalApi> CommandAllocator<A> {
|
||||
/// Return a fresh [`wgpu_hal::CommandEncoder`] in the "closed" state.
|
||||
///
|
||||
/// If we have free encoders in the pool, take one of those. Otherwise,
|
||||
/// create a new one on `device`.
|
||||
fn acquire_encoder(
|
||||
&mut self,
|
||||
device: &A::Device,
|
||||
queue: &A::Queue,
|
||||
) -> Result<A::CommandEncoder, hal::DeviceError> {
|
||||
match self.free_encoders.pop() {
|
||||
Some(encoder) => Ok(encoder),
|
||||
None => unsafe {
|
||||
let hal_desc = hal::CommandEncoderDescriptor { label: None, queue };
|
||||
device.create_command_encoder(&hal_desc)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Add `encoder` back to the free pool.
|
||||
fn release_encoder(&mut self, encoder: A::CommandEncoder) {
|
||||
self.free_encoders.push(encoder);
|
||||
}
|
||||
|
||||
/// Free the pool of command encoders.
|
||||
///
|
||||
/// This is only called when the `Device` is dropped.
|
||||
fn dispose(self, device: &A::Device) {
|
||||
resource_log!(
|
||||
"CommandAllocator::dispose encoders {}",
|
||||
self.free_encoders.len()
|
||||
);
|
||||
for cmd_encoder in self.free_encoders {
|
||||
unsafe {
|
||||
device.destroy_command_encoder(cmd_encoder);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Error)]
|
||||
#[error("Device is invalid")]
|
||||
pub struct InvalidDevice;
|
||||
|
@ -4,7 +4,7 @@ use crate::{
|
||||
api_log,
|
||||
command::{
|
||||
extract_texture_selector, validate_linear_texture_data, validate_texture_copy_range,
|
||||
ClearError, CommandBuffer, CopySide, ImageCopyTexture, TransferError,
|
||||
ClearError, CommandAllocator, CommandBuffer, CopySide, ImageCopyTexture, TransferError,
|
||||
},
|
||||
conv,
|
||||
device::{life::ResourceMaps, DeviceError, WaitIdleError},
|
||||
@ -258,7 +258,7 @@ impl<A: HalApi> PendingWrites<A> {
|
||||
#[must_use]
|
||||
fn post_submit(
|
||||
&mut self,
|
||||
command_allocator: &mut super::CommandAllocator<A>,
|
||||
command_allocator: &mut CommandAllocator<A>,
|
||||
device: &A::Device,
|
||||
queue: &A::Queue,
|
||||
) -> Option<EncoderInFlight<A>> {
|
||||
|
@ -7,8 +7,8 @@ use crate::{
|
||||
bgl,
|
||||
life::{LifetimeTracker, WaitIdleError},
|
||||
queue::PendingWrites,
|
||||
AttachmentData, CommandAllocator, DeviceLostInvocation, MissingDownlevelFlags,
|
||||
MissingFeatures, RenderPassContext, CLEANUP_WAIT_MS,
|
||||
AttachmentData, DeviceLostInvocation, MissingDownlevelFlags, MissingFeatures,
|
||||
RenderPassContext, CLEANUP_WAIT_MS,
|
||||
},
|
||||
hal_api::HalApi,
|
||||
hal_label,
|
||||
@ -97,7 +97,7 @@ pub struct Device<A: HalApi> {
|
||||
pub(crate) zero_buffer: Option<A::Buffer>,
|
||||
pub(crate) info: ResourceInfo<Device<A>>,
|
||||
|
||||
pub(crate) command_allocator: Mutex<Option<CommandAllocator<A>>>,
|
||||
pub(crate) command_allocator: Mutex<Option<command::CommandAllocator<A>>>,
|
||||
//Note: The submission index here corresponds to the last submission that is done.
|
||||
pub(crate) active_submission_index: AtomicU64, //SubmissionIndex,
|
||||
// NOTE: if both are needed, the `snatchable_lock` must be consistently acquired before the
|
||||
@ -223,9 +223,7 @@ impl<A: HalApi> Device<A> {
|
||||
let fence =
|
||||
unsafe { raw_device.create_fence() }.map_err(|_| CreateDeviceError::OutOfMemory)?;
|
||||
|
||||
let mut com_alloc = CommandAllocator {
|
||||
free_encoders: Vec::new(),
|
||||
};
|
||||
let mut com_alloc = command::CommandAllocator::new();
|
||||
let pending_encoder = com_alloc
|
||||
.acquire_encoder(&raw_device, raw_queue)
|
||||
.map_err(|_| CreateDeviceError::OutOfMemory)?;
|
||||
|
Loading…
Reference in New Issue
Block a user