Skip to content

Commit

Permalink
Updating to bevy 0.15
Browse files Browse the repository at this point in the history
  • Loading branch information
AnthonyTornetta committed Dec 5, 2024
1 parent fe0dae0 commit 7ac8516
Show file tree
Hide file tree
Showing 10 changed files with 963 additions and 79 deletions.
810 changes: 803 additions & 7 deletions Cargo.lock

Large diffs are not rendered by default.

32 changes: 26 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "bevy_easy_compute"
version = "0.14.1"
version = "0.15.0"
authors = [
"Cornchip <[email protected]>",
"Kjolnyr <[email protected]>",
Expand Down Expand Up @@ -52,11 +52,31 @@ rand = ">=0.8.5"
version = "0.15"
default-features = false
features = [
"bevy_sprite",
"bevy_core_pipeline",
"multi_threaded",
"sysinfo_plugin",
"x11",
"animation",
"bevy_asset",
"bevy_state",
"bevy_color",
"bevy_core_pipeline",
"bevy_pbr",
"bevy_gltf",
"bevy_render",
"bevy_sprite",
"bevy_text",
"bevy_ui",
"multi_threaded",
"png",
"hdr",
"x11",
"bevy_gizmos",
"android_shared_stdcxx",
"tonemapping_luts",
"smaa_luts",
"default_font",
"webgl2",
"sysinfo_plugin",
"bevy_scene",
"bevy_winit",
"bevy_window",
]

[[example]]
Expand Down
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Add the following line to your `Cargo.toml`

```toml
[dependencies]
bevy_easy_compute = "0.14.1"
bevy_easy_compute = "0.15"
```

## Usage
Expand Down Expand Up @@ -161,14 +161,13 @@ It will run at the end of the current frame, and you'll be able to read the data

(see [one_shot.rs](https://github.com/AnthonyTornetta/bevy_easy_compute/tree/main/examples/one_shot.rs))


## Examples

See [examples](https://github.com/AnthonyTornetta/bevy_easy_compute/tree/main/examples)


## Bevy version mapping

| Bevy | bevy_easy_compute |
| ---- | ----------------- |
| 0.15 | 0.15 |
| 0.14 | 0.14.1 |
23 changes: 7 additions & 16 deletions examples/boids/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,9 @@ mod worker;
use bevy::color::palettes::css;
use bevy::diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin};

use bevy::{
prelude::*,
sprite::{MaterialMesh2dBundle, Mesh2dHandle},
window::PrimaryWindow,
};
use bevy::prelude::*;

use bevy::window::PrimaryWindow;
use bevy_easy_compute::prelude::*;

use worker::{Boid, BoidWorker};
Expand Down Expand Up @@ -39,29 +36,23 @@ fn setup(
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<ColorMaterial>>,
) {
commands.spawn(Camera2dBundle::default());
commands.spawn(Camera2d::default());

let boid_mesh = meshes.add(RegularPolygon::new(2., 3));
let boid_material = materials.add(Color::from(css::ANTIQUE_WHITE));

// First boid in red, so we can follow it easily
commands.spawn((
BoidEntity(0),
MaterialMesh2dBundle {
mesh: Mesh2dHandle(boid_mesh.clone()),
material: materials.add(Color::from(css::ORANGE_RED)),
..Default::default()
},
Mesh2d(boid_mesh.clone()),
MeshMaterial2d(materials.add(Color::from(css::ORANGE_RED))),
));

for i in 1..NUM_BOIDS {
commands.spawn((
BoidEntity(i as usize),
MaterialMesh2dBundle {
mesh: Mesh2dHandle(boid_mesh.clone()),
material: boid_material.clone(),
..Default::default()
},
Mesh2d(boid_mesh.clone()),
MeshMaterial2d(boid_material.clone()),
));
}
}
Expand Down
2 changes: 1 addition & 1 deletion examples/game_of_life/render/draw_plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ impl Plugin for DrawPlugin {

/// Startup system for [`DrawPlugin`]
fn startup(mut commands: Commands) {
commands.spawn(Camera2dBundle::default());
commands.spawn(Camera2d::default());
}

/// Simple system to check that our custom setup has happened.
Expand Down
11 changes: 5 additions & 6 deletions examples/game_of_life/render/pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@
use bevy::{
asset::DirectAssetAccessExt,
image::BevyDefault,
prelude::{FromWorld, Resource, World},
render::{
render_resource::{
CachedRenderPipelineId, ColorTargetState, ColorWrites, FragmentState, MultisampleState,
PipelineCache, PrimitiveState, TextureFormat, VertexState,
},
texture::BevyDefault,
render::render_resource::{
CachedRenderPipelineId, ColorTargetState, ColorWrites, FragmentState, MultisampleState,
PipelineCache, PrimitiveState, TextureFormat, VertexState,
},
};

Expand Down Expand Up @@ -55,6 +53,7 @@ impl FromWorld for DrawParticlePipeline {
mask: !0,
alpha_to_coverage_enabled: false,
},
zero_initialize_workgroup_memory: false,
},
);

Expand Down
2 changes: 1 addition & 1 deletion examples/one_shot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ fn main() {
}

fn setup(mut commands: Commands) {
commands.spawn(Camera3dBundle::default());
commands.spawn(Camera3d::default());
println!("Click anywhere in the window to trigger a one-shot compute job");
}

Expand Down
148 changes: 111 additions & 37 deletions src/pipeline_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,27 @@
use std::borrow::Cow;
use std::iter::FusedIterator;
use std::mem;
use std::sync::Arc;

use bevy::prelude::*;
use bevy::render::render_resource::{
BindGroupLayout, BindGroupLayoutId, CachedPipelineState, ComputePipeline,
ComputePipelineDescriptor, ErasedPipelineLayout, ErasedShaderModule, Pipeline,
PipelineCacheError, ShaderDefVal, ShaderImport, Source,
ComputePipelineDescriptor, Pipeline, PipelineCacheError, ShaderDefVal, ShaderImport, Source,
};
use bevy::render::renderer::RenderDevice;
use bevy::render::renderer::{RenderAdapter, RenderDevice, WgpuWrapper};
use bevy::utils::{Entry, HashMap, HashSet};
use naga::valid::{Capabilities, ShaderStages};
use naga::valid::Capabilities;
use parking_lot::Mutex;
#[cfg(feature = "shader_format_spirv")]
use wgpu::util::make_spirv;
use wgpu::{
Features, PipelineCompilationOptions, PipelineLayout, PipelineLayoutDescriptor,
PushConstantRange, ShaderModuleDescriptor,
DownlevelFlags, Features, PipelineCompilationOptions, PipelineLayout, PipelineLayoutDescriptor,
PushConstantRange, ShaderModule, ShaderModuleDescriptor,
};

type ErasedShaderModule = Arc<WgpuWrapper<ShaderModule>>;
type ErasedPipelineLayout = Arc<WgpuWrapper<PipelineLayout>>;

pub struct CachedAppPipeline {
state: CachedPipelineState,
descriptor: Box<ComputePipelineDescriptor>,
Expand Down Expand Up @@ -62,41 +65,111 @@ struct ShaderCache {
}

impl ShaderCache {
fn new(render_device: &RenderDevice) -> Self {
const CAPABILITIES: &[(Features, Capabilities)] = &[
(Features::PUSH_CONSTANTS, Capabilities::PUSH_CONSTANT),
(Features::SHADER_F64, Capabilities::FLOAT64),
(
Features::SHADER_PRIMITIVE_INDEX,
fn new(render_device: &RenderDevice, render_adapter: &RenderAdapter) -> Self {
// TODO: This needs to be kept up to date with the capabilities in the `create_validator` function in wgpu-core
// https://github.com/gfx-rs/wgpu/blob/trunk/wgpu-core/src/device/mod.rs#L449
// We can't use the `wgpu-core` function to detect the device's capabilities because `wgpu-core` isn't included in WebGPU builds.
/// Get the device's capabilities for use in `naga_oil`.
fn get_capabilities(features: Features, downlevel: DownlevelFlags) -> Capabilities {
let mut capabilities = Capabilities::empty();
capabilities.set(
Capabilities::PUSH_CONSTANT,
features.contains(Features::PUSH_CONSTANTS),
);
capabilities.set(
Capabilities::FLOAT64,
features.contains(Features::SHADER_F64),
);
capabilities.set(
Capabilities::PRIMITIVE_INDEX,
),
(
Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING,
features.contains(Features::SHADER_PRIMITIVE_INDEX),
);
capabilities.set(
Capabilities::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING,
),
(
Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING,
Capabilities::SAMPLER_NON_UNIFORM_INDEXING,
),
(
Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING,
features.contains(
Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING,
),
);
capabilities.set(
Capabilities::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING,
),
];
let features = render_device.features();
let mut capabilities = Capabilities::empty();
for (feature, capability) in CAPABILITIES {
if features.contains(*feature) {
capabilities |= *capability;
}
features.contains(
Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING,
),
);
// TODO: This needs a proper wgpu feature
capabilities.set(
Capabilities::SAMPLER_NON_UNIFORM_INDEXING,
features.contains(
Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING,
),
);
capabilities.set(
Capabilities::STORAGE_TEXTURE_16BIT_NORM_FORMATS,
features.contains(Features::TEXTURE_FORMAT_16BIT_NORM),
);
capabilities.set(
Capabilities::MULTIVIEW,
features.contains(Features::MULTIVIEW),
);
capabilities.set(
Capabilities::EARLY_DEPTH_TEST,
features.contains(Features::SHADER_EARLY_DEPTH_TEST),
);
capabilities.set(
Capabilities::SHADER_INT64,
features.contains(Features::SHADER_INT64),
);
capabilities.set(
Capabilities::SHADER_INT64_ATOMIC_MIN_MAX,
features.intersects(
Features::SHADER_INT64_ATOMIC_MIN_MAX | Features::SHADER_INT64_ATOMIC_ALL_OPS,
),
);
capabilities.set(
Capabilities::SHADER_INT64_ATOMIC_ALL_OPS,
features.contains(Features::SHADER_INT64_ATOMIC_ALL_OPS),
);
capabilities.set(
Capabilities::MULTISAMPLED_SHADING,
downlevel.contains(DownlevelFlags::MULTISAMPLED_SHADING),
);
capabilities.set(
Capabilities::DUAL_SOURCE_BLENDING,
features.contains(Features::DUAL_SOURCE_BLENDING),
);
capabilities.set(
Capabilities::CUBE_ARRAY_TEXTURES,
downlevel.contains(DownlevelFlags::CUBE_ARRAY_TEXTURES),
);
capabilities.set(
Capabilities::SUBGROUP,
features.intersects(Features::SUBGROUP | Features::SUBGROUP_VERTEX),
);
capabilities.set(
Capabilities::SUBGROUP_BARRIER,
features.intersects(Features::SUBGROUP_BARRIER),
);
capabilities.set(
Capabilities::SUBGROUP_VERTEX_STAGE,
features.contains(Features::SUBGROUP_VERTEX),
);

capabilities
}

let capabilities = get_capabilities(
render_device.features(),
render_adapter.get_downlevel_capabilities().flags,
);

#[cfg(debug_assertions)]
let composer = naga_oil::compose::Composer::default();
#[cfg(not(debug_assertions))]
let composer = naga_oil::compose::Composer::non_validating();

let composer = composer.with_capabilities(capabilities, ShaderStages::COMPUTE);
let composer = composer.with_capabilities(capabilities);

// let composer = composer.with_capabilities(capabilities, ShaderStages::COMPUTE);

Self {
composer,
Expand Down Expand Up @@ -247,7 +320,7 @@ impl ShaderCache {
return Err(PipelineCacheError::CreateShaderModule(description));
}

entry.insert(ErasedShaderModule::new(shader_module))
entry.insert(Arc::new(WgpuWrapper::new(shader_module)))
}
};

Expand Down Expand Up @@ -337,13 +410,13 @@ impl LayoutCache {
.iter()
.map(|l| l.value())
.collect::<Vec<_>>();
ErasedPipelineLayout::new(render_device.create_pipeline_layout(
Arc::new(WgpuWrapper::new(render_device.create_pipeline_layout(
&PipelineLayoutDescriptor {
bind_group_layouts: &bind_group_layouts,
push_constant_ranges,
..default()
},
))
)))
})
}
}
Expand All @@ -359,9 +432,9 @@ pub struct AppPipelineCache {
}

impl AppPipelineCache {
pub fn new(device: RenderDevice) -> Self {
pub fn new(device: RenderDevice, render_adapter: RenderAdapter) -> Self {
Self {
shader_cache: ShaderCache::new(&device),
shader_cache: ShaderCache::new(&device, &render_adapter),
device,
layout_cache: default(),
waiting_pipelines: default(),
Expand Down Expand Up @@ -460,7 +533,8 @@ impl AppPipelineCache {
label: descriptor.label.as_deref(),
layout,
module: &compute_module,
entry_point: descriptor.entry_point.as_ref(),
entry_point: Some(descriptor.entry_point.as_ref()),
cache: None,
};

let pipeline = self.device.create_compute_pipeline(&descriptor);
Expand Down
Loading

0 comments on commit 7ac8516

Please sign in to comment.