use super::resource::ResourceId;
use crate::renderer::GpuRenderer;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ExecutionHint {
Raster,
Compute,
Hybrid,
}
pub struct ExecutionContext<'a> {
pub device: &'a wgpu::Device,
pub queue: &'a wgpu::Queue,
pub encoder: &'a mut wgpu::CommandEncoder,
pub registry: &'a crate::kvasir::registry::ResourceRegistry,
pub renderer: &'a crate::renderer::GpuRenderer,
pub target_view: &'a wgpu::TextureView,
pub depth_view: &'a wgpu::TextureView,
pub blur_env_bind_group_a: &'a wgpu::BindGroup,
pub blur_env_bind_group_b: &'a wgpu::BindGroup,
pub bloom_env_bind_group_a: &'a wgpu::BindGroup,
pub bloom_env_bind_group_b: &'a wgpu::BindGroup,
pub scale_factor: f32,
}
impl<'a> ExecutionContext<'a> {
pub fn begin_render_pass(
&mut self,
desc: &wgpu::RenderPassDescriptor<'_>,
) -> wgpu::RenderPass<'_> {
self.encoder.begin_render_pass(desc)
}
pub fn get_or_create_bind_group(
&self,
key: (crate::kvasir::resource::ResourceId, u32, bool),
layout: &wgpu::BindGroupLayout,
entries: &[wgpu::BindGroupEntry<'_>],
label: Option<&str>,
) -> wgpu::BindGroup {
let mut cache = GpuRenderer::lock_or_clear_cache(&self.renderer.bind_group_cache);
let full_key = (self.renderer.current_window, key.0, key.1, key.2);
if let std::collections::hash_map::Entry::Vacant(e) = cache.entry(full_key) {
let bg = self.device.create_bind_group(&wgpu::BindGroupDescriptor {
label,
layout,
entries,
});
e.insert(bg.clone());
bg
} else {
cache.get(&full_key).unwrap().clone()
}
}
}
#[cfg(not(target_arch = "wasm32"))]
pub trait KvasirNode: Send + Sync {
fn label(&self) -> &'static str;
fn inputs(&self) -> &[ResourceId];
fn outputs(&self) -> &[ResourceId];
fn pass_id(&self) -> super::nodes::PassId;
fn execute(&self, ctx: &mut ExecutionContext);
}
#[cfg(target_arch = "wasm32")]
pub trait KvasirNode {
fn label(&self) -> &'static str;
fn inputs(&self) -> &[ResourceId];
fn outputs(&self) -> &[ResourceId];
fn pass_id(&self) -> super::nodes::PassId;
fn execute(&self, ctx: &mut ExecutionContext);
}
#[cfg(test)]
mod p1_2_aliasing_contract_tests {
use super::*;
#[test]
fn renderer_field_is_immutable() {
fn _assert_immutable(_: &GpuRenderer) {}
let _f: fn(&GpuRenderer) = _assert_immutable;
}
#[test]
fn encoder_field_is_mutable() {
fn _assert_mut(_: &mut wgpu::CommandEncoder) {}
let _f: fn(&mut wgpu::CommandEncoder) = _assert_mut;
}
}