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