diff --git a/crates/bevy_core_pipeline/src/bloom/downsampling_pipeline.rs b/crates/bevy_core_pipeline/src/bloom/downsampling_pipeline.rs index 1d26ad9458..0d227d69a8 100644 --- a/crates/bevy_core_pipeline/src/bloom/downsampling_pipeline.rs +++ b/crates/bevy_core_pipeline/src/bloom/downsampling_pipeline.rs @@ -124,7 +124,10 @@ impl Specializer for BloomDownsamplingSpecializer { "bloom_downsampling_pipeline".into() }); - let fragment = descriptor.fragment.get_or_insert_default(); + // TODO: should this error? + let Some(fragment) = &mut descriptor.fragment else { + return Ok(key); + }; fragment.entry_point = Some(if key.first_downsample { "downsample_first".into() diff --git a/crates/bevy_core_pipeline/src/bloom/upsampling_pipeline.rs b/crates/bevy_core_pipeline/src/bloom/upsampling_pipeline.rs index f798d8b571..71a3b315fe 100644 --- a/crates/bevy_core_pipeline/src/bloom/upsampling_pipeline.rs +++ b/crates/bevy_core_pipeline/src/bloom/upsampling_pipeline.rs @@ -109,6 +109,10 @@ impl Specializer for BloomUpsamplingSpecializer { key: Self::Key, descriptor: &mut RenderPipelineDescriptor, ) -> Result, BevyError> { + let Some(fragment) = &mut descriptor.fragment else { + return Ok(key); + }; + let texture_format = if key.final_pipeline { ViewTarget::TEXTURE_FORMAT_HDR } else { @@ -147,17 +151,23 @@ impl Specializer for BloomUpsamplingSpecializer { }, }; - let fragment = descriptor.fragment.get_or_insert_default(); + let target = ColorTargetState { + format: texture_format, + blend: Some(BlendState { + // placeholder + color: color_blend, + alpha: BlendComponent { + src_factor: BlendFactor::Zero, + dst_factor: BlendFactor::One, + operation: BlendOperation::Add, + }, + }), + write_mask: ColorWrites::ALL, + }; - if let Some(Some(color_target)) = fragment.targets.first_mut() - && let Some(blend_state) = &mut color_target.blend - { - blend_state.color = color_blend; - color_target.format = texture_format; - Ok(key) - } else { - Err("color target state or blend state missing".into()) - } + fragment.set_target(0, target); + + Ok(key) } } diff --git a/crates/bevy_render/src/render_resource/pipeline.rs b/crates/bevy_render/src/render_resource/pipeline.rs index e94cf27cd3..858228453f 100644 --- a/crates/bevy_render/src/render_resource/pipeline.rs +++ b/crates/bevy_render/src/render_resource/pipeline.rs @@ -7,7 +7,7 @@ use crate::{ use alloc::borrow::Cow; use bevy_asset::Handle; use bevy_utils::WgpuWrapper; -use core::ops::Deref; +use core::{iter, ops::Deref}; use wgpu::{ ColorTargetState, DepthStencilState, MultisampleState, PrimitiveState, PushConstantRange, }; @@ -137,6 +137,12 @@ pub struct FragmentState { pub targets: Vec>, } +impl FragmentState { + pub fn set_target(&mut self, index: usize, target: ColorTargetState) { + filling_insert_at(&mut self.targets, index, None, Some(target)); + } +} + /// Describes a compute pipeline. #[derive(Clone, Debug, PartialEq, Eq, Default)] pub struct ComputePipelineDescriptor { @@ -153,3 +159,9 @@ pub struct ComputePipelineDescriptor { /// If this is false, reading from workgroup variables before writing to them will result in garbage values. pub zero_initialize_workgroup_memory: bool, } + +fn filling_insert_at(vec: &mut Vec, index: usize, filler: T, value: T) { + let num_to_fill = index.saturating_sub(vec.len() - 1); + vec.extend(iter::repeat_n(filler, num_to_fill)); + vec[index] = value; +}