//! Subpixel morphological antialiasing (SMAA).
//!
//! [SMAA] is a 2011 antialiasing technique that takes an aliased image and
//! smooths out the *jaggies*, making edges smoother. It's been used in numerous
//! games and has become a staple postprocessing technique. Compared to MSAA,
//! SMAA has the advantage of compatibility with deferred rendering and
//! reduction of GPU memory bandwidth.  Compared to FXAA, SMAA has the advantage
//! of improved quality, but the disadvantage of reduced performance. Compared
//! to TAA, SMAA has the advantage of stability and lack of *ghosting*
//! artifacts, but has the disadvantage of not supporting temporal accumulation,
//! which have made SMAA less popular when advanced photorealistic rendering
//! features are used in recent years.
//!
//! To use SMAA, add [`Smaa`] to a [`bevy_camera::Camera`]. In a
//! pinch, you can simply use the default settings (via the [`Default`] trait)
//! for a high-quality, high-performance appearance. When using SMAA, you will
//! likely want set [`bevy_render::view::Msaa`] to [`bevy_render::view::Msaa::Off`]
//! for every camera using SMAA.
//!
//! Those who have used SMAA in other engines should be aware that Bevy doesn't
//! yet support the following more advanced features of SMAA:
//!
//! * The temporal variant.
//!
//! * Depth- and chroma-based edge detection.
//!
//! * Predicated thresholding.
//!
//! * Compatibility with SSAA and MSAA.
//!
//! [SMAA]: https://www.iryoku.com/smaa/
use bevy_app::{App, Plugin};
use bevy_asset::{embedded_asset, load_embedded_asset, AssetServer, Handle};
#[cfg(not(feature = "smaa_luts"))]
use bevy_core_pipeline::tonemapping::lut_placeholder;
use bevy_core_pipeline::{
    core_2d::graph::{Core2d, Node2d},
    core_3d::graph::{Core3d, Node3d},
};
use bevy_derive::{Deref, DerefMut};
use bevy_ecs::{
    component::Component,
    entity::Entity,
    query::{QueryItem, With},
    reflect::ReflectComponent,
    resource::Resource,
    schedule::IntoScheduleConfigs as _,
    system::{lifetimeless::Read, Commands, Query, Res, ResMut},
    world::World,
};
use bevy_image::{BevyDefault, Image, ToExtents};
use bevy_math::{vec4, Vec4};
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
use bevy_render::{
    camera::ExtractedCamera,
    diagnostic::RecordDiagnostics,
    extract_component::{ExtractComponent, ExtractComponentPlugin},
    render_asset::RenderAssets,
    render_graph::{
        NodeRunError, RenderGraphContext, RenderGraphExt as _, ViewNode, ViewNodeRunner,
    },
    render_resource::{
        binding_types::{sampler, texture_2d, uniform_buffer},
        AddressMode, BindGroup, BindGroupEntries, BindGroupLayoutDescriptor,
        BindGroupLayoutEntries, CachedRenderPipelineId, ColorTargetState, ColorWrites,
        CompareFunction, DepthStencilState, DynamicUniformBuffer, FilterMode, FragmentState,
        LoadOp, Operations, PipelineCache, RenderPassColorAttachment,
        RenderPassDepthStencilAttachment, RenderPassDescriptor, RenderPipeline,
        RenderPipelineDescriptor, SamplerBindingType, SamplerDescriptor, ShaderStages, ShaderType,
        SpecializedRenderPipeline, SpecializedRenderPipelines, StencilFaceState, StencilOperation,
        StencilState, StoreOp, TextureDescriptor, TextureDimension, TextureFormat,
        TextureSampleType, TextureUsages, TextureView, VertexState,
    },
    renderer::{RenderContext, RenderDevice, RenderQueue},
    texture::{CachedTexture, GpuImage, TextureCache},
    view::{ExtractedView, ViewTarget},
    Render, RenderApp, RenderStartup, RenderSystems,
};
use bevy_shader::{Shader, ShaderDefVal};
use bevy_utils::prelude::default;

/// Adds support for subpixel morphological antialiasing, or SMAA.
#[derive(Default)]
pub struct SmaaPlugin;

/// A component for enabling Subpixel Morphological Anti-Aliasing (SMAA)
/// for a [`bevy_camera::Camera`].
#[derive(Clone, Copy, Default, Component, Reflect, ExtractComponent)]
#[reflect(Component, Default, Clone)]
#[doc(alias = "SubpixelMorphologicalAntiAliasing")]
pub struct Smaa {
    /// A predefined set of SMAA parameters: i.e. a quality level.
    ///
    /// Generally, you can leave this at its default level.
    pub preset: SmaaPreset,
}

/// A preset quality level for SMAA.
///
/// Higher values are slower but result in a higher-quality image.
///
/// The default value is *high*.
#[derive(Clone, Copy, Reflect, Default, PartialEq, Eq, Hash)]
#[reflect(Default, Clone, PartialEq, Hash)]
pub enum SmaaPreset {
    /// Four search steps; no diagonal or corner detection.
    Low,

    /// Eight search steps; no diagonal or corner detection.
    Medium,

    /// Sixteen search steps, 8 diagonal search steps, and corner detection.
    ///
    /// This is the default.
    #[default]
    High,

    /// Thirty-two search steps, 8 diagonal search steps, and corner detection.
    Ultra,
}

#[derive(Resource)]
struct SmaaLuts {
    /// The handle of the area LUT, a KTX2 format texture that SMAA uses internally.
    area_lut: Handle<Image>,
    /// The handle of the search LUT, a KTX2 format texture that SMAA uses internally.
    search_lut: Handle<Image>,
}

/// A render world resource that holds all render pipeline data needed for SMAA.
///
/// There are three separate passes, so we need three separate pipelines.
#[derive(Resource)]
pub struct SmaaPipelines {
    /// Pass 1: Edge detection.
    edge_detection: SmaaEdgeDetectionPipeline,
    /// Pass 2: Blending weight calculation.
    blending_weight_calculation: SmaaBlendingWeightCalculationPipeline,
    /// Pass 3: Neighborhood blending.
    neighborhood_blending: SmaaNeighborhoodBlendingPipeline,
}

/// The pipeline data for phase 1 of SMAA: edge detection.
struct SmaaEdgeDetectionPipeline {
    /// The bind group layout common to all passes.
    postprocess_bind_group_layout: BindGroupLayoutDescriptor,
    /// The bind group layout for data specific to this pass.
    edge_detection_bind_group_layout: BindGroupLayoutDescriptor,
    /// The shader asset handle.
    shader: Handle<Shader>,
}

/// The pipeline data for phase 2 of SMAA: blending weight calculation.
struct SmaaBlendingWeightCalculationPipeline {
    /// The bind group layout common to all passes.
    postprocess_bind_group_layout: BindGroupLayoutDescriptor,
    /// The bind group layout for data specific to this pass.
    blending_weight_calculation_bind_group_layout: BindGroupLayoutDescriptor,
    /// The shader asset handle.
    shader: Handle<Shader>,
}

/// The pipeline data for phase 3 of SMAA: neighborhood blending.
struct SmaaNeighborhoodBlendingPipeline {
    /// The bind group layout common to all passes.
    postprocess_bind_group_layout: BindGroupLayoutDescriptor,
    /// The bind group layout for data specific to this pass.
    neighborhood_blending_bind_group_layout: BindGroupLayoutDescriptor,
    /// The shader asset handle.
    shader: Handle<Shader>,
}

