diff --git a/Cargo.toml b/Cargo.toml index 8b070fc..d482503 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,9 +3,6 @@ name = "vidya" version = "0.1.0" edition = "2024" -[patch.crates-io] -bevy = {path = "../bevy"} - [workspace] resolver = "2" @@ -36,7 +33,7 @@ derive_more = { version = "1.0.0", features = ["deref", "debug", "deref_mut"] } tracing = "0.1" tracing-subscriber = {version ="0.3", features = ["env-filter"]} -glam = {version = "0.29.0", features = ["bytemuck"]} +glam = {version = "0.33", features = ["bytemuck"]} rand = "0.9" bitflags = "2.6" thread_local = "1.1.8" @@ -71,23 +68,22 @@ raw-window-handle = "0.6" egui = "0.32" egui_winit_platform = "0.27" -bevy = { version = "0.20.0-dev" } -bevy_app = { version = "0.20.0-dev" } -bevy_asset = { version = "0.20.0-dev" } -bevy_derive = { version = "0.20.0-dev" } -bevy_ecs = { version = "0.20.0-dev" } -bevy_hierarchy = { version = "0.20.0-dev" } -bevy_log = { version = "0.20.0-dev" } -bevy_math = { version = "0.20.0-dev" } -bevy_platform = { version = "0.20.0-dev" } -bevy_reflect = { version = "0.20.0-dev" } -bevy_tasks = { version = "0.20.0-dev" } -bevy_time = { version = "0.20.0-dev" } -bevy_transform = { version = "0.20.0-dev" } -bevy_utils = { version = "0.20.0-dev" } -bevy_window = { version = "0.20.0-dev" } -bevy_winit = { version = "0.20.0-dev" } +bevy = { path = "/var/code/bevy-engine/bevy" } +bevy_app = { path = "/var/code/bevy-engine/bevy/crates/bevy_app" } +bevy_asset = { path = "/var/code/bevy-engine/bevy/crates/bevy_asset" } +bevy_derive = { path = "/var/code/bevy-engine/bevy/crates/bevy_derive" } +bevy_ecs = { path = "/var/code/bevy-engine/bevy/crates/bevy_ecs" } +bevy_log = { path = "/var/code/bevy-engine/bevy/crates/bevy_log" } +bevy_math = { path = "/var/code/bevy-engine/bevy/crates/bevy_math" } +bevy_platform = { path = "/var/code/bevy-engine/bevy/crates/bevy_platform" } +bevy_reflect = { path = "/var/code/bevy-engine/bevy/crates/bevy_reflect" } +bevy_tasks = { path = "/var/code/bevy-engine/bevy/crates/bevy_tasks" } +bevy_time = { path = "/var/code/bevy-engine/bevy/crates/bevy_time" } +bevy_transform = { path = "/var/code/bevy-engine/bevy/crates/bevy_transform" } +bevy_utils = { path = "/var/code/bevy-engine/bevy/crates/bevy_utils" } +bevy_window = { path = "/var/code/bevy-engine/bevy/crates/bevy_window" } +bevy_winit = { path = "/var/code/bevy-engine/bevy/crates/bevy_winit" } [[example]] name = "bevy_integration" -path = "examples/bevy_integration.rs" \ No newline at end of file +path = "examples/bevy_integration.rs" diff --git a/crates/bevy_vulkan_render/src/extract_param.rs b/crates/bevy_vulkan_render/src/extract_param.rs index bd47807..b8c799a 100644 --- a/crates/bevy_vulkan_render/src/extract_param.rs +++ b/crates/bevy_vulkan_render/src/extract_param.rs @@ -2,10 +2,9 @@ use crate::extract_plugin::MainWorld; use bevy_ecs::{ change_detection::Tick, prelude::*, - query::FilteredAccessSet, system::{ - ReadOnlySystemParam, SystemMeta, SystemParam, SystemParamItem, SystemParamValidationError, - SystemState, + ReadOnlySystemParam, SystemAccess, SystemMeta, SystemParam, SystemParamItem, + SystemParamValidationError, SystemState, }, world::unsafe_world_cell::UnsafeWorldCell, }; @@ -83,15 +82,9 @@ where fn init_access( state: &Self::State, system_meta: &mut SystemMeta, - component_access_set: &mut FilteredAccessSet, - world: &mut World, - ) { - Res::::init_access( - &state.main_world_state, - system_meta, - component_access_set, - world, - ); + system_access: &mut SystemAccess, + ) -> Result<(), bevy_ecs::system::SystemParamAccessConflict> { + Res::::init_access(&state.main_world_state, system_meta, system_access) } #[inline] diff --git a/crates/bevy_vulkan_render/src/lib.rs b/crates/bevy_vulkan_render/src/lib.rs index 1f89fd6..0b9d859 100644 --- a/crates/bevy_vulkan_render/src/lib.rs +++ b/crates/bevy_vulkan_render/src/lib.rs @@ -89,6 +89,7 @@ fn mock_render_system() { impl Plugin for RenderPlugin { fn build(&self, app: &mut bevy_app::App) { app.add_plugins(ExtractPlugin::default()); + app.insert_non_send(window::Surfaces::default()); let asset_server = app.world().resource::().clone(); if let Some(render_app) = app.get_sub_app_mut(RenderApp) { @@ -100,18 +101,6 @@ impl Plugin for RenderPlugin { } } -fn init_vulkan(app: &mut App) -> Option<()> { - let device = renderer::device::Device::new_from_default_desc(None, &[]).ok()?; - - let device = RenderDevice { device }; - app.insert_resource(device.clone()); - - let render_app = app.sub_app_mut(RenderApp); - render_app.insert_resource(device.clone()); - - Some(()) -} - /// A "scratch" world used to avoid allocating new worlds every frame when /// swapping out the [`MainWorld`] for [`ExtractSchedule`]. #[derive(Resource, Default)] diff --git a/crates/bevy_vulkan_render/src/sync_world.rs b/crates/bevy_vulkan_render/src/sync_world.rs index 382d9b8..209fb49 100644 --- a/crates/bevy_vulkan_render/src/sync_world.rs +++ b/crates/bevy_vulkan_render/src/sync_world.rs @@ -93,12 +93,12 @@ impl Plugin for SyncWorldPlugin { fn build(&self, app: &mut bevy_app::App) { app.init_resource::(); app.add_observer( - |add: On, mut pending: ResMut| { + |add: On>, mut pending: ResMut| { pending.push(EntityRecord::Added(add.entity)); }, ); app.add_observer( - |remove: On, + |remove: On>, mut pending: ResMut, query: Query<&RenderEntity>| { if let Ok(e) = query.get(remove.entity) { @@ -344,6 +344,13 @@ mod render_entities_world_query_impls { <&RenderEntity as WorldQuery>::update_component_access(&component_id, access); } + fn init_nested_access( + state: &Self::State, + component_access_set: &mut bevy_ecs::query::FilteredAccessSet, + ) -> Result<(), bevy_ecs::query::FilteredAccessSet> { + <&RenderEntity as WorldQuery>::init_nested_access(state, component_access_set) + } + fn init_state(world: &mut World) -> ComponentId { <&RenderEntity as WorldQuery>::init_state(world) } @@ -358,6 +365,10 @@ mod render_entities_world_query_impls { ) -> bool { <&RenderEntity as WorldQuery>::matches_component_set(&state, set_contains_id) } + + fn update_archetypes(state: &mut Self::State, world: UnsafeWorldCell) { + <&RenderEntity as WorldQuery>::update_archetypes(state, world); + } } // SAFETY: Component access of Self::ReadOnly is a subset of Self. @@ -464,6 +475,13 @@ mod render_entities_world_query_impls { <&MainEntity as WorldQuery>::update_component_access(&component_id, access); } + fn init_nested_access( + state: &Self::State, + component_access_set: &mut bevy_ecs::query::FilteredAccessSet, + ) -> Result<(), bevy_ecs::query::FilteredAccessSet> { + <&MainEntity as WorldQuery>::init_nested_access(state, component_access_set) + } + fn init_state(world: &mut World) -> ComponentId { <&MainEntity as WorldQuery>::init_state(world) } @@ -478,6 +496,10 @@ mod render_entities_world_query_impls { ) -> bool { <&MainEntity as WorldQuery>::matches_component_set(&state, set_contains_id) } + + fn update_archetypes(state: &mut Self::State, world: UnsafeWorldCell) { + <&MainEntity as WorldQuery>::update_archetypes(state, world); + } } // SAFETY: Component access of Self::ReadOnly is a subset of Self. @@ -558,12 +580,12 @@ mod tests { main_world.init_resource::(); main_world.add_observer( - |add: On, mut pending: ResMut| { + |add: On>, mut pending: ResMut| { pending.push(EntityRecord::Added(add.entity)); }, ); main_world.add_observer( - |remove: On, + |remove: On>, mut pending: ResMut, query: Query<&RenderEntity>| { if let Ok(e) = query.get(remove.entity) { diff --git a/crates/bevy_vulkan_render/src/window/mod.rs b/crates/bevy_vulkan_render/src/window/mod.rs index 63a074e..0264fae 100644 --- a/crates/bevy_vulkan_render/src/window/mod.rs +++ b/crates/bevy_vulkan_render/src/window/mod.rs @@ -5,9 +5,9 @@ use std::{ use bevy_ecs::{entity::EntityHashMap, prelude::*}; use bevy_window::{PrimaryWindow, RawHandleWrapper, Window, WindowClosing}; -use renderer::{ash::vk, swapchain::WindowSurface}; +use renderer::{ash::vk, swapchain::Surface}; -use crate::{RenderDevice, extract_param::Extract}; +use crate::extract_param::Extract; pub struct ExtractedWindow { pub entity: Entity, @@ -39,7 +39,7 @@ impl DerefMut for ExtractedWindows { } } -#[derive(Default, Resource)] +#[derive(Default)] pub struct Surfaces { surfaces: EntityHashMap, configured: HashSet, @@ -57,11 +57,12 @@ impl Surfaces { } pub struct SurfaceData { - pub surface: WindowSurface, + renderer: renderer::Renderer2, + pub surface: Surface, } impl Deref for SurfaceData { - type Target = WindowSurface; + type Target = Surface; fn deref(&self) -> &Self::Target { &self.surface @@ -74,7 +75,7 @@ pub(crate) fn extract_windows( mut closing: Extract>, windows: Extract)>>, mut removed: Extract>, - mut surfaces: ResMut, + mut surfaces: NonSendMut, ) { for (entity, handle, window, primary) in windows.iter() { if primary.is_some() { @@ -116,7 +117,7 @@ pub(crate) fn extract_windows( pub(crate) fn need_surface_configuration( windows: Res, - surfaces: Res, + surfaces: NonSend, ) -> bool { windows .windows @@ -126,37 +127,43 @@ pub(crate) fn need_surface_configuration( pub(crate) fn configure_surfaces( windows: Res, - mut surfaces: ResMut, - device: Res, + mut surfaces: NonSendMut, ) { for window in windows.windows.values() { - let surface = surfaces.surfaces.entry(window.entity).or_insert_with(|| { + let surface_data = surfaces.surfaces.entry(window.entity).or_insert_with(|| { let (display_handle, window_handle) = ( window.handle.get_display_handle(), window.handle.get_window_handle(), ); - let surface = WindowSurface::new( - (**device).clone(), - vk::Extent2D { - width: window.physical_width, - height: window.physical_height, - }, - window_handle, - display_handle, - ) - .expect("Failed to create window surface"); + let renderer = + renderer::Renderer2::new(display_handle).expect("Failed to create Vulkan renderer"); + let surface = renderer + .create_surface( + window_handle, + vk::Extent2D { + width: window.physical_width, + height: window.physical_height, + }, + ) + .expect("Failed to create window surface"); - SurfaceData { surface } + SurfaceData { renderer, surface } }); if window.size_changed { - surface + surface_data .surface - .recreate_with(Some(vk::Extent2D { - width: window.physical_width, - height: window.physical_height, - })) + .configure( + surface_data.renderer.device(), + renderer::swapchain::SwapchainConfiguration { + extent: vk::Extent2D { + width: window.physical_width, + height: window.physical_height, + }, + ..Default::default() + }, + ) .expect("Failed to recreate surface"); } surfaces.configured.insert(window.entity); diff --git a/crates/renderer/src/lib.rs b/crates/renderer/src/lib.rs index f693353..422e11e 100644 --- a/crates/renderer/src/lib.rs +++ b/crates/renderer/src/lib.rs @@ -2,6 +2,7 @@ negative_impls, map_try_insert, debug_closure_helpers, + core_io, core_io_borrowed_buf, slice_partition_dedup )] diff --git a/crates/renderer/src/render_graph/commands.rs b/crates/renderer/src/render_graph/commands.rs index 1f88b15..6ffd1b5 100644 --- a/crates/renderer/src/render_graph/commands.rs +++ b/crates/renderer/src/render_graph/commands.rs @@ -471,52 +471,6 @@ pub struct RenderAttachment { pub store_op: vk::AttachmentStoreOp, } -impl RenderAttachment { - pub fn side_effect(&self, mut map: SideEffectMap, load: bool) { - for attachment in &self.color_attachments { - // The dependencies declared here need to be barrier'd before and - // after the render pass: the spec says pipelineBarrier inside of a - // render pass instance referencing framebuffer-local stages must - // contain only framebuffer-local stages. - - map.with( - vk::PipelineStageFlags2::COLOR_ATTACHMENT_OUTPUT, - if attachment.load_op == vk::AttachmentLoadOp::LOAD { - vk::AccessFlags2::COLOR_ATTACHMENT_READ - } else { - vk::AccessFlags2::empty() - }, - Some(attachment.layout), - ) - .insert_range(attachment.texture.id(), attachment.region); - } - if let Some(depth) = &self.depth_attachment { - map.with( - vk::PipelineStageFlags2::EARLY_FRAGMENT_TESTS, - if depth.load_op == vk::AttachmentLoadOp::LOAD { - vk::AccessFlags2::DEPTH_STENCIL_ATTACHMENT_READ - } else { - vk::AccessFlags2::empty() - }, - Some(depth.layout), - ) - .insert_range(depth.texture.id(), depth.region); - } - if let Some(stencil) = &self.stencil_attachment { - map.with( - vk::PipelineStageFlags2::EARLY_FRAGMENT_TESTS, - if stencil.load_op == vk::AttachmentLoadOp::LOAD { - vk::AccessFlags2::DEPTH_STENCIL_ATTACHMENT_READ - } else { - vk::AccessFlags2::empty() - }, - Some(stencil.layout), - ) - .insert_range(stencil.texture.id(), stencil.region); - } - } -} - pub struct BeginRendering { pub color_attachments: Vec, pub depth_attachment: Option, @@ -525,21 +479,7 @@ pub struct BeginRendering { pub layers: u32, } -pub struct EndRendering { - pub color_attachments: Vec, - pub depth_attachment: Option, - pub stencil_attachment: Option, -} - -impl BeginRendering { - fn end_rendering(&self) -> EndRendering { - EndRendering { - color_attachments: self.color_attachments.clone(), - depth_attachment: self.depth_attachment.clone(), - stencil_attachment: self.stencil_attachment.clone(), - } - } -} +pub struct EndRendering; impl Command for BeginRendering { fn side_effects(&self, mut map: SideEffectMap) { diff --git a/crates/renderer/src/render_graph/graph_builder.rs b/crates/renderer/src/render_graph/graph_builder.rs index d743b9a..af48359 100644 --- a/crates/renderer/src/render_graph/graph_builder.rs +++ b/crates/renderer/src/render_graph/graph_builder.rs @@ -154,13 +154,17 @@ mod api_demo { let staging_size = vertex_size + index_size + draw_calls_size + textures_indices_size; let mut staging = builder.make_staging_buffer(staging_size as u64); - use core::io::BorrowedBuf; - let mut buf = BorrowedBuf::from(staging.map_mut().unwrap()); - let mut cursor = buf.unfilled(); - cursor.append(bytemuck::cast_slice(&vertices)); - cursor.append(bytemuck::cast_slice(&indices)); - cursor.append(bytemuck::cast_slice(&draw_calls)); - cursor.append(bytemuck::cast_slice(&textures_indices)); + let staging_map = staging.map_mut().unwrap(); + let mut offset = 0; + for data in [ + bytemuck::cast_slice(&vertices), + bytemuck::cast_slice(&indices), + bytemuck::cast_slice(&draw_calls), + bytemuck::cast_slice(&textures_indices), + ] { + staging_map[offset..offset + data.len()].copy_from_slice(data); + offset += data.len(); + } let vertex_buffer = builder.make_buffer( vertex_size as u64, diff --git a/crates/renderer/src/render_graph/recorder.rs b/crates/renderer/src/render_graph/recorder.rs index 4ad4851..e3273ea 100644 --- a/crates/renderer/src/render_graph/recorder.rs +++ b/crates/renderer/src/render_graph/recorder.rs @@ -224,7 +224,7 @@ pub struct RenderPass<'cmd, 'a> { impl<'cmd, 'a> RenderPass<'cmd, 'a> { pub fn finalise(self) { - self.cmd_list.push_inner(super::commands::EndRendering); + self.cmd_list.push_inner(super::commands::EndRendering {}); } pub fn push(&mut self, command: C) { diff --git a/crates/text/src/lib.rs b/crates/text/src/lib.rs index 6e218f1..efc29c8 100644 --- a/crates/text/src/lib.rs +++ b/crates/text/src/lib.rs @@ -24,10 +24,8 @@ mod components { pub struct Text(pub String); } -const ROBOTO_BYTES: &[u8] = - include_bytes!("../../../assets/fonts/Roboto/Roboto-VariableFont_wdth,wght.ttf"); -const NOTO_SANS_HAN_BYTES: &[u8] = - include_bytes!("../../../assets/fonts/Noto_Sans_SC/NotoSansSC-VariableFont_wght.ttf"); +const ROBOTO_BYTES: &[u8] = include_bytes!("../../../assets/fonts/Roboto.ttf"); +const NOTO_SANS_HAN_BYTES: &[u8] = include_bytes!("../../../assets/fonts/NotoSansSC.ttf"); def_monotonic_id!(pub FontId); @@ -42,7 +40,7 @@ impl std::fmt::Debug for FontData { } } -#[derive(Debug, Default)] +#[derive(Debug, Default, TypePath)] struct FontLoader; #[derive(thiserror::Error, Debug)]