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;
use VulkanObject;
pub unsafe trait BufferAccess: DeviceOwned {
fn inner(&self) -> BufferInner;
fn size(&self) -> usize;
#[inline]
fn len(&self) -> usize
where Self: TypedBufferAccess,
Self::Content: Content
{
self.size() / <Self::Content as Content>::indiv_size()
}
#[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, _self_offset: usize, self_size: usize, other: &BufferAccess,
_other_offset: usize, _other_size: usize)
-> bool {
debug_assert!(self_size <= self.size());
if self.inner().buffer.internal_object() != other.inner().buffer.internal_object() {
return false;
}
true
}
fn conflicts_image(&self, self_offset: usize, self_size: usize, other: &ImageAccess,
other_first_layer: u32, other_num_layers: u32, other_first_mipmap: u32,
other_num_mipmaps: u32)
-> bool {
let other_key = other.conflict_key(other_first_layer,
other_num_layers,
other_first_mipmap,
other_num_mipmaps);
self.conflict_key(self_offset, self_size) == other_key
}
fn conflict_key(&self, _self_offset: usize, _self_size: usize) -> u64 {
unimplemented!()
}
#[inline]
fn conflicts_buffer_all(&self, other: &BufferAccess) -> bool {
self.conflicts_buffer(0, self.size(), other, 0, other.size())
}
#[inline]
fn conflicts_image_all(&self, other: &ImageAccess) -> bool {
self.conflicts_image(0,
self.size(),
other,
0,
other.dimensions().array_layers(),
0,
other.mipmap_levels())
}
#[inline]
fn conflict_key_all(&self) -> u64 {
self.conflict_key(0, self.size())
}
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, self_offset: usize, self_size: usize, other: &BufferAccess,
other_offset: usize, other_size: usize)
-> bool {
(**self).conflicts_buffer(self_offset, self_size, other, other_offset, other_size)
}
#[inline]
fn conflict_key(&self, self_offset: usize, self_size: usize) -> u64 {
(**self).conflict_key(self_offset, self_size)
}
#[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;
}
unsafe impl<T> TypedBufferAccess for T
where T: SafeDeref,
T::Target: TypedBufferAccess
{
type Content = <T::Target as TypedBufferAccess>::Content;
}