use crate::Error;
use crate::metal::{
AccelerationStructure, Buffer, ComputePipelineState, Device, RenderPipelineState, SamplerState,
Tensor, Texture,
};
use crate::metal4::{
BinaryFunction, BinaryFunctionDescriptor, ComputePipelineDescriptor, PipelineDescriptor,
PipelineStageDynamicLinkingDescriptor, RenderPipelineDynamicLinkingDescriptor,
};
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct ArgumentTableDescriptor {
pub(crate) inner: metal_rust_ffi::Mtl4ArgumentTableDescriptor,
}
impl ArgumentTableDescriptor {
#[must_use]
pub fn new() -> Self {
Self::default()
}
#[must_use]
pub fn label(&self) -> Option<&str> {
self.inner.label()
}
pub fn set_label(&mut self, label: Option<&str>) {
self.inner.set_label(label);
}
#[must_use]
pub const fn max_buffer_bind_count(&self) -> usize {
self.inner.max_buffer_bind_count()
}
pub fn set_max_buffer_bind_count(&mut self, count: usize) -> Result<(), Error> {
self.inner
.set_max_buffer_bind_count(count)
.map_err(Error::from_ffi)
}
#[must_use]
pub const fn max_texture_bind_count(&self) -> usize {
self.inner.max_texture_bind_count()
}
pub fn set_max_texture_bind_count(&mut self, count: usize) -> Result<(), Error> {
self.inner
.set_max_texture_bind_count(count)
.map_err(Error::from_ffi)
}
#[must_use]
pub const fn max_sampler_state_bind_count(&self) -> usize {
self.inner.max_sampler_state_bind_count()
}
pub fn set_max_sampler_state_bind_count(&mut self, count: usize) -> Result<(), Error> {
self.inner
.set_max_sampler_state_bind_count(count)
.map_err(Error::from_ffi)
}
#[must_use]
pub const fn initialize_bindings(&self) -> bool {
self.inner.initialize_bindings()
}
pub fn set_initialize_bindings(&mut self, initialize: bool) {
self.inner.set_initialize_bindings(initialize);
}
#[must_use]
pub const fn support_attribute_strides(&self) -> bool {
self.inner.support_attribute_strides()
}
pub fn set_support_attribute_strides(&mut self, support: bool) {
self.inner.set_support_attribute_strides(support);
}
}
#[derive(Clone)]
pub struct ArgumentTable {
pub(crate) inner: metal_rust_ffi::Mtl4ArgumentTable,
}
#[derive(Clone, Copy)]
pub enum ArgumentTableResource<'a> {
Buffer(&'a Buffer),
Tensor(&'a Tensor),
AccelerationStructure(&'a AccelerationStructure),
}
impl<'a> ArgumentTableResource<'a> {
fn to_ffi(self) -> metal_rust_ffi::Mtl4ArgumentTableResource<'a> {
match self {
Self::Buffer(value) => metal_rust_ffi::Mtl4ArgumentTableResource::Buffer(&value.inner),
Self::Tensor(value) => metal_rust_ffi::Mtl4ArgumentTableResource::Tensor(&value.inner),
Self::AccelerationStructure(value) => {
metal_rust_ffi::Mtl4ArgumentTableResource::AccelerationStructure(&value.inner)
}
}
}
}
impl Device {
pub fn new_mtl4_argument_table(
&self,
descriptor: &ArgumentTableDescriptor,
) -> Result<ArgumentTable, Error> {
self.inner
.new_mtl4_argument_table(&descriptor.inner)
.map(|inner| ArgumentTable { inner })
.map_err(Error::from_ffi)
}
}
impl ArgumentTable {
#[must_use]
pub fn device(&self) -> Device {
Device::from_ffi(self.inner.device())
}
#[must_use]
pub fn label(&self) -> Option<&str> {
self.inner.label()
}
pub fn set_buffer(&self, buffer: &Buffer, offset: usize, index: usize) -> Result<(), Error> {
self.inner
.set_buffer(&buffer.inner, offset, index)
.map_err(Error::from_ffi)
}
pub fn set_buffer_with_stride(
&self,
buffer: &Buffer,
offset: usize,
stride: usize,
index: usize,
) -> Result<(), Error> {
self.inner
.set_buffer_with_stride(&buffer.inner, offset, stride, index)
.map_err(Error::from_ffi)
}
pub fn set_buffers(
&self,
bindings: &[(&Buffer, usize)],
start_index: usize,
) -> Result<(), Error> {
let ffi = bindings
.iter()
.map(|&(buffer, offset)| (&buffer.inner, offset))
.collect::<Vec<_>>();
self.inner
.set_buffers(&ffi, start_index)
.map_err(Error::from_ffi)
}
pub fn set_texture(&self, texture: &Texture, index: usize) -> Result<(), Error> {
self.inner
.set_texture(&texture.inner, index)
.map_err(Error::from_ffi)
}
pub fn set_textures(&self, textures: &[&Texture], start_index: usize) -> Result<(), Error> {
let ffi = textures
.iter()
.map(|texture| &texture.inner)
.collect::<Vec<_>>();
self.inner
.set_textures(&ffi, start_index)
.map_err(Error::from_ffi)
}
pub fn set_resource(
&self,
resource: ArgumentTableResource<'_>,
index: usize,
) -> Result<(), Error> {
self.inner
.set_resource(resource.to_ffi(), index)
.map_err(Error::from_ffi)
}
pub fn set_sampler_state(&self, sampler: &SamplerState, index: usize) -> Result<(), Error> {
self.inner
.set_sampler_state(&sampler.inner, index)
.map_err(Error::from_ffi)
}
pub fn set_sampler_states(
&self,
samplers: &[&SamplerState],
start_index: usize,
) -> Result<(), Error> {
let ffi = samplers
.iter()
.map(|sampler| &sampler.inner)
.collect::<Vec<_>>();
self.inner
.set_sampler_states(&ffi, start_index)
.map_err(Error::from_ffi)
}
pub fn set_tensor(&self, tensor: &Tensor, index: usize) -> Result<(), Error> {
self.inner
.set_tensor(&tensor.inner, index)
.map_err(Error::from_ffi)
}
pub fn set_tensors(&self, tensors: &[&Tensor], start_index: usize) -> Result<(), Error> {
let ffi = tensors
.iter()
.map(|tensor| &tensor.inner)
.collect::<Vec<_>>();
self.inner
.set_tensors(&ffi, start_index)
.map_err(Error::from_ffi)
}
pub fn set_acceleration_structure(
&self,
structure: &AccelerationStructure,
index: usize,
) -> Result<(), Error> {
self.inner
.set_acceleration_structure(&structure.inner, index)
.map_err(Error::from_ffi)
}
pub fn set_acceleration_structures(
&self,
structures: &[&AccelerationStructure],
start_index: usize,
) -> Result<(), Error> {
let ffi = structures
.iter()
.map(|structure| &structure.inner)
.collect::<Vec<_>>();
self.inner
.set_acceleration_structures(&ffi, start_index)
.map_err(Error::from_ffi)
}
}
#[derive(Clone)]
pub struct Archive {
pub(crate) inner: metal_rust_ffi::Mtl4Archive,
}
impl Archive {
#[allow(dead_code)]
pub(crate) const fn from_ffi(inner: metal_rust_ffi::Mtl4Archive) -> Self {
Self { inner }
}
pub fn label(&self) -> Result<Option<String>, Error> {
self.inner.label().map_err(Error::from_ffi)
}
pub fn set_label(&self, label: Option<&str>) -> Result<(), Error> {
self.inner.set_label(label).map_err(Error::from_ffi)
}
pub fn new_binary_function(
&self,
descriptor: &BinaryFunctionDescriptor,
) -> Result<BinaryFunction, Error> {
self.inner
.new_binary_function(&descriptor.inner)
.map(BinaryFunction::from_ffi)
.map_err(Error::from_ffi)
}
pub fn new_compute_pipeline_state(
&self,
descriptor: &ComputePipelineDescriptor,
linking: Option<&PipelineStageDynamicLinkingDescriptor>,
) -> Result<ComputePipelineState, Error> {
self.inner
.new_compute_pipeline_state(&descriptor.inner, linking.map(|value| &value.inner))
.map(|inner| ComputePipelineState { inner })
.map_err(Error::from_ffi)
}
pub fn new_render_pipeline_state(
&self,
descriptor: &PipelineDescriptor,
linking: Option<&RenderPipelineDynamicLinkingDescriptor>,
) -> Result<RenderPipelineState, Error> {
self.inner
.new_render_pipeline_state(&descriptor.inner, linking.map(|value| &value.inner))
.map(|inner| RenderPipelineState { inner })
.map_err(Error::from_ffi)
}
}