mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-25 08:13:27 +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 bind;
|
||||||
mod bundle;
|
mod bundle;
|
||||||
mod clear;
|
mod clear;
|
||||||
@ -15,6 +16,7 @@ pub(crate) use self::clear::clear_texture;
|
|||||||
pub use self::{
|
pub use self::{
|
||||||
bundle::*, clear::ClearError, compute::*, draw::*, query::*, render::*, transfer::*,
|
bundle::*, clear::ClearError, compute::*, draw::*, query::*, render::*, transfer::*,
|
||||||
};
|
};
|
||||||
|
pub(crate) use allocator::CommandAllocator;
|
||||||
|
|
||||||
use self::memory_init::CommandBufferTextureMemoryActions;
|
use self::memory_init::CommandBufferTextureMemoryActions;
|
||||||
|
|
||||||
|
@ -361,7 +361,7 @@ impl<A: HalApi> LifetimeTracker<A> {
|
|||||||
pub fn triage_submissions(
|
pub fn triage_submissions(
|
||||||
&mut self,
|
&mut self,
|
||||||
last_done: SubmissionIndex,
|
last_done: SubmissionIndex,
|
||||||
command_allocator: &mut super::CommandAllocator<A>,
|
command_allocator: &mut crate::command::CommandAllocator<A>,
|
||||||
) -> SmallVec<[SubmittedWorkDoneClosure; 1]> {
|
) -> SmallVec<[SubmittedWorkDoneClosure; 1]> {
|
||||||
profiling::scope!("triage_submissions");
|
profiling::scope!("triage_submissions");
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@ use crate::{
|
|||||||
hub::Hub,
|
hub::Hub,
|
||||||
id::{BindGroupLayoutId, PipelineLayoutId},
|
id::{BindGroupLayoutId, PipelineLayoutId},
|
||||||
resource::{Buffer, BufferAccessError, BufferAccessResult, BufferMapOperation},
|
resource::{Buffer, BufferAccessError, BufferAccessResult, BufferMapOperation},
|
||||||
resource_log,
|
|
||||||
snatch::SnatchGuard,
|
snatch::SnatchGuard,
|
||||||
Label, DOWNLEVEL_ERROR_MESSAGE,
|
Label, DOWNLEVEL_ERROR_MESSAGE,
|
||||||
};
|
};
|
||||||
@ -377,59 +376,6 @@ fn map_buffer<A: HalApi>(
|
|||||||
Ok(mapping.ptr)
|
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)]
|
#[derive(Clone, Debug, Error)]
|
||||||
#[error("Device is invalid")]
|
#[error("Device is invalid")]
|
||||||
pub struct InvalidDevice;
|
pub struct InvalidDevice;
|
||||||
|
@ -4,7 +4,7 @@ use crate::{
|
|||||||
api_log,
|
api_log,
|
||||||
command::{
|
command::{
|
||||||
extract_texture_selector, validate_linear_texture_data, validate_texture_copy_range,
|
extract_texture_selector, validate_linear_texture_data, validate_texture_copy_range,
|
||||||
ClearError, CommandBuffer, CopySide, ImageCopyTexture, TransferError,
|
ClearError, CommandAllocator, CommandBuffer, CopySide, ImageCopyTexture, TransferError,
|
||||||
},
|
},
|
||||||
conv,
|
conv,
|
||||||
device::{life::ResourceMaps, DeviceError, WaitIdleError},
|
device::{life::ResourceMaps, DeviceError, WaitIdleError},
|
||||||
@ -258,7 +258,7 @@ impl<A: HalApi> PendingWrites<A> {
|
|||||||
#[must_use]
|
#[must_use]
|
||||||
fn post_submit(
|
fn post_submit(
|
||||||
&mut self,
|
&mut self,
|
||||||
command_allocator: &mut super::CommandAllocator<A>,
|
command_allocator: &mut CommandAllocator<A>,
|
||||||
device: &A::Device,
|
device: &A::Device,
|
||||||
queue: &A::Queue,
|
queue: &A::Queue,
|
||||||
) -> Option<EncoderInFlight<A>> {
|
) -> Option<EncoderInFlight<A>> {
|
||||||
|
@ -7,8 +7,8 @@ use crate::{
|
|||||||
bgl,
|
bgl,
|
||||||
life::{LifetimeTracker, WaitIdleError},
|
life::{LifetimeTracker, WaitIdleError},
|
||||||
queue::PendingWrites,
|
queue::PendingWrites,
|
||||||
AttachmentData, CommandAllocator, DeviceLostInvocation, MissingDownlevelFlags,
|
AttachmentData, DeviceLostInvocation, MissingDownlevelFlags, MissingFeatures,
|
||||||
MissingFeatures, RenderPassContext, CLEANUP_WAIT_MS,
|
RenderPassContext, CLEANUP_WAIT_MS,
|
||||||
},
|
},
|
||||||
hal_api::HalApi,
|
hal_api::HalApi,
|
||||||
hal_label,
|
hal_label,
|
||||||
@ -97,7 +97,7 @@ pub struct Device<A: HalApi> {
|
|||||||
pub(crate) zero_buffer: Option<A::Buffer>,
|
pub(crate) zero_buffer: Option<A::Buffer>,
|
||||||
pub(crate) info: ResourceInfo<Device<A>>,
|
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.
|
//Note: The submission index here corresponds to the last submission that is done.
|
||||||
pub(crate) active_submission_index: AtomicU64, //SubmissionIndex,
|
pub(crate) active_submission_index: AtomicU64, //SubmissionIndex,
|
||||||
// NOTE: if both are needed, the `snatchable_lock` must be consistently acquired before the
|
// 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 =
|
let fence =
|
||||||
unsafe { raw_device.create_fence() }.map_err(|_| CreateDeviceError::OutOfMemory)?;
|
unsafe { raw_device.create_fence() }.map_err(|_| CreateDeviceError::OutOfMemory)?;
|
||||||
|
|
||||||
let mut com_alloc = CommandAllocator {
|
let mut com_alloc = command::CommandAllocator::new();
|
||||||
free_encoders: Vec::new(),
|
|
||||||
};
|
|
||||||
let pending_encoder = com_alloc
|
let pending_encoder = com_alloc
|
||||||
.acquire_encoder(&raw_device, raw_queue)
|
.acquire_encoder(&raw_device, raw_queue)
|
||||||
.map_err(|_| CreateDeviceError::OutOfMemory)?;
|
.map_err(|_| CreateDeviceError::OutOfMemory)?;
|
||||||
|
Loading…
Reference in New Issue
Block a user