From 11a5083513fa23c25d72da7ed3b29b2eae1989bc Mon Sep 17 00:00:00 2001 From: Florian RICHER Date: Wed, 11 Dec 2024 20:41:04 +0100 Subject: [PATCH] Refactor vertex buffer creations --- src/renderer/app.rs | 60 +++++----- src/renderer/mod.rs | 6 +- src/renderer/pipelines/mod.rs | 2 +- src/renderer/pipelines/triangle_pipeline.rs | 21 ++-- src/renderer/render_context.rs | 6 +- src/renderer/scene.rs | 119 ++++++++++---------- src/renderer/vertex.rs | 26 ++++- 7 files changed, 132 insertions(+), 108 deletions(-) diff --git a/src/renderer/app.rs b/src/renderer/app.rs index fdf3ce2..784e6ce 100644 --- a/src/renderer/app.rs +++ b/src/renderer/app.rs @@ -1,20 +1,24 @@ +use crate::renderer::render_context::RenderContext; +use crate::renderer::{window_size_dependent_setup, Scene}; use std::sync::Arc; use vulkano::command_buffer::allocator::StandardCommandBufferAllocator; -use vulkano::device::{Device, DeviceCreateInfo, DeviceExtensions, DeviceFeatures, Queue, QueueCreateInfo, QueueFlags}; +use vulkano::command_buffer::{ + AutoCommandBufferBuilder, CommandBufferUsage, RenderingAttachmentInfo, RenderingInfo, +}; use vulkano::device::physical::PhysicalDeviceType; +use vulkano::device::{ + Device, DeviceCreateInfo, DeviceExtensions, DeviceFeatures, Queue, QueueCreateInfo, QueueFlags, +}; use vulkano::instance::{Instance, InstanceCreateFlags, InstanceCreateInfo}; use vulkano::memory::allocator::StandardMemoryAllocator; -use vulkano::swapchain::{acquire_next_image, Surface, SwapchainCreateInfo, SwapchainPresentInfo}; -use vulkano::{sync, Validated, Version, VulkanError, VulkanLibrary}; -use vulkano::command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage, RenderingAttachmentInfo, RenderingInfo}; use vulkano::render_pass::{AttachmentLoadOp, AttachmentStoreOp}; +use vulkano::swapchain::{acquire_next_image, Surface, SwapchainCreateInfo, SwapchainPresentInfo}; use vulkano::sync::GpuFuture; +use vulkano::{sync, Validated, Version, VulkanError, VulkanLibrary}; use winit::application::ApplicationHandler; use winit::event::WindowEvent; use winit::event_loop::{ActiveEventLoop, EventLoop}; use winit::window::WindowId; -use crate::renderer::render_context::RenderContext; -use crate::renderer::{window_size_dependent_setup, Scene}; pub struct App { instance: Arc, @@ -47,7 +51,7 @@ impl App { ..Default::default() }, ) - .unwrap(); + .unwrap(); let mut device_extensions = DeviceExtensions { khr_swapchain: true, @@ -60,9 +64,7 @@ impl App { .filter(|p| { p.api_version() >= Version::V1_3 || p.supported_extensions().khr_dynamic_rendering }) - .filter(|p| { - p.supported_extensions().contains(&device_extensions) - }) + .filter(|p| p.supported_extensions().contains(&device_extensions)) .filter_map(|p| { p.queue_family_properties() .iter() @@ -73,15 +75,13 @@ impl App { }) .map(|i| (p, i as u32)) }) - .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, - } + .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, }) .expect("no suitable physical device found"); @@ -110,7 +110,7 @@ impl App { ..Default::default() }, ) - .unwrap(); + .unwrap(); let queue = queues.next().unwrap(); let memory_allocator = Arc::new(StandardMemoryAllocator::new_default(device.clone())); @@ -141,16 +141,16 @@ impl ApplicationHandler for App { f64::from(600), )); - let window = Arc::new( - event_loop - .create_window(window_attributes) - .unwrap(), - ); + let window = Arc::new(event_loop.create_window(window_attributes).unwrap()); let surface = Surface::from_window(self.instance.clone(), window.clone()).unwrap(); self.rcx = Some(RenderContext::new(window, surface, &self.device)); - self.scene = Some(Scene::initialize(&self.device, &self.rcx.as_ref().unwrap().swapchain, &self.memory_allocator)); + self.scene = Some(Scene::initialize( + &self.device, + &self.rcx.as_ref().unwrap().swapchain, + &self.memory_allocator, + )); } fn window_event(&mut self, event_loop: &ActiveEventLoop, _id: WindowId, event: WindowEvent) { @@ -192,7 +192,7 @@ impl ApplicationHandler for App { rcx.swapchain.clone(), None, ) - .map_err(Validated::unwrap) + .map_err(Validated::unwrap) { Ok(r) => r, Err(VulkanError::OutOfDate) => { @@ -211,7 +211,7 @@ impl ApplicationHandler for App { self.queue.queue_family_index(), CommandBufferUsage::OneTimeSubmit, ) - .unwrap(); + .unwrap(); builder .begin_rendering(RenderingInfo { @@ -233,9 +233,7 @@ impl ApplicationHandler for App { scene.render(&mut builder); } - builder - .end_rendering() - .unwrap(); + builder.end_rendering().unwrap(); let command_buffer = builder.build().unwrap(); diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs index d056eb7..21def04 100644 --- a/src/renderer/mod.rs +++ b/src/renderer/mod.rs @@ -1,7 +1,7 @@ -mod render_context; mod app; -mod vertex; mod pipelines; +mod render_context; +mod vertex; pub use app::App; pub use pipelines::create_triangle_pipeline; @@ -10,8 +10,8 @@ pub use scene::Scene; pub use vertex::Vertex2D; use std::sync::Arc; -use vulkano::image::Image; use vulkano::image::view::ImageView; +use vulkano::image::Image; /// This function is called once during initialization, then again whenever the window is resized. fn window_size_dependent_setup(images: &[Arc]) -> Vec> { diff --git a/src/renderer/pipelines/mod.rs b/src/renderer/pipelines/mod.rs index db588d1..670717a 100644 --- a/src/renderer/pipelines/mod.rs +++ b/src/renderer/pipelines/mod.rs @@ -1,2 +1,2 @@ mod triangle_pipeline; -pub use triangle_pipeline::create_triangle_pipeline; \ No newline at end of file +pub use triangle_pipeline::create_triangle_pipeline; diff --git a/src/renderer/pipelines/triangle_pipeline.rs b/src/renderer/pipelines/triangle_pipeline.rs index e9de828..b5858e2 100644 --- a/src/renderer/pipelines/triangle_pipeline.rs +++ b/src/renderer/pipelines/triangle_pipeline.rs @@ -1,15 +1,17 @@ use std::sync::Arc; use vulkano::device::Device; -use vulkano::pipeline::graphics::vertex_input::{Vertex, VertexDefinition}; -use vulkano::pipeline::{DynamicState, GraphicsPipeline, PipelineLayout, PipelineShaderStageCreateInfo}; use vulkano::pipeline::graphics::color_blend::{ColorBlendAttachmentState, ColorBlendState}; -use vulkano::pipeline::graphics::GraphicsPipelineCreateInfo; 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::graphics::GraphicsPipelineCreateInfo; use vulkano::pipeline::layout::PipelineDescriptorSetLayoutCreateInfo; +use vulkano::pipeline::{ + DynamicState, GraphicsPipeline, PipelineLayout, PipelineShaderStageCreateInfo, +}; use vulkano::swapchain::Swapchain; use crate::renderer::Vertex2D; @@ -30,7 +32,10 @@ mod shaders { } } -pub fn create_triangle_pipeline(device: &Arc, swapchain: &Arc) -> Arc { +pub fn create_triangle_pipeline( + device: &Arc, + swapchain: &Arc, +) -> Arc { let vs = shaders::vs::load(device.clone()) .unwrap() .entry_point("main") @@ -40,9 +45,7 @@ pub fn create_triangle_pipeline(device: &Arc, swapchain: &Arc .entry_point("main") .unwrap(); - let vertex_input_state = Vertex2D::per_vertex() - .definition(&vs) - .unwrap(); + let vertex_input_state = Vertex2D::per_vertex().definition(&vs).unwrap(); let stages = [ PipelineShaderStageCreateInfo::new(vs), @@ -55,7 +58,7 @@ pub fn create_triangle_pipeline(device: &Arc, swapchain: &Arc .into_pipeline_layout_create_info(device.clone()) .unwrap(), ) - .unwrap(); + .unwrap(); let subpass = PipelineRenderingCreateInfo { color_attachment_formats: vec![Some(swapchain.image_format())], @@ -81,5 +84,5 @@ pub fn create_triangle_pipeline(device: &Arc, swapchain: &Arc ..GraphicsPipelineCreateInfo::layout(layout) }, ) - .unwrap() + .unwrap() } diff --git a/src/renderer/render_context.rs b/src/renderer/render_context.rs index 097479e..2248be3 100644 --- a/src/renderer/render_context.rs +++ b/src/renderer/render_context.rs @@ -1,13 +1,13 @@ +use crate::renderer::window_size_dependent_setup; use std::sync::Arc; use vulkano::device::Device; -use vulkano::image::ImageUsage; use vulkano::image::view::ImageView; +use vulkano::image::ImageUsage; use vulkano::pipeline::graphics::viewport::Viewport; use vulkano::swapchain::{Surface, Swapchain, SwapchainCreateInfo}; use vulkano::sync; use vulkano::sync::GpuFuture; use winit::window::Window; -use crate::renderer::window_size_dependent_setup; pub struct RenderContext { pub(super) window: Arc, @@ -51,7 +51,7 @@ impl RenderContext { ..Default::default() }, ) - .unwrap() + .unwrap() }; let attachment_image_views = window_size_dependent_setup(&images); diff --git a/src/renderer/scene.rs b/src/renderer/scene.rs index f8fe8aa..e327f05 100644 --- a/src/renderer/scene.rs +++ b/src/renderer/scene.rs @@ -1,12 +1,67 @@ use std::sync::Arc; -use vulkano::buffer::{Buffer, BufferCreateInfo, BufferUsage, Subbuffer}; +use vulkano::buffer::Subbuffer; use vulkano::command_buffer::{AutoCommandBufferBuilder, PrimaryAutoCommandBuffer}; use vulkano::device::Device; -use vulkano::memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}; +use vulkano::memory::allocator::StandardMemoryAllocator; use vulkano::pipeline::GraphicsPipeline; use vulkano::swapchain::Swapchain; -use crate::renderer::{Vertex2D, create_triangle_pipeline}; +use crate::renderer::{create_triangle_pipeline, Vertex2D}; + +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, @@ -14,66 +69,14 @@ pub struct Scene { } impl Scene { - fn create_vertex_buffer( - memory_allocator: &Arc, - ) -> Subbuffer<[Vertex2D]> { - let vertices = [ - // Triangle en haut à gauche - Vertex2D::new([-0.5, -0.75], // Coin supérieur gauche - [1.0, 0.0, 0.0]), // Couleur rouge - Vertex2D::new([-0.75, -0.25], // Coin supérieur - [0.0, 1.0, 0.0]), // Couleur verte - Vertex2D::new([-0.25, -0.25], // Coin supérieur droit - [0.0, 0.0, 1.0]), // Couleur bleue - - // Triangle en bas à gauche - Vertex2D::new([-0.5, 0.25], // Coin inférieur gauche - [0.5, 0.5, 0.5]), // Couleur gris - Vertex2D::new([-0.75, 0.75], // Coin inférieur - [0.2, 0.8, 0.2]), // Couleur vert clair - Vertex2D::new([-0.25, 0.75], // Coin inférieur droit - [0.8, 0.2, 0.2]), // Couleur rouge clair - - // Triangle en haut à droite - Vertex2D::new([0.5, -0.75], // Coin gauche supérieur - [1.0, 1.0, 0.0]), // Couleur jaune - Vertex2D::new([0.25, -0.25], // Coin gauche - [0.0, 1.0, 1.0]), // Couleur cyan - Vertex2D::new([0.75, -0.25], // Coin gauche inférieur - [1.0, 0.0, 1.0]), // Couleur magenta - - // Triangle en bas à droite - Vertex2D::new([0.5, 0.25], // Coin droit supérieur - [0.1, 0.5, 0.8]), // Couleur bleu clair - Vertex2D::new([0.25, 0.75], // Coin droit - [0.8, 0.6, 0.1]), // Couleur or - Vertex2D::new([0.75, 0.75], // Coin droit inférieur - [0.3, 0.4, 0.6]), // Couleur bleu foncé - ]; - - 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, - ) - .unwrap() - } - pub fn initialize( device: &Arc, swapchain: &Arc, memory_allocator: &Arc, ) -> Scene { let pipeline = create_triangle_pipeline(device, swapchain); - let vertex_buffer = Self::create_vertex_buffer(memory_allocator); + let vertex_buffer = + Vertex2D::create_buffer(Vec::from_iter(VERTICES), memory_allocator).unwrap(); Scene { pipeline, @@ -93,4 +96,4 @@ impl Scene { unsafe { builder.draw(vertex_count, instance_count, 0, 0) }.unwrap(); } -} \ No newline at end of file +} diff --git a/src/renderer/vertex.rs b/src/renderer/vertex.rs index 8eb4ff5..fc2ee21 100644 --- a/src/renderer/vertex.rs +++ b/src/renderer/vertex.rs @@ -1,5 +1,10 @@ -use vulkano::buffer::BufferContents; +use std::sync::Arc; +use vulkano::buffer::{ + AllocateBufferError, Buffer, BufferContents, BufferCreateInfo, BufferUsage, Subbuffer, +}; +use vulkano::memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}; use vulkano::pipeline::graphics::vertex_input::Vertex; +use vulkano::Validated; #[derive(BufferContents, Vertex)] #[repr(C)] @@ -12,7 +17,22 @@ pub struct Vertex2D { } impl Vertex2D { - pub fn new(position: [f32; 2], color: [f32; 3]) -> Self { - Self { position, color } + 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, + ) } }