diff options
Diffstat (limited to 'src/buffer/traits.rs')
-rw-r--r-- | src/buffer/traits.rs | 243 |
1 files changed, 0 insertions, 243 deletions
diff --git a/src/buffer/traits.rs b/src/buffer/traits.rs deleted file mode 100644 index 9b76b21..0000000 --- a/src/buffer/traits.rs +++ /dev/null @@ -1,243 +0,0 @@ -// Copyright (c) 2016 The vulkano developers -// Licensed under the Apache License, Version 2.0 -// <LICENSE-APACHE or -// https://www.apache.org/licenses/LICENSE-2.0> or the MIT -// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, -// at your option. All files in the project carrying such -// notice may not be copied, modified, or distributed except -// according to those terms. - -use crate::buffer::sys::{DeviceAddressUsageNotEnabledError, UnsafeBuffer}; -use crate::buffer::BufferSlice; -use crate::device::DeviceOwned; -use crate::device::Queue; -use crate::memory::Content; -use crate::sync::AccessError; -use crate::DeviceSize; -use crate::{SafeDeref, VulkanObject}; -use std::hash::Hash; -use std::hash::Hasher; -use std::num::NonZeroU64; -use std::ops::Range; - -/// Trait for objects that represent a way for the GPU to have access to a buffer or a slice of a -/// buffer. -/// -/// See also `TypedBufferAccess`. -pub unsafe trait BufferAccess: DeviceOwned { - /// Returns the inner information about this buffer. - fn inner(&self) -> BufferInner; - - /// Returns the size of the buffer in bytes. - fn size(&self) -> DeviceSize; - - /// Builds a `BufferSlice` object holding the buffer by reference. - #[inline] - fn as_buffer_slice(&self) -> BufferSlice<Self::Content, &Self> - where - Self: Sized + TypedBufferAccess, - { - BufferSlice::from_typed_buffer_access(self) - } - - /// Builds a `BufferSlice` object holding part of the buffer by reference. - /// - /// This method can only be called for buffers whose type is known to be an array. - /// - /// This method can be used when you want to perform an operation on some part of the buffer - /// and not on the whole buffer. - /// - /// Returns `None` if out of range. - #[inline] - fn slice<T>(&self, range: Range<DeviceSize>) -> Option<BufferSlice<[T], &Self>> - where - Self: Sized + TypedBufferAccess<Content = [T]>, - { - BufferSlice::slice(self.as_buffer_slice(), range) - } - - /// Builds a `BufferSlice` object holding the buffer by value. - #[inline] - fn into_buffer_slice(self) -> BufferSlice<Self::Content, Self> - where - Self: Sized + TypedBufferAccess, - { - BufferSlice::from_typed_buffer_access(self) - } - - /// Builds a `BufferSlice` object holding part of the buffer by reference. - /// - /// This method can only be called for buffers whose type is known to be an array. - /// - /// This method can be used when you want to perform an operation on a specific element of the - /// buffer and not on the whole buffer. - /// - /// Returns `None` if out of range. - #[inline] - fn index<T>(&self, index: DeviceSize) -> Option<BufferSlice<[T], &Self>> - where - Self: Sized + TypedBufferAccess<Content = [T]>, - { - self.slice(index..(index + 1)) - } - - /// Returns a key that uniquely identifies the buffer. Two buffers or images that potentially - /// overlap in memory must return the same key. - /// - /// The key is shared amongst all buffers and images, which means that you can make several - /// different buffer objects share the same memory, or make some buffer objects share memory - /// with images, as long as they return the same key. - /// - /// Since it is possible to accidentally return the same key for memory ranges that don't - /// overlap, the `conflicts_buffer` or `conflicts_image` function should always be called to - /// verify whether they actually overlap. - fn conflict_key(&self) -> (u64, u64); - - /// Locks the resource for usage on the GPU. Returns an error if the lock can't be acquired. - /// - /// This function exists to prevent the user from causing a data race by reading and writing - /// to the same resource at the same time. - /// - /// If you call this function, you should call `unlock()` once the resource is no longer in use - /// by the GPU. The implementation is not expected to automatically perform any unlocking and - /// can rely on the fact that `unlock()` is going to be called. - fn try_gpu_lock(&self, exclusive_access: bool, queue: &Queue) -> Result<(), AccessError>; - - /// Locks the resource for usage on the GPU. Supposes that the resource is already locked, and - /// simply increases the lock by one. - /// - /// Must only be called after `try_gpu_lock()` succeeded. - /// - /// If you call this function, you should call `unlock()` once the resource is no longer in use - /// by the GPU. The implementation is not expected to automatically perform any unlocking and - /// can rely on the fact that `unlock()` is going to be called. - unsafe fn increase_gpu_lock(&self); - - /// Unlocks the resource previously acquired with `try_gpu_lock` or `increase_gpu_lock`. - /// - /// # Safety - /// - /// Must only be called once per previous lock. - unsafe fn unlock(&self); - - /// Gets the device address for this buffer. - /// - /// # Safety - /// - /// No lock checking or waiting is performed. This is nevertheless still safe because the - /// returned value isn't directly dereferencable. Unsafe code is required to dereference the - /// value in a shader. - fn raw_device_address(&self) -> Result<NonZeroU64, DeviceAddressUsageNotEnabledError> { - let inner = self.inner(); - - if !inner.buffer.usage().device_address { - return Err(DeviceAddressUsageNotEnabledError); - } - - let dev = self.device(); - unsafe { - let info = ash::vk::BufferDeviceAddressInfo { - buffer: inner.buffer.internal_object(), - ..Default::default() - }; - let ptr = dev - .fns() - .ext_buffer_device_address - .get_buffer_device_address_ext(dev.internal_object(), &info); - - if ptr == 0 { - panic!("got null ptr from a valid GetBufferDeviceAddressEXT call"); - } - - Ok(NonZeroU64::new_unchecked(ptr + inner.offset)) - } - } -} - -/// Inner information about a buffer. -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] -pub struct BufferInner<'a> { - /// The underlying buffer object. - pub buffer: &'a UnsafeBuffer, - /// The offset in bytes from the start of the underlying buffer object to the start of the - /// buffer we're describing. - pub offset: DeviceSize, -} - -unsafe impl<T> BufferAccess for T -where - T: SafeDeref, - T::Target: BufferAccess, -{ - #[inline] - fn inner(&self) -> BufferInner { - (**self).inner() - } - - #[inline] - fn size(&self) -> DeviceSize { - (**self).size() - } - - #[inline] - fn conflict_key(&self) -> (u64, u64) { - (**self).conflict_key() - } - - #[inline] - fn try_gpu_lock(&self, exclusive_access: bool, queue: &Queue) -> Result<(), AccessError> { - (**self).try_gpu_lock(exclusive_access, queue) - } - - #[inline] - unsafe fn increase_gpu_lock(&self) { - (**self).increase_gpu_lock() - } - - #[inline] - unsafe fn unlock(&self) { - (**self).unlock() - } -} - -/// Extension trait for `BufferAccess`. Indicates the type of the content of the buffer. -pub unsafe trait TypedBufferAccess: BufferAccess { - /// The type of the content. - type Content: ?Sized; - - /// Returns the length of the buffer in number of elements. - /// - /// This method can only be called for buffers whose type is known to be an array. - #[inline] - fn len(&self) -> DeviceSize - where - Self::Content: Content, - { - self.size() / <Self::Content as Content>::indiv_size() - } -} - -unsafe impl<T> TypedBufferAccess for T -where - T: SafeDeref, - T::Target: TypedBufferAccess, -{ - type Content = <T::Target as TypedBufferAccess>::Content; -} - -impl PartialEq for dyn BufferAccess + Send + Sync { - #[inline] - fn eq(&self, other: &Self) -> bool { - self.inner() == other.inner() && self.size() == other.size() - } -} - -impl Eq for dyn BufferAccess + Send + Sync {} - -impl Hash for dyn BufferAccess + Send + Sync { - #[inline] - fn hash<H: Hasher>(&self, state: &mut H) { - self.inner().hash(state); - self.size().hash(state); - } -} |