cvkg_render_gpu/
pyramid.rs1use crate::kvasir::registry::ResourceRegistry;
2use crate::kvasir::resource::{ResourceDescriptor, ResourceId, ResourceKind, ResourceLifetime};
3use wgpu;
4
5pub struct ImagePyramid {
6 pub mips: Vec<ResourceId>,
7 pub luminance: ResourceId,
8 pub width: u32,
9 pub height: u32,
10 pub levels: u32,
11}
12
13impl ImagePyramid {
14 pub fn new(
15 registry: &mut ResourceRegistry,
16 device: &wgpu::Device,
17 width: u32,
18 height: u32,
19 levels: u32,
20 ) -> Self {
21 let mut mips = Vec::new();
22 let mut mip_w = width;
23 let mut mip_h = height;
24
25 for i in 0..levels {
26 let desc = ResourceDescriptor {
27 label: Some(format!("pyramid_mip_{}", i)),
28 kind: ResourceKind::Image {
29 width: mip_w,
30 height: mip_h,
31 format: wgpu::TextureFormat::Rgba16Float,
32 mip_level_count: 1,
33 usage: wgpu::TextureUsages::TEXTURE_BINDING
34 | wgpu::TextureUsages::RENDER_ATTACHMENT
35 | wgpu::TextureUsages::COPY_DST,
36 },
37 lifetime: ResourceLifetime::Frame,
38 };
39 mips.push(registry.allocate_image(device, &desc));
40
41 mip_w = (mip_w / 2).max(1);
42 mip_h = (mip_h / 2).max(1);
43 }
44
45 let luminance = registry.allocate_image(
46 device,
47 &ResourceDescriptor {
48 label: Some("pyramid_luminance".to_string()),
49 kind: ResourceKind::Image {
50 width: mips.last().map(|_| mip_w).unwrap_or(width),
51 height: mips.last().map(|_| mip_h).unwrap_or(height),
52 format: wgpu::TextureFormat::R8Unorm,
53 mip_level_count: 1,
54 usage: wgpu::TextureUsages::TEXTURE_BINDING
55 | wgpu::TextureUsages::RENDER_ATTACHMENT,
56 },
57 lifetime: ResourceLifetime::Frame,
58 },
59 );
60
61 Self {
62 mips,
63 luminance,
64 width,
65 height,
66 levels,
67 }
68 }
69
70 pub fn sample_at_blur_radius(&self, radius: f32) -> ResourceId {
71 let mip = (radius.log2().max(0.0) as usize).min(self.levels.saturating_sub(1) as usize);
75 self.mips[mip]
76 }
77}
78
79#[repr(C)]
80#[derive(Debug, Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)]
81pub struct BlurUniforms {
82 pub params: [f32; 4], pub mode: u32, pub _pad0: u32,
85 pub _pad1: u32,
86 pub _pad2: u32,
87}