From 0ee29a3649c507f451ae7f63e06deacc67664c91 Mon Sep 17 00:00:00 2001 From: Florian RICHER Date: Sun, 18 May 2025 18:02:54 +0200 Subject: [PATCH] render_plugin: Add first SubApp and default schedules --- Cargo.lock | 11 +++- Cargo.toml | 2 + crates/engine_render/Cargo.toml | 9 +++ crates/engine_render/src/lib.rs | 65 ++++++++++++++++++ crates/engine_vulkan/src/vulkan_context.rs | 76 ++++++++++++++++++++++ crates/engine_window/Cargo.toml | 1 - src/game/mod.rs | 2 + 7 files changed, 164 insertions(+), 2 deletions(-) create mode 100644 crates/engine_render/Cargo.toml create mode 100644 crates/engine_render/src/lib.rs create mode 100644 crates/engine_vulkan/src/vulkan_context.rs diff --git a/Cargo.lock b/Cargo.lock index d2dda1a..6467d38 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -670,6 +670,15 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" +[[package]] +name = "engine_render" +version = "0.1.0" +dependencies = [ + "bevy_app", + "bevy_ecs", + "log", +] + [[package]] name = "engine_vulkan" version = "0.1.0" @@ -690,7 +699,6 @@ version = "0.1.0" dependencies = [ "bevy_app", "bevy_ecs", - "env_logger", "log", "thiserror 2.0.12", "winit", @@ -1643,6 +1651,7 @@ version = "0.1.0" dependencies = [ "bevy_app", "bevy_ecs", + "engine_render", "engine_vulkan", "engine_window", "env_logger", diff --git a/Cargo.toml b/Cargo.toml index c5f1546..d8c8792 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,6 +30,7 @@ env_logger = "0.11" engine_vulkan = { path = "crates/engine_vulkan" } engine_window = { path = "crates/engine_window" } +engine_render = { path = "crates/engine_render" } [dependencies] log = { workspace = true } @@ -43,3 +44,4 @@ glam = { workspace = true } engine_vulkan = { workspace = true } engine_window = { workspace = true } +engine_render = { workspace = true } diff --git a/crates/engine_render/Cargo.toml b/crates/engine_render/Cargo.toml new file mode 100644 index 0000000..bd283f0 --- /dev/null +++ b/crates/engine_render/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "engine_render" +version = "0.1.0" +edition = "2024" + +[dependencies] +log = { workspace = true } +bevy_app = { workspace = true } +bevy_ecs = { workspace = true } diff --git a/crates/engine_render/src/lib.rs b/crates/engine_render/src/lib.rs new file mode 100644 index 0000000..febefbf --- /dev/null +++ b/crates/engine_render/src/lib.rs @@ -0,0 +1,65 @@ +use bevy_app::{App, AppLabel, Last, Plugin, SubApp}; +use bevy_ecs::{ + schedule::{IntoScheduleConfigs, Schedule, ScheduleLabel, SystemSet}, + system::Commands, +}; + +#[derive(Debug, Hash, PartialEq, Eq, Clone, SystemSet)] +pub enum RenderSystems { + Prepare, + Queue, + Render, + Present, +} + +#[derive(ScheduleLabel, Debug, Hash, PartialEq, Eq, Clone, Default)] +pub struct Render; + +impl Render { + pub fn base_schedule() -> Schedule { + use RenderSystems::*; + + let mut schedule = Schedule::new(Self); + + schedule.configure_sets((Prepare, Queue, Render, Present).chain()); + + schedule + } +} + +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, AppLabel)] +pub struct RenderApp; + +pub struct RenderPlugin; + +impl Plugin for RenderPlugin { + fn build(&self, app: &mut App) { + let mut render_app = SubApp::new(); + render_app.update_schedule = Some(Render.intern()); + + render_app.add_schedule(Render::base_schedule()); + + render_app.add_systems(Render, test_prepare.in_set(RenderSystems::Prepare)); + render_app.add_systems(Render, test_queue.in_set(RenderSystems::Queue)); + render_app.add_systems(Render, test_render.in_set(RenderSystems::Render)); + render_app.add_systems(Render, test_present.in_set(RenderSystems::Present)); + + app.insert_sub_app(RenderApp, render_app); + } +} + +fn test_prepare(mut commands: Commands) { + log::info!("test_prepare"); +} + +fn test_queue(mut commands: Commands) { + log::info!("test_queue"); +} + +fn test_render(mut commands: Commands) { + log::info!("test_render"); +} + +fn test_present(mut commands: Commands) { + log::info!("test_present"); +} diff --git a/crates/engine_vulkan/src/vulkan_context.rs b/crates/engine_vulkan/src/vulkan_context.rs new file mode 100644 index 0000000..08ff1ac --- /dev/null +++ b/crates/engine_vulkan/src/vulkan_context.rs @@ -0,0 +1,76 @@ +use std::{any::Any, sync::Arc}; + +use bevy_app::App; +use bevy_ecs::resource::Resource; +use engine_window::raw_handle::DisplayHandleWrapper; +use vulkano::{ + command_buffer::{ + AutoCommandBufferBuilder, CommandBufferUsage, PrimaryAutoCommandBuffer, + allocator::StandardCommandBufferAllocator, + }, + descriptor_set::allocator::StandardDescriptorSetAllocator, + device::{Device, Queue}, + instance::Instance, + memory::allocator::StandardMemoryAllocator, + swapchain::Surface, +}; +use winit::raw_window_handle::{HasDisplayHandle, HasWindowHandle}; + +use super::utils; + +#[derive(Resource)] +pub struct VulkanContext { + pub instance: Arc, + pub device: Arc, + pub graphics_queue: Arc, + + pub memory_allocator: Arc, + pub command_buffer_allocator: Arc, + pub descriptor_set_allocator: Arc, +} + +impl VulkanContext { + pub fn create_surface( + &self, + window: Arc, + ) -> Arc { + Surface::from_window(self.instance.clone(), window).unwrap() + } + + pub fn create_render_builder(&self) -> AutoCommandBufferBuilder { + AutoCommandBufferBuilder::primary( + self.command_buffer_allocator.clone(), + self.graphics_queue.queue_family_index(), + CommandBufferUsage::OneTimeSubmit, + ) + .unwrap() + } +} + +impl From<&App> for VulkanContext { + fn from(app: &App) -> Self { + let (device, mut queues) = utils::pick_graphics_device(&instance, &display_handle.0); + let graphics_queue = queues.next().unwrap(); + + let memory_allocator = Arc::new(StandardMemoryAllocator::new_default(device.clone())); + + let command_buffer_allocator = Arc::new(StandardCommandBufferAllocator::new( + device.clone(), + Default::default(), + )); + + let descriptor_set_allocator = Arc::new(StandardDescriptorSetAllocator::new( + device.clone(), + Default::default(), + )); + + Self { + instance: instance.clone(), + device, + graphics_queue, + memory_allocator, + command_buffer_allocator, + descriptor_set_allocator, + } + } +} diff --git a/crates/engine_window/Cargo.toml b/crates/engine_window/Cargo.toml index dc19716..b5016cc 100644 --- a/crates/engine_window/Cargo.toml +++ b/crates/engine_window/Cargo.toml @@ -6,7 +6,6 @@ edition = "2024" [dependencies] thiserror = { workspace = true } log = { workspace = true } -env_logger = { workspace = true } bevy_app = { workspace = true } bevy_ecs = { workspace = true } winit = { workspace = true } diff --git a/src/game/mod.rs b/src/game/mod.rs index 2c30bf8..ff3df3c 100644 --- a/src/game/mod.rs +++ b/src/game/mod.rs @@ -1,4 +1,5 @@ use bevy_app::App; +use engine_render::RenderPlugin; use engine_vulkan::{VulkanConfig, VulkanPlugin}; use engine_window::{WindowPlugin, config::WindowConfig}; use vulkano::device::{DeviceExtensions, DeviceFeatures}; @@ -30,6 +31,7 @@ pub fn init(app: &mut App) { app.add_plugins(( WindowPlugin { window_config }, VulkanPlugin { vulkan_config }, + RenderPlugin, )); // Window::new(app, window_config).unwrap(); // Vulkan::new(app).unwrap();