vidya/crates/renderer/src/util.rs

326 lines
12 KiB
Rust

use std::{borrow::Cow, ops::Deref};
use ash::vk;
#[macro_export]
macro_rules! def_monotonic_id {
($ty:ident) => {
#[derive(Copy, Clone, Hash, Eq, PartialEq, PartialOrd, Ord, Debug)]
pub struct $ty(::core::num::NonZero<u32>);
impl $ty {
pub fn new() -> Self {
use ::core::sync::atomic::{AtomicU32, Ordering};
static COUNTER: AtomicU32 = AtomicU32::new(1);
let inner = COUNTER.fetch_add(1, Ordering::Relaxed);
Self(
::core::num::NonZero::<u32>::new(inner)
.expect(&format!("integer overwarp for {}", stringify!($ty))),
)
}
pub fn as_u32(&self) -> u32 {
self.0.get()
}
}
};
}
pub trait MutexExt<'a, T: 'a> {
type Guard: Deref<Target = T> + 'a;
fn lock(&'a self) -> Self::Guard;
fn with_locked<R, F: FnOnce(&T) -> R>(&'a self, f: F) -> R {
let lock = MutexExt::lock(self);
f(&*lock)
}
}
impl<'a, T: 'a> MutexExt<'a, T> for parking_lot::Mutex<T> {
type Guard = parking_lot::MutexGuard<'a, T>;
fn lock(&'a self) -> Self::Guard {
self.lock()
}
}
pub trait FormatExt {
fn get_component_kind(&self) -> FormatComponentKind;
fn is_f32(&self) -> bool;
fn is_u32(&self) -> bool;
fn is_i32(&self) -> bool;
}
#[derive(Debug, PartialEq, Eq)]
pub enum FormatComponentKind {
Float,
UInt,
SInt,
}
fn format_to_primitive(format: vk::Format) -> FormatComponentKind {
use FormatComponentKind::*;
match format {
vk::Format::BC6H_SFLOAT_BLOCK => Float,
vk::Format::D32_SFLOAT => Float,
vk::Format::R16G16B16A16_SFLOAT => Float,
vk::Format::R16G16B16_SFLOAT => Float,
vk::Format::R16G16_SFLOAT => Float,
vk::Format::R16_SFLOAT => Float,
vk::Format::R32G32B32A32_SFLOAT => Float,
vk::Format::R32G32B32_SFLOAT => Float,
vk::Format::R32G32_SFLOAT => Float,
vk::Format::R32_SFLOAT => Float,
vk::Format::R64G64B64A64_SFLOAT => Float,
vk::Format::R64G64B64_SFLOAT => Float,
vk::Format::R64G64_SFLOAT => Float,
vk::Format::R64_SFLOAT => Float,
vk::Format::D32_SFLOAT_S8_UINT => Float,
vk::Format::A2B10G10R10_SINT_PACK32 => SInt,
vk::Format::A2R10G10B10_SINT_PACK32 => SInt,
vk::Format::A8B8G8R8_SINT_PACK32 => SInt,
vk::Format::B8G8R8A8_SINT => SInt,
vk::Format::B8G8R8_SINT => SInt,
vk::Format::R16G16B16A16_SINT => SInt,
vk::Format::R16G16B16_SINT => SInt,
vk::Format::R16G16_SINT => SInt,
vk::Format::R16_SINT => SInt,
vk::Format::R32G32B32A32_SINT => SInt,
vk::Format::R32G32B32_SINT => SInt,
vk::Format::R32G32_SINT => SInt,
vk::Format::R32_SINT => SInt,
vk::Format::R64G64B64A64_SINT => SInt,
vk::Format::R64G64B64_SINT => SInt,
vk::Format::R64G64_SINT => SInt,
vk::Format::R64_SINT => SInt,
vk::Format::R8G8B8A8_SINT => SInt,
vk::Format::R8G8B8_SINT => SInt,
vk::Format::R8G8_SINT => SInt,
vk::Format::R8_SINT => SInt,
vk::Format::A2B10G10R10_SNORM_PACK32 => Float,
vk::Format::A2R10G10B10_SNORM_PACK32 => Float,
vk::Format::A8B8G8R8_SNORM_PACK32 => Float,
vk::Format::B8G8R8A8_SNORM => Float,
vk::Format::B8G8R8_SNORM => Float,
vk::Format::BC4_SNORM_BLOCK => Float,
vk::Format::BC5_SNORM_BLOCK => Float,
vk::Format::EAC_R11G11_SNORM_BLOCK => Float,
vk::Format::EAC_R11_SNORM_BLOCK => Float,
vk::Format::R16G16B16A16_SNORM => Float,
vk::Format::R16G16B16_SNORM => Float,
vk::Format::R16G16_SNORM => Float,
vk::Format::R16_SNORM => Float,
vk::Format::R8G8B8A8_SNORM => Float,
vk::Format::R8G8B8_SNORM => Float,
vk::Format::R8G8_SNORM => Float,
vk::Format::R8_SNORM => Float,
vk::Format::A8B8G8R8_SRGB_PACK32 => Float,
vk::Format::ASTC_10X10_SRGB_BLOCK => Float,
vk::Format::ASTC_10X5_SRGB_BLOCK => Float,
vk::Format::ASTC_10X6_SRGB_BLOCK => Float,
vk::Format::ASTC_10X8_SRGB_BLOCK => Float,
vk::Format::ASTC_12X10_SRGB_BLOCK => Float,
vk::Format::ASTC_12X12_SRGB_BLOCK => Float,
vk::Format::ASTC_4X4_SRGB_BLOCK => Float,
vk::Format::ASTC_5X4_SRGB_BLOCK => Float,
vk::Format::ASTC_5X5_SRGB_BLOCK => Float,
vk::Format::ASTC_6X5_SRGB_BLOCK => Float,
vk::Format::ASTC_6X6_SRGB_BLOCK => Float,
vk::Format::ASTC_8X5_SRGB_BLOCK => Float,
vk::Format::ASTC_8X6_SRGB_BLOCK => Float,
vk::Format::ASTC_8X8_SRGB_BLOCK => Float,
vk::Format::B8G8R8A8_SRGB => Float,
vk::Format::B8G8R8_SRGB => Float,
vk::Format::BC1_RGBA_SRGB_BLOCK => Float,
vk::Format::BC1_RGB_SRGB_BLOCK => Float,
vk::Format::BC2_SRGB_BLOCK => Float,
vk::Format::BC3_SRGB_BLOCK => Float,
vk::Format::BC7_SRGB_BLOCK => Float,
vk::Format::ETC2_R8G8B8A1_SRGB_BLOCK => Float,
vk::Format::ETC2_R8G8B8A8_SRGB_BLOCK => Float,
vk::Format::ETC2_R8G8B8_SRGB_BLOCK => Float,
vk::Format::R8G8B8A8_SRGB => Float,
vk::Format::R8G8B8_SRGB => Float,
vk::Format::R8G8_SRGB => Float,
vk::Format::R8_SRGB => Float,
vk::Format::A2B10G10R10_SSCALED_PACK32 => Float,
vk::Format::A2R10G10B10_SSCALED_PACK32 => Float,
vk::Format::A8B8G8R8_SSCALED_PACK32 => Float,
vk::Format::B8G8R8A8_SSCALED => Float,
vk::Format::B8G8R8_SSCALED => Float,
vk::Format::R16G16B16A16_SSCALED => Float,
vk::Format::R16G16B16_SSCALED => Float,
vk::Format::R16G16_SSCALED => Float,
vk::Format::R16_SSCALED => Float,
vk::Format::R8G8B8A8_SSCALED => Float,
vk::Format::R8G8B8_SSCALED => Float,
vk::Format::R8G8_SSCALED => Float,
vk::Format::R8_SSCALED => Float,
vk::Format::B10G11R11_UFLOAT_PACK32 => Float,
vk::Format::BC6H_UFLOAT_BLOCK => Float,
vk::Format::E5B9G9R9_UFLOAT_PACK32 => Float,
vk::Format::A2B10G10R10_UINT_PACK32 => UInt,
vk::Format::A2R10G10B10_UINT_PACK32 => UInt,
vk::Format::A8B8G8R8_UINT_PACK32 => UInt,
vk::Format::B8G8R8A8_UINT => UInt,
vk::Format::B8G8R8_UINT => UInt,
vk::Format::R16G16B16A16_UINT => UInt,
vk::Format::R16G16B16_UINT => UInt,
vk::Format::R16G16_UINT => UInt,
vk::Format::R16_UINT => UInt,
vk::Format::R32G32B32A32_UINT => UInt,
vk::Format::R32G32B32_UINT => UInt,
vk::Format::R32G32_UINT => UInt,
vk::Format::R32_UINT => UInt,
vk::Format::R64G64B64A64_UINT => UInt,
vk::Format::R64G64B64_UINT => UInt,
vk::Format::R64G64_UINT => UInt,
vk::Format::R64_UINT => UInt,
vk::Format::R8G8B8A8_UINT => UInt,
vk::Format::R8G8B8_UINT => UInt,
vk::Format::R8G8_UINT => UInt,
vk::Format::R8_UINT => UInt,
vk::Format::S8_UINT => UInt,
vk::Format::A1R5G5B5_UNORM_PACK16 => Float,
vk::Format::A2B10G10R10_UNORM_PACK32 => Float,
vk::Format::A2R10G10B10_UNORM_PACK32 => Float,
vk::Format::A8B8G8R8_UNORM_PACK32 => Float,
vk::Format::ASTC_10X10_UNORM_BLOCK => Float,
vk::Format::ASTC_10X5_UNORM_BLOCK => Float,
vk::Format::ASTC_10X6_UNORM_BLOCK => Float,
vk::Format::ASTC_10X8_UNORM_BLOCK => Float,
vk::Format::ASTC_12X10_UNORM_BLOCK => Float,
vk::Format::ASTC_12X12_UNORM_BLOCK => Float,
vk::Format::ASTC_4X4_UNORM_BLOCK => Float,
vk::Format::ASTC_5X4_UNORM_BLOCK => Float,
vk::Format::ASTC_5X5_UNORM_BLOCK => Float,
vk::Format::ASTC_6X5_UNORM_BLOCK => Float,
vk::Format::ASTC_6X6_UNORM_BLOCK => Float,
vk::Format::ASTC_8X5_UNORM_BLOCK => Float,
vk::Format::ASTC_8X6_UNORM_BLOCK => Float,
vk::Format::ASTC_8X8_UNORM_BLOCK => Float,
vk::Format::B4G4R4A4_UNORM_PACK16 => Float,
vk::Format::B5G5R5A1_UNORM_PACK16 => Float,
vk::Format::B5G6R5_UNORM_PACK16 => Float,
vk::Format::B8G8R8A8_UNORM => Float,
vk::Format::B8G8R8_UNORM => Float,
vk::Format::BC1_RGBA_UNORM_BLOCK => Float,
vk::Format::BC1_RGB_UNORM_BLOCK => Float,
vk::Format::BC2_UNORM_BLOCK => Float,
vk::Format::BC3_UNORM_BLOCK => Float,
vk::Format::BC4_UNORM_BLOCK => Float,
vk::Format::BC5_UNORM_BLOCK => Float,
vk::Format::BC7_UNORM_BLOCK => Float,
vk::Format::D16_UNORM => Float,
vk::Format::D16_UNORM_S8_UINT => Float,
vk::Format::D24_UNORM_S8_UINT => Float,
vk::Format::EAC_R11G11_UNORM_BLOCK => Float,
vk::Format::EAC_R11_UNORM_BLOCK => Float,
vk::Format::ETC2_R8G8B8A1_UNORM_BLOCK => Float,
vk::Format::ETC2_R8G8B8A8_UNORM_BLOCK => Float,
vk::Format::ETC2_R8G8B8_UNORM_BLOCK => Float,
vk::Format::R16G16B16A16_UNORM => Float,
vk::Format::R16G16B16_UNORM => Float,
vk::Format::R16G16_UNORM => Float,
vk::Format::R16_UNORM => Float,
vk::Format::R4G4B4A4_UNORM_PACK16 => Float,
vk::Format::R4G4_UNORM_PACK8 => Float,
vk::Format::R5G5B5A1_UNORM_PACK16 => Float,
vk::Format::R5G6B5_UNORM_PACK16 => Float,
vk::Format::R8G8B8A8_UNORM => Float,
vk::Format::R8G8B8_UNORM => Float,
vk::Format::R8G8_UNORM => Float,
vk::Format::R8_UNORM => Float,
vk::Format::X8_D24_UNORM_PACK32 => Float,
vk::Format::A2B10G10R10_USCALED_PACK32 => Float,
vk::Format::A2R10G10B10_USCALED_PACK32 => Float,
vk::Format::A8B8G8R8_USCALED_PACK32 => Float,
vk::Format::B8G8R8A8_USCALED => Float,
vk::Format::B8G8R8_USCALED => Float,
vk::Format::R16G16B16A16_USCALED => Float,
vk::Format::R16G16B16_USCALED => Float,
vk::Format::R16G16_USCALED => Float,
vk::Format::R16_USCALED => Float,
vk::Format::R8G8B8A8_USCALED => Float,
vk::Format::R8G8B8_USCALED => Float,
vk::Format::R8G8_USCALED => Float,
vk::Format::R8_USCALED => Float,
_ => unimplemented!(),
}
}
impl FormatExt for vk::Format {
fn get_component_kind(&self) -> FormatComponentKind {
format_to_primitive(*self)
}
fn is_f32(&self) -> bool {
format_to_primitive(*self) == FormatComponentKind::Float
}
fn is_u32(&self) -> bool {
format_to_primitive(*self) == FormatComponentKind::UInt
}
fn is_i32(&self) -> bool {
format_to_primitive(*self) == FormatComponentKind::SInt
}
}
#[derive(Debug, Default, PartialEq, Eq, Hash, Clone, Copy)]
pub struct Rect2D {
top_left: glam::IVec2,
bottom_right: glam::IVec2,
}
impl Rect2D {
pub fn new(left: i32, top: i32, right: i32, bottom: i32) -> Self {
use glam::ivec2;
Self {
top_left: ivec2(left, top),
bottom_right: ivec2(right, bottom),
}
}
pub fn new_from_size(pos: glam::IVec2, size: glam::IVec2) -> Self {
use glam::ivec2;
Self {
top_left: pos,
bottom_right: pos + size,
}
}
pub fn into_offsets_3d(&self) -> [vk::Offset3D; 2] {
[
vk::Offset3D {
x: self.top_left.x,
y: self.top_left.y,
z: 0,
},
vk::Offset3D {
x: self.bottom_right.x,
y: self.bottom_right.y,
z: 1,
},
]
}
}
pub fn eq_f32(lhs: f32, rhs: f32) -> bool {
use core::num::FpCategory::*;
match (lhs.classify(), rhs.classify()) {
(Zero, Zero) | (Nan, Nan) => true,
(Infinite, Infinite) => lhs.signum() == rhs.signum(),
_ => lhs == rhs,
}
}
pub fn hash_f32<H: std::hash::Hasher>(state: &mut H, f: f32) {
use std::hash::Hash;
let classify = f.classify();
match classify {
std::num::FpCategory::Nan => (classify as u8).hash(state),
std::num::FpCategory::Infinite | std::num::FpCategory::Zero => {
(classify as u8, f.signum() as i8).hash(state)
}
std::num::FpCategory::Subnormal | std::num::FpCategory::Normal => f.to_bits().hash(state),
}
}