use concinnity_core::bake;
use concinnity_core::render::backend_init::MediaPayloads;
use concinnity_core::render::error::{RenderError, RenderResult};
use super::InitGpu;
use crate::vulkan::context::VkSceneAssets;
use crate::vulkan::texture::{self, *};
pub(super) fn build_scene_assets(
gpu: &InitGpu<'_>,
media: &MediaPayloads<'_>,
anisotropy: u32,
) -> RenderResult<VkSceneAssets> {
let hw = gpu.hw;
let device = &hw.device;
let textures: Vec<GpuImage> = if media.textures.is_empty() {
vec![texture::create_fallback_white(&gpu.upload())?]
} else {
media
.textures
.iter()
.enumerate()
.map(|(i, image)| {
texture::upload_texture_image(&gpu.upload(), image)
.map_err(|e| e.context(format_args!("texture[{i}]")))
})
.collect::<Result<Vec<_>, _>>()?
};
let upload_ctx = gpu.upload();
let fallback_textures = vec![
texture::create_fallback_flat_normal(&upload_ctx)?,
texture::create_fallback_white(&upload_ctx)?,
];
let scene_aniso = {
let feats = unsafe { hw.instance.get_physical_device_features(hw.physical_device) };
if feats.sampler_anisotropy != 0 {
let limit = unsafe {
hw.instance
.get_physical_device_properties(hw.physical_device)
}
.limits
.max_sampler_anisotropy;
(anisotropy.clamp(1, 16) as f32).min(limit)
} else {
1.0
}
};
let linear_sampler = create_sampler_linear_repeat(device, scene_aniso)?;
let cube_sampler = create_sampler_cube_linear(device)?;
let env_map = if let Some(bytes) = media.env_map_bytes {
let view = bake::environment_map::deserialize(bytes)
.map_err(|e| RenderError::Other(format!("EnvironmentMap payload malformed: {e}")))?;
upload_environment_map(
&gpu.upload(),
view.irradiance_face,
view.irradiance_bytes,
view.prefilter_face,
&view.prefilter_mip_bytes,
)?
} else {
EnvironmentMapTextures {
irradiance: texture::create_fallback_cubemap(&gpu.upload(), [0.05, 0.05, 0.05, 1.0])?,
prefilter: texture::create_fallback_cubemap(&gpu.upload(), [0.05, 0.05, 0.05, 1.0])?,
prefilter_mip_count: 0,
}
};
let color_lut = if let Some(bytes) = media.color_lut_bytes {
let (size, data) = bake::color_lut::deserialize(bytes)
.map_err(|e| RenderError::Other(format!("ColorLut payload malformed: {e}")))?;
upload_color_lut(&gpu.upload(), size, data)?
} else {
create_fallback_color_lut(&gpu.upload())?
};
let ssao_white = texture::create_fallback_white(&gpu.upload())?;
Ok(VkSceneAssets {
textures,
fallback_textures,
linear_sampler,
cube_sampler,
prefilter_mip_count: env_map.prefilter_mip_count,
env_map,
color_lut,
ssao_white,
})
}