diff --git a/crates/bevy_app/src/lib.rs b/crates/bevy_app/src/lib.rs index 04c42b306f..7349ce86b1 100644 --- a/crates/bevy_app/src/lib.rs +++ b/crates/bevy_app/src/lib.rs @@ -15,10 +15,7 @@ pub use schedule_runner::*; pub mod prelude { #[doc(hidden)] - pub use crate::{ - app::App, CoreStage, DynamicPlugin, Plugin, PluginGroup, - StartupStage, - }; + pub use crate::{app::App, CoreStage, DynamicPlugin, Plugin, PluginGroup, StartupStage}; } use bevy_ecs::schedule::StageLabel; diff --git a/crates/bevy_ecs/src/lib.rs b/crates/bevy_ecs/src/lib.rs index 6cbe96da14..69ea8d33a5 100644 --- a/crates/bevy_ecs/src/lib.rs +++ b/crates/bevy_ecs/src/lib.rs @@ -1229,7 +1229,9 @@ mod tests { fn clear_entities() { let mut world = World::default(); - world.register_component(ComponentDescriptor::new::(StorageType::SparseSet)).unwrap(); + world + .register_component(ComponentDescriptor::new::(StorageType::SparseSet)) + .unwrap(); world.insert_resource::(0); world.spawn().insert(1u32); world.spawn().insert(1.0f32); @@ -1243,9 +1245,25 @@ mod tests { world.clear_entities(); - assert_eq!(q1.iter(&world).len(), 0, "world should not contain table components"); - assert_eq!(q2.iter(&world).len(), 0, "world should not contain sparse set components"); - assert_eq!(world.entities().len(), 0, "world should not have any entities"); - assert_eq!(*world.get_resource::().unwrap(), 0, "world should still contain resources"); + assert_eq!( + q1.iter(&world).len(), + 0, + "world should not contain table components" + ); + assert_eq!( + q2.iter(&world).len(), + 0, + "world should not contain sparse set components" + ); + assert_eq!( + world.entities().len(), + 0, + "world should not have any entities" + ); + assert_eq!( + *world.get_resource::().unwrap(), + 0, + "world should still contain resources" + ); } } diff --git a/crates/crevice/src/lib.rs b/crates/crevice/src/lib.rs index bef2871cd6..610d9ceb5f 100644 --- a/crates/crevice/src/lib.rs +++ b/crates/crevice/src/lib.rs @@ -139,4 +139,4 @@ pub mod internal; #[cfg(feature = "mint")] mod mint; -mod glam; \ No newline at end of file +mod glam; diff --git a/pipelined/bevy_render2/src/camera/bundle.rs b/pipelined/bevy_render2/src/camera/bundle.rs index 12c9fbd9d6..48e5d75f45 100644 --- a/pipelined/bevy_render2/src/camera/bundle.rs +++ b/pipelined/bevy_render2/src/camera/bundle.rs @@ -1,4 +1,7 @@ -use crate::camera::{CAMERA_2D, CAMERA_3D, Camera, DepthCalculation, OrthographicProjection, PerspectiveProjection, ScalingMode}; +use crate::camera::{ + Camera, DepthCalculation, OrthographicProjection, PerspectiveProjection, ScalingMode, + CAMERA_2D, CAMERA_3D, +}; use bevy_ecs::bundle::Bundle; use bevy_transform::components::{GlobalTransform, Transform}; diff --git a/pipelined/bevy_render2/src/color/mod.rs b/pipelined/bevy_render2/src/color/mod.rs index b151a05e3f..cba45f1b7e 100644 --- a/pipelined/bevy_render2/src/color/mod.rs +++ b/pipelined/bevy_render2/src/color/mod.rs @@ -2,4 +2,4 @@ mod color; mod colorspace; pub use color::*; -pub use colorspace::*; \ No newline at end of file +pub use colorspace::*; diff --git a/pipelined/bevy_render2/src/main_pass/mod.rs b/pipelined/bevy_render2/src/main_pass/mod.rs index 4bbee2ef33..0d24810d8e 100644 --- a/pipelined/bevy_render2/src/main_pass/mod.rs +++ b/pipelined/bevy_render2/src/main_pass/mod.rs @@ -1,20 +1,17 @@ -mod draw_state; mod draw; +mod draw_state; -pub use draw_state::*; pub use draw::*; +pub use draw_state::*; -use crate::{RenderStage, pass::RenderPassColorAttachment, renderer::RenderContext}; use crate::{ camera::CameraPlugin, color::Color, - pass::{ - LoadOp, Operations, PassDescriptor, RenderPass, - TextureAttachment, - }, + pass::{LoadOp, Operations, PassDescriptor, RenderPass, TextureAttachment}, render_graph::{Node, RenderGraph, ResourceSlotInfo, ResourceSlots, WindowSwapChainNode}, render_resource::RenderResourceType, }; +use crate::{pass::RenderPassColorAttachment, renderer::RenderContext, RenderStage}; use bevy_app::{App, Plugin}; use bevy_ecs::prelude::*; use bevy_window::WindowId; @@ -120,17 +117,20 @@ impl Node for MainPassNode { let transparent_phase = world.get_resource::().unwrap(); let draw_functions = world.get_resource::().unwrap(); - render_context.begin_pass(&pass_descriptor, &mut |render_pass: &mut dyn RenderPass| { - let mut draw_functions = draw_functions.draw_function.lock(); - let mut tracked_pass = TrackedRenderPass::new(render_pass); - for drawable in transparent_phase.drawn_things.iter() { - draw_functions[drawable.draw_function].draw( - world, - &mut tracked_pass, - drawable.draw_key, - drawable.sort_key, - ); - } - }) + render_context.begin_render_pass( + &pass_descriptor, + &mut |render_pass: &mut dyn RenderPass| { + let mut draw_functions = draw_functions.draw_function.lock(); + let mut tracked_pass = TrackedRenderPass::new(render_pass); + for drawable in transparent_phase.drawn_things.iter() { + draw_functions[drawable.draw_function].draw( + world, + &mut tracked_pass, + drawable.draw_key, + drawable.sort_key, + ); + } + }, + ) } } diff --git a/pipelined/bevy_render2/src/mesh/mesh.rs b/pipelined/bevy_render2/src/mesh/mesh.rs index a7e9c36154..5b7d0401d9 100644 --- a/pipelined/bevy_render2/src/mesh/mesh.rs +++ b/pipelined/bevy_render2/src/mesh/mesh.rs @@ -1,6 +1,9 @@ mod conversions; -use crate::pipeline::{IndexFormat, InputStepMode, PrimitiveTopology, VertexAttribute, VertexBufferLayout, VertexFormat}; +use crate::pipeline::{ + IndexFormat, InputStepMode, PrimitiveTopology, VertexAttribute, VertexBufferLayout, + VertexFormat, +}; use bevy_core::cast_slice; use bevy_math::*; use bevy_reflect::TypeUuid; diff --git a/pipelined/bevy_render2/src/pass/compute_pass.rs b/pipelined/bevy_render2/src/pass/compute_pass.rs new file mode 100644 index 0000000000..d0f03a0c10 --- /dev/null +++ b/pipelined/bevy_render2/src/pass/compute_pass.rs @@ -0,0 +1,18 @@ +use crate::{ + pipeline::{BindGroupDescriptorId, PipelineId}, + render_resource::BindGroupId, + renderer::RenderContext, +}; + +pub trait ComputePass { + fn get_render_context(&self) -> &dyn RenderContext; + fn set_pipeline(&mut self, pipeline: PipelineId); + fn dispatch(&mut self, x: u32, y: u32, z: u32); + fn set_bind_group( + &mut self, + index: u32, + bind_group_descriptor_id: BindGroupDescriptorId, + bind_group: BindGroupId, + dynamic_uniform_indices: Option<&[u32]>, + ); +} diff --git a/pipelined/bevy_render2/src/pass/mod.rs b/pipelined/bevy_render2/src/pass/mod.rs index 26342576ec..a640c2fc14 100644 --- a/pipelined/bevy_render2/src/pass/mod.rs +++ b/pipelined/bevy_render2/src/pass/mod.rs @@ -1,8 +1,10 @@ +mod compute_pass; mod ops; #[allow(clippy::module_inception)] mod pass; mod render_pass; +pub use compute_pass::*; pub use ops::*; pub use pass::*; pub use render_pass::*; diff --git a/pipelined/bevy_render2/src/pass/pass.rs b/pipelined/bevy_render2/src/pass/pass.rs index 1ba7bba95f..0ee33e45e4 100644 --- a/pipelined/bevy_render2/src/pass/pass.rs +++ b/pipelined/bevy_render2/src/pass/pass.rs @@ -1,6 +1,5 @@ use crate::{color::Color, pass::Operations, render_resource::TextureId}; - #[derive(Debug, Clone)] pub enum TextureAttachment { Id(TextureId), diff --git a/pipelined/bevy_render2/src/pipeline/compute_pipeline.rs b/pipelined/bevy_render2/src/pipeline/compute_pipeline.rs new file mode 100644 index 0000000000..84acc48db5 --- /dev/null +++ b/pipelined/bevy_render2/src/pipeline/compute_pipeline.rs @@ -0,0 +1,29 @@ +use super::PipelineLayout; +use crate::shader::ComputeShaderStages; +use bevy_reflect::TypeUuid; + +#[derive(Clone, Debug, TypeUuid)] +#[uuid = "359c1fff-0c86-4fbb-8b66-4e2af422a2f1"] +pub struct ComputePipelineDescriptor { + pub name: Option, + pub layout: PipelineLayout, + pub shader_stages: ComputeShaderStages, +} + +impl ComputePipelineDescriptor { + pub fn new(shader_stages: ComputeShaderStages, layout: PipelineLayout) -> Self { + ComputePipelineDescriptor { + name: None, + layout, + shader_stages, + } + } + + pub fn default_config(shader_stages: ComputeShaderStages, layout: PipelineLayout) -> Self { + ComputePipelineDescriptor { + name: None, + layout, + shader_stages, + } + } +} diff --git a/pipelined/bevy_render2/src/pipeline/mod.rs b/pipelined/bevy_render2/src/pipeline/mod.rs index 16a03e2e02..66daddbad6 100644 --- a/pipelined/bevy_render2/src/pipeline/mod.rs +++ b/pipelined/bevy_render2/src/pipeline/mod.rs @@ -1,5 +1,6 @@ mod bind_group; mod binding; +mod compute_pipeline; #[allow(clippy::module_inception)] mod pipeline; mod pipeline_layout; @@ -9,6 +10,7 @@ mod vertex_format; pub use bind_group::*; pub use binding::*; +pub use compute_pipeline::*; pub use pipeline::*; pub use pipeline_layout::*; pub use state_descriptors::*; diff --git a/pipelined/bevy_render2/src/pipeline/pipeline.rs b/pipelined/bevy_render2/src/pipeline/pipeline.rs index 5b0a2402da..e1e1117636 100644 --- a/pipelined/bevy_render2/src/pipeline/pipeline.rs +++ b/pipelined/bevy_render2/src/pipeline/pipeline.rs @@ -10,7 +10,7 @@ use crate::{ BlendComponent, BlendState, ColorTargetState, DepthBiasState, DepthStencilState, MultisampleState, PolygonMode, PrimitiveState, StencilFaceState, StencilState, }, - shader::{ShaderStages}, + shader::ShaderStages, texture::TextureFormat, }; use bevy_reflect::{TypeUuid, Uuid}; diff --git a/pipelined/bevy_render2/src/render_graph/mod.rs b/pipelined/bevy_render2/src/render_graph/mod.rs index 70d9f98894..edb7b8d699 100644 --- a/pipelined/bevy_render2/src/render_graph/mod.rs +++ b/pipelined/bevy_render2/src/render_graph/mod.rs @@ -2,15 +2,15 @@ mod edge; mod graph; mod node; mod node_slot; -mod schedule; mod nodes; +mod schedule; pub use edge::*; pub use graph::*; pub use node::*; pub use node_slot::*; -pub use schedule::*; pub use nodes::*; +pub use schedule::*; use thiserror::Error; diff --git a/pipelined/bevy_render2/src/render_graph/nodes/mod.rs b/pipelined/bevy_render2/src/render_graph/nodes/mod.rs index 7702669d7e..11cf481ab1 100644 --- a/pipelined/bevy_render2/src/render_graph/nodes/mod.rs +++ b/pipelined/bevy_render2/src/render_graph/nodes/mod.rs @@ -1,3 +1,3 @@ mod window_swap_chain_node; -pub use window_swap_chain_node::*; \ No newline at end of file +pub use window_swap_chain_node::*; diff --git a/pipelined/bevy_render2/src/render_resource/bind_group.rs b/pipelined/bevy_render2/src/render_resource/bind_group.rs index 34c3460a23..8c6efcafa8 100644 --- a/pipelined/bevy_render2/src/render_resource/bind_group.rs +++ b/pipelined/bevy_render2/src/render_resource/bind_group.rs @@ -124,4 +124,4 @@ impl BindGroupBuilder { } } } -} \ No newline at end of file +} diff --git a/pipelined/bevy_render2/src/render_resource/buffer_vec.rs b/pipelined/bevy_render2/src/render_resource/buffer_vec.rs index 083cefc395..b59d2f8ab2 100644 --- a/pipelined/bevy_render2/src/render_resource/buffer_vec.rs +++ b/pipelined/bevy_render2/src/render_resource/buffer_vec.rs @@ -2,7 +2,7 @@ use crate::{ render_resource::{BufferId, BufferInfo, BufferMapMode, BufferUsage}, renderer::{RenderContext, RenderResources}, }; -use bevy_core::{Pod, cast_slice}; +use bevy_core::{cast_slice, Pod}; pub struct BufferVec { values: Vec, diff --git a/pipelined/bevy_render2/src/render_resource/render_resource_id.rs b/pipelined/bevy_render2/src/render_resource/render_resource_id.rs index 5110490031..01e51f1226 100644 --- a/pipelined/bevy_render2/src/render_resource/render_resource_id.rs +++ b/pipelined/bevy_render2/src/render_resource/render_resource_id.rs @@ -38,4 +38,4 @@ impl RenderResourceId { None } } -} \ No newline at end of file +} diff --git a/pipelined/bevy_render2/src/renderer/headless_render_resource_context.rs b/pipelined/bevy_render2/src/renderer/headless_render_resource_context.rs index 6974682b3c..2cb8b2e5f4 100644 --- a/pipelined/bevy_render2/src/renderer/headless_render_resource_context.rs +++ b/pipelined/bevy_render2/src/renderer/headless_render_resource_context.rs @@ -1,6 +1,6 @@ use super::RenderResourceContext; use crate::{ - pipeline::{BindGroupDescriptorId, PipelineDescriptor, PipelineId}, + pipeline::{BindGroupDescriptorId, ComputePipelineDescriptor, PipelineDescriptor, PipelineId}, render_resource::{ BindGroup, BufferId, BufferInfo, BufferMapMode, SamplerId, SwapChainDescriptor, TextureId, }, @@ -101,6 +101,13 @@ impl RenderResourceContext for HeadlessRenderResourceContext { PipelineId::new() } + fn create_compute_pipeline( + &self, + _pipeline_descriptor: &ComputePipelineDescriptor, + ) -> PipelineId { + PipelineId::new() + } + fn create_bind_group( &self, _bind_group_descriptor_id: BindGroupDescriptorId, diff --git a/pipelined/bevy_render2/src/renderer/render_context.rs b/pipelined/bevy_render2/src/renderer/render_context.rs index dcddc61cc6..12e8b0732a 100644 --- a/pipelined/bevy_render2/src/renderer/render_context.rs +++ b/pipelined/bevy_render2/src/renderer/render_context.rs @@ -1,6 +1,6 @@ use super::RenderResourceContext; use crate::{ - pass::{PassDescriptor, RenderPass}, + pass::{ComputePass, PassDescriptor, RenderPass}, render_resource::{BufferId, TextureId}, texture::Extent3d, }; @@ -49,9 +49,11 @@ pub trait RenderContext { destination_mip_level: u32, size: Extent3d, ); - fn begin_pass( + fn begin_render_pass( &mut self, pass_descriptor: &PassDescriptor, run_pass: &mut dyn FnMut(&mut dyn RenderPass), ); + + fn begin_compute_pass(&mut self, run_pass: &mut dyn FnMut(&mut dyn ComputePass)); } diff --git a/pipelined/bevy_render2/src/renderer/render_resource_context.rs b/pipelined/bevy_render2/src/renderer/render_resource_context.rs index ce74d852e2..70bf784b82 100644 --- a/pipelined/bevy_render2/src/renderer/render_resource_context.rs +++ b/pipelined/bevy_render2/src/renderer/render_resource_context.rs @@ -1,5 +1,5 @@ use crate::{ - pipeline::{BindGroupDescriptorId, PipelineDescriptor, PipelineId}, + pipeline::{BindGroupDescriptorId, ComputePipelineDescriptor, PipelineDescriptor, PipelineId}, render_resource::{ BindGroup, BufferId, BufferInfo, BufferMapMode, SamplerId, SwapChainDescriptor, TextureId, }, @@ -65,6 +65,10 @@ pub trait RenderResourceContext: Downcast + Send + Sync + 'static { fn get_aligned_uniform_size(&self, size: usize, dynamic: bool) -> usize; fn get_aligned_texture_size(&self, data_size: usize) -> usize; fn create_render_pipeline(&self, pipeline_descriptor: &PipelineDescriptor) -> PipelineId; + fn create_compute_pipeline( + &self, + _pipeline_descriptor: &ComputePipelineDescriptor, + ) -> PipelineId; fn bind_group_descriptor_exists(&self, bind_group_descriptor_id: BindGroupDescriptorId) -> bool; fn create_bind_group( diff --git a/pipelined/bevy_render2/src/shader/shader.rs b/pipelined/bevy_render2/src/shader/shader.rs index e9a4fd841b..95a34ccf13 100644 --- a/pipelined/bevy_render2/src/shader/shader.rs +++ b/pipelined/bevy_render2/src/shader/shader.rs @@ -253,6 +253,12 @@ pub struct ShaderStages { pub fragment: Option, } +/// All stages in a compute shader program +#[derive(Clone, Debug, Eq, PartialEq, Hash)] +pub struct ComputeShaderStages { + pub compute: ShaderId, +} + #[derive(Default)] pub struct ShaderLoader; diff --git a/pipelined/bevy_sprite2/src/lib.rs b/pipelined/bevy_sprite2/src/lib.rs index 54eaee7540..6e9aaa9623 100644 --- a/pipelined/bevy_sprite2/src/lib.rs +++ b/pipelined/bevy_sprite2/src/lib.rs @@ -1,12 +1,12 @@ mod bundle; -mod render; mod rect; +mod render; mod sprite; +pub use bundle::*; pub use rect::*; pub use render::*; pub use sprite::*; -pub use bundle::*; use bevy_app::prelude::*; use bevy_ecs::prelude::IntoSystem; diff --git a/pipelined/bevy_sprite2/src/sprite.rs b/pipelined/bevy_sprite2/src/sprite.rs index b4ca001c61..349c56488f 100644 --- a/pipelined/bevy_sprite2/src/sprite.rs +++ b/pipelined/bevy_sprite2/src/sprite.rs @@ -36,4 +36,4 @@ impl Sprite { flip_y: false, } } -} \ No newline at end of file +} diff --git a/pipelined/bevy_wgpu2/src/compute_pass.rs b/pipelined/bevy_wgpu2/src/compute_pass.rs new file mode 100644 index 0000000000..fd0a8209c2 --- /dev/null +++ b/pipelined/bevy_wgpu2/src/compute_pass.rs @@ -0,0 +1,74 @@ +use crate::{resources::WgpuResourceRefs, WgpuRenderContext}; +use bevy_render2::{ + pass::ComputePass, + pipeline::{BindGroupDescriptorId, ComputePipelineDescriptor, PipelineId}, + render_resource::BindGroupId, + renderer::RenderContext, +}; +use bevy_utils::tracing::trace; + +#[derive(Debug)] +pub struct WgpuComputePass<'a> { + pub compute_pass: wgpu::ComputePass<'a>, + pub render_context: &'a WgpuRenderContext, + pub wgpu_resources: WgpuResourceRefs<'a>, + pub pipeline_descriptor: Option<&'a ComputePipelineDescriptor>, +} + +impl<'a> ComputePass for WgpuComputePass<'a> { + fn get_render_context(&self) -> &dyn RenderContext { + self.render_context + } + + fn set_bind_group( + &mut self, + index: u32, + bind_group_descriptor_id: BindGroupDescriptorId, + bind_group: BindGroupId, + dynamic_uniform_indices: Option<&[u32]>, + ) { + if let Some(bind_group_info) = self + .wgpu_resources + .bind_groups + .get(&bind_group_descriptor_id) + { + if let Some(wgpu_bind_group) = bind_group_info.bind_groups.get(&bind_group) { + const EMPTY: &[u32] = &[]; + let dynamic_uniform_indices = + if let Some(dynamic_uniform_indices) = dynamic_uniform_indices { + dynamic_uniform_indices + } else { + EMPTY + }; + self.wgpu_resources + .used_bind_group_sender + .send(bind_group) + .unwrap(); + + trace!( + "set bind group {:?} {:?}: {:?}", + bind_group_descriptor_id, + dynamic_uniform_indices, + bind_group + ); + self.compute_pass + .set_bind_group(index, wgpu_bind_group, dynamic_uniform_indices); + } + } + } + + fn set_pipeline(&mut self, pipeline: PipelineId) { + let pipeline = self + .wgpu_resources + .compute_pipelines + .get(&pipeline) + .expect( + "Attempted to use a pipeline that does not exist in this `RenderPass`'s `RenderContext`.", + ); + self.compute_pass.set_pipeline(pipeline); + } + + fn dispatch(&mut self, x: u32, y: u32, z: u32) { + self.compute_pass.dispatch(x, y, z); + } +} diff --git a/pipelined/bevy_wgpu2/src/lib.rs b/pipelined/bevy_wgpu2/src/lib.rs index b20990bdef..c70413cb9b 100644 --- a/pipelined/bevy_wgpu2/src/lib.rs +++ b/pipelined/bevy_wgpu2/src/lib.rs @@ -1,5 +1,6 @@ pub mod diagnostic; +mod compute_pass; mod render_context; mod render_graph_executor; mod render_pass; @@ -8,6 +9,7 @@ mod renderer; mod resources; mod type_converter; +pub use compute_pass::*; pub use render_context::*; pub use render_pass::*; pub use render_resource_context::*; diff --git a/pipelined/bevy_wgpu2/src/render_context.rs b/pipelined/bevy_wgpu2/src/render_context.rs index 3a8cd67b00..4dc0b7335f 100644 --- a/pipelined/bevy_wgpu2/src/render_context.rs +++ b/pipelined/bevy_wgpu2/src/render_context.rs @@ -1,9 +1,12 @@ use super::WgpuRenderResourceContext; -use crate::{WgpuRenderPass, resources::WgpuResourceRefs, type_converter::WgpuInto}; +use crate::{ + compute_pass::WgpuComputePass, resources::WgpuResourceRefs, type_converter::WgpuInto, + WgpuRenderPass, +}; use bevy_render2::{ pass::{ - PassDescriptor, RenderPass, RenderPassColorAttachment, + ComputePass, PassDescriptor, RenderPass, RenderPassColorAttachment, RenderPassDepthStencilAttachment, TextureAttachment, }, render_resource::{BufferId, TextureId}, @@ -165,7 +168,7 @@ impl RenderContext for WgpuRenderContext { &mut self.render_resource_context } - fn begin_pass( + fn begin_render_pass( &mut self, pass_descriptor: &PassDescriptor, run_pass: &mut dyn FnMut(&mut dyn RenderPass), @@ -190,6 +193,29 @@ impl RenderContext for WgpuRenderContext { self.command_encoder.set(encoder); } + + fn begin_compute_pass(&mut self, run_pass: &mut dyn FnMut(&mut dyn ComputePass)) { + if !self.command_encoder.is_some() { + self.command_encoder.create(&self.device); + } + let resource_lock = self.render_resource_context.resources.read(); + let refs = resource_lock.refs(); + let mut encoder = self.command_encoder.take().unwrap(); + { + let compute_pass = + encoder.begin_compute_pass(&wgpu::ComputePassDescriptor { label: None }); + let mut wgpu_render_pass = WgpuComputePass { + compute_pass, + render_context: self, + wgpu_resources: refs, + pipeline_descriptor: None, + }; + + run_pass(&mut wgpu_render_pass); + } + + self.command_encoder.set(encoder); + } } pub fn create_render_pass<'a, 'b>( @@ -225,10 +251,7 @@ fn create_wgpu_color_attachment<'a>( refs: &WgpuResourceRefs<'a>, color_attachment: &RenderPassColorAttachment, ) -> wgpu::RenderPassColorAttachment<'a> { - let view = get_texture_view( - refs, - &color_attachment.attachment, - ); + let view = get_texture_view(refs, &color_attachment.attachment); let resolve_target = color_attachment .resolve_target @@ -246,10 +269,7 @@ fn create_wgpu_depth_stencil_attachment<'a>( refs: &WgpuResourceRefs<'a>, depth_stencil_attachment: &RenderPassDepthStencilAttachment, ) -> wgpu::RenderPassDepthStencilAttachment<'a> { - let view = get_texture_view( - refs, - &depth_stencil_attachment.attachment, - ); + let view = get_texture_view(refs, &depth_stencil_attachment.attachment); wgpu::RenderPassDepthStencilAttachment { view, diff --git a/pipelined/bevy_wgpu2/src/render_resource_context.rs b/pipelined/bevy_wgpu2/src/render_resource_context.rs index 8515fe3821..5d683d6a6c 100644 --- a/pipelined/bevy_wgpu2/src/render_resource_context.rs +++ b/pipelined/bevy_wgpu2/src/render_resource_context.rs @@ -4,8 +4,8 @@ use crate::{ }; use bevy_render2::{ pipeline::{ - BindGroupDescriptor, BindGroupDescriptorId, BindingShaderStage, PipelineDescriptor, - PipelineId, + BindGroupDescriptor, BindGroupDescriptorId, BindingShaderStage, ComputePipelineDescriptor, + PipelineDescriptor, PipelineId, }, render_resource::{ BindGroup, BufferId, BufferInfo, BufferMapMode, RenderResourceBinding, SamplerId, @@ -483,6 +483,52 @@ impl RenderResourceContext for WgpuRenderResourceContext { id } + fn create_compute_pipeline( + &self, + pipeline_descriptor: &ComputePipelineDescriptor, + ) -> PipelineId { + let layout = &pipeline_descriptor.layout; + for bind_group_descriptor in layout.bind_groups.iter() { + self.create_bind_group_layout(&bind_group_descriptor); + } + + let bind_group_layouts = self.resources.bind_group_layouts.read(); + // setup and collect bind group layouts + let bind_group_layouts = layout + .bind_groups + .iter() + .map(|bind_group| bind_group_layouts.get(&bind_group.id).unwrap()) + .collect::>(); + + let pipeline_layout = self + .device + .create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + label: None, + bind_group_layouts: bind_group_layouts.as_slice(), + push_constant_ranges: &[], + }); + + let shader_modules = self.resources.shader_modules.read(); + let compute_shader_module = shader_modules + .get(&pipeline_descriptor.shader_stages.compute) + .unwrap(); + + let compute_pipeline_descriptor = wgpu::ComputePipelineDescriptor { + label: None, + layout: Some(&pipeline_layout), + entry_point: "main", + module: compute_shader_module, + }; + + let compute_pipeline = self + .device + .create_compute_pipeline(&compute_pipeline_descriptor); + let mut compute_pipelines = self.resources.compute_pipelines.write(); + let id = PipelineId::new(); + compute_pipelines.insert(id, compute_pipeline); + id + } + fn bind_group_descriptor_exists( &self, bind_group_descriptor_id: BindGroupDescriptorId, diff --git a/pipelined/bevy_wgpu2/src/resources.rs b/pipelined/bevy_wgpu2/src/resources.rs index 14e7024f1b..13277197ef 100644 --- a/pipelined/bevy_wgpu2/src/resources.rs +++ b/pipelined/bevy_wgpu2/src/resources.rs @@ -48,6 +48,7 @@ pub struct WgpuResourcesReadLock<'a> { pub textures: RwLockReadGuard<'a, HashMap>, pub swap_chain_frames: RwLockReadGuard<'a, HashMap>, pub render_pipelines: RwLockReadGuard<'a, HashMap>, + pub compute_pipelines: RwLockReadGuard<'a, HashMap>, pub bind_groups: RwLockReadGuard<'a, HashMap>, pub used_bind_group_sender: Sender, } @@ -59,6 +60,7 @@ impl<'a> WgpuResourcesReadLock<'a> { textures: &self.textures, swap_chain_frames: &self.swap_chain_frames, render_pipelines: &self.render_pipelines, + compute_pipelines: &self.compute_pipelines, bind_groups: &self.bind_groups, used_bind_group_sender: &self.used_bind_group_sender, } @@ -73,6 +75,7 @@ pub struct WgpuResourceRefs<'a> { pub textures: &'a HashMap, pub swap_chain_frames: &'a HashMap, pub render_pipelines: &'a HashMap, + pub compute_pipelines: &'a HashMap, pub bind_groups: &'a HashMap, pub used_bind_group_sender: &'a Sender, } @@ -90,6 +93,7 @@ pub struct WgpuResources { pub samplers: Arc>>, pub shader_modules: Arc>>, pub render_pipelines: Arc>>, + pub compute_pipelines: Arc>>, pub bind_groups: Arc>>, pub bind_group_layouts: Arc>>, pub bind_group_counter: BindGroupCounter, @@ -102,6 +106,7 @@ impl WgpuResources { textures: self.texture_views.read(), swap_chain_frames: self.swap_chain_frames.read(), render_pipelines: self.render_pipelines.read(), + compute_pipelines: self.compute_pipelines.read(), bind_groups: self.bind_groups.read(), used_bind_group_sender: self.bind_group_counter.used_bind_group_sender.clone(), }