/// A unique identifier for a set of SMAA pipelines.
#[derive(Clone, PartialEq, Eq, Hash)]
pub struct SmaaNeighborhoodBlendingPipelineKey {
    /// The format of the framebuffer.
    texture_format: TextureFormat,
    /// The quality preset.
    preset: SmaaPreset,
}

/// A render world component that holds the pipeline IDs for the SMAA passes.
///
/// There are three separate SMAA passes, each with a different shader and bind
/// group layout, so we need three pipeline IDs.
#[derive(Component)]
pub struct ViewSmaaPipelines {
    /// The pipeline ID for edge detection (phase 1).
    edge_detection_pipeline_id: CachedRenderPipelineId,
    /// The pipeline ID for blending weight calculation (phase 2).
    blending_weight_calculation_pipeline_id: CachedRenderPipelineId,
    /// The pipeline ID for neighborhood blending (phase 3).
    neighborhood_blending_pipeline_id: CachedRenderPipelineId,
}

/// The render graph node that performs subpixel morphological antialiasing
/// (SMAA).
#[derive(Default)]
pub struct SmaaNode;

/// Values supplied to the GPU for SMAA.
///
/// Currently, this just contains the render target metrics and values derived
/// from them. These could be computed by the shader itself, but the original
/// SMAA HLSL code supplied them in a uniform, so we do the same for
/// consistency.
#[derive(Clone, Copy, ShaderType)]
pub struct SmaaInfoUniform {
    /// Information about the width and height of the framebuffer.
    ///
    /// * *x*: The reciprocal pixel width of the framebuffer.
    ///
    /// * *y*: The reciprocal pixel height of the framebuffer.
    ///
    /// * *z*: The pixel width of the framebuffer.
    ///
    /// * *w*: The pixel height of the framebuffer.
    pub rt_metrics: Vec4,
}

/// A render world component that stores the offset of each [`SmaaInfoUniform`]
/// within the [`SmaaInfoUniformBuffer`] for each view.
#[derive(Clone, Copy, Deref, DerefMut, Component)]
pub struct SmaaInfoUniformOffset(pub u32);

/// The GPU buffer that holds all [`SmaaInfoUniform`]s for all views.
///
/// This is a resource stored in the render world.
#[derive(Resource, Default, Deref, DerefMut)]
pub struct SmaaInfoUniformBuffer(pub DynamicUniformBuffer<SmaaInfoUniform>);

/// A render world component that holds the intermediate textures necessary to
/// perform SMAA.
///
/// This is stored on each view that has enabled SMAA.
#[derive(Component)]
pub struct SmaaTextures {
    /// The two-channel texture that stores the output from the first pass (edge
    /// detection).
    ///
    /// The second pass (blending weight calculation) reads this texture to do
    /// its work.
    pub edge_detection_color_texture: CachedTexture,

    /// The 8-bit stencil texture that records which pixels the first pass
    /// touched, so that the second pass doesn't have to examine other pixels.
    ///
    /// Each texel will contain a 0 if the first pass didn't touch the
    /// corresponding pixel or a 1 if the first pass did touch that pixel.
    pub edge_detection_stencil_texture: CachedTexture,

    /// A four-channel RGBA texture that stores the output from the second pass
    /// (blending weight calculation).
    ///
    /// The final pass (neighborhood blending) reads this texture to do its
    /// work.
    pub blend_texture: CachedTexture,
}

/// A render world component that stores the bind groups necessary to perform
/// SMAA.
///
/// This is stored on each view.
#[derive(Component)]
pub struct SmaaBindGroups {
    /// The bind group for the first pass (edge detection).
    pub edge_detection_bind_group: BindGroup,
    /// The bind group for the second pass (blending weight calculation).
    pub blending_weight_calculation_bind_group: BindGroup,
    /// The bind group for the final pass (neighborhood blending).
    pub neighborhood_blending_bind_group: BindGroup,
}

/// Stores the specialized render pipelines for SMAA.
///
/// Because SMAA uses three passes, we need three separate render pipeline
/// stores.
#[derive(Resource, Default)]
pub struct SmaaSpecializedRenderPipelines {
    /// Specialized render pipelines for the first phase (edge detection).
    edge_detection: SpecializedRenderPipelines<SmaaEdgeDetectionPipeline>,

    /// Specialized render pipelines for the second phase (blending weight
    /// calculation).
    blending_weight_calculation: SpecializedRenderPipelines<SmaaBlendingWeightCalculationPipeline>,

    /// Specialized render pipelines for the third phase (neighborhood
    /// blending).
    neighborhood_blending: SpecializedRenderPipelines<SmaaNeighborhoodBlendingPipeline>,
}

impl Plugin for SmaaPlugin {
    fn build(&self, app: &mut App) {
        // Load the shader.
        embedded_asset!(app, "smaa.wgsl");

        #[cfg(feature = "smaa_luts")]
        let smaa_luts = {
            use bevy_asset::RenderAssetUsages;
            use bevy_image::ImageLoaderSettings;

            // Load the two lookup textures. These are compressed textures in KTX2 format.
            embedded_asset!(app, "SMAAAreaLUT.ktx2");
            embedded_asset!(app, "SMAASearchLUT.ktx2");

            SmaaLuts {
                area_lut: load_embedded_asset!(
                    app,
                    "SMAAAreaLUT.ktx2",
                    |settings: &mut ImageLoaderSettings| {
                        settings.is_srgb = false;
                        settings.asset_usage = RenderAssetUsages::RENDER_WORLD;
                    }
                ),
                search_lut: load_embedded_asset!(
                    app,
                    "SMAASearchLUT.ktx2",
                    |settings: &mut ImageLoaderSettings| {
                        settings.is_srgb = false;
                        settings.asset_usage = RenderAssetUsages::RENDER_WORLD;
                    }
                ),
            }
        };
        #[cfg(not(feature = "smaa_luts"))]
        let smaa_luts = {
            let mut images = app.world_mut().resource_mut::<bevy_asset::Assets<Image>>();
            let handle = images.add(lut_placeholder());
            SmaaLuts {
                area_lut: handle.clone(),
                search_lut: handle.clone(),
            }
        };

        app.add_plugins(ExtractComponentPlugin::<Smaa>::default());

        let Some(render_app) = app.get_sub_app_mut(RenderApp) else {
            return;
        };

        render_app
            .insert_resource(smaa_luts)
            .init_resource::<SmaaSpecializedRenderPipelines>()
            .init_resource::<SmaaInfoUniformBuffer>()
            .add_systems(RenderStartup, init_smaa_pipelines)
            .add_systems(
                Render,
                (
                    prepare_smaa_pipelines.in_set(RenderSystems::Prepare),
                    prepare_smaa_uniforms.in_set(RenderSystems::PrepareResources),
                    prepare_smaa_textures.in_set(RenderSystems::PrepareResources),
                    prepare_smaa_bind_groups.in_set(RenderSystems::PrepareBindGroups),
                ),
            )
            .add_render_graph_node::<ViewNodeRunner<SmaaNode>>(Core3d, Node3d::Smaa)
            .add_render_graph_edges(
                Core3d,
                (
                    Node3d::Tonemapping,
                    Node3d::Smaa,
                    Node3d::EndMainPassPostProcessing,
                ),
            )
            .add_render_graph_node::<ViewNodeRunner<SmaaNode>>(Core2d, Node2d::Smaa)
            .add_render_graph_edges(
                Core2d,
                (
                    Node2d::Tonemapping,
                    Node2d::Smaa,
                    Node2d::EndMainPassPostProcessing,
                ),
            );
    }
}

