#![deny(unsafe_op_in_unsafe_fn)]
use concinnity_core::gfx::render_types;
use concinnity_core::render::error::{RenderError, RenderResult};
use concinnity_core::render::post::ssao::settings::SsaoSettings;
use concinnity_core::render::post::ssao::{SsaoInputs, SsaoPass};
use objc2::runtime::ProtocolObject;
use crate::metal::context::MtlContext;
use crate::metal::post::post_device::{MtlPostPipeline, MtlPostTarget};
pub(crate) type MtlSsaoPass = SsaoPass<MtlPostPipeline, MtlPostTarget>;
pub(crate) struct SsaoState {
pub settings: Option<SsaoSettings>,
pub pass: Option<MtlSsaoPass>,
pub white: crate::metal::allocator::PooledTexture,
}
impl MtlContext {
pub(in crate::metal) fn encode_ssao(
&self,
cmd_buf: &ProtocolObject<dyn objc2_metal::MTLCommandBuffer>,
ssao_params: &render_types::SsaoParams,
) -> RenderResult<u32> {
let (Some(pass), Some(normal_depth)) = (&self.ssao.pass, self.gbuffer_normal_depth())
else {
return Ok(0);
};
let output = self
.targets
.transient_pool
.texture_for("ao_output")
.ok_or_else(|| RenderError::Other("ao_output missing from transient pool".into()))?;
pass.encode(
&self.post_device(),
cmd_buf,
SsaoInputs {
normal_depth,
output,
},
ssao_params,
)?;
Ok(0)
}
}