use concinnity_core::gfx::render_types;
use concinnity_core::render::error::RenderResult;
use windows::Win32::Graphics::Direct3D12::*;
use windows::Win32::Graphics::Dxgi::Common::*;
use crate::directx::builtin_shaders::CompileProgram;
use crate::directx::pso::{Blend, GraphicsPso};
use crate::directx::root_sig::{RootSig, SamplerState, Visibility};
pub(super) fn main_input_layout() -> Vec<D3D12_INPUT_ELEMENT_DESC> {
vec![
D3D12_INPUT_ELEMENT_DESC {
SemanticName: windows::core::s!("POSITION"),
SemanticIndex: 0,
Format: DXGI_FORMAT_R32G32B32_FLOAT,
InputSlot: 0,
AlignedByteOffset: 0,
InputSlotClass: D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA,
InstanceDataStepRate: 0,
},
D3D12_INPUT_ELEMENT_DESC {
SemanticName: windows::core::s!("NORMAL"),
SemanticIndex: 0,
Format: DXGI_FORMAT_R32G32B32_FLOAT,
InputSlot: 0,
AlignedByteOffset: 12,
InputSlotClass: D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA,
InstanceDataStepRate: 0,
},
D3D12_INPUT_ELEMENT_DESC {
SemanticName: windows::core::s!("TANGENT"),
SemanticIndex: 0,
Format: DXGI_FORMAT_R32G32B32_FLOAT,
InputSlot: 0,
AlignedByteOffset: 24,
InputSlotClass: D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA,
InstanceDataStepRate: 0,
},
D3D12_INPUT_ELEMENT_DESC {
SemanticName: windows::core::s!("COLOR"),
SemanticIndex: 0,
Format: DXGI_FORMAT_R32G32B32_FLOAT,
InputSlot: 0,
AlignedByteOffset: 36,
InputSlotClass: D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA,
InstanceDataStepRate: 0,
},
D3D12_INPUT_ELEMENT_DESC {
SemanticName: windows::core::s!("TEXCOORD"),
SemanticIndex: 0,
Format: DXGI_FORMAT_R32G32_FLOAT,
InputSlot: 0,
AlignedByteOffset: 48,
InputSlotClass: D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA,
InstanceDataStepRate: 0,
},
]
}
fn text_input_layout() -> Vec<D3D12_INPUT_ELEMENT_DESC> {
vec![
D3D12_INPUT_ELEMENT_DESC {
SemanticName: windows::core::s!("POSITION"),
SemanticIndex: 0,
Format: DXGI_FORMAT_R32G32_FLOAT,
InputSlot: 0,
AlignedByteOffset: 0,
InputSlotClass: D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA,
InstanceDataStepRate: 0,
},
D3D12_INPUT_ELEMENT_DESC {
SemanticName: windows::core::s!("TEXCOORD"),
SemanticIndex: 0,
Format: DXGI_FORMAT_R32G32_FLOAT,
InputSlot: 0,
AlignedByteOffset: 8,
InputSlotClass: D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA,
InstanceDataStepRate: 0,
},
D3D12_INPUT_ELEMENT_DESC {
SemanticName: windows::core::s!("COLOR"),
SemanticIndex: 0,
Format: DXGI_FORMAT_R32G32B32_FLOAT,
InputSlot: 0,
AlignedByteOffset: 16,
InputSlotClass: D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA,
InstanceDataStepRate: 0,
},
D3D12_INPUT_ELEMENT_DESC {
SemanticName: windows::core::s!("MODE"),
SemanticIndex: 0,
Format: DXGI_FORMAT_R32_FLOAT,
InputSlot: 0,
AlignedByteOffset: 28,
InputSlotClass: D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA,
InstanceDataStepRate: 0,
},
]
}
pub(super) fn compile_composite_shaders(hot_reload: bool) -> RenderResult<(Vec<u8>, Vec<u8>)> {
let vs = super::builtin_shaders::FULLSCREEN_VERT.compile(hot_reload)?;
let ps = super::builtin_shaders::COMPOSITE_FRAG.compile(hot_reload)?;
Ok((vs, ps))
}
pub(super) fn create_composite_root_signature(
device: &ID3D12Device,
) -> RenderResult<ID3D12RootSignature> {
let sig = RootSig::new()
.srv_table(0, 1, Visibility::Pixel)
.srv_table(1, 1, Visibility::Pixel)
.constants::<render_types::CompositeParams>(0, Visibility::Pixel)
.srv_table(2, 1, Visibility::Pixel);
let sig = [3u32, 4, 5, 6, 7]
.into_iter()
.fold(sig, |sig, reg| sig.srv_table(reg, 1, Visibility::Pixel));
(0u32..8)
.fold(sig, |sig, reg| {
sig.static_sampler(SamplerState::LinearClamp, reg, Visibility::Pixel)
})
.build(device, "composite root sig")
}
pub(super) fn create_composite_pso(
device: &ID3D12Device,
root_sig: &ID3D12RootSignature,
vs: &[u8],
ps: &[u8],
rtv_format: DXGI_FORMAT,
) -> RenderResult<ID3D12PipelineState> {
GraphicsPso::fullscreen(root_sig, vs, ps, rtv_format, Blend::Opaque).build(device, "composite")
}
pub(super) fn compile_text_shaders(hot_reload: bool) -> RenderResult<(Vec<u8>, Vec<u8>)> {
let text_vs = super::builtin_shaders::TEXT_VERT.compile(hot_reload)?;
let text_ps = super::builtin_shaders::TEXT_FRAG.compile(hot_reload)?;
Ok((text_vs, text_ps))
}
pub(super) fn create_text_root_signature(
device: &ID3D12Device,
) -> RenderResult<ID3D12RootSignature> {
RootSig::new()
.constants::<render_types::TextUniforms>(0, Visibility::Vertex)
.srv_table(0, 1, Visibility::Pixel)
.sampler_table(0, 1, Visibility::Pixel)
.input_layout()
.build(device, "text root sig")
}
pub(super) fn create_text_pso(
device: &ID3D12Device,
root_sig: &ID3D12RootSignature,
vs: &[u8],
ps: &[u8],
rtv_format: DXGI_FORMAT,
sample_count: u32,
) -> RenderResult<ID3D12PipelineState> {
let layout = text_input_layout();
GraphicsPso::new(root_sig, vs, ps)
.input_layout(&layout)
.target(rtv_format, Blend::AlphaOver)
.samples(sample_count)
.build(device, "text")
}