use awsm_renderer_core::bind_groups::{
BindGroupDescriptor, BindGroupEntry, BindGroupLayoutResource, BindGroupResource,
BufferBindingLayout, BufferBindingType,
};
use awsm_renderer_core::buffers::BufferBinding;
use crate::bind_group_layout::{
BindGroupLayoutCacheKey, BindGroupLayoutCacheKeyEntry, BindGroupLayoutKey,
};
use crate::bind_groups::{AwsmBindGroupError, BindGroupRecreateContext};
use crate::error::Result;
use crate::render_passes::RenderPassInitContext;
pub struct LightCullingBindGroups {
pub bind_group_layout_key: BindGroupLayoutKey,
bind_group: Option<web_sys::GpuBindGroup>,
}
impl LightCullingBindGroups {
pub async fn new(ctx: &mut RenderPassInitContext<'_>) -> Result<Self> {
let entries = vec![
uniform_entry(),
uniform_entry(),
uniform_entry(),
uniform_entry(),
storage_rw_entry(),
storage_rw_entry(),
storage_rw_entry(),
];
let bind_group_layout_key = ctx
.bind_group_layouts
.get_key(ctx.gpu, BindGroupLayoutCacheKey { entries })?;
Ok(Self {
bind_group_layout_key,
bind_group: None,
})
}
pub fn get_bind_group(
&self,
) -> std::result::Result<&web_sys::GpuBindGroup, AwsmBindGroupError> {
self.bind_group
.as_ref()
.ok_or_else(|| AwsmBindGroupError::NotFound("Light Culling".to_string()))
}
pub fn recreate(&mut self, ctx: &BindGroupRecreateContext<'_>) -> Result<()> {
let buffers = ctx.light_culling_buffers;
let entries = vec![
BindGroupEntry::new(
0,
BindGroupResource::Buffer(BufferBinding::new(&ctx.camera.gpu_buffer)),
),
BindGroupEntry::new(
1,
BindGroupResource::Buffer(BufferBinding::new(&buffers.params_buffer)),
),
BindGroupEntry::new(
2,
BindGroupResource::Buffer(BufferBinding::new(&ctx.lights.gpu_info_buffer)),
),
BindGroupEntry::new(
3,
BindGroupResource::Buffer(BufferBinding::new(&ctx.lights.gpu_punctual_buffer)),
),
BindGroupEntry::new(
4,
BindGroupResource::Buffer(BufferBinding::new(&buffers.storage_buffer)),
),
BindGroupEntry::new(
5,
BindGroupResource::Buffer(BufferBinding::new(&buffers.overflow_buffer)),
),
BindGroupEntry::new(
6,
BindGroupResource::Buffer(BufferBinding::new(&buffers.tile_lights_buffer)),
),
];
let descriptor = BindGroupDescriptor::new(
ctx.bind_group_layouts.get(self.bind_group_layout_key)?,
Some("Light Culling"),
entries,
);
self.bind_group = Some(ctx.gpu.create_bind_group(&descriptor.into()));
Ok(())
}
}
fn uniform_entry() -> BindGroupLayoutCacheKeyEntry {
BindGroupLayoutCacheKeyEntry {
resource: BindGroupLayoutResource::Buffer(
BufferBindingLayout::new().with_binding_type(BufferBindingType::Uniform),
),
visibility_vertex: false,
visibility_fragment: false,
visibility_compute: true,
}
}
fn storage_rw_entry() -> BindGroupLayoutCacheKeyEntry {
BindGroupLayoutCacheKeyEntry {
resource: BindGroupLayoutResource::Buffer(
BufferBindingLayout::new().with_binding_type(BufferBindingType::Storage),
),
visibility_vertex: false,
visibility_fragment: false,
visibility_compute: true,
}
}