use std::marker::PhantomData;
use core::{ColorSlot, Resources};
use core::{format, handle, pso, state, target};
use core::memory::Typed;
use core::shade::OutputVar;
use super::{DataLink, DataBind, RawDataSet, AccessInfo};
pub struct RenderTarget<T>(Option<ColorSlot>, PhantomData<T>);
impl<T> PartialEq for RenderTarget<T> {
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}
}
impl<T> Eq for RenderTarget<T> {}
impl<T> std::hash::Hash for RenderTarget<T> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.0.hash(state);
}
}
impl<T> Clone for RenderTarget<T> {
fn clone(&self) -> Self {
Self(self.0.clone(), PhantomData)
}
}
impl<T> std::fmt::Debug for RenderTarget<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("RenderTarget").field(&self.0).finish()
}
}
pub struct BlendTarget<T>(RawRenderTarget, PhantomData<T>);
impl<T> PartialEq for BlendTarget<T> {
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}
}
impl<T> Eq for BlendTarget<T> {}
impl<T> std::hash::Hash for BlendTarget<T> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.0.hash(state);
}
}
impl<T> Clone for BlendTarget<T> {
fn clone(&self) -> Self {
Self(self.0.clone(), PhantomData)
}
}
impl<T> std::fmt::Debug for BlendTarget<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("BlendTarget").field(&self.0).finish()
}
}
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct RawRenderTarget(Option<ColorSlot>);
pub struct DepthTarget<T>(PhantomData<T>);
impl<T> PartialEq for DepthTarget<T> {
fn eq(&self, _: &Self) -> bool { true }
}
impl<T> Eq for DepthTarget<T> {}
impl<T> std::hash::Hash for DepthTarget<T> {
fn hash<H: std::hash::Hasher>(&self, _: &mut H) {}
}
impl<T> Clone for DepthTarget<T> {
fn clone(&self) -> Self {
Self(PhantomData)
}
}
impl<T> std::fmt::Debug for DepthTarget<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "DepthTarget")
}
}
pub struct StencilTarget<T>(PhantomData<T>);
impl<T> PartialEq for StencilTarget<T> {
fn eq(&self, _: &Self) -> bool { true }
}
impl<T> Eq for StencilTarget<T> {}
impl<T> std::hash::Hash for StencilTarget<T> {
fn hash<H: std::hash::Hasher>(&self, _: &mut H) {}
}
impl<T> Clone for StencilTarget<T> {
fn clone(&self) -> Self {
Self(PhantomData)
}
}
impl<T> std::fmt::Debug for StencilTarget<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "StencilTarget")
}
}
pub struct DepthStencilTarget<T>(PhantomData<T>);
impl<T> PartialEq for DepthStencilTarget<T> {
fn eq(&self, _: &Self) -> bool { true }
}
impl<T> Eq for DepthStencilTarget<T> {}
impl<T> std::hash::Hash for DepthStencilTarget<T> {
fn hash<H: std::hash::Hasher>(&self, _: &mut H) {}
}
impl<T> Clone for DepthStencilTarget<T> {
fn clone(&self) -> Self {
Self(PhantomData)
}
}
impl<T> std::fmt::Debug for DepthStencilTarget<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "DepthStencilTarget")
}
}
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct Scissor(bool);
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct BlendRef;
impl<'a, T: format::RenderFormat> DataLink<'a> for RenderTarget<T> {
type Init = &'a str;
fn new() -> Self {
RenderTarget(None, PhantomData)
}
fn is_active(&self) -> bool {
self.0.is_some()
}
fn link_output(&mut self, out: &OutputVar, init: &Self::Init) ->
Option<Result<pso::ColorTargetDesc, format::Format>> {
if out.name.is_empty() || &out.name == init {
self.0 = Some(out.slot);
let desc = (T::get_format(), state::ColorMask::all().into());
Some(Ok(desc))
} else {
None
}
}
}
impl<R: Resources, T> DataBind<R> for RenderTarget<T> {
type Data = handle::RenderTargetView<R, T>;
fn bind_to(&self,
out: &mut RawDataSet<R>,
data: &Self::Data,
man: &mut handle::Manager<R>,
_: &mut AccessInfo<R>) {
if let Some(slot) = self.0 {
out.pixel_targets.add_color(slot, man.ref_rtv(data.raw()), data.raw().get_dimensions());
}
}
}
impl<'a, T: format::BlendFormat> DataLink<'a> for BlendTarget<T> {
type Init = (&'a str, state::ColorMask, state::Blend);
fn new() -> Self {
BlendTarget(RawRenderTarget(None), PhantomData)
}
fn is_active(&self) -> bool {
self.0.is_active()
}
fn link_output(&mut self, out: &OutputVar, init: &Self::Init) ->
Option<Result<pso::ColorTargetDesc, format::Format>> {
self.0.link_output(out, &(init.0, T::get_format(), init.1, Some(init.2)))
}
}
impl<R: Resources, T> DataBind<R> for BlendTarget<T> {
type Data = handle::RenderTargetView<R, T>;
fn bind_to(&self,
out: &mut RawDataSet<R>,
data: &Self::Data,
man: &mut handle::Manager<R>,
access: &mut AccessInfo<R>) {
self.0.bind_to(out, data.raw(), man, access)
}
}
impl<'a> DataLink<'a> for RawRenderTarget {
type Init = (&'a str, format::Format, state::ColorMask, Option<state::Blend>);
fn new() -> Self {
RawRenderTarget(None)
}
fn is_active(&self) -> bool {
self.0.is_some()
}
fn link_output(&mut self, out: &OutputVar, init: &Self::Init) ->
Option<Result<pso::ColorTargetDesc, format::Format>> {
if out.name.is_empty() || &out.name == init.0 {
self.0 = Some(out.slot);
let desc = (init.1, pso::ColorInfo {
mask: init.2,
color: init.3.map(|b| b.color),
alpha: init.3.map(|b| b.alpha),
});
Some(Ok(desc))
}else {
None
}
}
}
impl<R: Resources> DataBind<R> for RawRenderTarget {
type Data = handle::RawRenderTargetView<R>;
fn bind_to(&self,
out: &mut RawDataSet<R>,
data: &Self::Data,
man: &mut handle::Manager<R>,
_: &mut AccessInfo<R>) {
if let Some(slot) = self.0 {
out.pixel_targets.add_color(slot, man.ref_rtv(data), data.get_dimensions());
}
}
}
impl<'a, T: format::DepthFormat> DataLink<'a> for DepthTarget<T> {
type Init = state::Depth;
fn new() -> Self { DepthTarget(PhantomData) }
fn is_active(&self) -> bool { true }
fn link_depth_stencil(&mut self, init: &Self::Init) -> Option<pso::DepthStencilDesc> {
Some((T::get_format(), (*init).into()))
}
}
impl<R: Resources, T> DataBind<R> for DepthTarget<T> {
type Data = handle::DepthStencilView<R, T>;
fn bind_to(&self,
out: &mut RawDataSet<R>,
data: &Self::Data,
man: &mut handle::Manager<R>,
_: &mut AccessInfo<R>) {
let dsv = data.raw();
out.pixel_targets.add_depth_stencil(man.ref_dsv(dsv), true, false, dsv.get_dimensions());
}
}
impl<'a, T: format::StencilFormat> DataLink<'a> for StencilTarget<T> {
type Init = state::Stencil;
fn new() -> Self { StencilTarget(PhantomData) }
fn is_active(&self) -> bool { true }
fn link_depth_stencil(&mut self, init: &Self::Init) -> Option<pso::DepthStencilDesc> {
Some((T::get_format(), (*init).into()))
}
}
impl<R: Resources, T> DataBind<R> for StencilTarget<T> {
type Data = (handle::DepthStencilView<R, T>, (target::Stencil, target::Stencil));
fn bind_to(&self,
out: &mut RawDataSet<R>,
data: &Self::Data,
man: &mut handle::Manager<R>,
_: &mut AccessInfo<R>) {
let dsv = data.0.raw();
out.pixel_targets.add_depth_stencil(man.ref_dsv(dsv), false, true, dsv.get_dimensions());
out.ref_values.stencil = data.1;
}
}
impl<'a, T: format::DepthStencilFormat> DataLink<'a> for DepthStencilTarget<T> {
type Init = (state::Depth, state::Stencil);
fn new() -> Self { DepthStencilTarget(PhantomData) }
fn is_active(&self) -> bool { true }
fn link_depth_stencil(&mut self, init: &Self::Init) -> Option<pso::DepthStencilDesc> {
Some((T::get_format(), (*init).into()))
}
}
impl<R: Resources, T> DataBind<R> for DepthStencilTarget<T> {
type Data = (handle::DepthStencilView<R, T>, (target::Stencil, target::Stencil));
fn bind_to(&self,
out: &mut RawDataSet<R>,
data: &Self::Data,
man: &mut handle::Manager<R>,
_: &mut AccessInfo<R>) {
let dsv = data.0.raw();
out.pixel_targets.add_depth_stencil(man.ref_dsv(dsv), true, true, dsv.get_dimensions());
out.ref_values.stencil = data.1;
}
}
impl<'a> DataLink<'a> for Scissor {
type Init = ();
fn new() -> Self { Scissor(false) }
fn is_active(&self) -> bool { self.0 }
fn link_scissor(&mut self) -> bool { self.0 = true; true }
}
impl<R: Resources> DataBind<R> for Scissor {
type Data = target::Rect;
fn bind_to(&self,
out: &mut RawDataSet<R>,
data: &Self::Data,
_: &mut handle::Manager<R>,
_: &mut AccessInfo<R>) {
out.scissor = *data;
}
}
impl<'a> DataLink<'a> for BlendRef {
type Init = ();
fn new() -> Self { BlendRef }
fn is_active(&self) -> bool { true }
}
impl<R: Resources> DataBind<R> for BlendRef {
type Data = target::ColorValue;
fn bind_to(&self,
out: &mut RawDataSet<R>,
data: &Self::Data,
_: &mut handle::Manager<R>,
_: &mut AccessInfo<R>) {
out.ref_values.blend = *data;
}
}