Refactorisation de la gestion des pipelines
This commit is contained in:
parent
f65f45fc9a
commit
1169c76b41
5 changed files with 155 additions and 143 deletions
|
@ -1,15 +1,18 @@
|
||||||
mod render_context;
|
mod render_context;
|
||||||
mod app;
|
mod app;
|
||||||
|
mod vertex;
|
||||||
|
mod pipelines;
|
||||||
pub use app::App;
|
pub use app::App;
|
||||||
|
pub use pipelines::create_triangle_pipeline;
|
||||||
|
|
||||||
mod scene;
|
mod scene;
|
||||||
pub use scene::Scene;
|
pub use scene::Scene;
|
||||||
|
pub use vertex::Vertex2D;
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use vulkano::image::Image;
|
use vulkano::image::Image;
|
||||||
use vulkano::image::view::ImageView;
|
use vulkano::image::view::ImageView;
|
||||||
|
|
||||||
|
|
||||||
/// This function is called once during initialization, then again whenever the window is resized.
|
/// This function is called once during initialization, then again whenever the window is resized.
|
||||||
fn window_size_dependent_setup(images: &[Arc<Image>]) -> Vec<Arc<ImageView>> {
|
fn window_size_dependent_setup(images: &[Arc<Image>]) -> Vec<Arc<ImageView>> {
|
||||||
images
|
images
|
||||||
|
|
2
src/renderer/pipelines/mod.rs
Normal file
2
src/renderer/pipelines/mod.rs
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
mod triangle_pipeline;
|
||||||
|
pub use triangle_pipeline::create_triangle_pipeline;
|
85
src/renderer/pipelines/triangle_pipeline.rs
Normal file
85
src/renderer/pipelines/triangle_pipeline.rs
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
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::viewport::ViewportState;
|
||||||
|
use vulkano::pipeline::layout::PipelineDescriptorSetLayoutCreateInfo;
|
||||||
|
use vulkano::swapchain::Swapchain;
|
||||||
|
|
||||||
|
use crate::renderer::Vertex2D;
|
||||||
|
|
||||||
|
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<Device>, swapchain: &Arc<Swapchain>) -> Arc<GraphicsPipeline> {
|
||||||
|
let vs = shaders::vs::load(device.clone())
|
||||||
|
.unwrap()
|
||||||
|
.entry_point("main")
|
||||||
|
.unwrap();
|
||||||
|
let fs = shaders::fs::load(device.clone())
|
||||||
|
.unwrap()
|
||||||
|
.entry_point("main")
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let vertex_input_state = Vertex2D::per_vertex()
|
||||||
|
.definition(&vs)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let stages = [
|
||||||
|
PipelineShaderStageCreateInfo::new(vs),
|
||||||
|
PipelineShaderStageCreateInfo::new(fs),
|
||||||
|
];
|
||||||
|
|
||||||
|
let layout = PipelineLayout::new(
|
||||||
|
device.clone(),
|
||||||
|
PipelineDescriptorSetLayoutCreateInfo::from_stages(&stages)
|
||||||
|
.into_pipeline_layout_create_info(device.clone())
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let subpass = PipelineRenderingCreateInfo {
|
||||||
|
color_attachment_formats: vec![Some(swapchain.image_format())],
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
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)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
}
|
|
@ -1,163 +1,57 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use vulkano::buffer::{Buffer, BufferContents, BufferCreateInfo, BufferUsage, Subbuffer};
|
use vulkano::buffer::{Buffer, BufferCreateInfo, BufferUsage, Subbuffer};
|
||||||
use vulkano::command_buffer::{AutoCommandBufferBuilder, PrimaryAutoCommandBuffer};
|
use vulkano::command_buffer::{AutoCommandBufferBuilder, PrimaryAutoCommandBuffer};
|
||||||
use vulkano::device::Device;
|
use vulkano::device::Device;
|
||||||
use vulkano::memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator};
|
use vulkano::memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator};
|
||||||
use vulkano::pipeline::graphics::vertex_input::{Vertex, VertexDefinition};
|
use vulkano::pipeline::GraphicsPipeline;
|
||||||
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::viewport::ViewportState;
|
|
||||||
use vulkano::pipeline::layout::PipelineDescriptorSetLayoutCreateInfo;
|
|
||||||
use vulkano::swapchain::Swapchain;
|
use vulkano::swapchain::Swapchain;
|
||||||
|
|
||||||
// We use `#[repr(C)]` here to force rustc to use a defined layout for our data, as the default
|
use crate::renderer::{Vertex2D, create_triangle_pipeline};
|
||||||
// representation has *no guarantees*.
|
|
||||||
#[derive(BufferContents, Vertex)]
|
|
||||||
#[repr(C)]
|
|
||||||
struct MyVertex {
|
|
||||||
#[format(R32G32_SFLOAT)]
|
|
||||||
position: [f32; 2],
|
|
||||||
|
|
||||||
#[format(R32G32B32_SFLOAT)]
|
|
||||||
color: [f32; 3],
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Scene {
|
pub struct Scene {
|
||||||
pipeline: Arc<GraphicsPipeline>,
|
pipeline: Arc<GraphicsPipeline>,
|
||||||
vertex_buffer: Subbuffer<[MyVertex]>,
|
vertex_buffer: Subbuffer<[Vertex2D]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Scene {
|
impl Scene {
|
||||||
pub fn initialize(device: &Arc<Device>, swapchain: &Arc<Swapchain>, memory_allocator: &Arc<StandardMemoryAllocator>) -> Scene {
|
fn create_vertex_buffer(
|
||||||
mod vs {
|
memory_allocator: &Arc<StandardMemoryAllocator>,
|
||||||
vulkano_shaders::shader! {
|
) -> Subbuffer<[Vertex2D]> {
|
||||||
ty: "vertex",
|
|
||||||
path: r"res/shaders/vertex.vert",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod fs {
|
|
||||||
vulkano_shaders::shader! {
|
|
||||||
ty: "fragment",
|
|
||||||
path: r"res/shaders/vertex.frag",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let pipeline = {
|
|
||||||
let vs = vs::load(device.clone())
|
|
||||||
.unwrap()
|
|
||||||
.entry_point("main")
|
|
||||||
.unwrap();
|
|
||||||
let fs = fs::load(device.clone())
|
|
||||||
.unwrap()
|
|
||||||
.entry_point("main")
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let vertex_input_state = MyVertex::per_vertex().definition(&vs).unwrap();
|
|
||||||
|
|
||||||
let stages = [
|
|
||||||
PipelineShaderStageCreateInfo::new(vs),
|
|
||||||
PipelineShaderStageCreateInfo::new(fs),
|
|
||||||
];
|
|
||||||
|
|
||||||
let layout = PipelineLayout::new(
|
|
||||||
device.clone(),
|
|
||||||
PipelineDescriptorSetLayoutCreateInfo::from_stages(&stages)
|
|
||||||
.into_pipeline_layout_create_info(device.clone())
|
|
||||||
.unwrap(),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let subpass = PipelineRenderingCreateInfo {
|
|
||||||
color_attachment_formats: vec![Some(swapchain.image_format())],
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
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)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.unwrap()
|
|
||||||
};
|
|
||||||
|
|
||||||
let vertices = [
|
let vertices = [
|
||||||
// Triangle en haut à gauche
|
// Triangle en haut à gauche
|
||||||
MyVertex {
|
Vertex2D::new([-0.5, -0.75], // Coin supérieur gauche
|
||||||
position: [-0.5, -0.75], // Coin supérieur gauche
|
[1.0, 0.0, 0.0]), // Couleur rouge
|
||||||
color: [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
|
||||||
MyVertex {
|
Vertex2D::new([-0.25, -0.25], // Coin supérieur droit
|
||||||
position: [-0.75, -0.25], // Coin supérieur
|
[0.0, 0.0, 1.0]), // Couleur bleue
|
||||||
color: [0.0, 1.0, 0.0], // Couleur verte
|
|
||||||
},
|
|
||||||
MyVertex {
|
|
||||||
position: [-0.25, -0.25], // Coin supérieur droit
|
|
||||||
color: [0.0, 0.0, 1.0], // Couleur bleue
|
|
||||||
},
|
|
||||||
|
|
||||||
// Triangle en bas à gauche
|
// Triangle en bas à gauche
|
||||||
MyVertex {
|
Vertex2D::new([-0.5, 0.25], // Coin inférieur gauche
|
||||||
position: [-0.5, 0.25], // Coin inférieur gauche
|
[0.5, 0.5, 0.5]), // Couleur gris
|
||||||
color: [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
|
||||||
MyVertex {
|
Vertex2D::new([-0.25, 0.75], // Coin inférieur droit
|
||||||
position: [-0.75, 0.75], // Coin inférieur
|
[0.8, 0.2, 0.2]), // Couleur rouge clair
|
||||||
color: [0.2, 0.8, 0.2], // Couleur vert clair
|
|
||||||
},
|
|
||||||
MyVertex {
|
|
||||||
position: [-0.25, 0.75], // Coin inférieur droit
|
|
||||||
color: [0.8, 0.2, 0.2], // Couleur rouge clair
|
|
||||||
},
|
|
||||||
|
|
||||||
// Triangle en haut à droite
|
// Triangle en haut à droite
|
||||||
MyVertex {
|
Vertex2D::new([0.5, -0.75], // Coin gauche supérieur
|
||||||
position: [0.5, -0.75], // Coin gauche supérieur
|
[1.0, 1.0, 0.0]), // Couleur jaune
|
||||||
color: [1.0, 1.0, 0.0], // Couleur jaune
|
Vertex2D::new([0.25, -0.25], // Coin gauche
|
||||||
},
|
[0.0, 1.0, 1.0]), // Couleur cyan
|
||||||
MyVertex {
|
Vertex2D::new([0.75, -0.25], // Coin gauche inférieur
|
||||||
position: [0.25, -0.25], // Coin gauche
|
[1.0, 0.0, 1.0]), // Couleur magenta
|
||||||
color: [0.0, 1.0, 1.0], // Couleur cyan
|
|
||||||
},
|
|
||||||
MyVertex {
|
|
||||||
position: [0.75, -0.25], // Coin gauche inférieur
|
|
||||||
color: [1.0, 0.0, 1.0], // Couleur magenta
|
|
||||||
},
|
|
||||||
|
|
||||||
// Triangle en bas à droite
|
// Triangle en bas à droite
|
||||||
MyVertex {
|
Vertex2D::new([0.5, 0.25], // Coin droit supérieur
|
||||||
position: [0.5, 0.25], // Coin droit supérieur
|
[0.1, 0.5, 0.8]), // Couleur bleu clair
|
||||||
color: [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
|
||||||
MyVertex {
|
Vertex2D::new([0.75, 0.75], // Coin droit inférieur
|
||||||
position: [0.25, 0.75], // Coin droit
|
[0.3, 0.4, 0.6]), // Couleur bleu foncé
|
||||||
color: [0.8, 0.6, 0.1], // Couleur or
|
|
||||||
},
|
|
||||||
MyVertex {
|
|
||||||
position: [0.75, 0.75], // Coin droit inférieur
|
|
||||||
color: [0.3, 0.4, 0.6], // Couleur bleu foncé
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
let vertex_buffer = Buffer::from_iter(
|
|
||||||
|
Buffer::from_iter(
|
||||||
memory_allocator.clone(),
|
memory_allocator.clone(),
|
||||||
BufferCreateInfo {
|
BufferCreateInfo {
|
||||||
usage: BufferUsage::VERTEX_BUFFER,
|
usage: BufferUsage::VERTEX_BUFFER,
|
||||||
|
@ -170,16 +64,26 @@ impl Scene {
|
||||||
},
|
},
|
||||||
vertices,
|
vertices,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
Self {
|
pub fn initialize(
|
||||||
|
device: &Arc<Device>,
|
||||||
|
swapchain: &Arc<Swapchain>,
|
||||||
|
memory_allocator: &Arc<StandardMemoryAllocator>,
|
||||||
|
) -> Scene {
|
||||||
|
let pipeline = create_triangle_pipeline(device, swapchain);
|
||||||
|
let vertex_buffer = Self::create_vertex_buffer(memory_allocator);
|
||||||
|
|
||||||
|
Scene {
|
||||||
pipeline,
|
pipeline,
|
||||||
vertex_buffer,
|
vertex_buffer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(&self, builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>) {
|
pub fn render(&self, builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>) {
|
||||||
builder.bind_pipeline_graphics(self.pipeline.clone())
|
builder
|
||||||
|
.bind_pipeline_graphics(self.pipeline.clone())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.bind_vertex_buffers(0, self.vertex_buffer.clone())
|
.bind_vertex_buffers(0, self.vertex_buffer.clone())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
18
src/renderer/vertex.rs
Normal file
18
src/renderer/vertex.rs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
use vulkano::buffer::BufferContents;
|
||||||
|
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 new(position: [f32; 2], color: [f32; 3]) -> Self {
|
||||||
|
Self { position, color }
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue