use crate::format::ClearValue;
use crate::format::Format;
use crate::format::FormatFeatures;
use crate::image::sys::UnsafeImage;
use crate::image::ImageDescriptorLayouts;
use crate::image::ImageDimensions;
use crate::image::ImageLayout;
use crate::image::SampleCount;
use crate::sync::AccessError;
use crate::SafeDeref;
use std::hash::Hash;
use std::hash::Hasher;
use std::sync::Arc;
pub unsafe trait ImageAccess: Send + Sync {
fn inner(&self) -> ImageInner;
#[inline]
fn format(&self) -> Format {
self.inner().image.format().unwrap()
}
#[inline]
fn mip_levels(&self) -> u32 {
self.inner().image.mip_levels()
}
#[inline]
fn samples(&self) -> SampleCount {
self.inner().image.samples()
}
#[inline]
fn dimensions(&self) -> ImageDimensions {
self.inner().image.dimensions()
}
#[inline]
fn format_features(&self) -> &FormatFeatures {
self.inner().image.format_features()
}
unsafe fn layout_initialized(&self) {}
fn is_layout_initialized(&self) -> bool {
false
}
unsafe fn initial_layout(&self) -> ImageLayout {
self.inner().image.initial_layout()
}
fn initial_layout_requirement(&self) -> ImageLayout;
fn final_layout_requirement(&self) -> ImageLayout;
#[inline]
unsafe fn forced_undefined_initial_layout(
self,
preinitialized: bool,
) -> Arc<ImageAccessFromUndefinedLayout<Self>>
where
Self: Sized,
{
Arc::new(ImageAccessFromUndefinedLayout {
image: self,
preinitialized,
})
}
fn descriptor_layouts(&self) -> Option<ImageDescriptorLayouts>;
fn conflict_key(&self) -> u64;
fn current_mip_levels_access(&self) -> std::ops::Range<u32>;
fn current_array_layers_access(&self) -> std::ops::Range<u32>;
fn try_gpu_lock(
&self,
exclusive_access: bool,
uninitialized_safe: bool,
expected_layout: ImageLayout,
) -> Result<(), AccessError>;
unsafe fn increase_gpu_lock(&self);
unsafe fn unlock(&self, transitioned_layout: Option<ImageLayout>);
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct ImageInner<'a> {
pub image: &'a UnsafeImage,
pub first_layer: usize,
pub num_layers: usize,
pub first_mipmap_level: usize,
pub num_mipmap_levels: usize,
}
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);
}
}
#[derive(Debug, Copy, Clone)]
pub struct ImageAccessFromUndefinedLayout<I> {
image: I,
preinitialized: bool,
}
unsafe impl<I> ImageAccess for ImageAccessFromUndefinedLayout<I>
where
I: ImageAccess,
{
#[inline]
fn inner(&self) -> ImageInner {
self.image.inner()
}
#[inline]
fn initial_layout_requirement(&self) -> ImageLayout {
if self.preinitialized {
ImageLayout::Preinitialized
} else {
ImageLayout::Undefined
}
}
#[inline]
fn final_layout_requirement(&self) -> ImageLayout {
self.image.final_layout_requirement()
}
#[inline]
fn descriptor_layouts(&self) -> Option<ImageDescriptorLayouts> {
self.image.descriptor_layouts()
}
#[inline]
fn conflict_key(&self) -> u64 {
self.image.conflict_key()
}
#[inline]
fn try_gpu_lock(
&self,
exclusive_access: bool,
uninitialized_safe: bool,
expected_layout: ImageLayout,
) -> Result<(), AccessError> {
self.image
.try_gpu_lock(exclusive_access, uninitialized_safe, expected_layout)
}
#[inline]
unsafe fn increase_gpu_lock(&self) {
self.image.increase_gpu_lock()
}
#[inline]
unsafe fn unlock(&self, new_layout: Option<ImageLayout>) {
self.image.unlock(new_layout)
}
fn current_mip_levels_access(&self) -> std::ops::Range<u32> {
self.image.current_mip_levels_access()
}
fn current_array_layers_access(&self) -> std::ops::Range<u32> {
self.image.current_array_layers_access()
}
}
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);
}
}
pub unsafe trait ImageClearValue<T>: ImageAccess {
fn decode(&self, value: T) -> Option<ClearValue>;
}
pub unsafe trait ImageContent<P>: ImageAccess {
fn matches_format(&self) -> bool;
}
unsafe impl<T> ImageAccess for T
where
T: SafeDeref + Send + Sync,
T::Target: ImageAccess,
{
#[inline]
fn inner(&self) -> ImageInner {
(**self).inner()
}
#[inline]
fn initial_layout_requirement(&self) -> ImageLayout {
(**self).initial_layout_requirement()
}
#[inline]
fn final_layout_requirement(&self) -> ImageLayout {
(**self).final_layout_requirement()
}
#[inline]
fn descriptor_layouts(&self) -> Option<ImageDescriptorLayouts> {
(**self).descriptor_layouts()
}
#[inline]
fn conflict_key(&self) -> u64 {
(**self).conflict_key()
}
#[inline]
fn try_gpu_lock(
&self,
exclusive_access: bool,
uninitialized_safe: bool,
expected_layout: ImageLayout,
) -> Result<(), AccessError> {
(**self).try_gpu_lock(exclusive_access, uninitialized_safe, expected_layout)
}
#[inline]
unsafe fn increase_gpu_lock(&self) {
(**self).increase_gpu_lock()
}
#[inline]
unsafe fn unlock(&self, transitioned_layout: Option<ImageLayout>) {
(**self).unlock(transitioned_layout)
}
#[inline]
unsafe fn layout_initialized(&self) {
(**self).layout_initialized();
}
#[inline]
fn is_layout_initialized(&self) -> bool {
(**self).is_layout_initialized()
}
fn current_mip_levels_access(&self) -> std::ops::Range<u32> {
(**self).current_mip_levels_access()
}
fn current_array_layers_access(&self) -> std::ops::Range<u32> {
(**self).current_array_layers_access()
}
}