mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-22 06:45:23 +00:00
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
This commit is contained in:
parent
c620aefd29
commit
a1176227f7
@ -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)
|
||||
|
||||
|
@ -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<T: ?Sized, A> DeviceOwned for CpuAccessibleBuffer<T, A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized, A> PartialEq for CpuAccessibleBuffer<T, A>
|
||||
where T: 'static + Send + Sync
|
||||
{
|
||||
#[inline]
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.inner() == other.inner() && self.size() == other.size()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized, A> Eq for CpuAccessibleBuffer<T, A>
|
||||
where T: 'static + Send + Sync
|
||||
{}
|
||||
|
||||
impl<T: ?Sized, A> Hash for CpuAccessibleBuffer<T, A>
|
||||
where T: 'static + Send + Sync
|
||||
{
|
||||
#[inline]
|
||||
fn hash<H: Hasher>(&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
|
||||
|
@ -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<T, A> DeviceOwned for CpuBufferPoolChunk<T, A>
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, A> PartialEq for CpuBufferPoolChunk<T, A>
|
||||
where A: MemoryPool
|
||||
{
|
||||
#[inline]
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.inner() == other.inner() && self.size() == other.size()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, A> Eq for CpuBufferPoolChunk<T, A>
|
||||
where A: MemoryPool
|
||||
{}
|
||||
|
||||
impl<T, A> Hash for CpuBufferPoolChunk<T, A>
|
||||
where A: MemoryPool
|
||||
{
|
||||
#[inline]
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.inner().hash(state);
|
||||
self.size().hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, A> Clone for CpuBufferPoolSubbuffer<T, A>
|
||||
where A: MemoryPool
|
||||
{
|
||||
@ -788,6 +813,29 @@ unsafe impl<T, A> DeviceOwned for CpuBufferPoolSubbuffer<T, A>
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, A> PartialEq for CpuBufferPoolSubbuffer<T, A>
|
||||
where A: MemoryPool
|
||||
{
|
||||
#[inline]
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.inner() == other.inner() && self.size() == other.size()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, A> Eq for CpuBufferPoolSubbuffer<T, A>
|
||||
where A: MemoryPool
|
||||
{}
|
||||
|
||||
impl<T, A> Hash for CpuBufferPoolSubbuffer<T, A>
|
||||
where A: MemoryPool
|
||||
{
|
||||
#[inline]
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.inner().hash(state);
|
||||
self.size().hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use buffer::CpuBufferPool;
|
||||
|
@ -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<T: ?Sized, A> TypedBufferAccess for DeviceLocalBuffer<T, A>
|
||||
{
|
||||
type Content = T;
|
||||
}
|
||||
|
||||
impl<T: ?Sized, A> PartialEq for DeviceLocalBuffer<T, A>
|
||||
where T: 'static + Send + Sync
|
||||
{
|
||||
#[inline]
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.inner() == other.inner() && self.size() == other.size()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized, A> Eq for DeviceLocalBuffer<T, A>
|
||||
where T: 'static + Send + Sync
|
||||
{}
|
||||
|
||||
impl<T: ?Sized, A> Hash for DeviceLocalBuffer<T, A>
|
||||
where T: 'static + Send + Sync
|
||||
{
|
||||
#[inline]
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.inner().hash(state);
|
||||
self.size().hash(state);
|
||||
}
|
||||
}
|
||||
|
@ -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<T: ?Sized, A> DeviceOwned for ImmutableBuffer<T, A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized, A> PartialEq for ImmutableBuffer<T, A> {
|
||||
#[inline]
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.inner() == other.inner() && self.size() == other.size()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized, A> Eq for ImmutableBuffer<T, A> {}
|
||||
|
||||
impl<T: ?Sized, A> Hash for ImmutableBuffer<T, A> {
|
||||
#[inline]
|
||||
fn hash<H: Hasher>(&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<T: ?Sized, A = PotentialDedicatedAllocation<StdMemoryPoolAlloc>> {
|
||||
@ -455,6 +474,23 @@ impl<T: ?Sized, A> Clone for ImmutableBufferInitialization<T, A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized, A> PartialEq for ImmutableBufferInitialization<T, A> {
|
||||
#[inline]
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.inner() == other.inner() && self.size() == other.size()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized, A> Eq for ImmutableBufferInitialization<T, A> {}
|
||||
|
||||
impl<T: ?Sized, A> Hash for ImmutableBufferInitialization<T, A> {
|
||||
#[inline]
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.inner().hash(state);
|
||||
self.size().hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use buffer::BufferUsage;
|
||||
|
@ -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<T, B> From<BufferSlice<T, B>> for BufferSlice<[T], B> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized, B> PartialEq for BufferSlice<T, B>
|
||||
where B: BufferAccess
|
||||
{
|
||||
#[inline]
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.inner() == other.inner() && self.size() == other.size()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized, B> Eq for BufferSlice<T, B>
|
||||
where B: BufferAccess
|
||||
{}
|
||||
|
||||
impl<T: ?Sized, B> Hash for BufferSlice<T, B>
|
||||
where B: BufferAccess
|
||||
{
|
||||
#[inline]
|
||||
fn hash<H: Hasher>(&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]
|
||||
|
@ -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<H: Hasher>(&self, state: &mut H) {
|
||||
self.buffer.hash(state);
|
||||
self.device.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct SparseLevel {
|
||||
pub sparse: bool,
|
||||
|
@ -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<T> TypedBufferAccess for T
|
||||
{
|
||||
type Content = <T::Target as TypedBufferAccess>::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<H: Hasher>(&self, state: &mut H) {
|
||||
self.inner().hash(state);
|
||||
self.size().hash(state);
|
||||
}
|
||||
}
|
||||
|
@ -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<R> DescriptorSet for FixedSizeDescriptorSet<R>
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<R> DescriptorSetDesc for FixedSizeDescriptorSet<R>
|
||||
{
|
||||
unsafe impl<R> DescriptorSetDesc for FixedSizeDescriptorSet<R> {
|
||||
#[inline]
|
||||
fn num_bindings(&self) -> usize {
|
||||
self.inner.num_bindings()
|
||||
@ -154,14 +156,37 @@ unsafe impl<R> DescriptorSetDesc for FixedSizeDescriptorSet<R>
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<R> DeviceOwned for FixedSizeDescriptorSet<R>
|
||||
{
|
||||
unsafe impl<R> DeviceOwned for FixedSizeDescriptorSet<R> {
|
||||
#[inline]
|
||||
fn device(&self) -> &Arc<Device> {
|
||||
self.inner.device()
|
||||
}
|
||||
}
|
||||
|
||||
impl<R> PartialEq for FixedSizeDescriptorSet<R>
|
||||
where R: PersistentDescriptorSetResources
|
||||
{
|
||||
#[inline]
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.inner().internal_object() == other.inner().internal_object() &&
|
||||
self.device() == other.device()
|
||||
}
|
||||
}
|
||||
|
||||
impl<R> Eq for FixedSizeDescriptorSet<R>
|
||||
where R: PersistentDescriptorSetResources
|
||||
{}
|
||||
|
||||
impl<R> Hash for FixedSizeDescriptorSet<R>
|
||||
where R: PersistentDescriptorSetResources
|
||||
{
|
||||
#[inline]
|
||||
fn hash<H: Hasher>(&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.
|
||||
|
@ -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<T> 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<H: Hasher>(&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.
|
||||
|
@ -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<R, P> DeviceOwned for PersistentDescriptorSet<R, P>
|
||||
}
|
||||
}
|
||||
|
||||
impl<R, P> PartialEq for PersistentDescriptorSet<R, P>
|
||||
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<R, P> Eq for PersistentDescriptorSet<R, P>
|
||||
where P: DescriptorPoolAlloc,
|
||||
R: PersistentDescriptorSetResources
|
||||
{}
|
||||
|
||||
impl<R, P> Hash for PersistentDescriptorSet<R, P>
|
||||
where P: DescriptorPoolAlloc,
|
||||
R: PersistentDescriptorSetResources
|
||||
{
|
||||
#[inline]
|
||||
fn hash<H: Hasher>(&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.
|
||||
|
@ -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<H: Hasher>(&self, state: &mut H) {
|
||||
self.device.hash(state);
|
||||
self.instance.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Implemented on objects that belong to a Vulkan device.
|
||||
///
|
||||
/// # Safety
|
||||
|
@ -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<F, A> ImageViewAccess for AttachmentImage<F, A>
|
||||
}
|
||||
}
|
||||
|
||||
impl<F, A> PartialEq for AttachmentImage<F, A>
|
||||
where F: 'static + Send + Sync
|
||||
{
|
||||
#[inline]
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
ImageAccess::inner(self) == ImageAccess::inner(other)
|
||||
}
|
||||
}
|
||||
|
||||
impl<F, A> Eq for AttachmentImage<F, A>
|
||||
where F: 'static + Send + Sync
|
||||
{}
|
||||
|
||||
impl<F, A> Hash for AttachmentImage<F, A>
|
||||
where F: 'static + Send + Sync
|
||||
{
|
||||
#[inline]
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
ImageAccess::inner(self).hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::AttachmentImage;
|
||||
|
@ -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<F: 'static, A> ImageViewAccess for ImmutableImage<F, A>
|
||||
}
|
||||
}
|
||||
|
||||
impl<F, A> PartialEq for ImmutableImage<F, A>
|
||||
where F: 'static + Send + Sync
|
||||
{
|
||||
#[inline]
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
ImageAccess::inner(self) == ImageAccess::inner(other)
|
||||
}
|
||||
}
|
||||
|
||||
impl<F, A> Eq for ImmutableImage<F, A>
|
||||
where F: 'static + Send + Sync
|
||||
{}
|
||||
|
||||
impl<F, A> Hash for ImmutableImage<F, A>
|
||||
where F: 'static + Send + Sync
|
||||
{
|
||||
#[inline]
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
ImageAccess::inner(self).hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<F, A> ImageAccess for ImmutableImageInitialization<F, A>
|
||||
where F: 'static + Send + Sync
|
||||
{
|
||||
@ -457,3 +481,25 @@ unsafe impl<F, A> ImageAccess for ImmutableImageInitialization<F, A>
|
||||
self.image.initialized.store(true, Ordering::Relaxed);
|
||||
}
|
||||
}
|
||||
|
||||
impl<F, A> PartialEq for ImmutableImageInitialization<F, A>
|
||||
where F: 'static + Send + Sync
|
||||
{
|
||||
#[inline]
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
ImageAccess::inner(self) == ImageAccess::inner(other)
|
||||
}
|
||||
}
|
||||
|
||||
impl<F, A> Eq for ImmutableImageInitialization<F, A>
|
||||
where F: 'static + Send + Sync
|
||||
{}
|
||||
|
||||
impl<F, A> Hash for ImmutableImageInitialization<F, A>
|
||||
where F: 'static + Send + Sync
|
||||
{
|
||||
#[inline]
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
ImageAccess::inner(self).hash(state);
|
||||
}
|
||||
}
|
||||
|
@ -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<F, A> ImageViewAccess for StorageImage<F, A>
|
||||
}
|
||||
}
|
||||
|
||||
impl<F, A> PartialEq for StorageImage<F, A>
|
||||
where F: 'static + Send + Sync,
|
||||
A: MemoryPool
|
||||
{
|
||||
#[inline]
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
ImageAccess::inner(self) == ImageAccess::inner(other)
|
||||
}
|
||||
}
|
||||
|
||||
impl<F, A> Eq for StorageImage<F, A>
|
||||
where F: 'static + Send + Sync,
|
||||
A: MemoryPool
|
||||
{}
|
||||
|
||||
impl<F, A> Hash for StorageImage<F, A>
|
||||
where F: 'static + Send + Sync,
|
||||
A: MemoryPool
|
||||
{
|
||||
#[inline]
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
ImageAccess::inner(self).hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::StorageImage;
|
||||
|
@ -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<W> ImageViewAccess for SwapchainImage<W> {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl<W> PartialEq for SwapchainImage<W> {
|
||||
#[inline]
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
ImageAccess::inner(self) == ImageAccess::inner(other)
|
||||
}
|
||||
}
|
||||
|
||||
impl<W> Eq for SwapchainImage<W> {}
|
||||
|
||||
impl<W> Hash for SwapchainImage<W> {
|
||||
#[inline]
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
ImageAccess::inner(self).hash(state);
|
||||
}
|
||||
}
|
||||
|
@ -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<H: Hasher>(&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<H: Hasher>(&self, state: &mut H) {
|
||||
self.view.hash(state);
|
||||
self.device.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::iter::Empty;
|
||||
|
@ -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<T> 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<H: Hasher>(&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<I> ImageAccess for ImageAccessFromUndefinedLayout<I>
|
||||
}
|
||||
}
|
||||
|
||||
impl<I> PartialEq for ImageAccessFromUndefinedLayout<I>
|
||||
where I: ImageAccess
|
||||
{
|
||||
#[inline]
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.inner() == other.inner()
|
||||
}
|
||||
}
|
||||
|
||||
impl<I> Eq for ImageAccessFromUndefinedLayout<I>
|
||||
where I: ImageAccess
|
||||
{}
|
||||
|
||||
impl<I> Hash for ImageAccessFromUndefinedLayout<I>
|
||||
where I: ImageAccess
|
||||
{
|
||||
#[inline]
|
||||
fn hash<H: Hasher>(&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<T> 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<H: Hasher>(&self, state: &mut H) {
|
||||
self.inner().hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe trait AttachmentImageView: ImageViewAccess {
|
||||
fn accept(&self, initial_layout: ImageLayout, final_layout: ImageLayout) -> bool;
|
||||
}
|
||||
|
@ -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<H: Hasher>(&self, state: &mut H) {
|
||||
self.instance.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
// Same as Cow but less annoying.
|
||||
enum OwnedOrRef<T: 'static> {
|
||||
Owned(T),
|
||||
|
@ -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<VertexDefinition, Layout, RenderP> {
|
||||
num_viewports: u32,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Hash)]
|
||||
struct Inner {
|
||||
pipeline: vk::Pipeline,
|
||||
device: Arc<Device>,
|
||||
@ -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<Vec<Arc<dyn BufferAccess + Send + Sync>>> {
|
||||
pub unsafe trait GraphicsPipelineAbstract: PipelineLayoutAbstract + RenderPassAbstract + VertexSource<Vec<Arc<dyn BufferAccess + Send + Sync>>> + DeviceOwned {
|
||||
/// Returns an opaque object that represents the inside of the graphics pipeline.
|
||||
fn inner(&self) -> GraphicsPipelineSys;
|
||||
|
||||
@ -474,6 +477,52 @@ unsafe impl<T> GraphicsPipelineAbstract for T
|
||||
}
|
||||
}
|
||||
|
||||
impl<Mv, L, Rp> PartialEq for GraphicsPipeline<Mv, L, Rp>
|
||||
where L: PipelineLayoutAbstract,
|
||||
Rp: RenderPassAbstract,
|
||||
Mv: VertexSource<Vec<Arc<dyn BufferAccess + Send + Sync>>>
|
||||
{
|
||||
#[inline]
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.inner == other.inner
|
||||
}
|
||||
}
|
||||
|
||||
impl<Mv, L, Rp> Eq for GraphicsPipeline<Mv, L, Rp>
|
||||
where L: PipelineLayoutAbstract,
|
||||
Rp: RenderPassAbstract,
|
||||
Mv: VertexSource<Vec<Arc<dyn BufferAccess + Send + Sync>>>
|
||||
{}
|
||||
|
||||
impl<Mv, L, Rp> Hash for GraphicsPipeline<Mv, L, Rp>
|
||||
where L: PipelineLayoutAbstract,
|
||||
Rp: RenderPassAbstract,
|
||||
Mv: VertexSource<Vec<Arc<dyn BufferAccess + Send + Sync>>>
|
||||
{
|
||||
#[inline]
|
||||
fn hash<H: Hasher>(&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<H: Hasher>(&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 ()>);
|
||||
|
Loading…
Reference in New Issue
Block a user