Path: blob/main/crates/bevy_anti_alias/src/contrast_adaptive_sharpening/node.rs
6596 views
use std::sync::Mutex;12use crate::contrast_adaptive_sharpening::ViewCasPipeline;3use bevy_ecs::prelude::*;4use bevy_render::{5diagnostic::RecordDiagnostics,6extract_component::{ComponentUniforms, DynamicUniformIndex},7render_graph::{Node, NodeRunError, RenderGraphContext},8render_resource::{9BindGroup, BindGroupEntries, BufferId, Operations, PipelineCache,10RenderPassColorAttachment, RenderPassDescriptor, TextureViewId,11},12renderer::RenderContext,13view::{ExtractedView, ViewTarget},14};1516use super::{CasPipeline, CasUniform};1718pub struct CasNode {19query: QueryState<20(21&'static ViewTarget,22&'static ViewCasPipeline,23&'static DynamicUniformIndex<CasUniform>,24),25With<ExtractedView>,26>,27cached_bind_group: Mutex<Option<(BufferId, TextureViewId, BindGroup)>>,28}2930impl FromWorld for CasNode {31fn from_world(world: &mut World) -> Self {32Self {33query: QueryState::new(world),34cached_bind_group: Mutex::new(None),35}36}37}3839impl Node for CasNode {40fn update(&mut self, world: &mut World) {41self.query.update_archetypes(world);42}4344fn run(45&self,46graph: &mut RenderGraphContext,47render_context: &mut RenderContext,48world: &World,49) -> Result<(), NodeRunError> {50let view_entity = graph.view_entity();51let pipeline_cache = world.resource::<PipelineCache>();52let sharpening_pipeline = world.resource::<CasPipeline>();53let uniforms = world.resource::<ComponentUniforms<CasUniform>>();5455let Ok((target, pipeline, uniform_index)) = self.query.get_manual(world, view_entity)56else {57return Ok(());58};5960let uniforms_id = uniforms.buffer().unwrap().id();61let Some(uniforms) = uniforms.binding() else {62return Ok(());63};6465let Some(pipeline) = pipeline_cache.get_render_pipeline(pipeline.0) else {66return Ok(());67};6869let diagnostics = render_context.diagnostic_recorder();7071let view_target = target.post_process_write();72let source = view_target.source;73let destination = view_target.destination;7475let mut cached_bind_group = self.cached_bind_group.lock().unwrap();76let bind_group = match &mut *cached_bind_group {77Some((buffer_id, texture_id, bind_group))78if source.id() == *texture_id && uniforms_id == *buffer_id =>79{80bind_group81}82cached_bind_group => {83let bind_group = render_context.render_device().create_bind_group(84"cas_bind_group",85&sharpening_pipeline.texture_bind_group,86&BindGroupEntries::sequential((87view_target.source,88&sharpening_pipeline.sampler,89uniforms,90)),91);9293let (_, _, bind_group) =94cached_bind_group.insert((uniforms_id, source.id(), bind_group));95bind_group96}97};9899let pass_descriptor = RenderPassDescriptor {100label: Some("contrast_adaptive_sharpening"),101color_attachments: &[Some(RenderPassColorAttachment {102view: destination,103depth_slice: None,104resolve_target: None,105ops: Operations::default(),106})],107depth_stencil_attachment: None,108timestamp_writes: None,109occlusion_query_set: None,110};111112let mut render_pass = render_context113.command_encoder()114.begin_render_pass(&pass_descriptor);115let pass_span = diagnostics.time_span(&mut render_pass, "contrast_adaptive_sharpening");116117render_pass.set_pipeline(pipeline);118render_pass.set_bind_group(0, bind_group, &[uniform_index.index()]);119render_pass.draw(0..3, 0..1);120121pass_span.end(&mut render_pass);122123Ok(())124}125}126127128