From 76ed448e59bfb2abfe2b89eed1af629853683065 Mon Sep 17 00:00:00 2001 From: ErikWDev Date: Wed, 18 Dec 2024 21:52:02 +0100 Subject: [PATCH 1/2] feature: added and implemented set_viewport --- blade-graphics/src/gles/command.rs | 32 +++++++++++++++++++++----- blade-graphics/src/gles/mod.rs | 4 ++-- blade-graphics/src/lib.rs | 8 +++++++ blade-graphics/src/metal/command.rs | 24 ++++++++++++++++++++ blade-graphics/src/traits.rs | 3 ++- blade-graphics/src/vulkan/command.rs | 34 +++++++++++++++++++++++++++- 6 files changed, 95 insertions(+), 10 deletions(-) diff --git a/blade-graphics/src/gles/command.rs b/blade-graphics/src/gles/command.rs index 1f140c9..19e2b6f 100644 --- a/blade-graphics/src/gles/command.rs +++ b/blade-graphics/src/gles/command.rs @@ -1,4 +1,4 @@ -use std::{str, time::Duration}; +use std::{ops::Range, str, time::Duration}; const COLOR_ATTACHMENTS: &[u32] = &[ glow::COLOR_ATTACHMENT0, @@ -210,8 +210,13 @@ impl super::CommandEncoder { targets.colors.len() as _ )); self.commands.push(super::Command::SetViewport { - size: target_size, - depth: 0.0..1.0, + viewport: crate::Viewport { + x: 0.0, + y: 0.0, + w: target_size[0] as _, + h: target_size[1] as _, + }, + depth_range: 0.0..1.0, }); self.commands .push(super::Command::SetScissor(crate::ScissorRect { @@ -442,6 +447,13 @@ impl crate::traits::RenderPipelineEncoder for super::PipelineEncoder<'_> { self.commands.push(super::Command::SetScissor(rect.clone())); } + fn set_viewport(&mut self, viewport: &crate::Viewport, depth_range: Range) { + self.commands.push(super::Command::SetViewport { + viewport: viewport.clone(), + depth_range, + }); + } + fn bind_vertex(&mut self, index: u32, vertex_buf: crate::BufferPiece) { assert_eq!(index, 0); self.commands.push(super::Command::BindVertex { @@ -1008,9 +1020,17 @@ impl super::Command { (None, None) => (), }, Self::Barrier => unimplemented!(), - Self::SetViewport { size, ref depth } => { - gl.viewport(0, 0, size[0] as i32, size[1] as i32); - gl.depth_range_f32(depth.start, depth.end); + Self::SetViewport { + ref viewport, + ref depth_range, + } => { + gl.viewport( + viewport.x as i32, + viewport.y as i32, + viewport.w as i32, + viewport.h as i32, + ); + gl.depth_range_f32(depth_range.start, depth_range.end); } Self::SetScissor(ref rect) => { gl.scissor(rect.x, rect.y, rect.w as i32, rect.h as i32); diff --git a/blade-graphics/src/gles/mod.rs b/blade-graphics/src/gles/mod.rs index 83a0f2e..8e1a294 100644 --- a/blade-graphics/src/gles/mod.rs +++ b/blade-graphics/src/gles/mod.rs @@ -297,8 +297,8 @@ enum Command { }, Barrier, SetViewport { - size: [u16; 2], - depth: Range, + viewport: crate::Viewport, + depth_range: Range, }, SetScissor(crate::ScissorRect), SetStencilFunc { diff --git a/blade-graphics/src/lib.rs b/blade-graphics/src/lib.rs index 417038d..4bce060 100644 --- a/blade-graphics/src/lib.rs +++ b/blade-graphics/src/lib.rs @@ -1142,4 +1142,12 @@ pub struct ScissorRect { pub h: u32, } +#[derive(Clone, Debug, PartialEq)] +pub struct Viewport { + pub x: f32, + pub y: f32, + pub w: f32, + pub h: f32, +} + pub type Timings = std::collections::HashMap; diff --git a/blade-graphics/src/metal/command.rs b/blade-graphics/src/metal/command.rs index ebd5dad..a0e951c 100644 --- a/blade-graphics/src/metal/command.rs +++ b/blade-graphics/src/metal/command.rs @@ -529,6 +529,18 @@ impl super::RenderCommandEncoder<'_> { self.raw.set_scissor_rect(scissor); } + pub fn set_viewport(&mut self, viewport: &crate::Viewport, depth_range: Range) { + let viewport = metal::MTLViewport { + originX: viewport.x as _, + originY: viewport.y as _, + width: viewport.w as _, + height: viewport.h as _, + znear: depth_range.start as _, + zfar: depth_range.end as _, // TODO: aparently broken on some Intel GPU:s? see wgpu-hal + }; + self.raw.set_viewport(viewport); + } + pub fn with<'p>( &'p mut self, pipeline: &'p super::RenderPipeline, @@ -646,6 +658,18 @@ impl crate::traits::RenderPipelineEncoder for super::RenderPipelineContext<'_> { self.encoder.set_scissor_rect(scissor); } + fn set_viewport(&mut self, viewport: &crate::Viewport, depth_range: Range) { + let viewport = metal::MTLViewport { + originX: viewport.x as _, + originY: viewport.y as _, + width: viewport.w as _, + height: viewport.h as _, + znear: depth_range.start as _, + zfar: depth_range.end as _, // TODO: aparently broken on some Intel GPU:s? see wgpu-hal + }; + self.encoder.set_viewport(viewport); + } + fn bind_vertex(&mut self, index: u32, vertex_buf: crate::BufferPiece) { self.encoder.set_vertex_buffer( index as u64, diff --git a/blade-graphics/src/traits.rs b/blade-graphics/src/traits.rs index 5ac2327..62c85c4 100644 --- a/blade-graphics/src/traits.rs +++ b/blade-graphics/src/traits.rs @@ -1,4 +1,4 @@ -use std::{fmt::Debug, hash::Hash}; +use std::{fmt::Debug, hash::Hash, ops::Range}; pub trait ResourceDevice { type Buffer: Send + Sync + Clone + Copy + Debug + Hash + PartialEq; @@ -121,6 +121,7 @@ pub trait RenderPipelineEncoder: PipelineEncoder { //TODO: reconsider exposing this here fn set_scissor_rect(&mut self, rect: &super::ScissorRect); + fn set_viewport(&mut self, viewport: &super::Viewport, depth_range: Range); fn bind_vertex(&mut self, index: u32, vertex_buf: Self::BufferPiece); fn draw( &mut self, diff --git a/blade-graphics/src/vulkan/command.rs b/blade-graphics/src/vulkan/command.rs index c74b75e..ac24dd3 100644 --- a/blade-graphics/src/vulkan/command.rs +++ b/blade-graphics/src/vulkan/command.rs @@ -1,5 +1,5 @@ use ash::vk; -use std::{str, time::Duration}; +use std::{ops::Range, str, time::Duration}; impl super::CrashHandler { fn add_marker(&mut self, marker: &str) -> u32 { @@ -816,6 +816,22 @@ impl<'a> super::RenderCommandEncoder<'a> { }; } + pub fn set_viewport(&mut self, viewport: &crate::Viewport, depth_range: Range) { + let vk_viewports = [vk::Viewport { + x: viewport.x, + y: viewport.y, + width: viewport.w, + height: -viewport.h, // flip Y + min_depth: depth_range.start, + max_depth: depth_range.end, + }]; + unsafe { + self.device + .core + .cmd_set_viewport(self.cmd_buf.raw, 0, &vk_viewports) + }; + } + pub fn with<'b, 'p>( &'b mut self, pipeline: &'p super::RenderPipeline, @@ -922,6 +938,22 @@ impl crate::traits::RenderPipelineEncoder for super::PipelineEncoder<'_, '_> { }; } + fn set_viewport(&mut self, viewport: &crate::Viewport, depth_range: Range) { + let vk_viewports = [vk::Viewport { + x: viewport.x, + y: viewport.y, + width: viewport.w, + height: -viewport.h, // flip Y + min_depth: depth_range.start, + max_depth: depth_range.end, + }]; + unsafe { + self.device + .core + .cmd_set_viewport(self.cmd_buf.raw, 0, &vk_viewports) + }; + } + fn bind_vertex(&mut self, index: u32, vertex_buf: crate::BufferPiece) { unsafe { self.device.core.cmd_bind_vertex_buffers( From 39f2b4a42fc7227cce0d2dbb3ea3bd24194be797 Mon Sep 17 00:00:00 2001 From: ErikWDev Date: Wed, 18 Dec 2024 21:57:49 +0100 Subject: [PATCH 2/2] metal, missing import --- blade-graphics/src/metal/command.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blade-graphics/src/metal/command.rs b/blade-graphics/src/metal/command.rs index a0e951c..42b1296 100644 --- a/blade-graphics/src/metal/command.rs +++ b/blade-graphics/src/metal/command.rs @@ -1,4 +1,4 @@ -use std::{marker::PhantomData, mem, time::Duration}; +use std::{marker::PhantomData, mem, ops::Range, time::Duration}; impl crate::ShaderBindable for T { fn bind_to(&self, ctx: &mut super::PipelineContext, index: u32) {