pub fn init_smaa_pipelines(mut commands: Commands, asset_server: Res<AssetServer>) {
    // Create the postprocess bind group layout (all passes, bind group 0).
    let postprocess_bind_group_layout = BindGroupLayoutDescriptor::new(
        "SMAA postprocess bind group layout",
        &BindGroupLayoutEntries::sequential(
            ShaderStages::FRAGMENT,
            (
                texture_2d(TextureSampleType::Float { filterable: true }),
                uniform_buffer::<SmaaInfoUniform>(true).visibility(ShaderStages::VERTEX_FRAGMENT),
            ),
        ),
    );

    // Create the edge detection bind group layout (pass 1, bind group 1).
    let edge_detection_bind_group_layout = BindGroupLayoutDescriptor::new(
        "SMAA edge detection bind group layout",
        &BindGroupLayoutEntries::sequential(
            ShaderStages::FRAGMENT,
            (sampler(SamplerBindingType::Filtering),),
        ),
    );

    // Create the blending weight calculation bind group layout (pass 2, bind group 1).
    let blending_weight_calculation_bind_group_layout = BindGroupLayoutDescriptor::new(
        "SMAA blending weight calculation bind group layout",
        &BindGroupLayoutEntries::sequential(
            ShaderStages::FRAGMENT,
            (
                texture_2d(TextureSampleType::Float { filterable: true }), // edges texture
                sampler(SamplerBindingType::Filtering),                    // edges sampler
                texture_2d(TextureSampleType::Float { filterable: true }), // search texture
                texture_2d(TextureSampleType::Float { filterable: true }), // area texture
            ),
        ),
    );

    // Create the neighborhood blending bind group layout (pass 3, bind group 1).
    let neighborhood_blending_bind_group_layout = BindGroupLayoutDescriptor::new(
        "SMAA neighborhood blending bind group layout",
        &BindGroupLayoutEntries::sequential(
            ShaderStages::FRAGMENT,
            (
                texture_2d(TextureSampleType::Float { filterable: true }),
                sampler(SamplerBindingType::Filtering),
            ),
        ),
    );

    let shader = load_embedded_asset!(asset_server.as_ref(), "smaa.wgsl");

    commands.insert_resource(SmaaPipelines {
        edge_detection: SmaaEdgeDetectionPipeline {
            postprocess_bind_group_layout: postprocess_bind_group_layout.clone(),
            edge_detection_bind_group_layout,
            shader: shader.clone(),
        },
        blending_weight_calculation: SmaaBlendingWeightCalculationPipeline {
            postprocess_bind_group_layout: postprocess_bind_group_layout.clone(),
            blending_weight_calculation_bind_group_layout,
            shader: shader.clone(),
        },
        neighborhood_blending: SmaaNeighborhoodBlendingPipeline {
            postprocess_bind_group_layout,
            neighborhood_blending_bind_group_layout,
            shader,
        },
    });
}

// Phase 1: edge detection.
impl SpecializedRenderPipeline for SmaaEdgeDetectionPipeline {
    type Key = SmaaPreset;

    fn specialize(&self, preset: Self::Key) -> RenderPipelineDescriptor {
        let shader_defs = vec!["SMAA_EDGE_DETECTION".into(), preset.shader_def()];

        // We mark the pixels that we touched with a 1 so that the blending
        // weight calculation (phase 2) will only consider those. This reduces
        // the overhead of phase 2 considerably.
        let stencil_face_state = StencilFaceState {
            compare: CompareFunction::Always,
            fail_op: StencilOperation::Replace,
            depth_fail_op: StencilOperation::Replace,
            pass_op: StencilOperation::Replace,
        };

        RenderPipelineDescriptor {
            label: Some("SMAA edge detection".into()),
            layout: vec![
                self.postprocess_bind_group_layout.clone(),
                self.edge_detection_bind_group_layout.clone(),
            ],
            vertex: VertexState {
                shader: self.shader.clone(),
                shader_defs: shader_defs.clone(),
                entry_point: Some("edge_detection_vertex_main".into()),
                buffers: vec![],
            },
            fragment: Some(FragmentState {
                shader: self.shader.clone(),
                shader_defs,
                entry_point: Some("luma_edge_detection_fragment_main".into()),
                targets: vec![Some(ColorTargetState {
                    format: TextureFormat::Rg8Unorm,
                    blend: None,
                    write_mask: ColorWrites::ALL,
                })],
            }),
            depth_stencil: Some(DepthStencilState {
                format: TextureFormat::Stencil8,
                depth_write_enabled: false,
                depth_compare: CompareFunction::Always,
                stencil: StencilState {
                    front: stencil_face_state,
                    back: stencil_face_state,
                    read_mask: 1,
                    write_mask: 1,
                },
                bias: default(),
            }),
            ..default()
        }
    }
}

// Phase 2: blending weight calculation.
impl SpecializedRenderPipeline for SmaaBlendingWeightCalculationPipeline {
    type Key = SmaaPreset;

    fn specialize(&self, preset: Self::Key) -> RenderPipelineDescriptor {
        let shader_defs = vec![
            "SMAA_BLENDING_WEIGHT_CALCULATION".into(),
            preset.shader_def(),
        ];

        // Only consider the pixels that were touched in phase 1.
        let stencil_face_state = StencilFaceState {
            compare: CompareFunction::Equal,
            fail_op: StencilOperation::Keep,
            depth_fail_op: StencilOperation::Keep,
            pass_op: StencilOperation::Keep,
        };

        RenderPipelineDescriptor {
            label: Some("SMAA blending weight calculation".into()),
            layout: vec![
                self.postprocess_bind_group_layout.clone(),
                self.blending_weight_calculation_bind_group_layout.clone(),
            ],
            vertex: VertexState {
                shader: self.shader.clone(),
                shader_defs: shader_defs.clone(),
                entry_point: Some("blending_weight_calculation_vertex_main".into()),
                buffers: vec![],
            },
            fragment: Some(FragmentState {
                shader: self.shader.clone(),
                shader_defs,
                entry_point: Some("blending_weight_calculation_fragment_main".into()),
                targets: vec![Some(ColorTargetState {
                    format: TextureFormat::Rgba8Unorm,
                    blend: None,
                    write_mask: ColorWrites::ALL,
                })],
            }),
            depth_stencil: Some(DepthStencilState {
                format: TextureFormat::Stencil8,
                depth_write_enabled: false,
                depth_compare: CompareFunction::Always,
                stencil: StencilState {
                    front: stencil_face_state,
                    back: stencil_face_state,
                    read_mask: 1,
                    write_mask: 1,
                },
                bias: default(),
            }),
            ..default()
        }
    }
}

impl SpecializedRenderPipeline for SmaaNeighborhoodBlendingPipeline {
    type Key = SmaaNeighborhoodBlendingPipelineKey;

