Allow for more pipelines
This commit is contained in:
196
src/vulkan.rs
196
src/vulkan.rs
@@ -1,3 +1,5 @@
|
||||
use crate::pipelines::{Drawcall, LineShader};
|
||||
use crate::pipelines::DefaultShader;
|
||||
use std::sync::Arc;
|
||||
use std::time::SystemTime;
|
||||
|
||||
@@ -6,16 +8,13 @@ use image::{ImageBuffer, ImageFormat, Rgb, Rgba};
|
||||
use image::buffer::ConvertBuffer;
|
||||
use vulkano::{command_buffer::CommandBuffer, buffer::{BufferUsage, CpuAccessibleBuffer}, image::{ImageLayout, MipmapsCount}};
|
||||
use vulkano::command_buffer::{AutoCommandBuffer, AutoCommandBufferBuilder, DynamicState};
|
||||
use vulkano::descriptor::descriptor_set::PersistentDescriptorSet;
|
||||
use vulkano::descriptor::DescriptorSet;
|
||||
use vulkano::device::{Device, DeviceExtensions, Queue};
|
||||
use vulkano::format::{ClearValue, Format};
|
||||
use vulkano::framebuffer::{Framebuffer, FramebufferAbstract, RenderPassAbstract, Subpass};
|
||||
use vulkano::framebuffer::{Framebuffer, FramebufferAbstract, RenderPassAbstract};
|
||||
use vulkano::image::{AttachmentImage, Dimensions, ImageUsage, ImmutableImage, SwapchainImage, ImageViewAccess};
|
||||
use vulkano::instance::{ApplicationInfo, Instance, InstanceExtensions, PhysicalDevice, Version};
|
||||
use vulkano::instance::debug::{DebugCallback, MessageSeverity, MessageType};
|
||||
use vulkano::memory::pool::{PotentialDedicatedAllocation, StdMemoryPoolAlloc};
|
||||
use vulkano::pipeline::{GraphicsPipeline, GraphicsPipelineAbstract};
|
||||
use vulkano::pipeline::viewport::Viewport;
|
||||
use vulkano::sampler::{Filter, MipmapMode, Sampler, SamplerAddressMode};
|
||||
use vulkano::swapchain::{AcquireError, ColorSpace, FullscreenExclusive, PresentMode, Surface, SurfaceTransform, Swapchain, SwapchainCreationError};
|
||||
@@ -27,10 +26,11 @@ use winit::event::{Event, WindowEvent};
|
||||
use winit::event_loop::{ControlFlow, EventLoop};
|
||||
use winit::window::{Window, WindowBuilder};
|
||||
|
||||
use line_vs::ty::LinePushConstants;
|
||||
use vs::ty::PushConstants;
|
||||
use crate::pipelines::{line_vs::ty::LinePushConstants};
|
||||
use crate::pipelines::vs::ty::PushConstants;
|
||||
|
||||
use crate::gameobject::{GameObject, GameObjectHandle};
|
||||
use crate::pipelines::vs;
|
||||
use crate::{gameobject::{GameObject, GameObjectHandle}};
|
||||
use crate::mesh::CPUMesh;
|
||||
use crate::config::RenderConfig;
|
||||
|
||||
@@ -63,8 +63,8 @@ pub trait Game {
|
||||
}
|
||||
|
||||
pub struct Mesh {
|
||||
vertex_buffer: Arc<CpuAccessibleBuffer<[Vertex]>>,
|
||||
index_buffer: Arc<CpuAccessibleBuffer<[u32]>>,
|
||||
pub vertex_buffer: Arc<CpuAccessibleBuffer<[Vertex]>>,
|
||||
pub index_buffer: Arc<CpuAccessibleBuffer<[u32]>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
@@ -98,9 +98,7 @@ pub struct VulkanRenderer {
|
||||
pub framebuffers: Vec<Arc<dyn FramebufferAbstract + Send + Sync>>,
|
||||
pub sampler: Arc<Sampler>,
|
||||
pub dynamic_state: DynamicState,
|
||||
pub pipeline: Arc<dyn GraphicsPipelineAbstract + Send + Sync>,
|
||||
pub line_pipeline: Arc<dyn GraphicsPipelineAbstract + Send + Sync>,
|
||||
pub line_vertex_buffer: Arc<CpuAccessibleBuffer<[LinePoint], PotentialDedicatedAllocation<StdMemoryPoolAlloc>>>,
|
||||
pub pipelines: Vec<Box<dyn Drawcall>>,
|
||||
pub surface: Arc<Surface<Window>>,
|
||||
pub swapchain: Arc<Swapchain<Window>>,
|
||||
pub render_pass: Arc<dyn RenderPassAbstract + Send + Sync>,
|
||||
@@ -233,9 +231,6 @@ impl VulkanRenderer {
|
||||
PresentMode::Fifo, FullscreenExclusive::Default, true, ColorSpace::SrgbNonLinear).unwrap()
|
||||
};
|
||||
|
||||
// what is host_cached
|
||||
let line_vertex_buffer = CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::vertex_buffer(), false, data.line_vertices.iter().cloned()).unwrap();
|
||||
|
||||
// Render pass
|
||||
let render_pass = Arc::new(vulkano::single_pass_renderpass!(
|
||||
device.clone(),
|
||||
@@ -272,10 +267,12 @@ impl VulkanRenderer {
|
||||
MipmapMode::Nearest, SamplerAddressMode::Repeat, SamplerAddressMode::Repeat,
|
||||
SamplerAddressMode::Repeat, 0.0, 1.0, 0.0, 0.0).unwrap();
|
||||
|
||||
let pipeline: Arc<dyn GraphicsPipelineAbstract + Send + Sync> =
|
||||
create_pipeline::<Vertex>(device.clone(), render_pass.clone(), false).unwrap();
|
||||
let line_pipeline: Arc<dyn GraphicsPipelineAbstract + Send + Sync> =
|
||||
create_pipeline::<LinePoint>(device.clone(), render_pass.clone(), true).unwrap();
|
||||
let line_vertex_buffer = CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::vertex_buffer(), false, data.line_vertices.iter().cloned()).unwrap();
|
||||
|
||||
let pipelines: Vec<Box<dyn Drawcall>> = vec![
|
||||
Box::new(DefaultShader::new(device.clone(), render_pass.clone())),
|
||||
Box::new(LineShader::new(device.clone(), render_pass.clone(), line_vertex_buffer)),
|
||||
];
|
||||
|
||||
let default_tex = {
|
||||
let image = image::load_from_memory_with_format(include_bytes!("../models/missing-texture.jpg"),
|
||||
@@ -337,8 +334,8 @@ impl VulkanRenderer {
|
||||
let previous_frame_end = Some(Box::new(sync::now(device.clone())) as Box<dyn GpuFuture>);
|
||||
|
||||
(VulkanRenderer { game_data: data, device, framebuffers, sampler,
|
||||
dynamic_state, pipeline, line_pipeline, uniform_buffers,
|
||||
surface, swapchain, render_pass, queue, line_vertex_buffer,
|
||||
dynamic_state, pipelines, uniform_buffers,
|
||||
surface, swapchain, render_pass, queue,
|
||||
recreate_swapchain: false, debug_callback, previous_frame_end,
|
||||
msaa_sample_count: render_config.msaa_samples
|
||||
}, events_loop)
|
||||
@@ -350,26 +347,11 @@ impl VulkanRenderer {
|
||||
builder.update_buffer(self.uniform_buffers[fb_index].clone(), uniform_buffer_data).unwrap();
|
||||
builder.begin_render_pass(self.framebuffers[fb_index].clone(), false, vec![ClearValue::None, ClearValue::Float([0.0, 0.0, 0.0, 1.0]), ClearValue::Depth(1.0)]).unwrap();
|
||||
|
||||
// Load and draw meshes etc.
|
||||
for i in 0..self.game_data.game_objects.len() {
|
||||
let game_object = &self.game_data.game_objects[i];
|
||||
let mesh = &self.game_data.meshes[game_object.mesh_index];
|
||||
self.game_data.push_constants.model = game_object.get_model_matrix().into();
|
||||
|
||||
builder.draw_indexed(
|
||||
self.pipeline.clone(),
|
||||
&self.dynamic_state,
|
||||
vec![mesh.vertex_buffer.clone()],
|
||||
mesh.index_buffer.clone(),
|
||||
game_object.descriptor_sets[fb_index].clone(),
|
||||
self.game_data.push_constants.clone()).unwrap();
|
||||
// Draw meshes etc.
|
||||
for pipeline in &self.pipelines {
|
||||
pipeline.draw(&mut builder, fb_index, &self.game_data, &self.dynamic_state);
|
||||
}
|
||||
|
||||
// Draw line grid
|
||||
if self.game_data.use_line_pipeline {
|
||||
builder.draw(self.line_pipeline.clone(), &self.dynamic_state, vec![self.line_vertex_buffer.clone()], (), self.game_data.line_push_constants.clone()).unwrap();
|
||||
}
|
||||
|
||||
|
||||
// General cleanup
|
||||
builder.end_render_pass().unwrap();
|
||||
Arc::new(builder.build().unwrap())
|
||||
@@ -416,12 +398,9 @@ impl VulkanRenderer {
|
||||
|
||||
// recreate pipeline if requested
|
||||
if self.game_data.recreate_pipeline {
|
||||
if let Some(pipeline_ok) = create_pipeline::<Vertex>(self.device.clone(), self.render_pass.clone(), false) {
|
||||
self.pipeline = pipeline_ok;
|
||||
println!("Updated pipeline.");
|
||||
} else {
|
||||
println!("Failed to update pipeline.");
|
||||
}
|
||||
let device = self.device.clone();
|
||||
let render_pass = self.render_pass.clone();
|
||||
self.pipelines.iter_mut().for_each(|pipeline| pipeline.recreate_pipeline(device.clone(), render_pass.clone()));
|
||||
self.game_data.recreate_pipeline = false;
|
||||
}
|
||||
|
||||
@@ -523,27 +502,27 @@ impl VulkanRenderer {
|
||||
).unwrap();
|
||||
|
||||
// Generate mipmaps
|
||||
let mut mip_width = image_view.dimensions().width() as i32;
|
||||
let mut mip_height = image_view.dimensions().height() as i32;
|
||||
// let mut mip_width = image_view.dimensions().width() as i32;
|
||||
// let mut mip_height = image_view.dimensions().height() as i32;
|
||||
|
||||
for i in 0..image_view.mipmap_levels() {
|
||||
command_buffer_builder.blit_image(
|
||||
image_view.clone(),
|
||||
[0; 3],
|
||||
[mip_width, mip_height, 1],
|
||||
0,
|
||||
i,
|
||||
image_view.clone(),
|
||||
[0; 3],
|
||||
[mip_width / 2, mip_height / 2, 1],
|
||||
0,
|
||||
i + 1,
|
||||
dimensions.array_layers_with_cube(),
|
||||
Filter::Linear).unwrap();
|
||||
// for i in 0..image_view.mipmap_levels() {
|
||||
// command_buffer_builder.blit_image(
|
||||
// image_view.clone(),
|
||||
// [0; 3],
|
||||
// [mip_width, mip_height, 1],
|
||||
// 0,
|
||||
// i,
|
||||
// image_view.clone(),
|
||||
// [0; 3],
|
||||
// [mip_width / 2, mip_height / 2, 1],
|
||||
// 0,
|
||||
// i + 1,
|
||||
// dimensions.array_layers_with_cube(),
|
||||
// Filter::Linear).unwrap();
|
||||
|
||||
if mip_width > 1 { mip_width = mip_width / 2; }
|
||||
if mip_height > 1 { mip_height = mip_height / 2; }
|
||||
}
|
||||
// if mip_width > 1 { mip_width = mip_width / 2; }
|
||||
// if mip_height > 1 { mip_height = mip_height / 2; }
|
||||
// }
|
||||
|
||||
let command_buffer = command_buffer_builder.build().unwrap();
|
||||
let command_buffer_future = command_buffer.execute(self.queue.clone()).unwrap();
|
||||
@@ -552,22 +531,8 @@ impl VulkanRenderer {
|
||||
self.game_data.textures.push(image_view);
|
||||
}
|
||||
|
||||
pub fn add_game_object(self: &mut Self, mut game_object: GameObject) -> GameObjectHandle {
|
||||
let descriptor_set_layout = self.pipeline.descriptor_set_layout(0).unwrap().clone();
|
||||
|
||||
println!("Diff: {:?}, Norm: {:?}", game_object.texture_index, game_object.normal_map_index);
|
||||
|
||||
let descriptor_sets = self.uniform_buffers.iter().map(|uniform_buffer| {
|
||||
let builder = PersistentDescriptorSet::start(descriptor_set_layout.clone());
|
||||
let result: Arc<RendererDescriptorSets> = Arc::new(builder
|
||||
.add_buffer(uniform_buffer.clone()).unwrap()
|
||||
.add_sampled_image(self.game_data.textures[game_object.texture_index].clone(), self.sampler.clone()).unwrap()
|
||||
.add_sampled_image(self.game_data.textures[game_object.normal_map_index].clone(), self.sampler.clone()).unwrap()
|
||||
.build().unwrap());
|
||||
result
|
||||
}).collect();
|
||||
|
||||
game_object.descriptor_sets = descriptor_sets;
|
||||
pub fn add_game_object(self: &mut Self, mut game_object: GameObject, pipeline_index: usize) -> GameObjectHandle {
|
||||
self.pipelines[pipeline_index].create_descriptor_set(&mut game_object, self);
|
||||
self.game_data.game_objects.push(game_object);
|
||||
|
||||
GameObjectHandle {
|
||||
@@ -621,71 +586,4 @@ fn window_size_dependent_setup(device: Arc<Device>, images: &[Arc<SwapchainImage
|
||||
}
|
||||
|
||||
framebuffers
|
||||
}
|
||||
|
||||
pub mod vs {
|
||||
vulkano_shaders::shader!{
|
||||
ty: "vertex",
|
||||
path: "shaders/triangle.vert"
|
||||
}
|
||||
}
|
||||
|
||||
pub mod line_vs {
|
||||
vulkano_shaders::shader!{
|
||||
ty: "vertex",
|
||||
path: "shaders/line.vert"
|
||||
}
|
||||
}
|
||||
|
||||
pub mod fs {
|
||||
vulkano_shaders::shader! {
|
||||
ty: "fragment",
|
||||
path: "shaders/triangle.frag"
|
||||
}
|
||||
}
|
||||
|
||||
pub mod line_fs {
|
||||
vulkano_shaders::shader! {
|
||||
ty: "fragment",
|
||||
path: "shaders/line.frag"
|
||||
}
|
||||
}
|
||||
|
||||
fn create_pipeline<V: vulkano::pipeline::vertex::Vertex>(device: Arc<Device>, render_pass: Arc<dyn RenderPassAbstract + Send + Sync>, is_line: bool) -> Option<Arc<dyn GraphicsPipelineAbstract + Send + Sync>> {
|
||||
let sub_pass = Subpass::from(render_pass.clone(), 0).unwrap();
|
||||
let pipeline;
|
||||
|
||||
if is_line {
|
||||
let vertex_shader = line_vs::Shader::load(device.clone()).unwrap();
|
||||
let fragment_shader = line_fs::Shader::load(device.clone()).unwrap();
|
||||
|
||||
pipeline = Arc::new(GraphicsPipeline::start()
|
||||
.vertex_input_single_buffer::<V>()
|
||||
.vertex_shader(vertex_shader.main_entry_point(), ())
|
||||
.line_list()
|
||||
.viewports_dynamic_scissors_irrelevant(1)
|
||||
.depth_stencil_simple_depth()
|
||||
.fragment_shader(fragment_shader.main_entry_point(), ())
|
||||
.render_pass(sub_pass.clone())
|
||||
.build(device.clone())
|
||||
.unwrap());
|
||||
} else {
|
||||
let vertex_shader = vs::Shader::load(device.clone()).unwrap();
|
||||
let fragment_shader = fs::Shader::load(device.clone()).unwrap();
|
||||
|
||||
pipeline = Arc::new(GraphicsPipeline::start()
|
||||
.vertex_input_single_buffer::<V>()
|
||||
.vertex_shader(vertex_shader.main_entry_point(), ())
|
||||
.triangle_list()
|
||||
.viewports_dynamic_scissors_irrelevant(1)
|
||||
.depth_stencil_simple_depth()
|
||||
.fragment_shader(fragment_shader.main_entry_point(), ())
|
||||
.blend_alpha_blending()
|
||||
.cull_mode_back()
|
||||
.render_pass(sub_pass.clone())
|
||||
.build(device.clone())
|
||||
.unwrap());
|
||||
}
|
||||
|
||||
return Some(pipeline);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user