use concinnity_core::components::sdf_programs::SdfPrograms;
use concinnity_core::render::backend::{PipelineSwap, PreparedPipelines};
use concinnity_core::render::error::RenderResult;
use super::{VolumePipelineTargets, VolumePipelines, build_volume_pipelines};
use crate::shader::raymarch_source;
use crate::vulkan::context::VkContext;
use crate::vulkan::pipeline_builder::volume_for;
impl VkContext {
pub(in crate::vulkan) fn replace_sdf_volume_pipelines(
&mut self,
volume: usize,
programs: &SdfPrograms,
prepared: Option<PreparedPipelines>,
) -> RenderResult<PipelineSwap> {
let Some(targets) = self.volume_pipeline_targets() else {
return Ok(PipelineSwap::NotResident);
};
let Some(record) = self.raymarch.as_ref().and_then(|rm| rm.volumes.get(volume)) else {
return Ok(PipelineSwap::NotResident);
};
let VolumePipelines {
pipeline,
front_pipeline,
shadow_pipeline,
prepass_pipelines,
} = match volume_for(prepared, &self.pipeline_gate, targets, record.flags) {
Some(pipelines) => pipelines,
None => build_volume_pipelines(
&self.hw.device,
&targets,
programs,
record.flags,
&record.label,
)?,
};
self.wait_idle();
if let Some(record) = self
.raymarch
.as_mut()
.and_then(|rm| rm.volumes.get_mut(volume))
{
record.pipeline = pipeline;
record.front_pipeline = front_pipeline;
record.shadow_pipeline = shadow_pipeline;
record.prepass_pipelines = prepass_pipelines;
record.refractive = raymarch_source::taps_scene(programs);
}
self.hw.device.reclaim_idle();
Ok(PipelineSwap::Swapped)
}
pub(in crate::vulkan) fn volume_pipeline_targets(&self) -> Option<VolumePipelineTargets> {
let rm = self.raymarch.as_ref()?;
Some(rm.volume_targets(
self.shadow.render_pass.handle(),
self.targets.msaa_samples,
self.hot_reload.enabled,
))
}
}