    fn specialize(&self, key: Self::Key) -> RenderPipelineDescriptor {
        let shader_defs = vec!["SMAA_NEIGHBORHOOD_BLENDING".into(), key.preset.shader_def()];

        RenderPipelineDescriptor {
            label: Some("SMAA neighborhood blending".into()),
            layout: vec![
                self.postprocess_bind_group_layout.clone(),
                self.neighborhood_blending_bind_group_layout.clone(),
            ],
            vertex: VertexState {
                shader: self.shader.clone(),
                shader_defs: shader_defs.clone(),
                entry_point: Some("neighborhood_blending_vertex_main".into()),
                buffers: vec![],
            },
            fragment: Some(FragmentState {
                shader: self.shader.clone(),
                shader_defs,
                entry_point: Some("neighborhood_blending_fragment_main".into()),
                targets: vec![Some(ColorTargetState {
                    format: key.texture_format,
                    blend: None,
                    write_mask: ColorWrites::ALL,
                })],
            }),
            ..default()
        }
    }
}

/// A system, part of the render app, that specializes the three pipelines
/// needed for SMAA according to each view's SMAA settings.
fn prepare_smaa_pipelines(
    mut commands: Commands,
    pipeline_cache: Res<PipelineCache>,
    mut specialized_render_pipelines: ResMut<SmaaSpecializedRenderPipelines>,
    smaa_pipelines: Res<SmaaPipelines>,
    view_targets: Query<(Entity, &ExtractedView, &Smaa)>,
) {
    for (entity, view, smaa) in &view_targets {
        let edge_detection_pipeline_id = specialized_render_pipelines.edge_detection.specialize(
            &pipeline_cache,
            &smaa_pipelines.edge_detection,
            smaa.preset,
        );

        let blending_weight_calculation_pipeline_id = specialized_render_pipelines
            .blending_weight_calculation
            .specialize(
                &pipeline_cache,
                &smaa_pipelines.blending_weight_calculation,
                smaa.preset,
            );

        let neighborhood_blending_pipeline_id = specialized_render_pipelines
            .neighborhood_blending
            .specialize(
                &pipeline_cache,
                &smaa_pipelines.neighborhood_blending,
                SmaaNeighborhoodBlendingPipelineKey {
                    texture_format: if view.hdr {
                        ViewTarget::TEXTURE_FORMAT_HDR
                    } else {
                        TextureFormat::bevy_default()
                    },
                    preset: smaa.preset,
                },
            );

        commands.entity(entity).insert(ViewSmaaPipelines {
            edge_detection_pipeline_id,
            blending_weight_calculation_pipeline_id,
            neighborhood_blending_pipeline_id,
        });
    }
}

/// A system, part of the render app, that builds the [`SmaaInfoUniform`] data
/// for each view with SMAA enabled and writes the resulting data to GPU memory.
fn prepare_smaa_uniforms(
    mut commands: Commands,
    render_device: Res<RenderDevice>,
    render_queue: Res<RenderQueue>,
    view_targets: Query<(Entity, &ExtractedView), With<Smaa>>,
    mut smaa_info_buffer: ResMut<SmaaInfoUniformBuffer>,
) {
    smaa_info_buffer.clear();
    for (entity, view) in &view_targets {
        let offset = smaa_info_buffer.push(&SmaaInfoUniform {
            rt_metrics: vec4(
                1.0 / view.viewport.z as f32,
                1.0 / view.viewport.w as f32,
                view.viewport.z as f32,
                view.viewport.w as f32,
            ),
        });
        commands
            .entity(entity)
            .insert(SmaaInfoUniformOffset(offset));
    }

    smaa_info_buffer.write_buffer(&render_device, &render_queue);
}

/// A system, part of the render app, that builds the intermediate textures for
/// each view with SMAA enabled.
///
/// Phase 1 (edge detection) needs a two-channel RG texture and an 8-bit stencil
/// texture; phase 2 (blend weight calculation) needs a four-channel RGBA
/// texture.
fn prepare_smaa_textures(
    mut commands: Commands,
    render_device: Res<RenderDevice>,
    mut texture_cache: ResMut<TextureCache>,
    view_targets: Query<(Entity, &ExtractedCamera), (With<ExtractedView>, With<Smaa>)>,
) {
    for (entity, camera) in &view_targets {
        let Some(texture_size) = camera.physical_target_size else {
            continue;
        };

        // Create the two-channel RG texture for phase 1 (edge detection).
        let edge_detection_color_texture = texture_cache.get(
            &render_device,
            TextureDescriptor {
                label: Some("SMAA edge detection color texture"),
                size: texture_size.to_extents(),
                mip_level_count: 1,
                sample_count: 1,
                dimension: TextureDimension::D2,
                format: TextureFormat::Rg8Unorm,
                usage: TextureUsages::TEXTURE_BINDING | TextureUsages::RENDER_ATTACHMENT,
                view_formats: &[],
            },
        );

        // Create the stencil texture for phase 1 (edge detection).
        let edge_detection_stencil_texture = texture_cache.get(
            &render_device,
            TextureDescriptor {
                label: Some("SMAA edge detection stencil texture"),
                size: texture_size.to_extents(),
                mip_level_count: 1,
                sample_count: 1,
                dimension: TextureDimension::D2,
                format: TextureFormat::Stencil8,
                usage: TextureUsages::RENDER_ATTACHMENT,
                view_formats: &[],
            },
        );

        // Create the four-channel RGBA texture for phase 2 (blending weight
        // calculation).
        let blend_texture = texture_cache.get(
            &render_device,
            TextureDescriptor {
                label: Some("SMAA blend texture"),
                size: texture_size.to_extents(),
                mip_level_count: 1,
                sample_count: 1,
                dimension: TextureDimension::D2,
                format: TextureFormat::Rgba8Unorm,
                usage: TextureUsages::TEXTURE_BINDING | TextureUsages::RENDER_ATTACHMENT,
                view_formats: &[],
            },
        );

        commands.entity(entity).insert(SmaaTextures {
            edge_detection_color_texture,
            edge_detection_stencil_texture,
            blend_texture,
        });
    }
}

