use super::{
Argument, ArgumentType, ArrayType, BindingAccess, DataType, PixelFormat, PointerType,
StructMember, StructType, TensorAuxiliaryPlaneType, TensorBinding, TensorReferenceType,
TextureReferenceType, TextureSwizzleChannels, TextureType, TextureViewDescriptor,
};
use crate::Error;
use std::ops::Range;
#[derive(Clone)]
pub struct ArgumentMetadata {
pub name: Option<String>,
pub index: usize,
pub array_length: usize,
pub access: BindingAccess,
pub active: bool,
pub kind: ArgumentType,
pub details: ArgumentDetails,
}
#[derive(Clone)]
pub enum ArgumentDetails {
Buffer {
alignment: usize,
data_size: usize,
data_type: DataType,
pointer_type: Option<PointerType>,
struct_type: Option<StructType>,
},
Texture {
data_type: DataType,
texture_type: TextureType,
is_depth: bool,
},
ThreadgroupMemory {
alignment: usize,
data_size: usize,
},
Other,
}
impl Argument {
pub fn metadata(&self) -> Result<ArgumentMetadata, Error> {
let kind = self.r#type()?;
let details = if kind == ArgumentType::ArgumentTypeBuffer {
ArgumentDetails::Buffer {
alignment: self.buffer_alignment()?,
data_size: self.buffer_data_size()?,
data_type: self.buffer_data_type()?,
pointer_type: self.buffer_pointer_type()?,
struct_type: self.buffer_struct_type()?,
}
} else if kind == ArgumentType::ArgumentTypeTexture {
ArgumentDetails::Texture {
data_type: self.texture_data_type()?,
texture_type: self.texture_type()?,
is_depth: self.is_depth_texture()?,
}
} else if kind == ArgumentType::ArgumentTypeThreadgroupMemory {
ArgumentDetails::ThreadgroupMemory {
alignment: self.threadgroup_memory_alignment()?,
data_size: self.threadgroup_memory_data_size()?,
}
} else {
ArgumentDetails::Other
};
Ok(ArgumentMetadata {
name: self.name()?,
index: self.index()?,
array_length: self.array_length()?,
access: self.access()?,
active: self.is_active()?,
kind,
details,
})
}
}
impl StructMember {
pub fn array_type(&self) -> Result<Option<ArrayType>, Error> {
self.inner
.array_type()
.map(|value| value.map(ArrayType::from_ffi))
.map_err(Error::from_ffi)
}
pub fn pointer_type(&self) -> Result<Option<PointerType>, Error> {
self.inner
.pointer_type()
.map(|value| value.map(PointerType::from_ffi))
.map_err(Error::from_ffi)
}
pub fn struct_type(&self) -> Result<Option<StructType>, Error> {
self.inner
.struct_type()
.map(|value| value.map(StructType::from_ffi))
.map_err(Error::from_ffi)
}
pub fn tensor_reference_type(&self) -> Result<Option<TensorReferenceType>, Error> {
self.inner
.tensor_reference_type()
.map(|value| value.map(TensorReferenceType::from_ffi))
.map_err(Error::from_ffi)
}
pub fn texture_reference_type(&self) -> Result<Option<TextureReferenceType>, Error> {
self.inner
.texture_reference_type()
.map(|value| value.map(TextureReferenceType::from_ffi))
.map_err(Error::from_ffi)
}
}
impl StructType {
pub fn member_by_name(&self, name: &str) -> Result<Option<StructMember>, Error> {
self.inner
.member_by_name(name)
.map(|value| value.map(StructMember::from_ffi))
.map_err(Error::from_ffi)
}
pub fn members(&self) -> Result<Vec<StructMember>, Error> {
self.inner
.members_vec()
.map(|values| values.into_iter().map(StructMember::from_ffi).collect())
.map_err(Error::from_ffi)
}
}
impl ArrayType {
pub fn element_array_type(&self) -> Result<Option<ArrayType>, Error> {
self.inner
.element_array_type()
.map(|value| value.map(ArrayType::from_ffi))
.map_err(Error::from_ffi)
}
pub fn element_pointer_type(&self) -> Result<Option<PointerType>, Error> {
self.inner
.element_pointer_type()
.map(|value| value.map(PointerType::from_ffi))
.map_err(Error::from_ffi)
}
pub fn element_struct_type(&self) -> Result<Option<StructType>, Error> {
self.inner
.element_struct_type()
.map(|value| value.map(StructType::from_ffi))
.map_err(Error::from_ffi)
}
pub fn element_tensor_reference_type(&self) -> Result<Option<TensorReferenceType>, Error> {
self.inner
.element_tensor_reference_type()
.map(|value| value.map(TensorReferenceType::from_ffi))
.map_err(Error::from_ffi)
}
pub fn element_texture_reference_type(&self) -> Result<Option<TextureReferenceType>, Error> {
self.inner
.element_texture_reference_type()
.map(|value| value.map(TextureReferenceType::from_ffi))
.map_err(Error::from_ffi)
}
}
impl PointerType {
pub fn element_array_type(&self) -> Result<Option<ArrayType>, Error> {
self.inner
.element_array_type()
.map(|value| value.map(ArrayType::from_ffi))
.map_err(Error::from_ffi)
}
pub fn element_struct_type(&self) -> Result<Option<StructType>, Error> {
self.inner
.element_struct_type()
.map(|value| value.map(StructType::from_ffi))
.map_err(Error::from_ffi)
}
}
impl TensorReferenceType {
pub fn auxiliary_planes(&self) -> Result<Vec<TensorAuxiliaryPlaneType>, Error> {
self.inner
.auxiliary_plane_types()
.map(|values| {
values
.into_iter()
.map(TensorAuxiliaryPlaneType::from_ffi)
.collect()
})
.map_err(Error::from_ffi)
}
}
impl TensorBinding {
pub fn auxiliary_planes(&self) -> Result<Vec<TensorAuxiliaryPlaneType>, Error> {
self.inner
.auxiliary_plane_types()
.map(|values| {
values
.into_iter()
.map(TensorAuxiliaryPlaneType::from_ffi)
.collect()
})
.map_err(Error::from_ffi)
}
}
impl TextureViewDescriptor {
pub fn with_properties(
pixel_format: PixelFormat,
texture_type: TextureType,
levels: Range<usize>,
slices: Range<usize>,
swizzle: &TextureSwizzleChannels,
) -> Result<Self, Error> {
metal_rust_ffi::__private::objects::metal::TextureViewDescriptor::with_properties(
pixel_format,
texture_type,
levels,
slices,
swizzle,
)
.map(Self::from_ffi)
.map_err(Error::from_ffi)
}
pub fn level_range(&self) -> Result<Range<usize>, Error> {
self.inner.level_range().map_err(Error::from_ffi)
}
pub fn set_level_range(&self, value: Range<usize>) -> Result<(), Error> {
self.inner.set_level_range(value).map_err(Error::from_ffi)
}
pub fn slice_range(&self) -> Result<Range<usize>, Error> {
self.inner.slice_range().map_err(Error::from_ffi)
}
pub fn set_slice_range(&self, value: Range<usize>) -> Result<(), Error> {
self.inner.set_slice_range(value).map_err(Error::from_ffi)
}
pub fn swizzle(&self) -> Result<TextureSwizzleChannels, Error> {
self.inner.swizzle().map_err(Error::from_ffi)
}
pub fn set_swizzle(&self, value: &TextureSwizzleChannels) -> Result<(), Error> {
self.inner.set_swizzle(value).map_err(Error::from_ffi)
}
}