mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-25 16:24:24 +00:00
Handle command pool creation error
This commit is contained in:
parent
9929b8719f
commit
e860dd995f
@ -306,11 +306,13 @@ impl GlobalPlay for wgc::hub::Global<IdentityPassThroughFactory> {
|
||||
.unwrap();
|
||||
}
|
||||
A::Submit(_index, commands) => {
|
||||
let encoder = self.device_create_command_encoder::<B>(
|
||||
device,
|
||||
&wgt::CommandEncoderDescriptor { label: ptr::null() },
|
||||
comb_manager.alloc(device.backend()),
|
||||
);
|
||||
let encoder = self
|
||||
.device_create_command_encoder::<B>(
|
||||
device,
|
||||
&wgt::CommandEncoderDescriptor { label: ptr::null() },
|
||||
comb_manager.alloc(device.backend()),
|
||||
)
|
||||
.unwrap();
|
||||
let cmdbuf = self.encode_commands::<B>(encoder, commands);
|
||||
self.queue_submit::<B>(device, &[cmdbuf]).unwrap();
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ use crate::{
|
||||
|
||||
use hal::{command::CommandBuffer as _, device::Device as _, pool::CommandPool as _};
|
||||
use parking_lot::Mutex;
|
||||
use thiserror::Error;
|
||||
|
||||
use std::thread;
|
||||
|
||||
@ -80,30 +81,37 @@ impl<B: GfxBackend> CommandAllocator<B> {
|
||||
limits: wgt::Limits,
|
||||
private_features: PrivateFeatures,
|
||||
#[cfg(feature = "trace")] enable_tracing: bool,
|
||||
) -> CommandBuffer<B> {
|
||||
) -> Result<CommandBuffer<B>, CommandAllocatorError> {
|
||||
//debug_assert_eq!(device_id.backend(), B::VARIANT);
|
||||
let thread_id = thread::current().id();
|
||||
let mut inner = self.inner.lock();
|
||||
|
||||
let init = inner
|
||||
.pools
|
||||
.entry(thread_id)
|
||||
.or_insert_with(|| CommandPool {
|
||||
raw: unsafe {
|
||||
tracing::info!("Starting on thread {:?}", thread_id);
|
||||
device.create_command_pool(
|
||||
self.queue_family,
|
||||
hal::pool::CommandPoolCreateFlags::RESET_INDIVIDUAL,
|
||||
)
|
||||
}
|
||||
.unwrap(),
|
||||
total: 0,
|
||||
available: Vec::new(),
|
||||
pending: Vec::new(),
|
||||
})
|
||||
.allocate();
|
||||
use std::collections::hash_map::Entry;
|
||||
let pool = match inner.pools.entry(thread_id) {
|
||||
Entry::Occupied(e) => e.into_mut(),
|
||||
Entry::Vacant(e) => {
|
||||
tracing::info!("Starting on thread {:?}", thread_id);
|
||||
let raw = unsafe {
|
||||
device
|
||||
.create_command_pool(
|
||||
self.queue_family,
|
||||
hal::pool::CommandPoolCreateFlags::RESET_INDIVIDUAL,
|
||||
)
|
||||
.or(Err(CommandAllocatorError::OutOfMemory))?
|
||||
};
|
||||
let pool = CommandPool {
|
||||
raw,
|
||||
total: 0,
|
||||
available: Vec::new(),
|
||||
pending: Vec::new(),
|
||||
};
|
||||
e.insert(pool)
|
||||
}
|
||||
};
|
||||
|
||||
CommandBuffer {
|
||||
let init = pool.allocate();
|
||||
|
||||
Ok(CommandBuffer {
|
||||
raw: vec![init],
|
||||
is_recording: true,
|
||||
recorded_thread_id: thread_id,
|
||||
@ -118,12 +126,15 @@ impl<B: GfxBackend> CommandAllocator<B> {
|
||||
} else {
|
||||
None
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: hal::Backend> CommandAllocator<B> {
|
||||
pub fn new(queue_family: hal::queue::QueueFamilyId, device: &B::Device) -> Self {
|
||||
pub fn new(
|
||||
queue_family: hal::queue::QueueFamilyId,
|
||||
device: &B::Device,
|
||||
) -> Result<Self, CommandAllocatorError> {
|
||||
let internal_thread_id = thread::current().id();
|
||||
tracing::info!("Starting on (internal) thread {:?}", internal_thread_id);
|
||||
let mut pools = FastHashMap::default();
|
||||
@ -136,18 +147,18 @@ impl<B: hal::Backend> CommandAllocator<B> {
|
||||
queue_family,
|
||||
hal::pool::CommandPoolCreateFlags::RESET_INDIVIDUAL,
|
||||
)
|
||||
.unwrap()
|
||||
.or(Err(CommandAllocatorError::OutOfMemory))?
|
||||
},
|
||||
total: 0,
|
||||
available: Vec::new(),
|
||||
pending: Vec::new(),
|
||||
},
|
||||
);
|
||||
CommandAllocator {
|
||||
Ok(CommandAllocator {
|
||||
queue_family,
|
||||
internal_thread_id,
|
||||
inner: Mutex::new(Inner { pools }),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn allocate_for_thread_id(&self, thread_id: thread::ThreadId) -> B::CommandBuffer {
|
||||
@ -242,3 +253,9 @@ impl<B: hal::Backend> CommandAllocator<B> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Error)]
|
||||
pub enum CommandAllocatorError {
|
||||
#[error("not enough memory left")]
|
||||
OutOfMemory,
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ mod render;
|
||||
mod transfer;
|
||||
|
||||
pub(crate) use self::allocator::CommandAllocator;
|
||||
pub use self::allocator::CommandAllocatorError;
|
||||
pub use self::bundle::*;
|
||||
pub use self::compute::*;
|
||||
pub use self::render::*;
|
||||
|
@ -217,8 +217,9 @@ impl<B: GfxBackend> Device<B> {
|
||||
private_features: PrivateFeatures,
|
||||
desc: &wgt::DeviceDescriptor,
|
||||
trace_path: Option<&std::path::Path>,
|
||||
) -> Self {
|
||||
let cmd_allocator = command::CommandAllocator::new(queue_group.family, &raw);
|
||||
) -> Result<Self, CreateDeviceError> {
|
||||
let cmd_allocator = command::CommandAllocator::new(queue_group.family, &raw)
|
||||
.or(Err(CreateDeviceError::OutOfMemory))?;
|
||||
let heaps = unsafe {
|
||||
Heaps::new(
|
||||
&mem_props,
|
||||
@ -240,7 +241,7 @@ impl<B: GfxBackend> Device<B> {
|
||||
None => (),
|
||||
}
|
||||
|
||||
Device {
|
||||
Ok(Device {
|
||||
raw,
|
||||
adapter_id,
|
||||
cmd_allocator,
|
||||
@ -273,7 +274,7 @@ impl<B: GfxBackend> Device<B> {
|
||||
limits: desc.limits.clone(),
|
||||
features: desc.features.clone(),
|
||||
pending_writes: queue::PendingWrites::new(),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn last_completed_submission_index(&self) -> SubmissionIndex {
|
||||
@ -2031,7 +2032,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
device_id: id::DeviceId,
|
||||
desc: &wgt::CommandEncoderDescriptor<Label>,
|
||||
id_in: Input<G, id::CommandEncoderId>,
|
||||
) -> id::CommandEncoderId {
|
||||
) -> Result<id::CommandEncoderId, command::CommandAllocatorError> {
|
||||
span!(_guard, INFO, "Device::create_command_encoder");
|
||||
|
||||
let hub = B::hub(self);
|
||||
@ -2052,7 +2053,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
device.private_features,
|
||||
#[cfg(feature = "trace")]
|
||||
device.trace.is_some(),
|
||||
);
|
||||
)?;
|
||||
|
||||
unsafe {
|
||||
let raw_command_buffer = command_buffer.raw.last_mut().unwrap();
|
||||
@ -2065,8 +2066,11 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
raw_command_buffer.begin_primary(hal::command::CommandBufferFlags::ONE_TIME_SUBMIT);
|
||||
}
|
||||
|
||||
hub.command_buffers
|
||||
.register_identity(id_in, command_buffer, &mut token)
|
||||
let id = hub
|
||||
.command_buffers
|
||||
.register_identity(id_in, command_buffer, &mut token);
|
||||
|
||||
Ok(id)
|
||||
}
|
||||
|
||||
pub fn command_encoder_destroy<B: GfxBackend>(&self, command_encoder_id: id::CommandEncoderId) {
|
||||
@ -3035,6 +3039,12 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Error)]
|
||||
pub enum CreateDeviceError {
|
||||
#[error("not enough memory left")]
|
||||
OutOfMemory,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Error)]
|
||||
pub enum CreateBufferError {
|
||||
#[error("failed to map buffer while creating: {0}")]
|
||||
|
@ -423,9 +423,10 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
let cmdbuf = &mut command_buffer_guard[cmb_id];
|
||||
#[cfg(feature = "trace")]
|
||||
match device.trace {
|
||||
Some(ref trace) => trace
|
||||
.lock()
|
||||
.add(Action::Submit(submit_index, cmdbuf.commands.take().unwrap())),
|
||||
Some(ref trace) => trace.lock().add(Action::Submit(
|
||||
submit_index,
|
||||
cmdbuf.commands.take().unwrap(),
|
||||
)),
|
||||
None => (),
|
||||
};
|
||||
|
||||
|
@ -248,14 +248,18 @@ impl AdapterInfo {
|
||||
#[derive(Clone, Debug, Error, PartialEq)]
|
||||
/// Error when requesting a device from the adaptor
|
||||
pub enum RequestDeviceError {
|
||||
#[error("unsupported features were requested: {0:?}")]
|
||||
UnsupportedFeature(wgt::Features),
|
||||
#[error("device has no queue supporting graphics")]
|
||||
NoGraphicsQueue,
|
||||
#[error(transparent)]
|
||||
DeviceCreationError(#[from] hal::device::CreationError),
|
||||
#[error("connection to device was lost during initialization")]
|
||||
DeviceLost,
|
||||
#[error("device initialization failed due to implementation specific errors")]
|
||||
Internal,
|
||||
#[error("some of the requested device limits are not supported")]
|
||||
LimitsExceeded,
|
||||
#[error("device has no queue supporting graphics")]
|
||||
NoGraphicsQueue,
|
||||
#[error("not enough memory left")]
|
||||
OutOfMemory,
|
||||
#[error("unsupported features were requested: {0:?}")]
|
||||
UnsupportedFeature(wgt::Features),
|
||||
}
|
||||
|
||||
/// Supported physical device types.
|
||||
@ -679,7 +683,16 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
.iter()
|
||||
.find(|family| family.queue_type().supports_graphics())
|
||||
.ok_or(RequestDeviceError::NoGraphicsQueue)?;
|
||||
let mut gpu = unsafe { phd.open(&[(family, &[1.0])], enabled_features)? };
|
||||
let mut gpu =
|
||||
unsafe { phd.open(&[(family, &[1.0])], enabled_features) }.map_err(|err| {
|
||||
use hal::device::CreationError::*;
|
||||
match err {
|
||||
DeviceLost => RequestDeviceError::DeviceLost,
|
||||
InitializationFailed => RequestDeviceError::Internal,
|
||||
OutOfMemory(_) => RequestDeviceError::OutOfMemory,
|
||||
_ => panic!("failed to create `gfx-hal` device: {}", err),
|
||||
}
|
||||
})?;
|
||||
|
||||
let limits = phd.limits();
|
||||
assert_eq!(
|
||||
@ -722,6 +735,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
desc,
|
||||
trace_path,
|
||||
)
|
||||
.or(Err(RequestDeviceError::OutOfMemory))?
|
||||
};
|
||||
|
||||
Ok(hub.devices.register_identity(id_in, device, &mut token))
|
||||
|
Loading…
Reference in New Issue
Block a user