From a1176227f7f52db83cf2cbfeea7128cdec339196 Mon Sep 17 00:00:00 2001 From: Rua Date: Sat, 1 Feb 2020 22:33:17 +0100 Subject: [PATCH] Add Eq and Hash implementations to types used in draw calls (#1314) * Add Eq and Hash implementations to various buffer and image types * Changelog entry * Add Eq and Hash to graphics pipelines too * Changelog entry * Remove Eq and Hash from dyn GraphicsPipelineAbstract, as the device cannot be checked * Add Eq and Hash to GraphicsPipelineAbstract, include size in buffer equality * Add Eq and Hash to descriptor sets * Changelog entry * Add Eq and Hash to Instance, check for it in Device --- CHANGELOG_VULKANO.md | 6 ++ vulkano/src/buffer/cpu_access.rs | 26 ++++++++ vulkano/src/buffer/cpu_pool.rs | 48 +++++++++++++++ vulkano/src/buffer/device_local.rs | 25 ++++++++ vulkano/src/buffer/immutable.rs | 36 +++++++++++ vulkano/src/buffer/slice.rs | 25 ++++++++ vulkano/src/buffer/sys.rs | 19 ++++++ vulkano/src/buffer/traits.rs | 21 ++++++- .../descriptor_set/fixed_size_pool.rs | 33 +++++++++-- vulkano/src/descriptor/descriptor_set/mod.rs | 25 +++++++- .../descriptor/descriptor_set/persistent.rs | 29 +++++++++ vulkano/src/device/mod.rs | 20 +++++++ vulkano/src/image/attachment.rs | 24 ++++++++ vulkano/src/image/immutable.rs | 46 +++++++++++++++ vulkano/src/image/storage.rs | 27 +++++++++ vulkano/src/image/swapchain.rs | 18 ++++++ vulkano/src/image/sys.rs | 36 +++++++++++ vulkano/src/image/traits.rs | 59 ++++++++++++++++++- vulkano/src/instance/instance.rs | 18 ++++++ vulkano/src/pipeline/graphics_pipeline/mod.rs | 51 +++++++++++++++- 20 files changed, 584 insertions(+), 8 deletions(-) diff --git a/CHANGELOG_VULKANO.md b/CHANGELOG_VULKANO.md index 820b8536..4e7d92d3 100644 --- a/CHANGELOG_VULKANO.md +++ b/CHANGELOG_VULKANO.md @@ -18,6 +18,12 @@ - `Swapchain::acquire_next_image()`` now returns ``(image_id, suboptimal, aquire_future)`` + *suboptimal indicates that the swapchain is usable, but should be recreated* - Fixed Join Future implementation to not submit joined command buffers twice. +- The traits `GraphicsPipelineAbstract` and `DescriptorSet` now require `DeviceOwned`. +- Added `PartialEq`, `Eq` and `Hash` implementations to all types involved in a draw call, including: + - `Instance`, `Device`, `GraphicsPipeline` and `dyn GraphicsPipelineAbstract` + - `UnsafeBuffer` and all types implementing `BufferAccess` + - `UnsafeImage`, `UnsafeImageView` and all types implementing `ImageAccess` or `ImageViewAccess` + - All types implementing `DescriptorSet` # Version 0.16.0 (2019-11-01) diff --git a/vulkano/src/buffer/cpu_access.rs b/vulkano/src/buffer/cpu_access.rs index 6dc1659a..41ca724f 100644 --- a/vulkano/src/buffer/cpu_access.rs +++ b/vulkano/src/buffer/cpu_access.rs @@ -19,6 +19,8 @@ use smallvec::SmallVec; use std::error; use std::fmt; +use std::hash::Hash; +use std::hash::Hasher; use std::iter; use std::marker::PhantomData; use std::mem; @@ -458,6 +460,30 @@ unsafe impl DeviceOwned for CpuAccessibleBuffer { } } +impl PartialEq for CpuAccessibleBuffer + where T: 'static + Send + Sync +{ + #[inline] + fn eq(&self, other: &Self) -> bool { + self.inner() == other.inner() && self.size() == other.size() + } +} + +impl Eq for CpuAccessibleBuffer + where T: 'static + Send + Sync +{} + +impl Hash for CpuAccessibleBuffer + where T: 'static + Send + Sync +{ + #[inline] + fn hash(&self, state: &mut H) { + self.inner().hash(state); + self.size().hash(state); + } +} + + /// Object that can be used to read or write the content of a `CpuAccessibleBuffer`. /// /// Note that this object holds a rwlock read guard on the chunk. If another thread tries to access diff --git a/vulkano/src/buffer/cpu_pool.rs b/vulkano/src/buffer/cpu_pool.rs index 5987c5de..c6ea89dd 100644 --- a/vulkano/src/buffer/cpu_pool.rs +++ b/vulkano/src/buffer/cpu_pool.rs @@ -8,6 +8,8 @@ // according to those terms. use std::cmp; +use std::hash::Hash; +use std::hash::Hasher; use std::iter; use std::marker::PhantomData; use std::mem; @@ -721,6 +723,29 @@ unsafe impl DeviceOwned for CpuBufferPoolChunk } } +impl PartialEq for CpuBufferPoolChunk + where A: MemoryPool +{ + #[inline] + fn eq(&self, other: &Self) -> bool { + self.inner() == other.inner() && self.size() == other.size() + } +} + +impl Eq for CpuBufferPoolChunk + where A: MemoryPool +{} + +impl Hash for CpuBufferPoolChunk + where A: MemoryPool +{ + #[inline] + fn hash(&self, state: &mut H) { + self.inner().hash(state); + self.size().hash(state); + } +} + impl Clone for CpuBufferPoolSubbuffer where A: MemoryPool { @@ -788,6 +813,29 @@ unsafe impl DeviceOwned for CpuBufferPoolSubbuffer } } +impl PartialEq for CpuBufferPoolSubbuffer + where A: MemoryPool +{ + #[inline] + fn eq(&self, other: &Self) -> bool { + self.inner() == other.inner() && self.size() == other.size() + } +} + +impl Eq for CpuBufferPoolSubbuffer + where A: MemoryPool +{} + +impl Hash for CpuBufferPoolSubbuffer + where A: MemoryPool +{ + #[inline] + fn hash(&self, state: &mut H) { + self.inner().hash(state); + self.size().hash(state); + } +} + #[cfg(test)] mod tests { use buffer::CpuBufferPool; diff --git a/vulkano/src/buffer/device_local.rs b/vulkano/src/buffer/device_local.rs index 649120fa..fb07e003 100644 --- a/vulkano/src/buffer/device_local.rs +++ b/vulkano/src/buffer/device_local.rs @@ -14,6 +14,8 @@ //! write simultaneously, or write and write simultaneously will block with a semaphore. use smallvec::SmallVec; +use std::hash::Hash; +use std::hash::Hasher; use std::marker::PhantomData; use std::mem; use std::sync::Arc; @@ -284,3 +286,26 @@ unsafe impl TypedBufferAccess for DeviceLocalBuffer { type Content = T; } + +impl PartialEq for DeviceLocalBuffer + where T: 'static + Send + Sync +{ + #[inline] + fn eq(&self, other: &Self) -> bool { + self.inner() == other.inner() && self.size() == other.size() + } +} + +impl Eq for DeviceLocalBuffer + where T: 'static + Send + Sync +{} + +impl Hash for DeviceLocalBuffer + where T: 'static + Send + Sync +{ + #[inline] + fn hash(&self, state: &mut H) { + self.inner().hash(state); + self.size().hash(state); + } +} diff --git a/vulkano/src/buffer/immutable.rs b/vulkano/src/buffer/immutable.rs index 8e2babfb..ae61ea2d 100644 --- a/vulkano/src/buffer/immutable.rs +++ b/vulkano/src/buffer/immutable.rs @@ -19,6 +19,8 @@ //! use smallvec::SmallVec; +use std::hash::Hash; +use std::hash::Hasher; use std::marker::PhantomData; use std::mem; use std::sync::Arc; @@ -377,6 +379,23 @@ unsafe impl DeviceOwned for ImmutableBuffer { } } +impl PartialEq for ImmutableBuffer { + #[inline] + fn eq(&self, other: &Self) -> bool { + self.inner() == other.inner() && self.size() == other.size() + } +} + +impl Eq for ImmutableBuffer {} + +impl Hash for ImmutableBuffer { + #[inline] + fn hash(&self, state: &mut H) { + self.inner().hash(state); + self.size().hash(state); + } +} + /// Access to the immutable buffer that can be used for the initial upload. //#[derive(Debug)] // TODO: pub struct ImmutableBufferInitialization> { @@ -455,6 +474,23 @@ impl Clone for ImmutableBufferInitialization { } } +impl PartialEq for ImmutableBufferInitialization { + #[inline] + fn eq(&self, other: &Self) -> bool { + self.inner() == other.inner() && self.size() == other.size() + } +} + +impl Eq for ImmutableBufferInitialization {} + +impl Hash for ImmutableBufferInitialization { + #[inline] + fn hash(&self, state: &mut H) { + self.inner().hash(state); + self.size().hash(state); + } +} + #[cfg(test)] mod tests { use buffer::BufferUsage; diff --git a/vulkano/src/buffer/slice.rs b/vulkano/src/buffer/slice.rs index 25e81562..4399b550 100644 --- a/vulkano/src/buffer/slice.rs +++ b/vulkano/src/buffer/slice.rs @@ -7,6 +7,8 @@ // notice may not be copied, modified, or distributed except // according to those terms. +use std::hash::Hash; +use std::hash::Hasher; use std::marker::PhantomData; use std::mem; use std::mem::MaybeUninit; @@ -285,6 +287,29 @@ impl From> for BufferSlice<[T], B> { } } +impl PartialEq for BufferSlice + where B: BufferAccess +{ + #[inline] + fn eq(&self, other: &Self) -> bool { + self.inner() == other.inner() && self.size() == other.size() + } +} + +impl Eq for BufferSlice + where B: BufferAccess +{} + +impl Hash for BufferSlice + where B: BufferAccess +{ + #[inline] + fn hash(&self, state: &mut H) { + self.inner().hash(state); + self.size().hash(state); + } +} + /// Takes a `BufferSlice` that points to a struct, and returns a `BufferSlice` that points to /// a specific field of that struct. #[macro_export] diff --git a/vulkano/src/buffer/sys.rs b/vulkano/src/buffer/sys.rs index 295e9b75..32e12b39 100644 --- a/vulkano/src/buffer/sys.rs +++ b/vulkano/src/buffer/sys.rs @@ -27,6 +27,8 @@ use smallvec::SmallVec; use std::error; use std::fmt; +use std::hash::Hash; +use std::hash::Hasher; use std::mem; use std::mem::MaybeUninit; use std::ptr; @@ -338,6 +340,23 @@ impl Drop for UnsafeBuffer { } } +impl PartialEq for UnsafeBuffer { + #[inline] + fn eq(&self, other: &Self) -> bool { + self.buffer == other.buffer && self.device == other.device + } +} + +impl Eq for UnsafeBuffer {} + +impl Hash for UnsafeBuffer { + #[inline] + fn hash(&self, state: &mut H) { + self.buffer.hash(state); + self.device.hash(state); + } +} + #[derive(Debug, Copy, Clone)] pub struct SparseLevel { pub sparse: bool, diff --git a/vulkano/src/buffer/traits.rs b/vulkano/src/buffer/traits.rs index 5ed99440..cab2f96f 100644 --- a/vulkano/src/buffer/traits.rs +++ b/vulkano/src/buffer/traits.rs @@ -8,6 +8,8 @@ // according to those terms. use std::ops::Range; +use std::hash::Hash; +use std::hash::Hasher; use buffer::BufferSlice; use buffer::sys::UnsafeBuffer; @@ -139,7 +141,7 @@ pub unsafe trait BufferAccess: DeviceOwned { } /// Inner information about a buffer. -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub struct BufferInner<'a> { /// The underlying buffer object. pub buffer: &'a UnsafeBuffer, @@ -213,3 +215,20 @@ unsafe impl TypedBufferAccess for T { type Content = ::Content; } + +impl PartialEq for dyn BufferAccess { + #[inline] + fn eq(&self, other: &Self) -> bool { + self.inner() == other.inner() && self.size() == other.size() + } +} + +impl Eq for dyn BufferAccess {} + +impl Hash for dyn BufferAccess { + #[inline] + fn hash(&self, state: &mut H) { + self.inner().hash(state); + self.size().hash(state); + } +} diff --git a/vulkano/src/descriptor/descriptor_set/fixed_size_pool.rs b/vulkano/src/descriptor/descriptor_set/fixed_size_pool.rs index b1c7104d..7b6d6cb3 100644 --- a/vulkano/src/descriptor/descriptor_set/fixed_size_pool.rs +++ b/vulkano/src/descriptor/descriptor_set/fixed_size_pool.rs @@ -8,9 +8,12 @@ // according to those terms. use crossbeam::queue::SegQueue; +use std::hash::Hash; +use std::hash::Hasher; use std::sync::Arc; use OomError; +use VulkanObject; use buffer::BufferAccess; use buffer::BufferViewRef; use descriptor::descriptor::DescriptorDesc; @@ -141,8 +144,7 @@ unsafe impl DescriptorSet for FixedSizeDescriptorSet } } -unsafe impl DescriptorSetDesc for FixedSizeDescriptorSet -{ +unsafe impl DescriptorSetDesc for FixedSizeDescriptorSet { #[inline] fn num_bindings(&self) -> usize { self.inner.num_bindings() @@ -154,14 +156,37 @@ unsafe impl DescriptorSetDesc for FixedSizeDescriptorSet } } -unsafe impl DeviceOwned for FixedSizeDescriptorSet -{ +unsafe impl DeviceOwned for FixedSizeDescriptorSet { #[inline] fn device(&self) -> &Arc { self.inner.device() } } +impl PartialEq for FixedSizeDescriptorSet + where R: PersistentDescriptorSetResources +{ + #[inline] + fn eq(&self, other: &Self) -> bool { + self.inner().internal_object() == other.inner().internal_object() && + self.device() == other.device() + } +} + +impl Eq for FixedSizeDescriptorSet + where R: PersistentDescriptorSetResources +{} + +impl Hash for FixedSizeDescriptorSet + where R: PersistentDescriptorSetResources +{ + #[inline] + fn hash(&self, state: &mut H) { + self.inner().internal_object().hash(state); + self.device().hash(state); + } +} + // The fields of this struct can be considered as fields of the `FixedSizeDescriptorSet`. They are // in a separate struct because we don't want to expose the fact that we implement the // `DescriptorPool` trait. diff --git a/vulkano/src/descriptor/descriptor_set/mod.rs b/vulkano/src/descriptor/descriptor_set/mod.rs index 6138da09..03f23351 100644 --- a/vulkano/src/descriptor/descriptor_set/mod.rs +++ b/vulkano/src/descriptor/descriptor_set/mod.rs @@ -35,8 +35,13 @@ //! - The `DescriptorSetsCollection` trait is implemented on collections of types that implement //! `DescriptorSet`. It is what you pass to the draw functions. +use std::hash::Hash; +use std::hash::Hasher; + use SafeDeref; +use VulkanObject; use buffer::BufferAccess; +use device::DeviceOwned; use descriptor::descriptor::DescriptorDesc; use image::ImageViewAccess; @@ -77,7 +82,7 @@ mod unsafe_layout; /// Trait for objects that contain a collection of resources that will be accessible by shaders. /// /// Objects of this type can be passed when submitting a draw command. -pub unsafe trait DescriptorSet: DescriptorSetDesc { +pub unsafe trait DescriptorSet: DescriptorSetDesc + DeviceOwned { /// Returns the inner `UnsafeDescriptorSet`. fn inner(&self) -> &UnsafeDescriptorSet; @@ -130,6 +135,24 @@ unsafe impl DescriptorSet for T } } +impl PartialEq for dyn DescriptorSet { + #[inline] + fn eq(&self, other: &Self) -> bool { + self.inner().internal_object() == other.inner().internal_object() && + self.device() == other.device() + } +} + +impl Eq for dyn DescriptorSet {} + +impl Hash for dyn DescriptorSet { + #[inline] + fn hash(&self, state: &mut H) { + self.inner().internal_object().hash(state); + self.device().hash(state); + } +} + /// Trait for objects that describe the layout of the descriptors of a set. pub unsafe trait DescriptorSetDesc { /// Returns the number of binding slots in the set. diff --git a/vulkano/src/descriptor/descriptor_set/persistent.rs b/vulkano/src/descriptor/descriptor_set/persistent.rs index 2aa4ac38..48b2fd92 100644 --- a/vulkano/src/descriptor/descriptor_set/persistent.rs +++ b/vulkano/src/descriptor/descriptor_set/persistent.rs @@ -9,6 +9,8 @@ use std::error; use std::fmt; +use std::hash::Hash; +use std::hash::Hasher; use std::sync::Arc; use OomError; @@ -130,6 +132,33 @@ unsafe impl DeviceOwned for PersistentDescriptorSet } } +impl PartialEq for PersistentDescriptorSet + where P: DescriptorPoolAlloc, + R: PersistentDescriptorSetResources +{ + #[inline] + fn eq(&self, other: &Self) -> bool { + self.inner().internal_object() == other.inner().internal_object() && + self.device() == other.device() + } +} + +impl Eq for PersistentDescriptorSet + where P: DescriptorPoolAlloc, + R: PersistentDescriptorSetResources +{} + +impl Hash for PersistentDescriptorSet + where P: DescriptorPoolAlloc, + R: PersistentDescriptorSetResources +{ + #[inline] + fn hash(&self, state: &mut H) { + self.inner().internal_object().hash(state); + self.device().hash(state); + } +} + /// Prototype of a `PersistentDescriptorSet`. /// /// The template parameter `R` is an unspecified type that represents the list of resources. diff --git a/vulkano/src/device/mod.rs b/vulkano/src/device/mod.rs index ba682a10..71e5c467 100644 --- a/vulkano/src/device/mod.rs +++ b/vulkano/src/device/mod.rs @@ -96,6 +96,8 @@ use std::collections::hash_map::Entry; use std::error; use std::fmt; use std::hash::BuildHasherDefault; +use std::hash::Hash; +use std::hash::Hasher; use std::mem::MaybeUninit; use std::ops::Deref; use std::ptr; @@ -539,6 +541,24 @@ impl Drop for Device { } } +impl PartialEq for Device { + #[inline] + fn eq(&self, other: &Self) -> bool { + self.device == other.device && self.instance == other.instance + } +} + +impl Eq for Device {} + +impl Hash for Device { + #[inline] + fn hash(&self, state: &mut H) { + self.device.hash(state); + self.instance.hash(state); + } +} + + /// Implemented on objects that belong to a Vulkan device. /// /// # Safety diff --git a/vulkano/src/image/attachment.rs b/vulkano/src/image/attachment.rs index ea020ae4..eb266c71 100644 --- a/vulkano/src/image/attachment.rs +++ b/vulkano/src/image/attachment.rs @@ -7,6 +7,8 @@ // notice may not be copied, modified, or distributed except // according to those terms. +use std::hash::Hash; +use std::hash::Hasher; use std::iter::Empty; use std::sync::Arc; use std::sync::atomic::AtomicBool; @@ -575,6 +577,28 @@ unsafe impl ImageViewAccess for AttachmentImage } } +impl PartialEq for AttachmentImage + where F: 'static + Send + Sync +{ + #[inline] + fn eq(&self, other: &Self) -> bool { + ImageAccess::inner(self) == ImageAccess::inner(other) + } +} + +impl Eq for AttachmentImage + where F: 'static + Send + Sync +{} + +impl Hash for AttachmentImage + where F: 'static + Send + Sync +{ + #[inline] + fn hash(&self, state: &mut H) { + ImageAccess::inner(self).hash(state); + } +} + #[cfg(test)] mod tests { use super::AttachmentImage; diff --git a/vulkano/src/image/immutable.rs b/vulkano/src/image/immutable.rs index 9df3223f..99860dd2 100644 --- a/vulkano/src/image/immutable.rs +++ b/vulkano/src/image/immutable.rs @@ -8,6 +8,8 @@ // according to those terms. use smallvec::SmallVec; +use std::hash::Hash; +use std::hash::Hasher; use std::sync::Arc; use std::sync::atomic::AtomicBool; use std::sync::atomic::Ordering; @@ -392,6 +394,28 @@ unsafe impl ImageViewAccess for ImmutableImage } } +impl PartialEq for ImmutableImage + where F: 'static + Send + Sync +{ + #[inline] + fn eq(&self, other: &Self) -> bool { + ImageAccess::inner(self) == ImageAccess::inner(other) + } +} + +impl Eq for ImmutableImage + where F: 'static + Send + Sync +{} + +impl Hash for ImmutableImage + where F: 'static + Send + Sync +{ + #[inline] + fn hash(&self, state: &mut H) { + ImageAccess::inner(self).hash(state); + } +} + unsafe impl ImageAccess for ImmutableImageInitialization where F: 'static + Send + Sync { @@ -457,3 +481,25 @@ unsafe impl ImageAccess for ImmutableImageInitialization self.image.initialized.store(true, Ordering::Relaxed); } } + +impl PartialEq for ImmutableImageInitialization + where F: 'static + Send + Sync +{ + #[inline] + fn eq(&self, other: &Self) -> bool { + ImageAccess::inner(self) == ImageAccess::inner(other) + } +} + +impl Eq for ImmutableImageInitialization + where F: 'static + Send + Sync +{} + +impl Hash for ImmutableImageInitialization + where F: 'static + Send + Sync +{ + #[inline] + fn hash(&self, state: &mut H) { + ImageAccess::inner(self).hash(state); + } +} diff --git a/vulkano/src/image/storage.rs b/vulkano/src/image/storage.rs index 03abe6b4..97bf9eb8 100644 --- a/vulkano/src/image/storage.rs +++ b/vulkano/src/image/storage.rs @@ -8,6 +8,8 @@ // according to those terms. use smallvec::SmallVec; +use std::hash::Hash; +use std::hash::Hasher; use std::sync::Arc; use std::sync::atomic::AtomicUsize; use std::sync::atomic::Ordering; @@ -308,6 +310,31 @@ unsafe impl ImageViewAccess for StorageImage } } +impl PartialEq for StorageImage + where F: 'static + Send + Sync, + A: MemoryPool +{ + #[inline] + fn eq(&self, other: &Self) -> bool { + ImageAccess::inner(self) == ImageAccess::inner(other) + } +} + +impl Eq for StorageImage + where F: 'static + Send + Sync, + A: MemoryPool +{} + +impl Hash for StorageImage + where F: 'static + Send + Sync, + A: MemoryPool +{ + #[inline] + fn hash(&self, state: &mut H) { + ImageAccess::inner(self).hash(state); + } +} + #[cfg(test)] mod tests { use super::StorageImage; diff --git a/vulkano/src/image/swapchain.rs b/vulkano/src/image/swapchain.rs index 4595a159..c73badcd 100644 --- a/vulkano/src/image/swapchain.rs +++ b/vulkano/src/image/swapchain.rs @@ -7,6 +7,8 @@ // notice may not be copied, modified, or distributed except // according to those terms. +use std::hash::Hash; +use std::hash::Hasher; use std::sync::Arc; use buffer::BufferAccess; @@ -210,3 +212,19 @@ unsafe impl ImageViewAccess for SwapchainImage { true } } + +impl PartialEq for SwapchainImage { + #[inline] + fn eq(&self, other: &Self) -> bool { + ImageAccess::inner(self) == ImageAccess::inner(other) + } +} + +impl Eq for SwapchainImage {} + +impl Hash for SwapchainImage { + #[inline] + fn hash(&self, state: &mut H) { + ImageAccess::inner(self).hash(state); + } +} diff --git a/vulkano/src/image/sys.rs b/vulkano/src/image/sys.rs index 5cf5330d..7689b930 100644 --- a/vulkano/src/image/sys.rs +++ b/vulkano/src/image/sys.rs @@ -16,6 +16,8 @@ use smallvec::SmallVec; use std::error; use std::fmt; +use std::hash::Hash; +use std::hash::Hasher; use std::mem; use std::mem::MaybeUninit; use std::ops::Range; @@ -827,6 +829,23 @@ impl Drop for UnsafeImage { } } +impl PartialEq for UnsafeImage { + #[inline] + fn eq(&self, other: &Self) -> bool { + self.image == other.image && self.device == other.device + } +} + +impl Eq for UnsafeImage {} + +impl Hash for UnsafeImage { + #[inline] + fn hash(&self, state: &mut H) { + self.image.hash(state); + self.device.hash(state); + } +} + /// Error that can happen when creating an instance. #[derive(Clone, Debug, PartialEq, Eq)] pub enum ImageCreationError { @@ -1123,6 +1142,23 @@ impl Drop for UnsafeImageView { } } +impl PartialEq for UnsafeImageView { + #[inline] + fn eq(&self, other: &Self) -> bool { + self.view == other.view && self.device == other.device + } +} + +impl Eq for UnsafeImageView {} + +impl Hash for UnsafeImageView { + #[inline] + fn hash(&self, state: &mut H) { + self.view.hash(state); + self.device.hash(state); + } +} + #[cfg(test)] mod tests { use std::iter::Empty; diff --git a/vulkano/src/image/traits.rs b/vulkano/src/image/traits.rs index 9fd95f60..d6246b3c 100644 --- a/vulkano/src/image/traits.rs +++ b/vulkano/src/image/traits.rs @@ -7,6 +7,9 @@ // notice may not be copied, modified, or distributed except // according to those terms. +use std::hash::Hash; +use std::hash::Hasher; + use buffer::BufferAccess; use format::ClearValue; use format::Format; @@ -232,7 +235,7 @@ pub unsafe trait ImageAccess { } /// Inner information about an image. -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub struct ImageInner<'a> { /// The underlying image object. pub image: &'a UnsafeImage, @@ -311,6 +314,22 @@ unsafe impl ImageAccess for T } } +impl PartialEq for dyn ImageAccess { + #[inline] + fn eq(&self, other: &Self) -> bool { + self.inner() == other.inner() + } +} + +impl Eq for dyn ImageAccess {} + +impl Hash for dyn ImageAccess { + #[inline] + fn hash(&self, state: &mut H) { + self.inner().hash(state); + } +} + /// Wraps around an object that implements `ImageAccess` and modifies the initial layout /// requirement to be either `Undefined` or `Preinitialized`. #[derive(Debug, Copy, Clone)] @@ -373,6 +392,28 @@ unsafe impl ImageAccess for ImageAccessFromUndefinedLayout } } +impl PartialEq for ImageAccessFromUndefinedLayout + where I: ImageAccess +{ + #[inline] + fn eq(&self, other: &Self) -> bool { + self.inner() == other.inner() + } +} + +impl Eq for ImageAccessFromUndefinedLayout + where I: ImageAccess +{} + +impl Hash for ImageAccessFromUndefinedLayout + where I: ImageAccess +{ + #[inline] + fn hash(&self, state: &mut H) { + self.inner().hash(state); + } +} + /// Extension trait for images. Checks whether the value `T` can be used as a clear value for the /// given image. // TODO: isn't that for image views instead? @@ -481,6 +522,22 @@ unsafe impl ImageViewAccess for T } } +impl PartialEq for dyn ImageViewAccess { + #[inline] + fn eq(&self, other: &Self) -> bool { + self.inner() == other.inner() + } +} + +impl Eq for dyn ImageViewAccess {} + +impl Hash for dyn ImageViewAccess { + #[inline] + fn hash(&self, state: &mut H) { + self.inner().hash(state); + } +} + pub unsafe trait AttachmentImageView: ImageViewAccess { fn accept(&self, initial_layout: ImageLayout, final_layout: ImageLayout) -> bool; } diff --git a/vulkano/src/instance/instance.rs b/vulkano/src/instance/instance.rs index cb37efd0..69a667c1 100644 --- a/vulkano/src/instance/instance.rs +++ b/vulkano/src/instance/instance.rs @@ -13,6 +13,8 @@ use std::error; use std::ffi::CStr; use std::ffi::CString; use std::fmt; +use std::hash::Hash; +use std::hash::Hasher; use std::mem; use std::ops::Deref; use std::ptr; @@ -496,6 +498,22 @@ impl Drop for Instance { } } +impl PartialEq for Instance { + #[inline] + fn eq(&self, other: &Self) -> bool { + self.instance == other.instance + } +} + +impl Eq for Instance {} + +impl Hash for Instance { + #[inline] + fn hash(&self, state: &mut H) { + self.instance.hash(state); + } +} + // Same as Cow but less annoying. enum OwnedOrRef { Owned(T), diff --git a/vulkano/src/pipeline/graphics_pipeline/mod.rs b/vulkano/src/pipeline/graphics_pipeline/mod.rs index 0fe3e707..912a7f84 100644 --- a/vulkano/src/pipeline/graphics_pipeline/mod.rs +++ b/vulkano/src/pipeline/graphics_pipeline/mod.rs @@ -8,6 +8,8 @@ // according to those terms. use std::fmt; +use std::hash::Hash; +use std::hash::Hasher; use std::marker::PhantomData; use std::ptr; use std::sync::Arc; @@ -74,6 +76,7 @@ pub struct GraphicsPipeline { num_viewports: u32, } +#[derive(PartialEq, Eq, Hash)] struct Inner { pipeline: vk::Pipeline, device: Arc, @@ -324,7 +327,7 @@ impl Drop for Inner { /// object. /// When using this trait `AutoCommandBufferBuilder::draw*` calls will need the buffers to be /// wrapped in a `vec!()`. -pub unsafe trait GraphicsPipelineAbstract: PipelineLayoutAbstract + RenderPassAbstract + VertexSource>> { +pub unsafe trait GraphicsPipelineAbstract: PipelineLayoutAbstract + RenderPassAbstract + VertexSource>> + DeviceOwned { /// Returns an opaque object that represents the inside of the graphics pipeline. fn inner(&self) -> GraphicsPipelineSys; @@ -474,6 +477,52 @@ unsafe impl GraphicsPipelineAbstract for T } } +impl PartialEq for GraphicsPipeline + where L: PipelineLayoutAbstract, + Rp: RenderPassAbstract, + Mv: VertexSource>> +{ + #[inline] + fn eq(&self, other: &Self) -> bool { + self.inner == other.inner + } +} + +impl Eq for GraphicsPipeline + where L: PipelineLayoutAbstract, + Rp: RenderPassAbstract, + Mv: VertexSource>> +{} + +impl Hash for GraphicsPipeline + where L: PipelineLayoutAbstract, + Rp: RenderPassAbstract, + Mv: VertexSource>> +{ + #[inline] + fn hash(&self, state: &mut H) { + self.inner.hash(state); + } +} + +impl PartialEq for dyn GraphicsPipelineAbstract { + #[inline] + fn eq(&self, other: &Self) -> bool { + GraphicsPipelineAbstract::inner(self).0 == GraphicsPipelineAbstract::inner(other).0 && + DeviceOwned::device(self) == DeviceOwned::device(other) + } +} + +impl Eq for dyn GraphicsPipelineAbstract {} + +impl Hash for dyn GraphicsPipelineAbstract { + #[inline] + fn hash(&self, state: &mut H) { + GraphicsPipelineAbstract::inner(self).0.hash(state); + DeviceOwned::device(self).hash(state); + } +} + /// Opaque object that represents the inside of the graphics pipeline. #[derive(Debug, Copy, Clone)] pub struct GraphicsPipelineSys<'a>(vk::Pipeline, PhantomData<&'a ()>);