use concinnity_core::render::error::RenderResult;
use concinnity_core::render::post::device::PostExtent;
use concinnity_core::render::post::taa::{TaaInputs, TaaPass, TaaRing};
use std::cell::Cell;
use windows::Win32::Graphics::Direct3D12::*;
use crate::directx::context::DxContext;
use crate::directx::post::post_device::{DxPostDevice, PostPipeline, PostTarget};
pub(in crate::directx) type DxTaaPass = TaaPass<PostPipeline, PostTarget>;
pub(in crate::directx) struct TaaResources {
pub(in crate::directx) pass: DxTaaPass,
pub(in crate::directx) frame: Cell<u32>,
}
impl TaaResources {
pub(in crate::directx) fn new(
device: &DxPostDevice,
width: u32,
height: u32,
) -> RenderResult<Self> {
Ok(Self {
pass: TaaPass::new(device, TaaRing::ping_pong(), PostExtent { width, height })?,
frame: Cell::new(0),
})
}
pub(in crate::directx) fn output_index(&self) -> usize {
self.pass.ring().write()
}
pub(in crate::directx) fn output(&self) -> &PostTarget {
self.pass.target(self.output_index())
}
pub(in crate::directx) fn resize_to(
&mut self,
device: &DxPostDevice,
width: u32,
height: u32,
) -> RenderResult<()> {
self.pass.resize(device, PostExtent { width, height })?;
self.frame.set(0);
Ok(())
}
}
impl DxContext {
pub(in crate::directx) fn encode_taa(
&self,
cmd: &ID3D12GraphicsCommandList,
frame_idx: usize,
reactive_written: bool,
) {
let Some(taa) = &self.taa else { return };
let Some(gbuffer) = &self.gbuffer else { return };
let device = self.post_device(frame_idx);
if let Err(e) = taa.pass.encode(
&device,
cmd,
taa.output_index(),
TaaInputs {
scene: self.scene_srv_for_post(),
velocity: gbuffer.velocity_srv_gpu,
reactive: reactive_written.then(|| self.targets.reactive_mask.srv_gpu()),
},
) {
tracing::error!("TAA resolve: {e}");
}
}
}