Split Mesh data and Pipeline
This commit is contained in:
parent
4f96a1e4b5
commit
078e9daba9
13 changed files with 331 additions and 109 deletions
207
src/game/assets/pipelines/simple.rs
Normal file
207
src/game/assets/pipelines/simple.rs
Normal file
|
@ -0,0 +1,207 @@
|
|||
use std::{error::Error, sync::Arc};
|
||||
|
||||
use vulkano::{
|
||||
buffer::Subbuffer,
|
||||
command_buffer::{AutoCommandBufferBuilder, PrimaryAutoCommandBuffer},
|
||||
descriptor_set::{
|
||||
allocator::StandardDescriptorSetAllocator, layout::DescriptorSetLayoutCreateInfo,
|
||||
},
|
||||
device::Device,
|
||||
format::Format,
|
||||
pipeline::{
|
||||
DynamicState, GraphicsPipeline, Pipeline, PipelineBindPoint, PipelineLayout,
|
||||
PipelineShaderStageCreateInfo,
|
||||
graphics::{
|
||||
GraphicsPipelineCreateInfo,
|
||||
color_blend::{ColorBlendAttachmentState, ColorBlendState},
|
||||
depth_stencil::{DepthState, DepthStencilState},
|
||||
input_assembly::InputAssemblyState,
|
||||
multisample::MultisampleState,
|
||||
rasterization::RasterizationState,
|
||||
subpass::PipelineRenderingCreateInfo,
|
||||
vertex_input::{Vertex, VertexDefinition},
|
||||
viewport::ViewportState,
|
||||
},
|
||||
layout::{PipelineDescriptorSetLayoutCreateInfo, PipelineLayoutCreateFlags},
|
||||
},
|
||||
};
|
||||
|
||||
use crate::core::render::{
|
||||
primitives::{
|
||||
AsBindableDescriptorSet, AsRecordable, AsRenderableMesh, mvp::Mvp, transform::TransformRaw,
|
||||
vertex::Vertex3D,
|
||||
},
|
||||
texture::Texture,
|
||||
};
|
||||
|
||||
pub struct SimplePipelineRenderData<'a, T>
|
||||
where
|
||||
T: AsRenderableMesh<Vertex3D, u32>,
|
||||
{
|
||||
pub mesh: &'a T,
|
||||
pub mvp_uniform: &'a Subbuffer<[Mvp]>,
|
||||
pub texture: &'a Texture,
|
||||
pub instances: &'a Subbuffer<[TransformRaw]>,
|
||||
}
|
||||
|
||||
pub struct SimplePipeline {
|
||||
pipeline: Arc<GraphicsPipeline>,
|
||||
}
|
||||
|
||||
impl SimplePipeline {
|
||||
pub fn new(
|
||||
device: &Arc<Device>,
|
||||
swapchain_format: Format,
|
||||
depth_format: Format,
|
||||
) -> Result<Self, Box<dyn Error>> {
|
||||
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())?;
|
||||
|
||||
let vertex_input_state =
|
||||
[Vertex3D::per_vertex(), TransformRaw::per_instance()].definition(&vs)?;
|
||||
|
||||
let stages = [
|
||||
PipelineShaderStageCreateInfo::new(vs),
|
||||
PipelineShaderStageCreateInfo::new(fs),
|
||||
];
|
||||
|
||||
let mvp_bindings = Mvp::as_descriptor_set_layout_bindings();
|
||||
let texture_bindings = Texture::as_descriptor_set_layout_bindings();
|
||||
|
||||
let vertex_descriptor_set_layout = DescriptorSetLayoutCreateInfo {
|
||||
bindings: mvp_bindings,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let fragment_descriptor_set_layout = DescriptorSetLayoutCreateInfo {
|
||||
bindings: texture_bindings,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let create_info = PipelineDescriptorSetLayoutCreateInfo {
|
||||
set_layouts: vec![vertex_descriptor_set_layout, fragment_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_format)],
|
||||
depth_attachment_format: Some(depth_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(),
|
||||
)),
|
||||
depth_stencil_state: Some(DepthStencilState {
|
||||
depth: Some(DepthState::simple()),
|
||||
..Default::default()
|
||||
}),
|
||||
dynamic_state: [DynamicState::Viewport].into_iter().collect(),
|
||||
subpass: Some(subpass.into()),
|
||||
..GraphicsPipelineCreateInfo::layout(layout)
|
||||
},
|
||||
)?;
|
||||
|
||||
Ok(Self { pipeline })
|
||||
}
|
||||
|
||||
pub fn pipeline(&self) -> &Arc<GraphicsPipeline> {
|
||||
&self.pipeline
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: AsRenderableMesh<Vertex3D, u32>> AsRecordable<SimplePipelineRenderData<'a, T>>
|
||||
for SimplePipeline
|
||||
{
|
||||
fn record_render_commands(
|
||||
builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>,
|
||||
descriptor_set_allocator: &Arc<StandardDescriptorSetAllocator>,
|
||||
pipeline: &Arc<GraphicsPipeline>,
|
||||
data: &SimplePipelineRenderData<'a, T>,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
let layouts = pipeline.layout().set_layouts();
|
||||
|
||||
let uniform_descriptor_set =
|
||||
Mvp::as_descriptor_set(descriptor_set_allocator, &layouts[0], data.mvp_uniform)?;
|
||||
|
||||
let texture_descriptor_set =
|
||||
Texture::as_descriptor_set(descriptor_set_allocator, &layouts[1], data.texture)?;
|
||||
|
||||
builder.bind_pipeline_graphics(pipeline.clone())?;
|
||||
|
||||
builder.bind_descriptor_sets(
|
||||
PipelineBindPoint::Graphics,
|
||||
pipeline.layout().clone(),
|
||||
0,
|
||||
vec![uniform_descriptor_set, texture_descriptor_set],
|
||||
)?;
|
||||
|
||||
builder.bind_vertex_buffers(
|
||||
0,
|
||||
(data.mesh.vertex_buffer().clone(), data.instances.clone()),
|
||||
)?;
|
||||
|
||||
match data.mesh.index_buffer() {
|
||||
Some(index_buffer) => {
|
||||
builder.bind_index_buffer(index_buffer.clone())?;
|
||||
unsafe {
|
||||
builder.draw_indexed(
|
||||
data.mesh.index_count(),
|
||||
data.instances.len() as u32,
|
||||
data.mesh.first_index(),
|
||||
data.mesh.vertex_offset(),
|
||||
0,
|
||||
)?;
|
||||
}
|
||||
}
|
||||
None => unsafe {
|
||||
builder.draw(
|
||||
data.mesh.vertex_count(),
|
||||
data.instances.len() as u32,
|
||||
data.mesh.first_vertex(),
|
||||
0,
|
||||
)?;
|
||||
},
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub mod shaders {
|
||||
pub mod vs {
|
||||
vulkano_shaders::shader! {
|
||||
ty: "vertex",
|
||||
path: r"res/shaders/simple.vert",
|
||||
generate_structs: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub mod fs {
|
||||
vulkano_shaders::shader! {
|
||||
ty: "fragment",
|
||||
path: r"res/shaders/simple.frag",
|
||||
generate_structs: false,
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue