From 9bc9c8d481dea04951d2b73023e3349d5b071da9 Mon Sep 17 00:00:00 2001 From: Florian RICHER Date: Sun, 25 May 2025 18:39:24 +0200 Subject: [PATCH] new_repo: Split ECS pattern with "standard pattern" --- src/core/camera/mod.rs | 19 -- src/core/mod.rs | 2 - src/core/render/material.rs | 7 - src/core/render/mesh.rs | 14 -- src/core/render/mod.rs | 3 - src/core/render/vertex.rs | 38 ---- src/main.rs | 22 --- src/old_app/app.rs | 178 ----------------- src/old_app/mod.rs | 5 - src/old_app/pipelines/mod.rs | 1 - src/old_app/pipelines/triangle_pipeline.rs | 111 ----------- src/old_app/scene.rs | 175 ----------------- src/old_app/vulkan_context.rs | 213 --------------------- src/old_app/window_render_context.rs | 102 ---------- 14 files changed, 890 deletions(-) delete mode 100644 src/core/camera/mod.rs delete mode 100644 src/core/mod.rs delete mode 100644 src/core/render/material.rs delete mode 100644 src/core/render/mesh.rs delete mode 100644 src/core/render/mod.rs delete mode 100644 src/core/render/vertex.rs delete mode 100644 src/old_app/app.rs delete mode 100644 src/old_app/mod.rs delete mode 100644 src/old_app/pipelines/mod.rs delete mode 100644 src/old_app/pipelines/triangle_pipeline.rs delete mode 100644 src/old_app/scene.rs delete mode 100644 src/old_app/vulkan_context.rs delete mode 100644 src/old_app/window_render_context.rs diff --git a/src/core/camera/mod.rs b/src/core/camera/mod.rs deleted file mode 100644 index f9b6925..0000000 --- a/src/core/camera/mod.rs +++ /dev/null @@ -1,19 +0,0 @@ -use bevy_ecs::component::Component; -use glam::{Mat4, Quat, Vec3}; - -pub trait Camera: Into + Component {} - -#[derive(Component)] -pub struct Camera3D { - pub projection: Mat4, - pub position: Vec3, - pub rotation: Quat, -} - -impl Into for Camera3D { - fn into(self) -> Mat4 { - Mat4::from_rotation_translation(self.rotation, self.position) * self.projection - } -} - -impl Camera for Camera3D {} diff --git a/src/core/mod.rs b/src/core/mod.rs deleted file mode 100644 index a8707c6..0000000 --- a/src/core/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod camera; -pub mod render; diff --git a/src/core/render/material.rs b/src/core/render/material.rs deleted file mode 100644 index 539d4bc..0000000 --- a/src/core/render/material.rs +++ /dev/null @@ -1,7 +0,0 @@ -use std::sync::Arc; - -use bevy_ecs::component::Component; -use vulkano::pipeline::GraphicsPipeline; - -#[derive(Component)] -pub struct Material(pub Arc); diff --git a/src/core/render/mesh.rs b/src/core/render/mesh.rs deleted file mode 100644 index ca5ec0f..0000000 --- a/src/core/render/mesh.rs +++ /dev/null @@ -1,14 +0,0 @@ -use bevy_ecs::component::Component; - -use super::vertex::Vertex2D; - -#[derive(Component)] -pub struct Mesh2D { - pub vertices: Vec, -} - -impl Mesh2D { - pub fn new(vertices: Vec) -> Self { - Self { vertices } - } -} diff --git a/src/core/render/mod.rs b/src/core/render/mod.rs deleted file mode 100644 index 5d003a8..0000000 --- a/src/core/render/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod material; -pub mod mesh; -pub mod vertex; diff --git a/src/core/render/vertex.rs b/src/core/render/vertex.rs deleted file mode 100644 index 9bf133e..0000000 --- a/src/core/render/vertex.rs +++ /dev/null @@ -1,38 +0,0 @@ -use std::sync::Arc; -use vulkano::Validated; -use vulkano::buffer::{ - AllocateBufferError, Buffer, BufferContents, BufferCreateInfo, BufferUsage, Subbuffer, -}; -use vulkano::memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}; -use vulkano::pipeline::graphics::vertex_input::Vertex; - -#[derive(BufferContents, Vertex)] -#[repr(C)] -pub struct Vertex2D { - #[format(R32G32_SFLOAT)] - pub position: [f32; 2], - - #[format(R32G32B32_SFLOAT)] - pub color: [f32; 3], -} - -impl Vertex2D { - pub fn create_buffer( - vertices: Vec, - memory_allocator: &Arc, - ) -> Result, Validated> { - Buffer::from_iter( - memory_allocator.clone(), - BufferCreateInfo { - usage: BufferUsage::VERTEX_BUFFER, - ..Default::default() - }, - AllocationCreateInfo { - memory_type_filter: MemoryTypeFilter::PREFER_DEVICE - | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, - ..Default::default() - }, - vertices, - ) - } -} diff --git a/src/main.rs b/src/main.rs index 34fad4b..b74f7c5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,18 +2,11 @@ use winit::event_loop::{ControlFlow, EventLoop}; use bevy_app::{App, AppExit}; -pub mod core; pub mod game; -pub mod old_app; fn main() { env_logger::init(); - run_new_app(); - // run_old_app(); -} - -fn run_new_app() { let mut app = App::default(); game::init(&mut app); match app.run() { @@ -23,18 +16,3 @@ fn run_new_app() { } } } - -fn run_old_app() { - let event_loop = EventLoop::new().unwrap(); - event_loop.set_control_flow(ControlFlow::Poll); - - let vulkan_context = old_app::vulkan_context::VulkanContext::from(&event_loop); - let mut app = old_app::app::App::from(vulkan_context); - - match event_loop.run_app(&mut app) { - Ok(_) => {} - Err(e) => { - log::error!("Error running old app: {e}"); - } - } -} diff --git a/src/old_app/app.rs b/src/old_app/app.rs deleted file mode 100644 index cfcf038..0000000 --- a/src/old_app/app.rs +++ /dev/null @@ -1,178 +0,0 @@ -use crate::old_app::scene::Scene; -use crate::old_app::vulkan_context::VulkanContext; -use crate::old_app::window_render_context::WindowRenderContext; -use std::sync::Arc; -use vulkano::command_buffer::{RenderingAttachmentInfo, RenderingInfo}; -use vulkano::render_pass::{AttachmentLoadOp, AttachmentStoreOp}; -use vulkano::swapchain::{SwapchainPresentInfo, acquire_next_image}; -use vulkano::sync::GpuFuture; -use vulkano::{Validated, VulkanError, sync}; -use winit::application::ApplicationHandler; -use winit::event::WindowEvent; -use winit::event_loop::ActiveEventLoop; -use winit::window::WindowId; - -pub struct App { - vulkan_context: VulkanContext, - window_render_context: Option, - scene: Option, -} - -impl From for App { - fn from(vulkan_context: VulkanContext) -> Self { - Self { - vulkan_context, - window_render_context: None, - scene: None, - } - } -} - -impl ApplicationHandler for App { - fn resumed(&mut self, event_loop: &ActiveEventLoop) { - let window_attributes = winit::window::Window::default_attributes() - .with_title("Rust ASH Test") - .with_inner_size(winit::dpi::PhysicalSize::new( - f64::from(800), - f64::from(600), - )); - - let window = Arc::new(event_loop.create_window(window_attributes).unwrap()); - - let surface = self.vulkan_context.create_surface(window.clone()); - - self.window_render_context = Some(WindowRenderContext::new( - window, - surface, - &self.vulkan_context.device, - )); - self.scene = Some( - Scene::load( - &self.vulkan_context, - self.window_render_context.as_ref().unwrap(), - ) - .unwrap(), - ); - } - - fn window_event(&mut self, event_loop: &ActiveEventLoop, _id: WindowId, event: WindowEvent) { - match event { - WindowEvent::CloseRequested => { - log::debug!("The close button was pressed; stopping"); - event_loop.exit(); - } - WindowEvent::Resized(_) => { - let rcx = self.window_render_context.as_mut().unwrap(); - rcx.recreate_swapchain = true; - } - WindowEvent::RedrawRequested => { - let (image_index, acquire_future) = { - let rcx = self.window_render_context.as_mut().unwrap(); - let window_size = rcx.window.inner_size(); - - if window_size.width == 0 || window_size.height == 0 { - return; - } - - rcx.previous_frame_end.as_mut().unwrap().cleanup_finished(); - rcx.update_swapchain().unwrap(); - - let (image_index, suboptimal, acquire_future) = - match acquire_next_image(rcx.swapchain.clone(), None) - .map_err(Validated::unwrap) - { - Ok(r) => r, - Err(VulkanError::OutOfDate) => { - rcx.recreate_swapchain = true; - return; - } - Err(e) => panic!("failed to acquire next image: {e}"), - }; - - if suboptimal { - rcx.recreate_swapchain = true; - } - - (image_index, acquire_future) - }; - - let mut builder = self.vulkan_context.create_render_builder(); - - { - let rcx = self.window_render_context.as_ref().unwrap(); - builder - .begin_rendering(RenderingInfo { - color_attachments: vec![Some(RenderingAttachmentInfo { - load_op: AttachmentLoadOp::Clear, - store_op: AttachmentStoreOp::Store, - clear_value: Some([0.0, 0.0, 0.0, 1.0].into()), - ..RenderingAttachmentInfo::image_view( - rcx.attachment_image_views[image_index as usize].clone(), - ) - })], - ..Default::default() - }) - .unwrap() - .set_viewport(0, [rcx.viewport.clone()].into_iter().collect()) - .unwrap(); - } - - if let Some(scene) = self.scene.as_ref() { - scene - .render( - &self.vulkan_context, - &self.window_render_context.as_ref().unwrap(), - &mut builder, - ) - .unwrap(); - } - - builder.end_rendering().unwrap(); - - let command_buffer = builder.build().unwrap(); - - { - let rcx = self.window_render_context.as_mut().unwrap(); - - let future = rcx - .previous_frame_end - .take() - .unwrap() - .join(acquire_future) - .then_execute(self.vulkan_context.graphics_queue.clone(), command_buffer) - .unwrap() - .then_swapchain_present( - self.vulkan_context.graphics_queue.clone(), - SwapchainPresentInfo::swapchain_image_index( - rcx.swapchain.clone(), - image_index, - ), - ) - .then_signal_fence_and_flush(); - - match future.map_err(Validated::unwrap) { - Ok(future) => { - rcx.previous_frame_end = Some(future.boxed()); - } - Err(VulkanError::OutOfDate) => { - rcx.recreate_swapchain = true; - rcx.previous_frame_end = - Some(sync::now(self.vulkan_context.device.clone()).boxed()); - } - Err(e) => { - println!("failed to flush future: {e}"); - rcx.previous_frame_end = - Some(sync::now(self.vulkan_context.device.clone()).boxed()); - } - } - } - } - _ => {} - } - } - - fn about_to_wait(&mut self, _event_loop: &ActiveEventLoop) { - let rcx = self.window_render_context.as_mut().unwrap(); - rcx.window.request_redraw(); - } -} diff --git a/src/old_app/mod.rs b/src/old_app/mod.rs deleted file mode 100644 index 9fce0a9..0000000 --- a/src/old_app/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub mod app; -pub mod pipelines; -pub mod scene; -pub mod vulkan_context; -pub mod window_render_context; diff --git a/src/old_app/pipelines/mod.rs b/src/old_app/pipelines/mod.rs deleted file mode 100644 index e5f30a7..0000000 --- a/src/old_app/pipelines/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod triangle_pipeline; diff --git a/src/old_app/pipelines/triangle_pipeline.rs b/src/old_app/pipelines/triangle_pipeline.rs deleted file mode 100644 index e573747..0000000 --- a/src/old_app/pipelines/triangle_pipeline.rs +++ /dev/null @@ -1,111 +0,0 @@ -use std::collections::BTreeMap; -use std::error::Error; -use std::sync::Arc; -use vulkano::descriptor_set::layout::{ - DescriptorSetLayoutBinding, DescriptorSetLayoutCreateInfo, DescriptorType, -}; -use vulkano::device::Device; -use vulkano::pipeline::graphics::GraphicsPipelineCreateInfo; -use vulkano::pipeline::graphics::color_blend::{ColorBlendAttachmentState, ColorBlendState}; -use vulkano::pipeline::graphics::input_assembly::InputAssemblyState; -use vulkano::pipeline::graphics::multisample::MultisampleState; -use vulkano::pipeline::graphics::rasterization::RasterizationState; -use vulkano::pipeline::graphics::subpass::PipelineRenderingCreateInfo; -use vulkano::pipeline::graphics::vertex_input::{Vertex, VertexDefinition}; -use vulkano::pipeline::graphics::viewport::ViewportState; -use vulkano::pipeline::layout::{PipelineDescriptorSetLayoutCreateInfo, PipelineLayoutCreateFlags}; -use vulkano::pipeline::{ - DynamicState, GraphicsPipeline, PipelineLayout, PipelineShaderStageCreateInfo, -}; -use vulkano::shader::{EntryPoint, ShaderStages}; -use vulkano::swapchain::Swapchain; - -use crate::core::render::vertex::Vertex2D; - -pub mod shaders { - pub mod vs { - vulkano_shaders::shader! { - ty: "vertex", - path: r"res/shaders/vertex.vert", - } - } - - pub mod fs { - vulkano_shaders::shader! { - ty: "fragment", - path: r"res/shaders/vertex.frag", - } - } -} - -pub fn create_triangle_pipeline( - device: &Arc, - swapchain: &Arc, -) -> Result, Box> { - let (vs, fs) = load_shaders(device)?; - let vertex_input_state = Vertex2D::per_vertex().definition(&vs)?; - - let stages = [ - PipelineShaderStageCreateInfo::new(vs), - PipelineShaderStageCreateInfo::new(fs), - ]; - - let mut bindings = BTreeMap::::new(); - let mut descriptor_set_layout_binding = - DescriptorSetLayoutBinding::descriptor_type(DescriptorType::UniformBuffer); - descriptor_set_layout_binding.stages = ShaderStages::VERTEX; - bindings.insert(0, descriptor_set_layout_binding); - - let descriptor_set_layout = DescriptorSetLayoutCreateInfo { - bindings, - ..Default::default() - }; - - let create_info = PipelineDescriptorSetLayoutCreateInfo { - set_layouts: vec![descriptor_set_layout], - flags: PipelineLayoutCreateFlags::default(), - push_constant_ranges: vec![], - } - .into_pipeline_layout_create_info(device.clone())?; - - let layout = PipelineLayout::new(device.clone(), create_info)?; - - let subpass = PipelineRenderingCreateInfo { - color_attachment_formats: vec![Some(swapchain.image_format())], - ..Default::default() - }; - - let pipeline = GraphicsPipeline::new( - device.clone(), - None, - GraphicsPipelineCreateInfo { - stages: stages.into_iter().collect(), - vertex_input_state: Some(vertex_input_state), - input_assembly_state: Some(InputAssemblyState::default()), - viewport_state: Some(ViewportState::default()), - rasterization_state: Some(RasterizationState::default()), - multisample_state: Some(MultisampleState::default()), - color_blend_state: Some(ColorBlendState::with_attachment_states( - subpass.color_attachment_formats.len() as u32, - ColorBlendAttachmentState::default(), - )), - dynamic_state: [DynamicState::Viewport].into_iter().collect(), - subpass: Some(subpass.into()), - ..GraphicsPipelineCreateInfo::layout(layout) - }, - )?; - - Ok(pipeline) -} - -fn load_shaders(device: &Arc) -> Result<(EntryPoint, EntryPoint), Box> { - let vs = shaders::vs::load(device.clone())? - .entry_point("main") - .ok_or("Failed find main entry point of vertex shader".to_string())?; - - let fs = shaders::fs::load(device.clone())? - .entry_point("main") - .ok_or("Failed find main entry point of fragment shader".to_string())?; - - Ok((vs, fs)) -} diff --git a/src/old_app/scene.rs b/src/old_app/scene.rs deleted file mode 100644 index 72e3f48..0000000 --- a/src/old_app/scene.rs +++ /dev/null @@ -1,175 +0,0 @@ -use crate::old_app::pipelines::triangle_pipeline::shaders::vs; -use glam::{Mat3, Mat4, Vec3}; -use std::error::Error; -use std::sync::Arc; -use std::time::Instant; -use vulkano::buffer::{Buffer, BufferCreateInfo, BufferUsage, Subbuffer}; -use vulkano::command_buffer::{AutoCommandBufferBuilder, PrimaryAutoCommandBuffer}; -use vulkano::descriptor_set::{DescriptorSet, WriteDescriptorSet}; -use vulkano::memory::allocator::{AllocationCreateInfo, MemoryTypeFilter}; -use vulkano::pipeline::{GraphicsPipeline, Pipeline, PipelineBindPoint}; - -use crate::core::render::vertex::Vertex2D; -use crate::old_app::pipelines::triangle_pipeline::create_triangle_pipeline; - -use super::vulkan_context::VulkanContext; -use super::window_render_context::WindowRenderContext; - -const VERTICES: [Vertex2D; 12] = [ - // Triangle en haut à gauche - Vertex2D { - position: [-0.5, -0.75], - color: [1.0, 0.0, 0.0], - }, - Vertex2D { - position: [-0.75, -0.25], - color: [0.0, 1.0, 0.0], - }, - Vertex2D { - position: [-0.25, -0.25], - color: [0.0, 0.0, 1.0], - }, - // Triangle en bas à gauche - Vertex2D { - position: [-0.5, 0.25], - color: [0.5, 0.5, 0.5], - }, - Vertex2D { - position: [-0.75, 0.75], - color: [0.2, 0.8, 0.2], - }, - Vertex2D { - position: [-0.25, 0.75], - color: [0.8, 0.2, 0.2], - }, - // Triangle en haut à droite - Vertex2D { - position: [0.5, -0.75], - color: [1.0, 1.0, 0.0], - }, - Vertex2D { - position: [0.25, -0.25], - color: [0.0, 1.0, 1.0], - }, - Vertex2D { - position: [0.75, -0.25], - color: [1.0, 0.0, 1.0], - }, - // Triangle en bas à droite - Vertex2D { - position: [0.5, 0.25], - color: [0.1, 0.5, 0.8], - }, - Vertex2D { - position: [0.25, 0.75], - color: [0.8, 0.6, 0.1], - }, - Vertex2D { - position: [0.75, 0.75], - color: [0.3, 0.4, 0.6], - }, -]; - -pub struct Scene { - pipeline: Arc, - vertex_buffer: Subbuffer<[Vertex2D]>, - - rotation_start: Instant, -} - -impl Scene { - pub fn load( - vulkan_context: &VulkanContext, - window_render_context: &WindowRenderContext, - ) -> Result> { - let pipeline = - create_triangle_pipeline(&vulkan_context.device, &window_render_context.swapchain)?; - let vertex_buffer = - Vertex2D::create_buffer(Vec::from_iter(VERTICES), &vulkan_context.memory_allocator)?; - - Ok(Scene { - pipeline, - vertex_buffer, - rotation_start: Instant::now(), - }) - } - - pub fn render( - &self, - vulkan_context: &VulkanContext, - window_render_context: &WindowRenderContext, - builder: &mut AutoCommandBufferBuilder, - ) -> Result<(), Box> { - let vertex_count = self.vertex_buffer.len() as u32; - let instance_count = vertex_count / 3; - - let uniform_buffer = self.get_uniform_buffer(vulkan_context, window_render_context); - let layout = &self.pipeline.layout().set_layouts()[0]; - let descriptor_set = DescriptorSet::new( - vulkan_context.descriptor_set_allocator.clone(), - layout.clone(), - [WriteDescriptorSet::buffer(0, uniform_buffer)], - [], - ) - .unwrap(); - - unsafe { - builder - .bind_pipeline_graphics(self.pipeline.clone())? - .bind_descriptor_sets( - PipelineBindPoint::Graphics, - self.pipeline.layout().clone(), - 0, - descriptor_set, - )? - .bind_vertex_buffers(0, self.vertex_buffer.clone())? - .draw(vertex_count, instance_count, 0, 0)?; - } - - Ok(()) - } - - fn get_uniform_buffer( - &self, - vulkan_context: &VulkanContext, - window_render_context: &WindowRenderContext, - ) -> Subbuffer { - let swapchain = &window_render_context.swapchain; - let elapsed = self.rotation_start.elapsed(); - let rotation = elapsed.as_secs() as f64 + elapsed.subsec_nanos() as f64 / 1_000_000_000.0; - let rotation = Mat3::from_rotation_y(rotation as f32); - - // NOTE: This teapot was meant for OpenGL where the origin is at the lower left - // instead the origin is at the upper left in Vulkan, so we reverse the Y axis. - let aspect_ratio = swapchain.image_extent()[0] as f32 / swapchain.image_extent()[1] as f32; - - let proj = Mat4::perspective_rh_gl(std::f32::consts::FRAC_PI_2, aspect_ratio, 0.01, 100.0); - let view = Mat4::look_at_rh( - Vec3::new(0.3, 0.3, 1.0), - Vec3::new(0.0, 0.0, 0.0), - Vec3::new(0.0, -1.0, 0.0), - ); - let scale = Mat4::from_scale(Vec3::splat(1.0)); - - let uniform_data = vs::MVPData { - world: Mat4::from_mat3(rotation).to_cols_array_2d(), - view: (view * scale).to_cols_array_2d(), - projection: proj.to_cols_array_2d(), - }; - - Buffer::from_data( - vulkan_context.memory_allocator.clone(), - BufferCreateInfo { - usage: BufferUsage::UNIFORM_BUFFER, - ..Default::default() - }, - AllocationCreateInfo { - memory_type_filter: MemoryTypeFilter::PREFER_DEVICE - | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, - ..Default::default() - }, - uniform_data, - ) - .unwrap() - } -} diff --git a/src/old_app/vulkan_context.rs b/src/old_app/vulkan_context.rs deleted file mode 100644 index 332dbcf..0000000 --- a/src/old_app/vulkan_context.rs +++ /dev/null @@ -1,213 +0,0 @@ -use std::{any::Any, sync::Arc}; - -use vulkano::{ - Version, VulkanLibrary, - command_buffer::{ - AutoCommandBufferBuilder, CommandBufferUsage, PrimaryAutoCommandBuffer, - allocator::StandardCommandBufferAllocator, - }, - descriptor_set::allocator::StandardDescriptorSetAllocator, - device::{ - Device, DeviceCreateInfo, DeviceExtensions, DeviceFeatures, Queue, QueueCreateInfo, - QueueFlags, - physical::{PhysicalDevice, PhysicalDeviceType}, - }, - instance::{Instance, InstanceCreateFlags, InstanceCreateInfo, InstanceExtensions}, - memory::allocator::StandardMemoryAllocator, - swapchain::Surface, -}; -use winit::{ - event_loop::EventLoop, - raw_window_handle::{HasDisplayHandle, HasWindowHandle}, -}; - -pub struct VulkanContext { - instance: Arc, - pub device: Arc, - pub graphics_queue: Arc, - - pub memory_allocator: Arc, - pub command_buffer_allocator: Arc, - pub descriptor_set_allocator: Arc, -} - -impl From<&EventLoop<()>> for VulkanContext { - fn from(event_loop: &EventLoop<()>) -> Self { - let library = load_library(); - - let enabled_extensions = Surface::required_extensions(event_loop).unwrap(); - log::debug!("Surface required extensions: {enabled_extensions:?}"); - - let instance = create_instance(library.clone(), enabled_extensions); - - let (device, mut queues) = pick_graphics_device(&instance, event_loop); - 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, - device, - graphics_queue, - memory_allocator, - command_buffer_allocator, - descriptor_set_allocator, - } - } -} - -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() - } -} - -fn load_library() -> Arc { - let library = VulkanLibrary::new().unwrap(); - - log::debug!("Available layer:"); - for layer in library.layer_properties().unwrap() { - log::debug!( - "\t - Layer name: {}, Description: {}, Implementation Version: {}, Vulkan Version: {}", - layer.name(), - layer.description(), - layer.implementation_version(), - layer.vulkan_version() - ); - } - - library -} - -fn create_instance( - library: Arc, - required_extensions: InstanceExtensions, -) -> Arc { - Instance::new( - library, - InstanceCreateInfo { - // Enable enumerating devices that use non-conformant Vulkan implementations. - // (e.g. MoltenVK) - flags: InstanceCreateFlags::ENUMERATE_PORTABILITY, - enabled_extensions: required_extensions, - enabled_layers: vec![String::from("VK_LAYER_KHRONOS_validation")], - ..Default::default() - }, - ) - .unwrap() -} - -fn find_physical_device_queue_family_indexes( - physical_device: &Arc, - event_loop: &EventLoop<()>, -) -> Option { - let mut graphic_queue_family_index = None; - - for (i, queue_family_property) in physical_device.queue_family_properties().iter().enumerate() { - if queue_family_property - .queue_flags - .intersects(QueueFlags::GRAPHICS) - && physical_device - .presentation_support(i as u32, event_loop) - .unwrap() - { - graphic_queue_family_index = Some(i as u32); - } - } - - graphic_queue_family_index -} - -fn pick_physical_device_and_queue_family_indexes( - instance: &Arc, - event_loop: &EventLoop<()>, - device_extensions: &DeviceExtensions, -) -> Option<(Arc, u32)> { - instance - .enumerate_physical_devices() - .unwrap() - .filter(|p| { - p.api_version() >= Version::V1_3 || p.supported_extensions().khr_dynamic_rendering - }) - .filter(|p| p.supported_extensions().contains(device_extensions)) - .filter_map(|p| { - find_physical_device_queue_family_indexes(&p, event_loop) - .and_then(|indexes| Some((p, indexes))) - }) - .min_by_key(|(p, _)| match p.properties().device_type { - PhysicalDeviceType::DiscreteGpu => 0, - PhysicalDeviceType::IntegratedGpu => 1, - PhysicalDeviceType::VirtualGpu => 2, - PhysicalDeviceType::Cpu => 3, - PhysicalDeviceType::Other => 4, - _ => 5, - }) -} - -fn pick_graphics_device( - instance: &Arc, - event_loop: &EventLoop<()>, -) -> ( - Arc, - impl ExactSizeIterator> + use<>, -) { - let mut device_extensions = DeviceExtensions { - khr_swapchain: true, - ..DeviceExtensions::empty() - }; - - let (physical_device, graphics_family_index) = - pick_physical_device_and_queue_family_indexes(instance, event_loop, &device_extensions) - .unwrap(); - - log::debug!( - "Using device: {} (type: {:?})", - physical_device.properties().device_name, - physical_device.properties().device_type, - ); - - if physical_device.api_version() < Version::V1_3 { - device_extensions.khr_dynamic_rendering = true; - } - - log::debug!("Using device extensions: {:#?}", device_extensions); - - Device::new( - physical_device, - DeviceCreateInfo { - queue_create_infos: vec![QueueCreateInfo { - queue_family_index: graphics_family_index, - ..Default::default() - }], - enabled_extensions: device_extensions, - enabled_features: DeviceFeatures { - dynamic_rendering: true, - ..DeviceFeatures::empty() - }, - ..Default::default() - }, - ) - .unwrap() -} diff --git a/src/old_app/window_render_context.rs b/src/old_app/window_render_context.rs deleted file mode 100644 index 54120d0..0000000 --- a/src/old_app/window_render_context.rs +++ /dev/null @@ -1,102 +0,0 @@ -use std::sync::Arc; -use vulkano::device::Device; -use vulkano::image::view::ImageView; -use vulkano::image::{Image, ImageUsage}; -use vulkano::pipeline::graphics::viewport::Viewport; -use vulkano::swapchain::{Surface, Swapchain, SwapchainCreateInfo}; -use vulkano::sync::GpuFuture; -use vulkano::{Validated, VulkanError, sync}; -use winit::window::Window; - -pub struct WindowRenderContext { - pub window: Arc, - pub swapchain: Arc, - pub attachment_image_views: Vec>, - pub viewport: Viewport, - pub recreate_swapchain: bool, - pub previous_frame_end: Option>, -} - -impl WindowRenderContext { - pub fn new(window: Arc, surface: Arc, device: &Arc) -> Self { - let window_size = window.inner_size(); - - let (swapchain, images) = { - let surface_capabilities = device - .physical_device() - .surface_capabilities(&surface, Default::default()) - .unwrap(); - - let (image_format, _) = device - .physical_device() - .surface_formats(&surface, Default::default()) - .unwrap()[0]; - - Swapchain::new( - device.clone(), - surface, - SwapchainCreateInfo { - // 2 because with some graphics driver, it crash on fullscreen because fullscreen need to min image to works. - min_image_count: surface_capabilities.min_image_count.max(2), - image_format, - image_extent: window_size.into(), - image_usage: ImageUsage::COLOR_ATTACHMENT, - composite_alpha: surface_capabilities - .supported_composite_alpha - .into_iter() - .next() - .unwrap(), - - ..Default::default() - }, - ) - .unwrap() - }; - - let attachment_image_views = window_size_dependent_setup(&images); - - let viewport = Viewport { - offset: [0.0, 0.0], - extent: window_size.into(), - depth_range: 0.0..=1.0, - }; - - let recreate_swapchain = false; - let previous_frame_end = Some(sync::now(device.clone()).boxed()); - - Self { - window, - swapchain, - attachment_image_views, - viewport, - recreate_swapchain, - previous_frame_end, - } - } - - pub fn update_swapchain(&mut self) -> Result<(), Validated> { - if !self.recreate_swapchain { - return Ok(()); - } - - let window_size = self.window.inner_size(); - let (new_swapchain, new_images) = self.swapchain.recreate(SwapchainCreateInfo { - image_extent: window_size.into(), - ..self.swapchain.create_info() - })?; - - self.swapchain = new_swapchain; - self.attachment_image_views = window_size_dependent_setup(&new_images); - self.viewport.extent = window_size.into(); - self.recreate_swapchain = false; - - Ok(()) - } -} - -fn window_size_dependent_setup(images: &[Arc]) -> Vec> { - images - .iter() - .map(|image| ImageView::new_default(image.clone()).unwrap()) - .collect::>() -}