/// A system, part of the render app, that builds the SMAA bind groups for each
/// view with SMAA enabled.
fn prepare_smaa_bind_groups(
    mut commands: Commands,
    render_device: Res<RenderDevice>,
    smaa_pipelines: Res<SmaaPipelines>,
    smaa_luts: Res<SmaaLuts>,
    images: Res<RenderAssets<GpuImage>>,
    pipeline_cache: Res<PipelineCache>,
    view_targets: Query<(Entity, &SmaaTextures), (With<ExtractedView>, With<Smaa>)>,
) {
    // Fetch the two lookup textures. These are bundled in this library.
    let (Some(search_texture), Some(area_texture)) = (
        images.get(&smaa_luts.search_lut),
        images.get(&smaa_luts.area_lut),
    ) else {
        return;
    };

    for (entity, smaa_textures) in &view_targets {
        // We use the same sampler settings for all textures, so we can build
        // only one and reuse it.
        let sampler = render_device.create_sampler(&SamplerDescriptor {
            label: Some("SMAA sampler"),
            address_mode_u: AddressMode::ClampToEdge,
            address_mode_v: AddressMode::ClampToEdge,
            address_mode_w: AddressMode::ClampToEdge,
            mag_filter: FilterMode::Linear,
            min_filter: FilterMode::Linear,
            ..default()
        });

        commands.entity(entity).insert(SmaaBindGroups {
            edge_detection_bind_group: render_device.create_bind_group(
                Some("SMAA edge detection bind group"),
                &pipeline_cache.get_bind_group_layout(
                    &smaa_pipelines
                        .edge_detection
                        .edge_detection_bind_group_layout,
                ),
                &BindGroupEntries::sequential((&sampler,)),
            ),
            blending_weight_calculation_bind_group: render_device.create_bind_group(
                Some("SMAA blending weight calculation bind group"),
                &pipeline_cache.get_bind_group_layout(
                    &smaa_pipelines
                        .blending_weight_calculation
                        .blending_weight_calculation_bind_group_layout,
                ),
                &BindGroupEntries::sequential((
                    &smaa_textures.edge_detection_color_texture.default_view,
                    &sampler,
                    &search_texture.texture_view,
                    &area_texture.texture_view,
                )),
            ),
            neighborhood_blending_bind_group: render_device.create_bind_group(
                Some("SMAA neighborhood blending bind group"),
                &pipeline_cache.get_bind_group_layout(
                    &smaa_pipelines
                        .neighborhood_blending
                        .neighborhood_blending_bind_group_layout,
                ),
                &BindGroupEntries::sequential((
                    &smaa_textures.blend_texture.default_view,
                    &sampler,
                )),
            ),
        });
    }
}

impl ViewNode for SmaaNode {
    type ViewQuery = (
        Read<ViewTarget>,
        Read<ViewSmaaPipelines>,
        Read<SmaaInfoUniformOffset>,
        Read<SmaaTextures>,
        Read<SmaaBindGroups>,
    );

    fn run<'w>(
        &self,
        _: &mut RenderGraphContext,
        render_context: &mut RenderContext<'w>,
        (
            view_target,
            view_pipelines,
            view_smaa_uniform_offset,
            smaa_textures,
            view_smaa_bind_groups,
        ): QueryItem<'w, '_, Self::ViewQuery>,
        world: &'w World,
    ) -> Result<(), NodeRunError> {
        let pipeline_cache = world.resource::<PipelineCache>();
        let smaa_pipelines = world.resource::<SmaaPipelines>();
        let smaa_info_uniform_buffer = world.resource::<SmaaInfoUniformBuffer>();

        // Fetch the render pipelines.
        let (
            Some(edge_detection_pipeline),
            Some(blending_weight_calculation_pipeline),
            Some(neighborhood_blending_pipeline),
        ) = (
            pipeline_cache.get_render_pipeline(view_pipelines.edge_detection_pipeline_id),
            pipeline_cache
                .get_render_pipeline(view_pipelines.blending_weight_calculation_pipeline_id),
            pipeline_cache.get_render_pipeline(view_pipelines.neighborhood_blending_pipeline_id),
        )
        else {
            return Ok(());
        };

        let diagnostics = render_context.diagnostic_recorder();
        render_context.command_encoder().push_debug_group("smaa");
        let time_span = diagnostics.time_span(render_context.command_encoder(), "smaa");

        // Fetch the framebuffer textures.
        let postprocess = view_target.post_process_write();
        let (source, destination) = (postprocess.source, postprocess.destination);

        // Stage 1: Edge detection pass.
        perform_edge_detection(
            render_context,
            pipeline_cache,
            smaa_pipelines,
            smaa_textures,
            view_smaa_bind_groups,
            smaa_info_uniform_buffer,
            view_smaa_uniform_offset,
            edge_detection_pipeline,
            source,
        );

        // Stage 2: Blending weight calculation pass.
        perform_blending_weight_calculation(
            render_context,
            pipeline_cache,
            smaa_pipelines,
            smaa_textures,
            view_smaa_bind_groups,
            smaa_info_uniform_buffer,
            view_smaa_uniform_offset,
            blending_weight_calculation_pipeline,
            source,
        );

        // Stage 3: Neighborhood blending pass.
        perform_neighborhood_blending(
            render_context,
            pipeline_cache,
            smaa_pipelines,
            view_smaa_bind_groups,
            smaa_info_uniform_buffer,
            view_smaa_uniform_offset,
            neighborhood_blending_pipeline,
            source,
            destination,
        );

        time_span.end(render_context.command_encoder());
        render_context.command_encoder().pop_debug_group();

        Ok(())
    }
}

/// Performs edge detection (phase 1).
///
/// This runs as part of the [`SmaaNode`]. It reads from the source texture and
/// writes to the two-channel RG edges texture. Additionally, it ensures that
/// all pixels it didn't touch are stenciled out so that phase 2 won't have to
/// examine them.
fn perform_edge_detection(
    render_context: &mut RenderContext,
    pipeline_cache: &PipelineCache,
    smaa_pipelines: &SmaaPipelines,
    smaa_textures: &SmaaTextures,
    view_smaa_bind_groups: &SmaaBindGroups,
    smaa_info_uniform_buffer: &SmaaInfoUniformBuffer,
    view_smaa_uniform_offset: &SmaaInfoUniformOffset,
    edge_detection_pipeline: &RenderPipeline,
    source: &TextureView,
) {
    // Create the edge detection bind group.
    let postprocess_bind_group = render_context.render_device().create_bind_group(
        None,
        &pipeline_cache
            .get_bind_group_layout(&smaa_pipelines.edge_detection.postprocess_bind_group_layout),
        &BindGroupEntries::sequential((source, &**smaa_info_uniform_buffer)),
    );

    // Create the edge detection pass descriptor.
    let pass_descriptor = RenderPassDescriptor {
        label: Some("SMAA edge detection pass"),
        color_attachments: &[Some(RenderPassColorAttachment {
            view: &smaa_textures.edge_detection_color_texture.default_view,
            depth_slice: None,
            resolve_target: None,
            ops: default(),
        })],
        depth_stencil_attachment: Some(RenderPassDepthStencilAttachment {
            view: &smaa_textures.edge_detection_stencil_texture.default_view,
            depth_ops: None,
            stencil_ops: Some(Operations {
                load: LoadOp::Clear(0),
                store: StoreOp::Store,
            }),
        }),
        timestamp_writes: None,
        occlusion_query_set: None,
    };

    // Run the actual render pass.
    let mut render_pass = render_context
        .command_encoder()
        .begin_render_pass(&pass_descriptor);
    render_pass.set_pipeline(edge_detection_pipeline);
    render_pass.set_bind_group(0, &postprocess_bind_group, &[**view_smaa_uniform_offset]);
    render_pass.set_bind_group(1, &view_smaa_bind_groups.edge_detection_bind_group, &[]);
    render_pass.set_stencil_reference(1);
    render_pass.draw(0..3, 0..1);
}

