667: Add asserts to validate that a resource exists when used r=kvark a=DavidPeicho

Hi,

As discussed in #610, this is mostly for C/C++ users. Some questions:
* Would it be possible to display the ID of the resource that failed? I don't know what you think about implementing the `Display` trait on the `Id` struct? 
* Do you see other places needing for checks?

Thanks!

Co-authored-by: David Peicho <david.peicho@gmail.com>
This commit is contained in:
bors[bot] 2020-05-26 22:23:31 +00:00 committed by GitHub
commit 4c136418ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 21 deletions

View File

@ -1319,6 +1319,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
panic!("Mismatched buffer binding type for {:?}. Expected a type of UniformBuffer, StorageBuffer or ReadonlyStorageBuffer", decl)
}
};
assert_eq!(
bb.offset % alignment,
0,
@ -1326,6 +1327,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
bb.offset,
alignment
);
let buffer = used
.buffers
.use_extend(&*buffer_guard, bb.buffer, (), internal_use)
@ -1360,6 +1362,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
| binding_model::BindingType::ComparisonSampler => {}
_ => panic!("Mismatched sampler binding type in {:?}. Expected a type of Sampler or ComparisonSampler", decl.ty),
}
let sampler = used
.samplers
.use_extend(&*sampler_guard, id, (), ())

View File

@ -80,6 +80,7 @@ impl IdentityManager {
pub struct Storage<T, I: TypedId> {
//TODO: consider concurrent hashmap?
map: VecMap<(T, Epoch)>,
kind: &'static str,
_phantom: PhantomData<I>,
}
@ -87,8 +88,15 @@ impl<T, I: TypedId> ops::Index<I> for Storage<T, I> {
type Output = T;
fn index(&self, id: I) -> &T {
let (index, epoch, _) = id.unzip();
let (ref value, storage_epoch) = self.map[index as usize];
assert_eq!(epoch, storage_epoch);
let (ref value, storage_epoch) = match self.map.get(index as usize) {
Some(v) => v,
None => panic!("{}[{}] does not exist", self.kind, index),
};
assert_eq!(
epoch, *storage_epoch,
"{}[{}] is no longer alive",
self.kind, index
);
value
}
}
@ -96,8 +104,15 @@ impl<T, I: TypedId> ops::Index<I> for Storage<T, I> {
impl<T, I: TypedId> ops::IndexMut<I> for Storage<T, I> {
fn index_mut(&mut self, id: I) -> &mut T {
let (index, epoch, _) = id.unzip();
let (ref mut value, storage_epoch) = self.map[index as usize];
assert_eq!(epoch, storage_epoch);
let (ref mut value, storage_epoch) = match self.map.get_mut(index as usize) {
Some(v) => v,
None => panic!("{}[{}] does not exist", self.kind, index),
};
assert_eq!(
epoch, *storage_epoch,
"{}[{}] is no longer alive",
self.kind, index
);
value
}
}
@ -304,22 +319,24 @@ pub struct Registry<T, I: TypedId, F: IdentityHandlerFactory<I>> {
}
impl<T, I: TypedId, F: IdentityHandlerFactory<I>> Registry<T, I, F> {
fn new(backend: Backend, factory: &F) -> Self {
fn new(backend: Backend, factory: &F, kind: &'static str) -> Self {
Registry {
identity: factory.spawn(0),
data: RwLock::new(Storage {
map: VecMap::new(),
kind,
_phantom: PhantomData,
}),
backend,
}
}
fn without_backend(factory: &F) -> Self {
fn without_backend(factory: &F, kind: &'static str) -> Self {
Registry {
identity: factory.spawn(1),
data: RwLock::new(Storage {
map: VecMap::new(),
kind,
_phantom: PhantomData,
}),
backend: Backend::Empty,
@ -398,20 +415,20 @@ pub struct Hub<B: hal::Backend, F: GlobalIdentityHandlerFactory> {
impl<B: GfxBackend, F: GlobalIdentityHandlerFactory> Hub<B, F> {
fn new(factory: &F) -> Self {
Hub {
adapters: Registry::new(B::VARIANT, factory),
devices: Registry::new(B::VARIANT, factory),
swap_chains: Registry::new(B::VARIANT, factory),
pipeline_layouts: Registry::new(B::VARIANT, factory),
shader_modules: Registry::new(B::VARIANT, factory),
bind_group_layouts: Registry::new(B::VARIANT, factory),
bind_groups: Registry::new(B::VARIANT, factory),
command_buffers: Registry::new(B::VARIANT, factory),
render_pipelines: Registry::new(B::VARIANT, factory),
compute_pipelines: Registry::new(B::VARIANT, factory),
buffers: Registry::new(B::VARIANT, factory),
textures: Registry::new(B::VARIANT, factory),
texture_views: Registry::new(B::VARIANT, factory),
samplers: Registry::new(B::VARIANT, factory),
adapters: Registry::new(B::VARIANT, factory, "Adapter"),
devices: Registry::new(B::VARIANT, factory, "Device"),
swap_chains: Registry::new(B::VARIANT, factory, "SwapChain"),
pipeline_layouts: Registry::new(B::VARIANT, factory, "PipelineLayout"),
shader_modules: Registry::new(B::VARIANT, factory, "ShaderModule"),
bind_group_layouts: Registry::new(B::VARIANT, factory, "BindGroupLayout"),
bind_groups: Registry::new(B::VARIANT, factory, "BindGroup"),
command_buffers: Registry::new(B::VARIANT, factory, "CommandBuffer"),
render_pipelines: Registry::new(B::VARIANT, factory, "RenderPipeline"),
compute_pipelines: Registry::new(B::VARIANT, factory, "ComputePipeline"),
buffers: Registry::new(B::VARIANT, factory, "Buffer"),
textures: Registry::new(B::VARIANT, factory, "Texture"),
texture_views: Registry::new(B::VARIANT, factory, "TextureView"),
samplers: Registry::new(B::VARIANT, factory, "Sampler"),
}
}
}
@ -556,7 +573,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
pub fn new(name: &str, factory: G) -> Self {
Global {
instance: Instance::new(name, 1),
surfaces: Registry::without_backend(&factory),
surfaces: Registry::without_backend(&factory, "Surface"),
hubs: Hubs::new(&factory),
}
}