diff options
Diffstat (limited to 'stockton-render')
-rw-r--r-- | stockton-render/src/draw/camera.rs | 168 | ||||
-rw-r--r-- | stockton-render/src/draw/context.rs | 30 | ||||
-rw-r--r-- | stockton-render/src/draw/data/stockton.frag | 7 | ||||
-rw-r--r-- | stockton-render/src/draw/data/stockton.vert | 8 |
4 files changed, 58 insertions, 155 deletions
diff --git a/stockton-render/src/draw/camera.rs b/stockton-render/src/draw/camera.rs index cbad9b1..1a16803 100644 --- a/stockton-render/src/draw/camera.rs +++ b/stockton-render/src/draw/camera.rs @@ -19,7 +19,7 @@ use std::iter::once; use std::f32::consts::PI; use hal::prelude::*; use hal::buffer::Usage; -use na::{look_at_lh, perspective_lh_zo, radians}; +use na::{look_at_lh, perspective_lh_zo}; use core::mem::ManuallyDrop; @@ -30,6 +30,9 @@ use stockton_types::{Vector3, Matrix4}; use na::{Mat4, Vec4}; /// 90 degrees in radians +const R89: f32 = (PI / 180.0) * 89.0; + +/// 90 degrees in radians const R90: f32 = PI / 2.0; /// 180 degrees in radians @@ -69,32 +72,23 @@ pub struct CameraSettings { /// Holds settings related to the projection of world space to screen space /// Also holds maths for generating important matrices -pub struct WorkingCamera<'a> { +pub struct WorkingCamera { /// Settings for the camera settings: CameraSettings, /// Aspect ratio as a fraction aspect_ratio: f32, - /// Layout of the descriptor set to pass to the shader - pub descriptor_set_layout: ManuallyDrop<DescriptorSetLayout>, - - /// Buffer of memory used for passing data to shaders - // TODO: Does this need to be staged? - buffer: ManuallyDrop<StagedBuffer<'a, Matrix4>>, - - // TODO: Share descriptor pool with textures? - descriptor_pool: ManuallyDrop<DescriptorPool>, - descriptor_set: DescriptorSet, + /// Cached view projection matrix + vp_matrix: Mat4, - /// If true, buffer needs updated + /// If true, cached value needs updated is_dirty: bool } -impl<'a> WorkingCamera<'a> { - pub fn defaults(aspect_ratio: f32, device: &mut Device, adapter: &Adapter, - command_queue: &mut CommandQueue, - command_pool: &mut CommandPool) -> Result<WorkingCamera<'a>, error::CreationError> { +impl WorkingCamera { + /// Return a camera with default settings + pub fn defaults(aspect_ratio: f32) -> WorkingCamera { WorkingCamera::with_settings(CameraSettings { position: Vector3::new(0.0, 0.0, 0.0), rotation: Vector3::new(0.0, R90, 0.0), @@ -102,100 +96,33 @@ impl<'a> WorkingCamera<'a> { fov: f32::to_radians(90.0), near: 0.1, far: 1024.0, - }, aspect_ratio, device, adapter, command_queue, command_pool) + }, aspect_ratio) } - /// Return a camera with default settings - // TODO - pub fn with_settings(settings: CameraSettings, aspect_ratio: f32, device: &mut Device, adapter: &Adapter, - command_queue: &mut CommandQueue, - command_pool: &mut CommandPool) -> Result<WorkingCamera<'a>, error::CreationError> { - - let descriptor_type = { - use hal::pso::{DescriptorType, BufferDescriptorType, BufferDescriptorFormat}; - - DescriptorType::Buffer { - ty: BufferDescriptorType::Uniform, - format: BufferDescriptorFormat::Structured { - dynamic_offset: false - } - } - }; - - // Create set layout - let descriptor_set_layout = unsafe { - use hal::pso::{DescriptorSetLayoutBinding, ShaderStageFlags}; - - device.create_descriptor_set_layout( - &[ - DescriptorSetLayoutBinding { - binding: 0, - ty: descriptor_type, - count: 1, - stage_flags: ShaderStageFlags::VERTEX, - immutable_samplers: false - } - ], - &[], - ) - }.map_err(|_| error::CreationError::OutOfMemoryError)?; - - // Create pool and allocate set - let (descriptor_pool, descriptor_set) = unsafe { - use hal::pso::{DescriptorRangeDesc, DescriptorPoolCreateFlags}; - - let mut pool = device.create_descriptor_pool( - 1, - &[ - DescriptorRangeDesc { - ty: descriptor_type, - count: 1 - } - ], - DescriptorPoolCreateFlags::empty() - ).map_err(|_| error::CreationError::OutOfMemoryError)?; - - let set = pool.allocate_set(&descriptor_set_layout).map_err(|_| error::CreationError::OutOfMemoryError)?; - - (pool, set) - }; - - // Create buffer for descriptor - let mut buffer = StagedBuffer::new(device, adapter, Usage::UNIFORM, 1)?; - - // Bind our buffer to our descriptor set - unsafe { - use hal::pso::{Descriptor, DescriptorSetWrite}; - use hal::buffer::SubRange; - - device.write_descriptor_sets(once( - DescriptorSetWrite { - set: &descriptor_set, - binding: 0, - array_offset: 0, - descriptors: once( - Descriptor::Buffer(buffer.commit(device, command_queue, command_pool), SubRange::WHOLE) - ) - } - )); - } - - Ok(WorkingCamera { + /// Return a camera with the given settings + pub fn with_settings(settings: CameraSettings, aspect_ratio: f32) -> WorkingCamera { + WorkingCamera { aspect_ratio, settings, + vp_matrix: Mat4::identity(), + is_dirty: true + } + } - descriptor_set_layout: ManuallyDrop::new(descriptor_set_layout), - buffer: ManuallyDrop::new(buffer), - - descriptor_pool: ManuallyDrop::new(descriptor_pool), - descriptor_set: descriptor_set, + /// Get the VP matrix, updating cache if needed + pub fn get_matrix<'a>(&'a mut self) -> &'a Mat4 { + // Update matrix if needed + if self.is_dirty { + self.vp_matrix = self.calc_vp_matrix(); + self.is_dirty = false; + } - is_dirty: true - }) + // Return the matrix + &self.vp_matrix } /// Returns a matrix that transforms from world space to screen space - pub fn vp_matrix(&self) -> Matrix4 { + fn calc_vp_matrix(&self) -> Matrix4 { // Get look direction from euler angles let direction = euler_to_direction(&self.settings.rotation); @@ -238,10 +165,10 @@ impl<'a> WorkingCamera<'a> { self.settings.rotation += euler; // Clamp -pi/2 < pitch < pi/2 - if self.settings.rotation.x > R90 { - self.settings.rotation.x = R90; - } else if self.settings.rotation.x < -R90 { - self.settings.rotation.x = -R90; + if self.settings.rotation.x > R89 { + self.settings.rotation.x = R89; + } else if self.settings.rotation.x <= -R89 { + self.settings.rotation.x = -R89; } // -pi < yaw <= pi @@ -269,35 +196,6 @@ impl<'a> WorkingCamera<'a> { self.is_dirty = true; } - /// Ensures the VP matrix on the GPU is up-to-date - pub fn commit<'b>(&'b mut self, device: &Device, - command_queue: &mut CommandQueue, - command_pool: &mut CommandPool) -> &'b DescriptorSet { - // Update buffer if needed - if self.is_dirty { - self.buffer[0] = self.vp_matrix(); - self.buffer.commit(device, command_queue, command_pool); - - self.is_dirty = false; - } - - // Return the descriptor set for matrices - &self.descriptor_set - } - - /// This should be called before dropping - pub fn deactivate(mut self, device: &mut Device) -> () { - unsafe { - use core::ptr::read; - - ManuallyDrop::into_inner(read(&self.buffer)).deactivate(device); - - self.descriptor_pool.reset(); - device.destroy_descriptor_pool(ManuallyDrop::into_inner(read(&self.descriptor_pool))); - device.destroy_descriptor_set_layout(ManuallyDrop::into_inner(read(&self.descriptor_set_layout))); - } - } - pub fn camera_pos(&self) -> Vector3 { self.settings.position } diff --git a/stockton-render/src/draw/context.rs b/stockton-render/src/draw/context.rs index 16fbf9f..a02203d 100644 --- a/stockton-render/src/draw/context.rs +++ b/stockton-render/src/draw/context.rs @@ -118,7 +118,7 @@ pub struct RenderingContext<'a> { pub vert_buffer: ManuallyDrop<StagedBuffer<'a, UVPoint>>, pub index_buffer: ManuallyDrop<StagedBuffer<'a, (u16, u16, u16)>>, - camera: ManuallyDrop<WorkingCamera<'a>> + camera: WorkingCamera } impl<'a> RenderingContext<'a> { @@ -268,10 +268,9 @@ impl<'a> RenderingContext<'a> { // Camera // TODO: Settings let ratio = extent.width as f32 / extent.height as f32; - let camera = WorkingCamera::defaults(ratio, &mut device, &adapter, &mut queue_group.queues[0], &mut cmd_pool)?; + let camera = WorkingCamera::defaults(ratio); let mut descriptor_set_layouts: ArrayVec<[_; 2]> = ArrayVec::new(); - descriptor_set_layouts.push(camera.descriptor_set_layout.deref()); descriptor_set_layouts.push(texture_store.descriptor_set_layout.deref()); // Graphics pipeline @@ -308,7 +307,7 @@ impl<'a> RenderingContext<'a> { vert_buffer: ManuallyDrop::new(vert_buffer), index_buffer: ManuallyDrop::new(index_buffer), - camera: ManuallyDrop::new(camera) + camera }) } @@ -339,7 +338,6 @@ impl<'a> RenderingContext<'a> { let (pipeline_layout, pipeline) = { let mut descriptor_set_layouts: ArrayVec<[_; 2]> = ArrayVec::new(); - descriptor_set_layouts.push(self.camera.descriptor_set_layout.deref()); descriptor_set_layouts.push(self.texture_store.descriptor_set_layout.deref()); let subpass = hal::pass::Subpass { @@ -583,7 +581,11 @@ impl<'a> RenderingContext<'a> { // Pipeline layout let layout = unsafe { - device.create_pipeline_layout(set_layouts, &[]) + device.create_pipeline_layout( + set_layouts, + // vp matrix, 4x4 f32 + &[(ShaderStageFlags::VERTEX, 0..64)] + ) }.map_err(|_| error::CreationError::OutOfMemoryError)?; // Colour blending @@ -752,6 +754,7 @@ impl<'a> RenderingContext<'a> { unsafe { use hal::buffer::{IndexBufferView, SubRange}; use hal::command::{SubpassContents, CommandBufferFlags, ClearValue, ClearColor}; + use hal::pso::ShaderStageFlags; let buffer = &mut self.cmd_buffers[image_index]; let clear_values = [ClearValue { @@ -789,10 +792,7 @@ impl<'a> RenderingContext<'a> { ); buffer.bind_graphics_pipeline(&self.pipeline); - let mut descriptor_sets: ArrayVec<[_; 2]> = ArrayVec::new(); - descriptor_sets.push(self.camera.commit(&self.device, - &mut self.queue_group.queues[0], - &mut self.cmd_pool)); + let mut descriptor_sets: ArrayVec<[_; 1]> = ArrayVec::new(); descriptor_sets.push(&self.texture_store.descriptor_set); buffer.bind_graphics_descriptor_sets( @@ -802,6 +802,15 @@ impl<'a> RenderingContext<'a> { &[] ); + let vp = self.camera.get_matrix().as_slice(); + let vp = std::mem::transmute::<&[f32], &[u32]>(vp); + + buffer.push_graphics_constants( + &self.pipeline_layout, + ShaderStageFlags::VERTEX, + 0, + vp); + buffer.bind_vertex_buffers(0, vbufs); buffer.bind_index_buffer(IndexBufferView { buffer: ibuf, @@ -924,7 +933,6 @@ impl<'a> core::ops::Drop for RenderingContext<'a> { ManuallyDrop::into_inner(read(&self.vert_buffer)).deactivate(&mut self.device); ManuallyDrop::into_inner(read(&self.index_buffer)).deactivate(&mut self.device); ManuallyDrop::into_inner(read(&self.texture_store)).deactivate(&mut self.device); - ManuallyDrop::into_inner(read(&self.camera)).deactivate(&mut self.device); self.device.destroy_command_pool( ManuallyDrop::into_inner(read(&self.cmd_pool)), diff --git a/stockton-render/src/draw/data/stockton.frag b/stockton-render/src/draw/data/stockton.frag index b558335..c50e1b9 100644 --- a/stockton-render/src/draw/data/stockton.frag +++ b/stockton-render/src/draw/data/stockton.frag @@ -1,9 +1,8 @@ #version 450 -// DescriptorSet 0 = Matrices -// DescriptorSet 1 = Textures -layout(set = 1, binding = 0) uniform texture2D tex[2]; -layout(set = 1, binding = 1) uniform sampler samp[2]; +// DescriptorSet 0 = Textures +layout(set = 0, binding = 0) uniform texture2D tex[2]; +layout(set = 0, binding = 1) uniform sampler samp[2]; layout (location = 1) in vec2 frag_uv; layout (location = 2) in flat int frag_tex; diff --git a/stockton-render/src/draw/data/stockton.vert b/stockton-render/src/draw/data/stockton.vert index d3f4438..3146a25 100644 --- a/stockton-render/src/draw/data/stockton.vert +++ b/stockton-render/src/draw/data/stockton.vert @@ -1,11 +1,9 @@ #version 450 // DescriptorSet 0 = Matrices -layout (binding = 0) uniform UniformBufferObject { +layout (push_constant) uniform PushConsts { mat4 vp; -} matrices; - -// DescriptorSet 1 = Textures/Samplers +} push; layout (location = 0) in vec3 position; layout (location = 1) in vec2 uv; @@ -19,7 +17,7 @@ layout (location = 2) out flat int frag_tex; void main() { - gl_Position = matrices.vp * vec4(position, 1.0); + gl_Position = push.vp * vec4(position, 1.0); frag_uv = uv; frag_tex = tex; }
\ No newline at end of file |