Add buffer creation error type

This commit is contained in:
Gabriel Majeri 2020-07-18 11:12:15 +03:00
parent a689aea3f2
commit 2ac778b312
2 changed files with 24 additions and 19 deletions

View File

@ -154,7 +154,8 @@ impl GlobalPlay for wgc::hub::Global<IdentityPassThroughFactory> {
A::CreateBuffer { id, desc } => { A::CreateBuffer { id, desc } => {
let label = Label::new(&desc.label); let label = Label::new(&desc.label);
self.device_maintain_ids::<B>(device); self.device_maintain_ids::<B>(device);
self.device_create_buffer::<B>(device, &desc.map_label(|_| label.as_ptr()), id); self.device_create_buffer::<B>(device, &desc.map_label(|_| label.as_ptr()), id)
.unwrap();
} }
A::DestroyBuffer(id) => { A::DestroyBuffer(id) => {
self.buffer_destroy::<B>(id); self.buffer_destroy::<B>(id);

View File

@ -22,6 +22,7 @@ use hal::{
window::{PresentationSurface as _, Surface as _}, window::{PresentationSurface as _, Surface as _},
}; };
use parking_lot::{Mutex, MutexGuard}; use parking_lot::{Mutex, MutexGuard};
use thiserror::Error;
use wgt::{BufferAddress, BufferSize, InputStepMode, TextureDimension, TextureFormat}; use wgt::{BufferAddress, BufferSize, InputStepMode, TextureDimension, TextureFormat};
use std::{ use std::{
@ -383,7 +384,7 @@ impl<B: GfxBackend> Device<B> {
self_id: id::DeviceId, self_id: id::DeviceId,
desc: &wgt::BufferDescriptor<Label>, desc: &wgt::BufferDescriptor<Label>,
memory_kind: gfx_memory::Kind, memory_kind: gfx_memory::Kind,
) -> resource::Buffer<B> { ) -> Result<resource::Buffer<B>, CreateBufferError> {
debug_assert_eq!(self_id.backend(), B::VARIANT); debug_assert_eq!(self_id.backend(), B::VARIANT);
let (mut usage, _memory_properties) = conv::map_buffer_usage(desc.usage); let (mut usage, _memory_properties) = conv::map_buffer_usage(desc.usage);
if desc.mapped_at_creation && !desc.usage.contains(wgt::BufferUsage::MAP_WRITE) { if desc.mapped_at_creation && !desc.usage.contains(wgt::BufferUsage::MAP_WRITE) {
@ -406,11 +407,9 @@ impl<B: GfxBackend> Device<B> {
let is_native_only = self let is_native_only = self
.features .features
.contains(wgt::Features::MAPPABLE_PRIMARY_BUFFERS); .contains(wgt::Features::MAPPABLE_PRIMARY_BUFFERS);
assert!( if !is_native_only {
is_native_only, return Err(CreateBufferError::UsageMismatch(desc.usage));
"MAP usage can only be combined with the opposite COPY, requested {:?}", }
desc.usage
);
MemoryUsage::Dynamic { MemoryUsage::Dynamic {
sparse_updates: false, sparse_updates: false,
} }
@ -437,7 +436,7 @@ impl<B: GfxBackend> Device<B> {
.unwrap() .unwrap()
}; };
resource::Buffer { Ok(resource::Buffer {
raw: buffer, raw: buffer,
device_id: Stored { device_id: Stored {
value: self_id, value: self_id,
@ -450,7 +449,7 @@ impl<B: GfxBackend> Device<B> {
sync_mapped_writes: None, sync_mapped_writes: None,
map_state: resource::BufferMapState::Idle, map_state: resource::BufferMapState::Idle,
life_guard: LifeGuard::new(), life_guard: LifeGuard::new(),
} })
} }
fn create_texture( fn create_texture(
@ -660,7 +659,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
device_id: id::DeviceId, device_id: id::DeviceId,
desc: &wgt::BufferDescriptor<Label>, desc: &wgt::BufferDescriptor<Label>,
id_in: Input<G, id::BufferId>, id_in: Input<G, id::BufferId>,
) -> id::BufferId { ) -> Result<id::BufferId, CreateBufferError> {
span!(_guard, INFO, "Device::create_buffer"); span!(_guard, INFO, "Device::create_buffer");
let hub = B::hub(self); let hub = B::hub(self);
@ -668,17 +667,13 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
log::info!("Create buffer {:?} with ID {:?}", desc, id_in); log::info!("Create buffer {:?} with ID {:?}", desc, id_in);
if desc.mapped_at_creation { if desc.mapped_at_creation && desc.size % wgt::COPY_BUFFER_ALIGNMENT != 0 {
assert_eq!( return Err(CreateBufferError::UnalignedSize);
desc.size % wgt::COPY_BUFFER_ALIGNMENT,
0,
"Buffers that are mapped at creation have to be aligned to COPY_BUFFER_ALIGNMENT"
);
} }
let (device_guard, mut token) = hub.devices.read(&mut token); let (device_guard, mut token) = hub.devices.read(&mut token);
let device = &device_guard[device_id]; let device = &device_guard[device_id];
let mut buffer = device.create_buffer(device_id, desc, gfx_memory::Kind::General); let mut buffer = device.create_buffer(device_id, desc, gfx_memory::Kind::General)?;
let ref_count = buffer.life_guard.add_ref(); let ref_count = buffer.life_guard.add_ref();
let buffer_use = if !desc.mapped_at_creation { let buffer_use = if !desc.mapped_at_creation {
@ -699,6 +694,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
}; };
} }
Err(e) => { Err(e) => {
// TODO: return error on failure?
log::error!("failed to create buffer in a mapped state: {:?}", e); log::error!("failed to create buffer in a mapped state: {:?}", e);
} }
}; };
@ -714,7 +710,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
mapped_at_creation: false, mapped_at_creation: false,
}, },
gfx_memory::Kind::Linear, gfx_memory::Kind::Linear,
); )?;
let ptr = stage let ptr = stage
.memory .memory
.map(&device.raw, hal::memory::Segment::ALL) .map(&device.raw, hal::memory::Segment::ALL)
@ -749,7 +745,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
.buffers .buffers
.init(id, ref_count, BufferState::with_usage(buffer_use)) .init(id, ref_count, BufferState::with_usage(buffer_use))
.unwrap(); .unwrap();
id Ok(id)
} }
#[cfg(feature = "replay")] #[cfg(feature = "replay")]
@ -3035,3 +3031,11 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
} }
} }
} }
#[derive(Clone, Debug, Error)]
pub enum CreateBufferError {
#[error("`MAP` usage can only be combined with the opposite `COPY`, requested {0:?}")]
UsageMismatch(wgt::BufferUsage),
#[error("buffers that are mapped at creation have to be aligned to `COPY_BUFFER_ALIGNMENT`")]
UnalignedSize,
}