d3d11 0.3.1

Safe(r) bindings to the D3D11 API
Documentation
use std::mem::transmute;

use crate::{
    blend_state::BlendState, cast_optional_resource_refs, rtv::RenderTargetView,
    util::OptionalParam, DepthStencilState, DepthStencilView,
};

use super::DeviceContext;

#[cfg_attr(feature = "profiling", profiling::all_functions)]
impl DeviceContext {
    pub fn output_merger_set_render_targets(
        &self,
        render_target_views: &[Option<&RenderTargetView>],
        depth_stencil_view: Option<&DepthStencilView>,
    ) {
        unsafe {
            let raw_rtvs = cast_optional_resource_refs!(8, render_target_views);
            self.0.OMSetRenderTargets(
                Some(transmute(raw_rtvs.as_slice())),
                depth_stencil_view.map(|d| &d.0),
            );
        }
    }

    pub fn output_merger_get_render_targets(
        &self,
    ) -> ([Option<RenderTargetView>; 8], Option<DepthStencilView>) {
        let mut rtvs = [const { None }; 8];
        let mut dsv = None;
        unsafe {
            self.0.OMGetRenderTargets(Some(&mut rtvs), Some(&mut dsv));
        }
        (
            rtvs.map(|r| r.map(RenderTargetView)),
            dsv.map(DepthStencilView),
        )
    }

    pub fn output_merger_set_blend_state(
        &self,
        blend_state: impl OptionalParam<Output = BlendState>,
        blend_factor: Option<&[f32; 4]>,
        sample_mask: u32,
    ) {
        unsafe {
            self.0.OMSetBlendState(
                blend_state.as_option().map(|bs| &bs.0),
                blend_factor,
                sample_mask,
            );
        }
    }

    pub fn output_merger_set_depth_stencil_state(
        &self,
        depth_stencil_state: impl OptionalParam<Output = DepthStencilState>,
        stencil_ref: u32,
    ) {
        unsafe {
            self.0.OMSetDepthStencilState(
                depth_stencil_state.as_option().map(|dss| &dss.0),
                stencil_ref,
            );
        }
    }
}