use crate::{ffi, ArgumentEncoder, MetalDevice, SamplerState};
const DATA_TYPE_TEXTURE: usize = 58;
const DATA_TYPE_SAMPLER: usize = 59;
const DATA_TYPE_POINTER: usize = 60;
pub mod argument_buffers_tier {
pub const TIER1: usize = 0;
pub const TIER2: usize = 1;
}
pub mod binding_access {
pub const READ_ONLY: usize = 0;
pub const READ_WRITE: usize = 1;
pub const WRITE_ONLY: usize = 2;
}
pub mod texture_type {
pub const TYPE_1D: usize = 0;
pub const TYPE_1D_ARRAY: usize = 1;
pub const TYPE_2D: usize = 2;
pub const TYPE_2D_ARRAY: usize = 3;
pub const TYPE_2D_MULTISAMPLE: usize = 4;
pub const CUBE: usize = 5;
pub const CUBE_ARRAY: usize = 6;
pub const TYPE_3D: usize = 7;
pub const TYPE_2D_MULTISAMPLE_ARRAY: usize = 8;
pub const TEXTURE_BUFFER: usize = 9;
}
#[derive(Debug, Clone, Copy)]
pub struct ArgumentDescriptor {
data_type: usize,
index: usize,
array_length: usize,
access: usize,
texture_type: usize,
constant_block_alignment: usize,
}
impl ArgumentDescriptor {
#[must_use]
pub const fn buffer(index: usize, access: usize) -> Self {
Self {
data_type: DATA_TYPE_POINTER,
index,
array_length: 0,
access,
texture_type: texture_type::TYPE_2D,
constant_block_alignment: 0,
}
}
#[must_use]
pub const fn texture(index: usize, texture_type: usize, access: usize) -> Self {
Self {
data_type: DATA_TYPE_TEXTURE,
index,
array_length: 0,
access,
texture_type,
constant_block_alignment: 0,
}
}
#[must_use]
pub const fn sampler(index: usize) -> Self {
Self {
data_type: DATA_TYPE_SAMPLER,
index,
array_length: 0,
access: binding_access::READ_ONLY,
texture_type: texture_type::TYPE_2D,
constant_block_alignment: 0,
}
}
#[must_use]
pub const fn constant(data_type: usize, index: usize, array_length: usize) -> Self {
Self {
data_type,
index,
array_length,
access: binding_access::READ_ONLY,
texture_type: texture_type::TYPE_2D,
constant_block_alignment: 0,
}
}
#[must_use]
pub fn with_array_length(mut self, array_length: usize) -> Self {
self.array_length = array_length;
self
}
#[must_use]
pub fn with_constant_block_alignment(mut self, alignment: usize) -> Self {
self.constant_block_alignment = alignment;
self
}
const fn as_words(self) -> [usize; 6] {
[
self.data_type,
self.index,
self.array_length,
self.access,
self.texture_type,
self.constant_block_alignment,
]
}
}
impl MetalDevice {
#[must_use]
pub fn new_argument_encoder_with_descriptors(
&self,
descriptors: &[ArgumentDescriptor],
) -> Option<ArgumentEncoder> {
let mut words = Vec::with_capacity(descriptors.len().saturating_mul(6));
for descriptor in descriptors {
words.extend_from_slice(&descriptor.as_words());
}
let ptr = unsafe {
ffi::am_device_new_argument_encoder_with_descriptors(
self.as_ptr(),
words.as_ptr(),
descriptors.len(),
)
};
if ptr.is_null() {
None
} else {
Some(unsafe { ArgumentEncoder::from_retained_ptr(ptr) })
}
}
}
impl ArgumentEncoder {
pub fn set_sampler_state(&self, sampler: &SamplerState, index: usize) {
unsafe {
ffi::am_argument_encoder_set_sampler_state(self.as_ptr(), sampler.as_ptr(), index);
};
}
}