/// Performs blending weight calculation (phase 2).
///
/// This runs as part of the [`SmaaNode`]. It reads the edges texture and writes
/// to the blend weight texture, using the stencil buffer to avoid processing
/// pixels it doesn't need to examine.
fn perform_blending_weight_calculation(
    render_context: &mut RenderContext,
    pipeline_cache: &PipelineCache,
    smaa_pipelines: &SmaaPipelines,
    smaa_textures: &SmaaTextures,
    view_smaa_bind_groups: &SmaaBindGroups,
    smaa_info_uniform_buffer: &SmaaInfoUniformBuffer,
    view_smaa_uniform_offset: &SmaaInfoUniformOffset,
    blending_weight_calculation_pipeline: &RenderPipeline,
    source: &TextureView,
) {
    // Create the blending weight calculation bind group.
    let postprocess_bind_group = render_context.render_device().create_bind_group(
        None,
        &pipeline_cache.get_bind_group_layout(
            &smaa_pipelines
                .blending_weight_calculation
                .postprocess_bind_group_layout,
        ),
        &BindGroupEntries::sequential((source, &**smaa_info_uniform_buffer)),
    );

    // Create the blending weight calculation pass descriptor.
    let pass_descriptor = RenderPassDescriptor {
        label: Some("SMAA blending weight calculation pass"),
        color_attachments: &[Some(RenderPassColorAttachment {
            view: &smaa_textures.blend_texture.default_view,
            depth_slice: None,
            resolve_target: None,
            ops: default(),
        })],
        depth_stencil_attachment: Some(RenderPassDepthStencilAttachment {
            view: &smaa_textures.edge_detection_stencil_texture.default_view,
            depth_ops: None,
            stencil_ops: Some(Operations {
                load: LoadOp::Load,
                store: StoreOp::Discard,
            }),
        }),
        timestamp_writes: None,
        occlusion_query_set: None,
    };

    // Run the actual render pass.
    let mut render_pass = render_context
        .command_encoder()
        .begin_render_pass(&pass_descriptor);
    render_pass.set_pipeline(blending_weight_calculation_pipeline);
    render_pass.set_bind_group(0, &postprocess_bind_group, &[**view_smaa_uniform_offset]);
    render_pass.set_bind_group(
        1,
        &view_smaa_bind_groups.blending_weight_calculation_bind_group,
        &[],
    );
    render_pass.set_stencil_reference(1);
    render_pass.draw(0..3, 0..1);
}

/// Performs blending weight calculation (phase 3).
///
/// This runs as part of the [`SmaaNode`]. It reads from the blend weight
/// texture. It's the only phase that writes to the postprocessing destination.
fn perform_neighborhood_blending(
    render_context: &mut RenderContext,
    pipeline_cache: &PipelineCache,
    smaa_pipelines: &SmaaPipelines,
    view_smaa_bind_groups: &SmaaBindGroups,
    smaa_info_uniform_buffer: &SmaaInfoUniformBuffer,
    view_smaa_uniform_offset: &SmaaInfoUniformOffset,
    neighborhood_blending_pipeline: &RenderPipeline,
    source: &TextureView,
    destination: &TextureView,
) {
    let postprocess_bind_group = render_context.render_device().create_bind_group(
        None,
        &pipeline_cache.get_bind_group_layout(
            &smaa_pipelines
                .neighborhood_blending
                .postprocess_bind_group_layout,
        ),
        &BindGroupEntries::sequential((source, &**smaa_info_uniform_buffer)),
    );

    let pass_descriptor = RenderPassDescriptor {
        label: Some("SMAA neighborhood blending pass"),
        color_attachments: &[Some(RenderPassColorAttachment {
            view: destination,
            depth_slice: None,
            resolve_target: None,
            ops: default(),
        })],
        depth_stencil_attachment: None,
        timestamp_writes: None,
        occlusion_query_set: None,
    };

    let mut neighborhood_blending_render_pass = render_context
        .command_encoder()
        .begin_render_pass(&pass_descriptor);
    neighborhood_blending_render_pass.set_pipeline(neighborhood_blending_pipeline);
    neighborhood_blending_render_pass.set_bind_group(
        0,
        &postprocess_bind_group,
        &[**view_smaa_uniform_offset],
    );
    neighborhood_blending_render_pass.set_bind_group(
        1,
        &view_smaa_bind_groups.neighborhood_blending_bind_group,
        &[],
    );
    neighborhood_blending_render_pass.draw(0..3, 0..1);
}

impl SmaaPreset {
    /// Returns the `#define` in the shader corresponding to this quality
    /// preset.
    fn shader_def(&self) -> ShaderDefVal {
        match *self {
            SmaaPreset::Low => "SMAA_PRESET_LOW".into(),
            SmaaPreset::Medium => "SMAA_PRESET_MEDIUM".into(),
            SmaaPreset::High => "SMAA_PRESET_HIGH".into(),
            SmaaPreset::Ultra => "SMAA_PRESET_ULTRA".into(),
        }
    }
}

Homonyms

