use std::ops::Range;
#[derive(Debug, Clone)]
pub enum ViewportState {
Fixed {
data: Vec<(Viewport, Scissor)>,
},
FixedViewport {
viewports: Vec<Viewport>,
scissor_count_dynamic: bool,
},
FixedScissor {
scissors: Vec<Scissor>,
viewport_count_dynamic: bool,
},
Dynamic {
count: u32,
viewport_count_dynamic: bool,
scissor_count_dynamic: bool,
},
}
impl ViewportState {
#[inline]
pub fn new() -> Self {
Self::Fixed { data: Vec::new() }
}
pub fn viewport_fixed_scissor_fixed(
data: impl IntoIterator<Item = (Viewport, Scissor)>,
) -> Self {
Self::Fixed {
data: data.into_iter().collect(),
}
}
pub fn viewport_fixed_scissor_irrelevant(data: impl IntoIterator<Item = Viewport>) -> Self {
Self::Fixed {
data: data
.into_iter()
.map(|viewport| (viewport, Scissor::irrelevant()))
.collect(),
}
}
#[inline]
pub fn viewport_dynamic_scissor_irrelevant() -> Self {
Self::FixedScissor {
scissors: vec![Scissor::irrelevant()],
viewport_count_dynamic: false,
}
}
#[inline]
pub fn viewport_dynamic_scissor_dynamic(count: u32) -> Self {
Self::Dynamic {
count,
viewport_count_dynamic: false,
scissor_count_dynamic: false,
}
}
#[inline]
pub fn viewport_count_dynamic_scissor_count_dynamic() -> Self {
Self::Dynamic {
count: 0,
viewport_count_dynamic: true,
scissor_count_dynamic: true,
}
}
#[inline]
pub fn count(&self) -> Option<u32> {
Some(match *self {
ViewportState::Fixed { ref data } => data.len() as u32,
ViewportState::FixedViewport { ref viewports, .. } => viewports.len() as u32,
ViewportState::FixedScissor { ref scissors, .. } => scissors.len() as u32,
ViewportState::Dynamic {
viewport_count_dynamic: true,
scissor_count_dynamic: true,
..
} => return None,
ViewportState::Dynamic { count, .. } => count,
})
}
}
impl Default for ViewportState {
#[inline]
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct Viewport {
pub origin: [f32; 2],
pub dimensions: [f32; 2],
pub depth_range: Range<f32>,
}
impl From<Viewport> for ash::vk::Viewport {
#[inline]
fn from(val: Viewport) -> Self {
ash::vk::Viewport {
x: val.origin[0],
y: val.origin[1],
width: val.dimensions[0],
height: val.dimensions[1],
min_depth: val.depth_range.start,
max_depth: val.depth_range.end,
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct Scissor {
pub origin: [u32; 2],
pub dimensions: [u32; 2],
}
impl Scissor {
#[inline]
pub fn irrelevant() -> Scissor {
Scissor {
origin: [0, 0],
dimensions: [0x7fffffff, 0x7fffffff],
}
}
}
impl Default for Scissor {
#[inline]
fn default() -> Scissor {
Scissor::irrelevant()
}
}
impl From<Scissor> for ash::vk::Rect2D {
#[inline]
fn from(val: Scissor) -> Self {
ash::vk::Rect2D {
offset: ash::vk::Offset2D {
x: val.origin[0] as i32,
y: val.origin[1] as i32,
},
extent: ash::vk::Extent2D {
width: val.dimensions[0],
height: val.dimensions[1],
},
}
}
}