use std::ops::Range;
use buffer::BufferSlice;
use buffer::sys::UnsafeBuffer;
use device::DeviceOwned;
use device::Queue;
use image::ImageAccess;
use memory::Content;
use sync::AccessError;
use SafeDeref;
pub unsafe trait BufferAccess: DeviceOwned {
fn inner(&self) -> BufferInner;
fn size(&self) -> usize;
#[inline]
fn as_buffer_slice(&self) -> BufferSlice<Self::Content, &Self>
where Self: Sized + TypedBufferAccess
{
BufferSlice::from_typed_buffer_access(self)
}
#[inline]
fn slice<T>(&self, range: Range<usize>) -> Option<BufferSlice<[T], &Self>>
where Self: Sized + TypedBufferAccess<Content = [T]>
{
BufferSlice::slice(self.as_buffer_slice(), range)
}
#[inline]
fn into_buffer_slice(self) -> BufferSlice<Self::Content, Self>
where Self: Sized + TypedBufferAccess
{
BufferSlice::from_typed_buffer_access(self)
}
#[inline]
fn index<T>(&self, index: usize) -> Option<BufferSlice<[T], &Self>>
where Self: Sized + TypedBufferAccess<Content = [T]>
{
self.slice(index .. (index + 1))
}
fn conflicts_buffer(&self, other: &dyn BufferAccess) -> bool;
fn conflicts_image(&self, other: &dyn ImageAccess) -> bool;
fn conflict_key(&self) -> (u64, usize);
fn try_gpu_lock(&self, exclusive_access: bool, queue: &Queue) -> Result<(), AccessError>;
unsafe fn increase_gpu_lock(&self);
unsafe fn unlock(&self);
}
#[derive(Copy, Clone, Debug)]
pub struct BufferInner<'a> {
pub buffer: &'a UnsafeBuffer,
pub offset: usize,
}
unsafe impl<T> BufferAccess for T
where T: SafeDeref,
T::Target: BufferAccess
{
#[inline]
fn inner(&self) -> BufferInner {
(**self).inner()
}
#[inline]
fn size(&self) -> usize {
(**self).size()
}
#[inline]
fn conflicts_buffer(&self, other: &dyn BufferAccess) -> bool {
(**self).conflicts_buffer(other)
}
#[inline]
fn conflicts_image(&self, other: &dyn ImageAccess) -> bool {
(**self).conflicts_image(other)
}
#[inline]
fn conflict_key(&self) -> (u64, usize) {
(**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()
}
}
pub unsafe trait TypedBufferAccess: BufferAccess {
type Content: ?Sized;
#[inline]
fn len(&self) -> usize 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;
}