use super::{
CPUCacheMode, Device, HazardTrackingMode, PixelFormat, Region, Resource, ResourceID,
ResourceOptions, SharedTextureHandle, SparsePageSize, StorageMode, TextureCompressionType,
TextureSparseTier, TextureSwizzleChannels, TextureType, TextureUsage, TextureViewDescriptor,
};
use crate::Error;
pub struct TextureDescriptor {
pub(crate) inner: metal_rust_ffi::TextureDescriptor,
}
impl TextureDescriptor {
#[must_use]
pub fn new() -> Self {
Self {
inner: metal_rust_ffi::TextureDescriptor::new(),
}
}
pub fn new_2d(
pixel_format: PixelFormat,
width: usize,
height: usize,
storage: ResourceOptions,
usage: TextureUsage,
) -> Result<Self, Error> {
metal_rust_ffi::TextureDescriptor::new_2d(pixel_format, width, height, storage, usage)
.map(|inner| Self { inner })
.map_err(Error::from_ffi)
}
pub fn texture_2d(
pixel_format: PixelFormat,
width: usize,
height: usize,
mipmapped: bool,
) -> Result<Self, Error> {
metal_rust_ffi::TextureDescriptor::texture_2d(pixel_format, width, height, mipmapped)
.map(|inner| Self { inner })
.map_err(Error::from_ffi)
}
pub fn texture_cube(
pixel_format: PixelFormat,
size: usize,
mipmapped: bool,
) -> Result<Self, Error> {
metal_rust_ffi::TextureDescriptor::texture_cube(pixel_format, size, mipmapped)
.map(|inner| Self { inner })
.map_err(Error::from_ffi)
}
pub fn texture_buffer(
pixel_format: PixelFormat,
width: usize,
resource_options: ResourceOptions,
usage: TextureUsage,
) -> Result<Self, Error> {
metal_rust_ffi::TextureDescriptor::texture_buffer(
pixel_format,
width,
resource_options,
usage,
)
.map(|inner| Self { inner })
.map_err(Error::from_ffi)
}
pub fn set_mipmap_level_count(&self, count: usize) -> Result<(), Error> {
self.inner
.set_mipmap_level_count(count)
.map_err(Error::from_ffi)
}
#[must_use]
pub fn dimensions(&self) -> (usize, usize, usize) {
self.inner.dimensions()
}
pub fn set_dimensions(&self, width: usize, height: usize, depth: usize) -> Result<(), Error> {
self.inner
.set_dimensions(width, height, depth)
.map_err(Error::from_ffi)
}
#[must_use]
pub fn array_length(&self) -> usize {
self.inner.array_length()
}
pub fn set_array_length(&self, value: usize) -> Result<(), Error> {
self.inner.set_array_length(value).map_err(Error::from_ffi)
}
#[must_use]
pub fn sample_count(&self) -> usize {
self.inner.sample_count()
}
pub fn set_sample_count(&self, value: usize) -> Result<(), Error> {
self.inner.set_sample_count(value).map_err(Error::from_ffi)
}
#[must_use]
pub fn mipmap_level_count(&self) -> usize {
self.inner.mipmap_level_count()
}
#[must_use]
pub fn pixel_format(&self) -> PixelFormat {
self.inner.pixel_format()
}
pub fn set_pixel_format(&self, value: PixelFormat) {
self.inner.set_pixel_format(value);
}
pub fn texture_type(&self) -> Result<TextureType, Error> {
self.inner.texture_type().map_err(Error::from_ffi)
}
pub fn set_texture_type(&self, value: TextureType) {
self.inner.set_texture_type(value);
}
#[must_use]
pub fn resource_options(&self) -> ResourceOptions {
self.inner.resource_options()
}
pub fn set_resource_options(&self, value: ResourceOptions) {
self.inner.set_resource_options(value);
}
#[must_use]
pub fn usage(&self) -> TextureUsage {
self.inner.usage()
}
pub fn set_usage(&self, value: TextureUsage) {
self.inner.set_usage(value);
}
pub fn storage_mode(&self) -> Result<StorageMode, Error> {
self.inner.storage_mode().map_err(Error::from_ffi)
}
pub fn set_storage_mode(&self, value: StorageMode) {
self.inner.set_storage_mode(value);
}
#[must_use]
pub fn cpu_cache_mode(&self) -> CPUCacheMode {
self.inner.cpu_cache_mode()
}
pub fn set_cpu_cache_mode(&self, value: CPUCacheMode) {
self.inner.set_cpu_cache_mode(value);
}
#[must_use]
pub fn hazard_tracking_mode(&self) -> HazardTrackingMode {
self.inner.hazard_tracking_mode()
}
pub fn set_hazard_tracking_mode(&self, value: HazardTrackingMode) {
self.inner.set_hazard_tracking_mode(value);
}
#[must_use]
pub fn compression_type(&self) -> TextureCompressionType {
self.inner.compression_type()
}
pub fn set_compression_type(&self, value: TextureCompressionType) {
self.inner.set_compression_type(value);
}
#[must_use]
pub fn placement_sparse_page_size(&self) -> SparsePageSize {
self.inner.placement_sparse_page_size()
}
pub fn set_placement_sparse_page_size(&self, value: SparsePageSize) {
self.inner.set_placement_sparse_page_size(value);
}
#[must_use]
pub fn allows_gpu_optimized_contents(&self) -> bool {
self.inner.allows_gpu_optimized_contents()
}
pub fn set_allows_gpu_optimized_contents(&self, value: bool) {
self.inner.set_allows_gpu_optimized_contents(value);
}
#[must_use]
pub fn swizzle(&self) -> TextureSwizzleChannels {
self.inner.swizzle()
}
pub fn set_swizzle(&self, value: &TextureSwizzleChannels) -> Result<(), Error> {
self.inner.set_swizzle(value).map_err(Error::from_ffi)
}
}
impl Default for TextureDescriptor {
fn default() -> Self {
Self::new()
}
}
#[derive(Clone)]
pub struct Texture {
pub(crate) inner: metal_rust_ffi::Texture,
}
#[derive(Clone)]
pub struct IoSurface {
#[allow(dead_code)]
inner: metal_rust_ffi::IoSurface,
}
impl IoSurface {
pub(crate) const fn from_ffi(inner: metal_rust_ffi::IoSurface) -> Self {
Self { inner }
}
pub(crate) const fn as_ffi(&self) -> &metal_rust_ffi::IoSurface {
&self.inner
}
}
impl Texture {
pub(crate) const fn from_ffi(inner: metal_rust_ffi::Texture) -> Self {
Self { inner }
}
#[must_use]
pub fn width(&self) -> usize {
self.inner.width()
}
#[must_use]
pub fn height(&self) -> usize {
self.inner.height()
}
#[must_use]
pub fn layout(&self) -> (usize, usize, usize, usize) {
self.inner.layout()
}
pub fn texture_type(&self) -> Result<TextureType, Error> {
self.inner.texture_type().map_err(Error::from_ffi)
}
#[must_use]
pub fn usage(&self) -> TextureUsage {
self.inner.usage()
}
#[must_use]
pub fn is_framebuffer_only(&self) -> bool {
self.inner.is_framebuffer_only()
}
#[must_use]
pub fn is_shareable(&self) -> bool {
self.inner.is_shareable()
}
#[must_use]
pub fn is_sparse(&self) -> bool {
self.inner.is_sparse()
}
#[must_use]
pub fn allows_gpu_optimized_contents(&self) -> bool {
self.inner.allows_gpu_optimized_contents()
}
#[must_use]
pub fn compression_type(&self) -> TextureCompressionType {
self.inner.compression_type()
}
#[must_use]
pub fn sparse_texture_tier(&self) -> TextureSparseTier {
self.inner.sparse_texture_tier()
}
#[must_use]
pub fn parent_texture(&self) -> Option<Self> {
self.inner.parent_texture().map(Self::from_ffi)
}
#[must_use]
pub fn parent_relative_location(&self) -> (usize, usize) {
self.inner.parent_relative_location()
}
#[must_use]
pub fn buffer(&self) -> Option<super::Buffer> {
self.inner.buffer().map(super::Buffer::from_ffi)
}
#[must_use]
pub fn buffer_layout(&self) -> (usize, usize) {
self.inner.buffer_layout()
}
#[must_use]
pub fn sparse_tail(&self) -> (usize, usize) {
self.inner.sparse_tail()
}
#[must_use]
pub fn pixel_format(&self) -> PixelFormat {
self.inner.pixel_format()
}
#[must_use]
pub fn storage_mode(&self) -> StorageMode {
self.inner.storage_mode()
}
#[must_use]
pub fn gpu_resource_id(&self) -> ResourceID {
self.inner.gpu_resource_id()
}
#[must_use]
pub fn iosurface_plane(&self) -> usize {
self.inner.iosurface_plane()
}
#[must_use]
pub fn iosurface(&self) -> Option<IoSurface> {
self.inner.iosurface().map(IoSurface::from_ffi)
}
#[allow(deprecated)]
pub fn root_resource(&self) -> Option<Resource> {
self.inner.root_resource().map(Resource::from_ffi)
}
#[must_use]
pub fn remote_storage_texture(&self) -> Option<Self> {
self.inner.remote_storage_texture().map(Self::from_ffi)
}
pub fn new_remote_view(&self, device: &Device) -> Result<Self, Error> {
self.inner
.new_remote_view(&device.inner)
.map(Self::from_ffi)
.map_err(Error::from_ffi)
}
pub fn new_shared_texture_handle(&self) -> Result<SharedTextureHandle, Error> {
self.inner
.new_shared_texture_handle()
.map(SharedTextureHandle::from_ffi)
.map_err(Error::from_ffi)
}
pub fn view_with_pixel_format(&self, pixel_format: PixelFormat) -> Result<Self, Error> {
self.inner
.view_with_pixel_format(pixel_format)
.map(Self::from_ffi)
.map_err(Error::from_ffi)
}
pub fn view(
&self,
pixel_format: PixelFormat,
texture_type: TextureType,
levels: std::ops::Range<usize>,
slices: std::ops::Range<usize>,
) -> Result<Self, Error> {
self.inner
.view(pixel_format, texture_type, levels, slices)
.map(Self::from_ffi)
.map_err(Error::from_ffi)
}
pub fn view_with_swizzle(
&self,
pixel_format: PixelFormat,
texture_type: TextureType,
levels: std::ops::Range<usize>,
slices: std::ops::Range<usize>,
swizzle: &TextureSwizzleChannels,
) -> Result<Self, Error> {
self.inner
.view_with_swizzle(pixel_format, texture_type, levels, slices, swizzle)
.map(Self::from_ffi)
.map_err(Error::from_ffi)
}
pub fn view_with_descriptor(&self, descriptor: &TextureViewDescriptor) -> Result<Self, Error> {
self.inner
.view_with_descriptor(&descriptor.inner)
.map(Self::from_ffi)
.map_err(Error::from_ffi)
}
pub fn replace_region_2d(
&self,
region: Region,
mipmap_level: usize,
bytes: &[u8],
bytes_per_row: usize,
) -> Result<(), Error> {
self.inner
.replace_region_2d(region, mipmap_level, bytes, bytes_per_row)
.map_err(Error::from_ffi)
}
pub fn replace_region(
&self,
region: Region,
mipmap_level: usize,
slice: usize,
bytes: &[u8],
bytes_per_row: usize,
bytes_per_image: usize,
) -> Result<(), Error> {
self.inner
.replace_region(
region,
mipmap_level,
slice,
bytes,
bytes_per_row,
bytes_per_image,
)
.map_err(Error::from_ffi)
}
#[must_use]
pub fn swizzle(&self) -> TextureSwizzleChannels {
self.inner.swizzle()
}
}