From c11ed5c897503a374f2a81bd76198d3dba476fd6 Mon Sep 17 00:00:00 2001 From: Till Date: Tue, 13 Aug 2019 15:38:10 +0200 Subject: [PATCH] progress? --- shaders/triangle.frag | 7 ++- shaders/triangle.vert | 12 ++-- src/vulkan.rs | 125 ++++++++++++++++++++++-------------------- 3 files changed, 76 insertions(+), 68 deletions(-) diff --git a/shaders/triangle.frag b/shaders/triangle.frag index d7cec41..d49105c 100644 --- a/shaders/triangle.frag +++ b/shaders/triangle.frag @@ -1,11 +1,12 @@ #version 450 +#extension GL_ARB_separate_shader_objects : enable layout(location = 0) in vec2 tex_coords; -layout(location = 0) out vec4 f_color; +layout(location = 0) out vec4 out_color; -layout(set = 0, binding = 0) uniform sampler2D tex; +layout(binding = 1) uniform sampler2D tex; void main() { - f_color = texture(tex, tex_coords); + out_color = texture(tex, tex_coords); } \ No newline at end of file diff --git a/shaders/triangle.vert b/shaders/triangle.vert index 0550ccd..e6e49c0 100644 --- a/shaders/triangle.vert +++ b/shaders/triangle.vert @@ -1,17 +1,17 @@ #version 450 #extension GL_ARB_separate_shader_objects : enable +layout(binding = 0) uniform UniformBufferObject { + mat4 view; + mat4 projection; + float time; +} ubo; + layout(location = 0) in vec3 position; layout(location = 1) in vec2 uv; layout(location = 0) out vec2 tex_coords; -//layout(binding = 0) uniform UniformBufferObject { -// mat4 view; -// mat4 projection; -// float time; -//} ubo; - layout(push_constant) uniform PushConstants { mat4 model; mat4 view; diff --git a/src/vulkan.rs b/src/vulkan.rs index aa8646b..8d681db 100644 --- a/src/vulkan.rs +++ b/src/vulkan.rs @@ -1,5 +1,5 @@ -use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer, CpuBufferPool}; -use vulkano::command_buffer::{AutoCommandBufferBuilder, DynamicState}; +use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer}; +use vulkano::command_buffer::{AutoCommandBufferBuilder, DynamicState, AutoCommandBuffer}; use vulkano::device::{Device, DeviceExtensions, Queue}; use vulkano::framebuffer::{Framebuffer, FramebufferAbstract, Subpass, RenderPassAbstract}; use vulkano::image::{SwapchainImage, AttachmentImage, ImageUsage, ImmutableImage, Dimensions}; @@ -14,7 +14,7 @@ use vulkano::sync; use vulkano::format::{Format, ClearValue}; use vulkano::instance::debug::{DebugCallback, MessageTypes}; use vulkano::memory::pool::{PotentialDedicatedAllocation, StdMemoryPoolAlloc}; -use vulkano::descriptor::descriptor_set::{PersistentDescriptorSet, FixedSizeDescriptorSetsPool, FixedSizeDescriptorSet, PersistentDescriptorSetBuf, PersistentDescriptorSetSampler}; +use vulkano::descriptor::descriptor_set::{PersistentDescriptorSet, FixedSizeDescriptorSetsPool, FixedSizeDescriptorSet}; use vulkano::descriptor::DescriptorSet; use vulkano::sampler::{Sampler, Filter, MipmapMode, SamplerAddressMode}; @@ -71,14 +71,13 @@ pub struct Mesh { pub struct GameObject { pub mesh_index: usize, pub texture_index: usize, - pub descriptor_set: Arc, pub model_matrix: Matrix4, } pub(crate) type GameObjectHandle = usize; pub(crate) type MeshHandle = usize; -//type FixedGraphicsDescriptorSet = std::sync::Arc, (((), PersistentDescriptorSetSampler), PersistentDescriptorSetBuf>>)>>; +type FixedGraphicsDescriptorSet = Arc, ((), vulkano::descriptor::descriptor_set::PersistentDescriptorSetBuf>>)>>; pub struct GameData { pub start_time: SystemTime, @@ -98,7 +97,6 @@ pub struct VulkanRenderer { pub device: Arc, pub framebuffers: Vec>, pub sampler: Arc, - pub default_descriptor_set: Arc, pub dynamic_state: DynamicState, pub pipeline: Arc, pub line_pipeline: Arc, @@ -111,7 +109,8 @@ pub struct VulkanRenderer { pub recreate_swapchain: bool, pub debug_callback: Option, pub previous_frame_end: Option>, -// pub uniform_buffers: CpuBufferPool, + pub uniform_buffers: Vec>>, + pub descriptor_sets: Vec, } pub enum RenderLoopResult { @@ -155,9 +154,9 @@ impl VulkanRenderer { }; let app_info = ApplicationInfo { - application_name: Some("Asuro Editor".into()), + application_name: Some("Asuro's Editor".into()), application_version: Some(Version { major: 0, minor: 1, patch: 0 }), - engine_name: Some("Asuro Rust Engine".into()), + engine_name: Some("Asuro's Rust Engine".into()), engine_version: Some(Version { major: 0, minor: 1, patch: 0 }) }; @@ -222,26 +221,9 @@ impl VulkanRenderer { let (swapchain, images) = { let caps = surface.capabilities(physical).unwrap(); - let usage = caps.supported_usage_flags; - - // The alpha mode indicates how the alpha value of the final image will behave. For example - // you can choose whether the window will be opaque or transparent. let alpha = caps.supported_composite_alpha.iter().next().unwrap(); - - // Choosing the internal format that the images will have. let format = caps.supported_formats[0].0; - - // The dimensions of the window, only used to initially setup the swapchain. - // NOTE: - // On some drivers the swapchain dimensions are specified by `caps.current_extent` and the - // swapchain size must use these dimensions. - // These dimensions are always the same as the window dimensions - // - // However other drivers dont specify a value i.e. `caps.current_extent` is `None` - // These drivers will allow anything but the only sensible value is the window dimensions. - // - // Because for both of these cases, the swapchain needs to be the window dimensions, we just use that. data.dimensions = if let Some(dimensions) = window.get_inner_size() { let dimensions: (u32, u32) = dimensions.to_physical(window.get_hidpi_factor()).into(); [dimensions.0, dimensions.1] @@ -304,11 +286,6 @@ impl VulkanRenderer { default_tex_future.flush().unwrap(); - let default_descriptor_set = Arc::new(PersistentDescriptorSet::start(pipeline.clone(), 0) - .add_sampled_image(default_tex.clone(), sampler.clone()).unwrap() - .build().unwrap() - ); - data.textures.push(default_tex); // Dynamic viewports allow us to recreate just the viewport when the window is resized @@ -319,7 +296,33 @@ impl VulkanRenderer { // can draw we also need to create the actual framebuffers. let framebuffers = window_size_dependent_setup(device.clone(), &images, render_pass.clone(), &mut dynamic_state); -// let uniform_buffers = CpuBufferPool::::new(device.clone(), BufferUsage::all()); + let mut uniform_buffers = Vec::new(); + let uniform_buffer = vs::ty::UniformBufferObject { view: Matrix4::identity().into(), projection: Matrix4::identity().into(), time: 0.0 }; + + for _ in 0..swapchain.num_images() { + uniform_buffers.push(CpuAccessibleBuffer::from_data( + device.clone(), + BufferUsage::uniform_buffer_transfer_destination(), + uniform_buffer, + ).unwrap()); + } + + let descriptor_set_pool = Mutex::new(FixedSizeDescriptorSetsPool::new(pipeline.clone(), 0)); + let descriptor_sets = uniform_buffers + .iter() + .map(|uniform_buffer| + Arc::new( + descriptor_set_pool + .lock() + .unwrap() + .next() + .add_buffer(uniform_buffer.clone()) + .unwrap() + .build() + .unwrap() + ) + ) + .collect(); // In the loop below we are going to submit commands to the GPU. Submitting a command produces // an object that implements the `GpuFuture` trait, which holds the resources for as long as @@ -330,11 +333,39 @@ impl VulkanRenderer { let previous_frame_end = Some(Box::new(sync::now(device.clone())) as Box); VulkanRenderer { game_data: data, device, framebuffers, sampler, - dynamic_state, pipeline, line_pipeline, default_descriptor_set, + dynamic_state, pipeline, line_pipeline, uniform_buffers, descriptor_sets, surface, swapchain, render_pass, queue, line_vertex_buffer, events_loop, recreate_swapchain: false, debug_callback, previous_frame_end } } + fn create_command_buffers(self: &mut Self) -> Vec> { + let mut buffers = Vec::new(); + for fb_index in 0..self.framebuffers.len() { + let mut cbb = AutoCommandBufferBuilder::primary_simultaneous_use(self.device.clone(), self.queue.family()).unwrap() + .update_buffer(self.uniform_buffers[fb_index].clone(), vs::ty::UniformBufferObject { view: Matrix4::identity().into(), projection: Matrix4::identity().into(), time: 0.0 }).unwrap() + .begin_render_pass(self.framebuffers[fb_index].clone(), false, vec![ClearValue::Float([0.0, 0.0, 0.0, 1.0]), ClearValue::Depth(1.0)]).unwrap(); + + 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.model_matrix.into(); + cbb = cbb.draw_indexed( + self.pipeline.clone(), + &self.dynamic_state, + vec![mesh.vertex_buffer.clone()], + mesh.index_buffer.clone(), + self.descriptor_sets[fb_index].clone(), + self.game_data.push_constants.clone()).unwrap() + } + + cbb = cbb.draw(self.line_pipeline.clone(), &self.dynamic_state, vec![self.line_vertex_buffer.clone()], (), self.game_data.line_push_constants.clone()).unwrap() + .end_render_pass().unwrap(); + + buffers.push(Arc::new(cbb.build().unwrap())); + } + buffers + } + pub fn render_loop(self: &mut Self, game: &mut dyn Game) -> RenderLoopResult { // It is important to call this function from time to time, otherwise resources will keep // accumulating and you will eventually reach an out of memory error. @@ -396,25 +427,7 @@ impl VulkanRenderer { Err(err) => panic!("{:?}", err) }; - let mut cbb = AutoCommandBufferBuilder::primary_one_time_submit(self.device.clone(), self.queue.family()).unwrap() - .begin_render_pass(self.framebuffers[image_num].clone(), false, vec![[0.0, 0.0, 0.0, 1.0].into(), ClearValue::Depth(1.0)]).unwrap(); - - 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.model_matrix.into(); - cbb = cbb.draw_indexed(self.pipeline.clone(), - &self.dynamic_state, - vec![mesh.vertex_buffer.clone()], - mesh.index_buffer.clone(), - game_object.descriptor_set.clone(), - self.game_data.push_constants.clone()).unwrap(); - } - - cbb = cbb.draw(self.line_pipeline.clone(), &self.dynamic_state, vec![self.line_vertex_buffer.clone()], (), self.game_data.line_push_constants.clone()).unwrap() - .end_render_pass().unwrap(); - - let command_buffer = cbb.build().unwrap(); + let command_buffer = self.create_command_buffers()[image_num].clone(); let future = self.previous_frame_end.take().unwrap().join(acquire_future) .then_execute(self.queue.clone(), command_buffer).unwrap() @@ -599,13 +612,7 @@ fn create_pipeline(device: Arc, re impl GameObject { pub fn new(mesh: MeshHandle, texture_index: usize, renderer: &VulkanRenderer) -> GameObject { - println!("Texid: {}", texture_index); - let descriptor_set = Arc::new(PersistentDescriptorSet::start(renderer.pipeline.clone(), 0) - .add_sampled_image(renderer.game_data.textures[texture_index].clone(), renderer.sampler.clone()).unwrap() - .build().unwrap() - ); - - GameObject { mesh_index: mesh, texture_index, descriptor_set, model_matrix: Matrix4::identity() } + GameObject { mesh_index: mesh, texture_index, model_matrix: Matrix4::identity() } } }