use std::ops::Range;
use std::sync::Arc;
use vulkano::format::Format;
use vulkano::image::immutable::SubImage;
use vulkano::image::view::{
ComponentMapping, ImageView, ImageViewCreationError, ImageViewType, UnsafeImageView,
};
use vulkano::image::{
AttachmentImage, ImageAccess, ImageDescriptorLayouts, ImageDimensions, ImageInner,
ImageLayout, ImageViewAbstract, ImmutableImage, StorageImage,
};
use vulkano::sampler::Sampler;
use vulkano::sync::AccessError;
enum ImageVarient {
Storage(Arc<StorageImage>),
Immutable(Arc<ImmutableImage>),
Sub(Arc<SubImage>),
Attachment(Arc<AttachmentImage>),
}
unsafe impl ImageAccess for ImageVarient {
#[inline]
fn inner(&self) -> ImageInner<'_> {
match self {
Self::Storage(i) => i.inner(),
Self::Immutable(i) => i.inner(),
Self::Sub(i) => i.inner(),
Self::Attachment(i) => i.inner(),
}
}
#[inline]
fn initial_layout_requirement(&self) -> ImageLayout {
match self {
Self::Storage(i) => i.initial_layout_requirement(),
Self::Immutable(i) => i.initial_layout_requirement(),
Self::Sub(i) => i.initial_layout_requirement(),
Self::Attachment(i) => i.initial_layout_requirement(),
}
}
#[inline]
fn final_layout_requirement(&self) -> ImageLayout {
match self {
Self::Storage(i) => i.final_layout_requirement(),
Self::Immutable(i) => i.final_layout_requirement(),
Self::Sub(i) => i.final_layout_requirement(),
Self::Attachment(i) => i.final_layout_requirement(),
}
}
#[inline]
fn descriptor_layouts(&self) -> Option<ImageDescriptorLayouts> {
match self {
Self::Storage(i) => i.descriptor_layouts(),
Self::Immutable(i) => i.descriptor_layouts(),
Self::Sub(i) => i.descriptor_layouts(),
Self::Attachment(i) => i.descriptor_layouts(),
}
}
#[inline]
fn conflict_key(&self) -> u64 {
match self {
Self::Storage(i) => i.conflict_key(),
Self::Immutable(i) => i.conflict_key(),
Self::Sub(i) => i.conflict_key(),
Self::Attachment(i) => i.conflict_key(),
}
}
#[inline]
fn current_miplevels_access(&self) -> Range<u32> {
match self {
Self::Storage(i) => i.current_miplevels_access(),
Self::Immutable(i) => i.current_miplevels_access(),
Self::Sub(i) => i.current_miplevels_access(),
Self::Attachment(i) => i.current_miplevels_access(),
}
}
#[inline]
fn current_layer_levels_access(&self) -> Range<u32> {
match self {
Self::Storage(i) => i.current_layer_levels_access(),
Self::Immutable(i) => i.current_layer_levels_access(),
Self::Sub(i) => i.current_layer_levels_access(),
Self::Attachment(i) => i.current_layer_levels_access(),
}
}
#[inline]
fn try_gpu_lock(
&self,
exclusive_access: bool,
uninitialized_safe: bool,
expected_layout: ImageLayout,
) -> Result<(), AccessError> {
match self {
Self::Storage(i) =>
i.try_gpu_lock(exclusive_access, uninitialized_safe, expected_layout),
Self::Immutable(i) =>
i.try_gpu_lock(exclusive_access, uninitialized_safe, expected_layout),
Self::Sub(i) =>
i.try_gpu_lock(exclusive_access, uninitialized_safe, expected_layout),
Self::Attachment(i) =>
i.try_gpu_lock(exclusive_access, uninitialized_safe, expected_layout),
}
}
#[inline]
unsafe fn increase_gpu_lock(&self) {
match self {
Self::Storage(i) => i.increase_gpu_lock(),
Self::Immutable(i) => i.increase_gpu_lock(),
Self::Sub(i) => i.increase_gpu_lock(),
Self::Attachment(i) => i.increase_gpu_lock(),
}
}
#[inline]
unsafe fn unlock(&self, transitioned_layout: Option<ImageLayout>) {
match self {
Self::Storage(i) => i.unlock(transitioned_layout),
Self::Immutable(i) => i.unlock(transitioned_layout),
Self::Sub(i) => i.unlock(transitioned_layout),
Self::Attachment(i) => i.unlock(transitioned_layout),
}
}
}
pub struct ImtImageView {
view: Arc<ImageView<ImageVarient>>,
}
impl ImtImageView {
pub fn from_storage(image: Arc<StorageImage>) -> Result<Arc<Self>, ImageViewCreationError> {
Ok(Arc::new(ImtImageView {
view: ImageView::new(ImageVarient::Storage(image))?,
}))
}
pub fn from_immutable(
image: Arc<ImmutableImage>,
) -> Result<Arc<Self>, ImageViewCreationError> {
Ok(Arc::new(ImtImageView {
view: ImageView::new(ImageVarient::Immutable(image))?,
}))
}
pub fn from_sub(image: Arc<SubImage>) -> Result<Arc<Self>, ImageViewCreationError> {
Ok(Arc::new(ImtImageView {
view: ImageView::new(ImageVarient::Sub(image))?,
}))
}
pub fn from_attachment(
image: Arc<AttachmentImage>,
) -> Result<Arc<Self>, ImageViewCreationError> {
Ok(Arc::new(ImtImageView {
view: ImageView::new(ImageVarient::Attachment(image))?,
}))
}
#[inline]
pub fn dimensions(&self) -> ImageDimensions {
self.view.image().dimensions()
}
}
unsafe impl ImageViewAbstract for ImtImageView {
#[inline]
fn image(&self) -> &dyn ImageAccess {
self.view.image()
}
#[inline]
fn inner(&self) -> &UnsafeImageView {
self.view.inner()
}
#[inline]
fn array_layers(&self) -> Range<u32> {
self.view.array_layers()
}
#[inline]
fn format(&self) -> Format {
self.view.format()
}
#[inline]
fn component_mapping(&self) -> ComponentMapping {
self.view.component_mapping()
}
#[inline]
fn ty(&self) -> ImageViewType {
self.view.ty()
}
#[inline]
fn can_be_sampled(&self, _sampler: &Sampler) -> bool {
self.view.can_be_sampled(_sampler)
}
}
unsafe impl ImageAccess for ImtImageView {
#[inline]
fn inner(&self) -> ImageInner<'_> {
self.view.image().inner()
}
#[inline]
fn initial_layout_requirement(&self) -> ImageLayout {
self.view.image().initial_layout_requirement()
}
#[inline]
fn final_layout_requirement(&self) -> ImageLayout {
self.view.image().final_layout_requirement()
}
#[inline]
fn descriptor_layouts(&self) -> Option<ImageDescriptorLayouts> {
self.view.image().descriptor_layouts()
}
#[inline]
fn conflict_key(&self) -> u64 {
self.view.image().conflict_key()
}
#[inline]
fn current_miplevels_access(&self) -> Range<u32> {
self.view.image().current_miplevels_access()
}
#[inline]
fn current_layer_levels_access(&self) -> Range<u32> {
self.view.image().current_layer_levels_access()
}
#[inline]
fn try_gpu_lock(
&self,
exclusive_access: bool,
uninitialized_safe: bool,
expected_layout: ImageLayout,
) -> Result<(), AccessError> {
self.view.image().try_gpu_lock(exclusive_access, uninitialized_safe, expected_layout)
}
#[inline]
unsafe fn increase_gpu_lock(&self) {
self.view.image().increase_gpu_lock()
}
#[inline]
unsafe fn unlock(&self, transitioned_layout: Option<ImageLayout>) {
self.view.image().unlock(transitioned_layout)
}
}