#[macro_export]
macro_rules! gfx_pipeline_inner {
{
$( $field:ident: $ty:ty, )*
} => {
use $crate::pso::{DataLink, DataBind, Descriptor, InitError, RawDataSet};
#[derive(Clone, Debug)]
pub struct Data<R: $crate::Resources> {
$( pub $field: <$ty as DataBind<R>>::Data, )*
}
pub struct Meta {
$( $field: $ty, )*
}
pub struct Init<'a> {
$( pub $field: <$ty as DataLink<'a>>::Init, )*
}
impl<'a> $crate::pso::PipelineInit for Init<'a> {
type Meta = Meta;
fn link_to(&self, desc: &mut Descriptor, info: &$crate::ProgramInfo) -> Result<Self::Meta, InitError> {
let mut meta = Meta {
$( $field: <$ty as DataLink<'a>>::new(), )*
};
for at in &info.vertex_attributes {
$(
match meta.$field.link_input(at, &self.$field) {
Some(Ok(d)) => {
assert!(meta.$field.is_active());
desc.attributes[at.slot as usize] = Some(d);
continue;
},
Some(Err(fm)) => return Err(
InitError::VertexImport(at.slot, Some(fm))
),
None => (),
}
)*
return Err(InitError::VertexImport(at.slot, None));
}
for cb in &info.constant_buffers {
$(
match meta.$field.link_constant_buffer(cb, &self.$field) {
Some(Ok(())) => {
assert!(meta.$field.is_active());
continue;
},
Some(Err(_)) => return Err(
InitError::ConstantBuffer(cb.slot, Some(()))
),
None => (),
}
)*
return Err(InitError::ConstantBuffer(cb.slot, None));
}
for gc in &info.globals {
$(
match meta.$field.link_global_constant(gc, &self.$field) {
Some(Ok(())) => {
assert!(meta.$field.is_active());
continue;
},
Some(Err(_)) => return Err(
InitError::GlobalConstant(gc.location, Some(()))
),
None => (),
}
)*
return Err(InitError::GlobalConstant(gc.location, None));
}
for srv in &info.textures {
$(
match meta.$field.link_resource_view(srv, &self.$field) {
Some(Ok(())) => {
assert!(meta.$field.is_active());
continue;
},
Some(Err(_)) => return Err(
InitError::ResourceView(srv.slot, Some(()))
),
None => (),
}
)*
return Err(InitError::ResourceView(srv.slot, None));
}
for uav in &info.unordereds {
$(
match meta.$field.link_unordered_view(uav, &self.$field) {
Some(Ok(())) => {
assert!(meta.$field.is_active());
continue;
},
Some(Err(_)) => return Err(
InitError::UnorderedView(uav.slot, Some(()))
),
None => (),
}
)*
return Err(InitError::UnorderedView(uav.slot, None));
}
for sm in &info.samplers {
$(
match meta.$field.link_sampler(sm, &self.$field) {
Some(()) => {
assert!(meta.$field.is_active());
continue;
},
None => (),
}
)*
return Err(InitError::Sampler(sm.slot, None));
}
for out in &info.outputs {
$(
match meta.$field.link_output(out, &self.$field) {
Some(Ok(d)) => {
assert!(meta.$field.is_active());
desc.color_targets[out.slot as usize] = Some(d);
continue;
},
Some(Err(fm)) => return Err(
InitError::PixelExport(out.slot, Some(fm))
),
None => (),
}
)*
return Err(InitError::PixelExport(out.slot, None));
}
if !info.knows_outputs {
let mut out = $crate::core::shade::OutputVar {
name: String::new(),
slot: 0,
};
$(
match meta.$field.link_output(&out, &self.$field) {
Some(Ok(d)) => {
assert!(meta.$field.is_active());
desc.color_targets[out.slot as usize] = Some(d);
out.slot += 1;
},
Some(Err(fm)) => return Err(
InitError::PixelExport(out.slot, Some(fm))
),
None => (),
}
)*
}
for _ in 0 .. 1 {
$(
match meta.$field.link_depth_stencil(&self.$field) {
Some(d) => {
assert!(meta.$field.is_active());
desc.depth_stencil = Some(d);
continue;
},
None => (),
}
)*
}
Ok(meta)
}
}
impl<R: $crate::Resources> $crate::pso::PipelineData<R> for Data<R> {
type Meta = Meta;
fn bake(&self, meta: &Self::Meta, man: &mut $crate::handle::Manager<R>) -> RawDataSet<R> {
let mut out = RawDataSet::new();
$(
meta.$field.bind_to(&mut out, &self.$field, man);
)*
out
}
}
}
}
#[macro_export]
macro_rules! gfx_pipeline_base {
($module:ident {
$( $field:ident: $ty:ty, )*
}) => {
pub mod $module {
use $crate;
use super::*;
gfx_pipeline_inner!{ $(
$field: $ty,
)*}
}
}
}
#[macro_export]
macro_rules! gfx_pipeline {
($module:ident {
$( $field:ident: $ty:ty = $value:expr, )*
}) => {
pub mod $module {
use $crate;
use super::*;
gfx_pipeline_inner!{ $(
$field: $ty,
)*}
pub fn new() -> Init<'static> {
Init {
$( $field: $value, )*
}
}
}
}
}