Skip to content

Commit

Permalink
feat: storage bindings
Browse files Browse the repository at this point in the history
  • Loading branch information
mosure committed Dec 28, 2024
1 parent c28757c commit 778aa86
Show file tree
Hide file tree
Showing 13 changed files with 328 additions and 130 deletions.
9 changes: 5 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "bevy_interleave"
description = "bevy support for e2e packed to planar bind groups"
version = "0.3.0"
version = "0.4.0"
edition = "2021"
authors = ["mosure <[email protected]>"]
license = "MIT"
Expand Down Expand Up @@ -29,10 +29,11 @@ members = [


[dependencies]
bevy_interleave_interface = { path = "crates/bevy_interleave_interface", version = "0.3" }
bevy_interleave_macros = { path = "crates/bevy_interleave_macros", version = "0.3" }
bytemuck = "1.20"
bevy_interleave_interface = { path = "crates/bevy_interleave_interface", version = "0.4" }
bevy_interleave_macros = { path = "crates/bevy_interleave_macros", version = "0.4" }
bytemuck = "1.21"
serde = "1.0"
wgpu = "23.0.1"

[dependencies.bevy]
version = "0.15"
Expand Down
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
[![GitHub Issues](https://img.shields.io/github/issues/mosure/bevy_interleave)](https://github.com/mosure/bevy_interleave/issues)
[![crates.io](https://img.shields.io/crates/v/bevy_interleave.svg)](https://crates.io/crates/bevy_interleave)

bevy support for e2e packed to planar bind groups
bevy support for e2e packed to planar bind groups (e.g. statically typed meshes)


## minimal example
Expand All @@ -18,7 +18,6 @@ use bevy_interleave::prelude::*;
Planar,
ReflectInterleaved,
StorageBindings,
TextureBindings,
)]
pub struct MyStruct {
#[texture_format(TextureFormat::R32Sint)]
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_interleave_interface/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "bevy_interleave_interface"
version = "0.3.0"
version = "0.4.0"
edition = "2021"
description = "interface for e2e packed to planar bind groups"
homepage = "https://github.com/mosure/bevy_interleave"
Expand Down
39 changes: 25 additions & 14 deletions crates/bevy_interleave_interface/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
pub mod planar;
pub mod storage;
pub mod texture;


pub trait PlanarStorage {
// TODO: this needs to be refactored and better structured
pub trait PlanarHandle<T>
where
Self: bevy::ecs::component::Component,
Self: bevy::render::extract_component::ExtractComponent,
T: bevy::asset::Asset,
{
fn handle(&self) -> &bevy::asset::Handle<T>;
}

pub trait GpuPlanarStorage {
type PackedType;
type PlanarType;
type PlanarTypeHandle: bevy::ecs::component::Component;

fn bind_group(
&self,
Expand All @@ -17,22 +25,23 @@ pub trait PlanarStorage {
render_device: &bevy::render::renderer::RenderDevice,
read_only: bool,
) -> bevy::render::render_resource::BindGroupLayout;

fn prepare(
render_device: &bevy::render::renderer::RenderDevice,
planar: &Self::PlanarType,
) -> Self;
}


pub trait PlanarTextureHandle<T: bevy::asset::Asset>: bevy::ecs::component::Component {
fn handle(&self) -> &bevy::asset::Handle<T>;
pub trait PlanarStorage {
type PackedType; // Self
type PlanarType: bevy::asset::Asset + bevy::reflect::GetTypeRegistration + bevy::reflect::FromReflect;
type PlanarTypeHandle: PlanarHandle<Self::PlanarType>;
type GpuPlanarType: GpuPlanarStorage + bevy::render::render_asset::RenderAsset<SourceAsset = Self::PlanarType>;
}


// TODO: refactor planar texture to be more like planar storage
pub trait PlanarTexture {
type PackedType;
type PackedType; // Self
type PlanarType: bevy::asset::Asset;
type PlanarTypeHandle: PlanarTextureHandle<Self::PlanarType>;
type PlanarTypeHandle: PlanarHandle<Self::PlanarType>;

// note: planar texture's gpu type utilizes bevy's image render asset

fn bind_group(
&self,
Expand Down Expand Up @@ -72,4 +81,6 @@ pub trait Planar {
fn to_interleaved(&self) -> Vec<Self::PackedType>;

fn from_interleaved(packed: Vec<Self::PackedType>) -> Self where Self: Sized;

fn subset(&self, indices: &[usize]) -> Self;
}
31 changes: 0 additions & 31 deletions crates/bevy_interleave_interface/src/planar.rs

This file was deleted.

135 changes: 135 additions & 0 deletions crates/bevy_interleave_interface/src/storage.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
use std::marker::PhantomData;

use bevy::{
prelude::*,
reflect::GetTypeRegistration,
render::extract_component::ExtractComponentPlugin,
};

use crate::{
GpuPlanarStorage,
PlanarHandle,
PlanarStorage,
};


pub struct PlanarStoragePlugin<R> {
phantom: PhantomData<fn() -> R>,
}
impl<R> Default for PlanarStoragePlugin<R> {
fn default() -> Self {
Self {
phantom: PhantomData,
}
}
}

impl<R: 'static> Plugin for PlanarStoragePlugin<R>
where
R: PlanarStorage + Default + GetTypeRegistration + Clone + Reflect,
{
fn build(&self, app: &mut App) {
app.register_type::<R>();

app.register_type::<R::PlanarType>();
app.init_asset::<R::PlanarType>();
app.register_asset_reflect::<R::PlanarType>();

app.add_plugins(bevy::render::render_asset::RenderAssetPlugin::<R::GpuPlanarType>::default());
app.add_plugins(ExtractComponentPlugin::<R::PlanarTypeHandle>::default());

let render_app = app.sub_app_mut(bevy::render::RenderApp);
render_app.add_systems(
bevy::render::Render,
queue_gpu_storage_buffers::<R>.in_set(bevy::render::RenderSet::PrepareBindGroups),
);
}

fn finish(&self, app: &mut App) {
if let Some(render_app) = app.get_sub_app_mut(bevy::render::RenderApp) {
render_app.init_resource::<PlanarStorageLayouts::<R>>();
}
}
}


#[derive(bevy::prelude::Resource)]
pub struct PlanarStorageLayouts<R: PlanarStorage> {
pub bind_group_layout: bevy::render::render_resource::BindGroupLayout,
pub phantom: PhantomData<fn() -> R>,
}

impl<R: PlanarStorage>
FromWorld for PlanarStorageLayouts<R> {
fn from_world(world: &mut World) -> Self {
let render_device = world.resource::<bevy::render::renderer::RenderDevice>();

let read_only = true;
let bind_group_layout = R::GpuPlanarType::bind_group_layout(
render_device,
read_only,
);

Self {
bind_group_layout,
phantom: PhantomData,
}
}
}

#[derive(bevy::prelude::Component, Clone, Debug)]
pub struct PlanarStorageBindGroup<R: PlanarStorage> {
pub bind_group: bevy::render::render_resource::BindGroup,
pub phantom: PhantomData<fn() -> R>,
}


fn queue_gpu_storage_buffers<R>(
mut commands: Commands,
asset_server: Res<AssetServer>,
render_device: ResMut<bevy::render::renderer::RenderDevice>,
gpu_planars: Res<bevy::render::render_asset::RenderAssets<R::GpuPlanarType>>,
bind_group_layout: Res<PlanarStorageLayouts<R>>,
clouds: Query<
(
Entity,
&R::PlanarTypeHandle,
),
Without<PlanarStorageBindGroup::<R>>,
>,
)
where
R: PlanarStorage + Default + Clone + Reflect,
R::PlanarType: Asset,
{
let layout = &bind_group_layout.bind_group_layout;

info!("queue_gpu_storage_buffers");

for (entity, planar_handle,) in clouds.iter() {
info!("handle {:?}", planar_handle.handle());

if let Some(load_state) = asset_server.get_load_state(planar_handle.handle()) {
if load_state.is_loading() {
info!("loading");
continue;
}
}

if gpu_planars.get(planar_handle.handle()).is_none() {
info!("no gpu planar");
continue;
}

let gpu_planar: &<R as PlanarStorage>::GpuPlanarType = gpu_planars.get(planar_handle.handle()).unwrap();
let bind_group = gpu_planar.bind_group(
&render_device,
layout,
);

commands.entity(entity).insert(PlanarStorageBindGroup::<R> {
bind_group,
phantom: PhantomData,
});
}
}
3 changes: 2 additions & 1 deletion crates/bevy_interleave_interface/src/texture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ use bevy::{
};

use crate::{
PlanarHandle,
PlanarTexture,
PlanarTextureHandle,
};


Expand Down Expand Up @@ -75,6 +75,7 @@ FromWorld for PlanarTextureLayouts<R> {
}
}


fn prepare_textures<R>(
mut commands: Commands,
asset_server: Res<AssetServer>,
Expand Down
5 changes: 3 additions & 2 deletions crates/bevy_interleave_macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "bevy_interleave_macros"
version = "0.3.0"
version = "0.4.0"
edition = "2021"
description = "macros for e2e packed to planar bind groups"
homepage = "https://github.com/mosure/bevy_interleave"
Expand All @@ -13,13 +13,14 @@ keywords = [


[dependencies]
bevy_interleave_interface = { path = "../bevy_interleave_interface", version = "0.3.0" }
bevy_interleave_interface = { path = "../bevy_interleave_interface", version = "0.4.0" }
bytemuck = "1.14"
convert_case = "0.6"
proc-macro2 = "1.0"
quote = "1.0"
sha1 = "0.10"
syn = "2.0"
wgpu = "23.0.1"

[dependencies.bevy]
version = "0.15"
Expand Down
Loading

0 comments on commit 778aa86

Please sign in to comment.