cyberia/src/components/mod.rs
cyberia/src/pages/mod.rs
cyb/optica/src/output/mod.rs
neural/trident/src/compile/mod.rs
cyb/optica/src/parser/mod.rs
soft3/nox/rs/data/mod.rs
neural/trident/src/api/mod.rs
soft3/mir/src/graph/mod.rs
cyb/optica/src/render/mod.rs
cyb/optica/src/scanner/mod.rs
soft3/cybergraph/tests/common/mod.rs
neural/trident/src/verify/mod.rs
soft3/tru/rs/model/mod.rs
neural/trident/src/diagnostic/mod.rs
soft3/mudra/src/proof/mod.rs
cyb/optica/src/graph/mod.rs
soft3/glia/import/loader/mod.rs
soft3/glia/run/backend/mod.rs
neural/trident/src/import/mod.rs
soft3/tru/rs/pass/mod.rs
soft3/mir/src/bevy/mod.rs
neural/trident/src/package/mod.rs
neural/trident/src/lsp/mod.rs
neural/trident/src/field/mod.rs
cyb/prysm/atoms/rs/mod.rs
soft3/tru/rs/graph/mod.rs
neural/trident/src/deploy/mod.rs
soft3/mir/src/epoch/mod.rs
neural/trident/src/runtime/mod.rs
soft3/glia/run/arch/mod.rs
neural/trident/src/typecheck/mod.rs
neural/trident/src/gpu/mod.rs
soft3/nox/rs/jets/mod.rs
soft3/glia/run/tokenizer/mod.rs
soft3/mir/src/frame/mod.rs
neural/trident/src/ir/mod.rs
neural/trident/src/config/mod.rs
soft3/nox/rs/patterns/mod.rs
neural/trident/src/cost/mod.rs
soft3/glia/run/ir/mod.rs
neural/trident/src/cli/mod.rs
soft3/tru/rs/focusing/mod.rs
neural/trident/src/neural/mod.rs
cyb/optica/src/query/mod.rs
cyb/prysm/system/rs/mod.rs
neural/trident/src/ast/mod.rs
soft3/glia/run/bench/mod.rs
cyb/prysm/molecules/rs/mod.rs
cyb/optica/src/server/mod.rs
soft3/glia/run/core/mod.rs
neural/trident/src/syntax/mod.rs
cyb/honeycrisp/acpu/src/vector/mod.rs
soft3/glia/run/backend/cpu/mod.rs
soft3/zheng/rs/src/spartan/mod.rs
soft3/bbg/rs/src/storage/mod.rs
neural/trident/src/config/resolve/mod.rs
cyb/honeycrisp/aruminium/src/ffi/mod.rs
cyb/cyb/cyb-shell/src/worlds/mod.rs
cyb/wysm/crates/wasi/tests/mod.rs
soft3/zheng/rs/src/ccs/mod.rs
neural/trident/src/package/store/mod.rs
cyb/cyb/cyb-shell/src/shell/mod.rs
cyb/wysm/crates/wasmi/tests/mod.rs
neural/trident/src/verify/synthesize/mod.rs
cyb/honeycrisp/acpu/src/field/mod.rs
neural/rs/macros/src/addressed/mod.rs
soft3/glia/run/cli/cmd/mod.rs
neural/trident/src/cost/stack_verifier/mod.rs
neural/eidos/rs/src/stdlib/mod.rs
neural/trident/src/verify/sym/mod.rs
neural/trident/src/syntax/format/mod.rs
neural/trident/src/syntax/grammar/mod.rs
neural/trident/src/lsp/util/mod.rs
neural/rs/rsc/src/lints/mod.rs
neural/trident/src/typecheck/tests/mod.rs
neural/eidos/rs/src/surface/mod.rs
soft3/mir/src/frame/tiers/mod.rs
cyb/honeycrisp/acpu/src/pulse/mod.rs
neural/trident/src/ir/lir/mod.rs
neural/trident/src/package/registry/mod.rs
neural/trident/src/neural/model/mod.rs
neural/trident/src/package/hash/mod.rs
cyb/honeycrisp/acpu/src/sync/mod.rs
soft3/glia/run/arch/decoder/mod.rs
neural/trident/src/verify/report/mod.rs
neural/trident/src/ir/tir/mod.rs
cyb/honeycrisp/rane/src/mil/mod.rs
cyb/honeycrisp/acpu/src/crypto/mod.rs
soft3/zheng/rs/src/folding/mod.rs
neural/trident/src/ir/tree/mod.rs
cyb/honeycrisp/acpu/src/matrix/mod.rs
soft3/glia/run/backend/honeycrisp/mod.rs
neural/eidos/rs/src/elab/mod.rs
neural/rs/macros/src/registers/mod.rs
neural/trident/src/verify/solve/mod.rs
neural/rs/core/src/fixed_point/mod.rs
neural/trident/src/syntax/parser/mod.rs
neural/trident/src/neural/data/mod.rs
neural/trident/src/verify/smt/mod.rs
soft3/radio/iroh-blobs/examples/common/mod.rs
soft3/strata/nebu/rs/extension/mod.rs
neural/rs/darwin-sys/src/ffi/mod.rs
cyb/honeycrisp/acpu/src/sparse/mod.rs
soft3/glia/run/backend/wgpu/mod.rs
neural/rs/core/src/bounded/mod.rs
neural/eidos/rs/src/tactic_ext/mod.rs
neural/trident/src/cost/model/mod.rs
cyb/wysm/crates/wast/tests/mod.rs
soft3/radio/iroh-blobs/src/store/mod.rs
neural/trident/src/package/manifest/mod.rs
cyb/cyb/cyb-shell/src/agent/mod.rs
neural/trident/src/neural/training/mod.rs
neural/trident/src/verify/equiv/mod.rs
neural/trident/src/syntax/lexer/mod.rs
cyb/honeycrisp/acpu/src/numeric/mod.rs
soft3/radio/cyber-bao/src/io/mod.rs
neural/trident/src/ir/kir/mod.rs
cyb/honeycrisp/aruminium/src/render/mod.rs
neural/trident/src/neural/inference/mod.rs
cyb/honeycrisp/acpu/src/probe/mod.rs
neural/trident/src/api/tests/mod.rs
cyb/honeycrisp/acpu/src/gemm/mod.rs
soft3/nox/rs/jets/backends/mod.rs
neural/trident/src/lsp/semantic/mod.rs
neural/rs/macros/src/cell/mod.rs
neural/trident/src/config/scaffold/mod.rs
soft3/zheng/rs/src/sumcheck/mod.rs
cyb/evy/forks/bevy_ecs/src/entity/mod.rs
neural/trident/src/ir/tir/builder/mod.rs
cyb/evy/forks/bevy_ecs/src/system/mod.rs
cyb/evy/forks/bevy_sprite_render/src/render/mod.rs
soft3/strata/jali/wgsl/src/shaders/mod.rs
cyb/evy/forks/bevy_core_pipeline/src/tonemapping/mod.rs
cyb/evy/forks/bevy_anti_alias/src/dlss/mod.rs
cyb/evy/forks/bevy_core_pipeline/src/skybox/mod.rs
cyb/evy/forks/bevy_sprite_render/src/text2d/mod.rs
cyb/evy/forks/bevy_render/src/batching/mod.rs
cyb/evy/forks/bevy_core_pipeline/src/experimental/mod.rs
cyb/evy/forks/bevy_core_pipeline/src/oit/mod.rs
cyb/evy/forks/bevy_sprite_render/src/tilemap_chunk/mod.rs
cyb/evy/forks/bevy_pbr/src/atmosphere/mod.rs
cyb/evy/forks/bevy_post_process/src/motion_blur/mod.rs
cyb/wysm/crates/wasmi/src/store/mod.rs
cyb/evy/forks/bevy_render/src/render_graph/mod.rs
cyb/wysm/crates/wasmi/benches/bench/mod.rs
cyb/evy/forks/bevy_anti_alias/src/contrast_adaptive_sharpening/mod.rs
neural/trident/src/ir/tir/stack/mod.rs
cyb/evy/forks/bevy_render/src/texture/mod.rs
cyb/wysm/crates/c_api/src/types/mod.rs
soft3/strata/genies/wgsl/src/shaders/mod.rs
cyb/wysm/crates/core/src/memory/mod.rs
bootloader/go-cyber/mcp/rust/src/proto/mod.rs
cyb/evy/forks/bevy_ecs/src/bundle/mod.rs
cyb/evy/forks/bevy_mesh/src/primitives/mod.rs
cyb/evy/forks/bevy_ecs/src/schedule/mod.rs
cyb/wysm/crates/wasmi/src/module/mod.rs
cyb/evy/forks/bevy_sprite/src/texture_slice/mod.rs
cyb/evy/forks/bevy_ecs/src/observer/mod.rs
neural/trident/src/ir/tir/neural/mod.rs
cyb/evy/forks/bevy_render/src/view/mod.rs
neural/trident/src/ir/lir/lower/mod.rs
bootloader/go-cyber/mcp/rust/src/clients/mod.rs
cyb/evy/forks/bevy_core_pipeline/src/fullscreen_vertex_shader/mod.rs
cyb/wysm/crates/wasmi/tests/integration/mod.rs
cyb/wysm/crates/ir/src/decode/mod.rs
cyb/wysm/crates/wasmi/src/memory/mod.rs
cyb/evy/crates/evy_prysm_core/src/layout/mod.rs
cyb/evy/forks/bevy_anti_alias/src/fxaa/mod.rs
cyb/evy/forks/bevy_pbr/src/prepass/mod.rs
cyb/evy/forks/bevy_render/src/render_resource/mod.rs
cyb/evy/forks/bevy_ecs/src/query/mod.rs
cyb/evy/forks/bevy_core_pipeline/src/core_2d/mod.rs
cyb/wysm/crates/cli/src/commands/mod.rs
cyb/evy/forks/bevy_render/src/renderer/mod.rs
cyb/wysm/crates/collections/src/arena/mod.rs
cyb/evy/forks/bevy_post_process/src/effect_stack/mod.rs
cyb/evy/forks/bevy_ecs/src/change_detection/mod.rs
cyb/evy/forks/bevy_pbr/src/ssao/mod.rs
cyb/evy/forks/naga/src/keywords/mod.rs
cyb/evy/forks/naga/src/compact/mod.rs
neural/trident/src/ir/tir/lower/mod.rs
cyb/evy/forks/bevy_pbr/src/render/mod.rs
cyb/evy/forks/bevy_ecs/src/world/mod.rs
cyb/evy/forks/bevy_anti_alias/src/taa/mod.rs
cyb/evy/forks/bevy_ecs/src/reflect/mod.rs
soft3/strata/kuro/wgsl/src/shaders/mod.rs
cyb/evy/forks/bevy_ecs/src/error/mod.rs
neural/trident/src/ir/kir/lower/mod.rs
cyb/evy/forks/naga/src/proc/mod.rs
cyb/evy/forks/bevy_ecs/src/event/mod.rs
cyb/evy/forks/bevy_ecs/src/component/mod.rs
cyb/evy/forks/bevy_sprite_render/src/mesh2d/mod.rs
cyb/evy/forks/bevy_ecs/src/relationship/mod.rs
cyb/wysm/crates/wasmi/src/instance/mod.rs
cyb/evy/forks/bevy_pbr/src/ssr/mod.rs
bootloader/go-cyber/mcp/rust/src/tools/mod.rs
soft3/glia/run/backend/honeycrisp/kernels/mod.rs
cyb/evy/forks/naga/src/back/mod.rs
soft3/glia/run/backend/cpu/quant/mod.rs
cyb/wysm/crates/core/src/table/mod.rs
cyb/evy/forks/bevy_post_process/src/dof/mod.rs
cyb/evy/forks/bevy_pbr/src/light_probe/mod.rs
cyb/evy/forks/bevy_core_pipeline/src/prepass/mod.rs
cyb/evy/forks/bevy_core_pipeline/src/upscaling/mod.rs
cyb/wysm/crates/wasmi/src/table/mod.rs
cyb/evy/forks/bevy_post_process/src/bloom/mod.rs
cyb/evy/forks/bevy_pbr/src/lightmap/mod.rs
neural/trident/src/ir/tir/optimize/mod.rs
cyb/evy/forks/bevy_gizmos/src/primitives/mod.rs
cyb/evy/forks/bevy_post_process/src/auto_exposure/mod.rs
neural/trident/src/neural/data/tir_graph/mod.rs
cyb/evy/forks/bevy_render/src/experimental/mod.rs
cyb/wysm/crates/wasmi/src/engine/mod.rs
cyb/evy/forks/bevy_core_pipeline/src/deferred/mod.rs
cyb/evy/forks/naga/src/arena/mod.rs
cyb/evy/forks/bevy_render/src/diagnostic/mod.rs
cyb/evy/forks/bevy_render/src/render_phase/mod.rs
cyb/evy/forks/bevy_transform/src/components/mod.rs
soft3/strata/trop/wgsl/src/shaders/mod.rs
soft3/glia/run/backend/wgpu/kernels/mod.rs
cyb/evy/forks/bevy_sprite_render/src/texture_slice/mod.rs
cyb/evy/forks/bevy_core_pipeline/src/core_3d/mod.rs
cyb/evy/forks/bevy_render/src/mesh/mod.rs
neural/trident/src/ir/tree/lower/mod.rs
cyb/evy/forks/bevy_pbr/src/volumetric_fog/mod.rs
cyb/evy/forks/bevy_pbr/src/decal/mod.rs
cyb/wysm/crates/fuzz/src/oracle/mod.rs
cyb/evy/forks/bevy_ecs/src/message/mod.rs
cyb/evy/forks/naga/src/valid/mod.rs
cyb/evy/forks/bevy_core_pipeline/src/blit/mod.rs
cyb/evy/forks/naga/src/front/mod.rs
cyb/wysm/crates/wasi/src/sync/mod.rs
cyb/evy/forks/bevy_pbr/src/meshlet/mod.rs
cyb/evy/forks/bevy_pbr/src/deferred/mod.rs
neural/trident/src/syntax/parser/tests/mod.rs
cyb/evy/forks/bevy_ecs/src/storage/mod.rs
cyb/evy/forks/bevy_tasks/src/iter/mod.rs
soft3/glia/run/arch/decoder/families/mod.rs
cyb/wysm/crates/wasmi/src/func/mod.rs
cyb/evy/forks/naga/src/common/mod.rs
cyb/evy/forks/naga/src/front/wgsl/mod.rs
cyb/evy/forks/naga/src/back/spv/mod.rs
cyb/evy/forks/naga/src/back/dot/mod.rs
cyb/evy/forks/bevy_render/src/view/window/mod.rs
cyb/wysm/crates/wasi/src/sync/snapshots/mod.rs
cyb/evy/forks/bevy_render/src/experimental/occlusion_culling/mod.rs
cyb/evy/forks/bevy_ecs/src/schedule/graph/mod.rs
cyb/wysm/crates/wasmi/src/engine/translator/mod.rs
cyb/wysm/crates/wasmi/src/module/parser/mod.rs
cyb/wysm/crates/wasmi/src/engine/limits/mod.rs
cyb/wysm/crates/wasmi/src/engine/executor/mod.rs
cyb/evy/forks/bevy_ecs/src/system/commands/mod.rs
cyb/evy/forks/naga/src/back/wgsl/mod.rs
cyb/evy/forks/bevy_core_pipeline/src/oit/resolve/mod.rs
cyb/wysm/crates/wasmi/src/module/instantiate/mod.rs
cyb/evy/forks/bevy_core_pipeline/src/experimental/mip_generation/mod.rs
cyb/evy/forks/bevy_ecs/src/storage/table/mod.rs
bootloader/go-cyber/cw/packages/cyber-std/src/tokenfactory/mod.rs
cyb/evy/forks/bevy_render/src/view/visibility/mod.rs
cyb/evy/forks/bevy_ecs/src/schedule/executor/mod.rs
cyb/evy/forks/naga/src/front/spv/mod.rs
cyb/evy/forks/naga/src/back/msl/mod.rs
cyb/evy/forks/naga/src/front/glsl/mod.rs
cyb/evy/forks/bevy_ecs/src/world/entity_access/mod.rs
cyb/evy/forks/bevy_mesh/src/primitives/dim3/mod.rs
cyb/evy/forks/naga/src/back/glsl/mod.rs
cyb/evy/forks/naga/src/back/hlsl/mod.rs
struct Baz { m: mat3x2, } struct Baz { float2 m_0; float2 m_1; float2 m_2; }; float3x2 GetMatmOnBaz(Baz obj) { return float3x2(obj.m_0, obj.m_1, obj.m_2); }
cyb/wysm/crates/wasmi/src/engine/executor/handler/mod.rs
cyb/wysm/crates/wasmi/src/engine/translator/func/mod.rs
cyb/evy/forks/naga/src/front/wgsl/parse/mod.rs
cyb/evy/forks/naga/src/back/wgsl/polyfill/mod.rs
cyb/evy/forks/naga/src/front/wgsl/lower/mod.rs
cyb/wysm/crates/wasmi/src/engine/translator/func/simd/mod.rs
cyb/wysm/crates/wasmi/src/engine/translator/func/stack/mod.rs
cyb/wysm/crates/wasmi/src/engine/executor/handler/dispatch/mod.rs

Graph