command buffer abstraction, images/buffers start
This commit is contained in:
parent
d29b121aca
commit
f7e6a92018
88
crates/renderer/src/buffers.rs
Normal file
88
crates/renderer/src/buffers.rs
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
use std::{ops::Deref, sync::Arc};
|
||||||
|
|
||||||
|
use ash::{prelude::VkResult, vk};
|
||||||
|
use vk_mem::Alloc;
|
||||||
|
|
||||||
|
use crate::Device;
|
||||||
|
|
||||||
|
pub struct Buffer {
|
||||||
|
device: Device,
|
||||||
|
buffer: vk::Buffer,
|
||||||
|
allocation: vk_mem::Allocation,
|
||||||
|
usage: vk::BufferUsageFlags,
|
||||||
|
size: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for Buffer {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
self.device
|
||||||
|
.alloc()
|
||||||
|
.destroy_buffer(self.buffer, &mut self.allocation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Buffer {
|
||||||
|
pub fn new(
|
||||||
|
device: Device,
|
||||||
|
size: usize,
|
||||||
|
usage: vk::BufferUsageFlags,
|
||||||
|
queue_families: &[u32],
|
||||||
|
memory_usage: vk_mem::MemoryUsage,
|
||||||
|
alloc_flags: vk_mem::AllocationCreateFlags,
|
||||||
|
) -> VkResult<Arc<Self>> {
|
||||||
|
let sharing_mode = if queue_families.len() > 1 {
|
||||||
|
vk::SharingMode::EXCLUSIVE
|
||||||
|
} else {
|
||||||
|
vk::SharingMode::CONCURRENT
|
||||||
|
};
|
||||||
|
|
||||||
|
let (buffer, allocation) = unsafe {
|
||||||
|
device.alloc().create_buffer(
|
||||||
|
&vk::BufferCreateInfo::default()
|
||||||
|
.usage(usage)
|
||||||
|
.queue_family_indices(queue_families)
|
||||||
|
.sharing_mode(sharing_mode),
|
||||||
|
&vk_mem::AllocationCreateInfo {
|
||||||
|
flags: alloc_flags,
|
||||||
|
usage: memory_usage,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
)?
|
||||||
|
};
|
||||||
|
|
||||||
|
let buffer = Self {
|
||||||
|
device,
|
||||||
|
buffer,
|
||||||
|
allocation,
|
||||||
|
usage,
|
||||||
|
size: size as u64,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Arc::new(buffer))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn map(&mut self) -> VkResult<MappedBuffer<'_>> {
|
||||||
|
let bytes = unsafe {
|
||||||
|
let data = self.device.alloc().map_memory(&mut self.allocation)?;
|
||||||
|
let slice = core::slice::from_raw_parts(data, self.size as usize);
|
||||||
|
|
||||||
|
slice
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(MappedBuffer { bytes })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct MappedBuffer<'a> {
|
||||||
|
bytes: &'a [u8],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for MappedBuffer<'_> {
|
||||||
|
type Target = [u8];
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
self.bytes
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,20 +1,28 @@
|
||||||
use std::{future::Future, marker::PhantomData, sync::Arc};
|
use std::{future::Future, marker::PhantomData, sync::Arc};
|
||||||
|
|
||||||
use crate::sync::{self, FenceFuture};
|
use crate::{
|
||||||
|
buffers::Buffer,
|
||||||
|
images::{Image2D, QueueOwnership},
|
||||||
|
sync::{self, FenceFuture},
|
||||||
|
util::{FormatExt, MutexExt},
|
||||||
|
};
|
||||||
|
|
||||||
use super::{Device, Queue};
|
use super::{Device, Queue};
|
||||||
use ash::{prelude::*, vk};
|
use ash::{prelude::*, vk};
|
||||||
|
use parking_lot::Mutex;
|
||||||
|
|
||||||
pub struct SingleUseCommandPool {
|
pub struct SingleUseCommandPool {
|
||||||
device: Device,
|
device: Device,
|
||||||
pool: vk::CommandPool,
|
pool: Mutex<vk::CommandPool>,
|
||||||
queue: Queue,
|
queue: Queue,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for SingleUseCommandPool {
|
impl Drop for SingleUseCommandPool {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.device.dev().destroy_command_pool(self.pool, None);
|
self.pool.with_locked(|&pool| {
|
||||||
|
self.device.dev().destroy_command_pool(pool, None);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,7 +38,7 @@ impl SingleUseCommandPool {
|
||||||
|
|
||||||
Ok(Arc::new(Self {
|
Ok(Arc::new(Self {
|
||||||
device,
|
device,
|
||||||
pool,
|
pool: Mutex::new(pool),
|
||||||
queue,
|
queue,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
@ -43,8 +51,9 @@ impl SingleUseCommandPool {
|
||||||
&self.queue
|
&self.queue
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pool(&self) -> vk::CommandPool {
|
/// get the underlying pool, bypassing the mutex
|
||||||
self.pool
|
pub unsafe fn pool(&self) -> vk::CommandPool {
|
||||||
|
self.pool.data_ptr().read()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,12 +63,14 @@ pub struct SingleUseCommand {
|
||||||
buffer: vk::CommandBuffer,
|
buffer: vk::CommandBuffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl !Sync for SingleUseCommand {}
|
||||||
|
|
||||||
impl Drop for SingleUseCommand {
|
impl Drop for SingleUseCommand {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.device
|
self.pool.pool.with_locked(|&pool| {
|
||||||
.dev()
|
self.device.dev().free_command_buffers(pool, &[self.buffer])
|
||||||
.free_command_buffers(self.pool.pool(), &[self.buffer])
|
})
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,10 +102,89 @@ impl SingleUseCommand {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn buffer(&self) -> vk::CommandBuffer {
|
/// Safety: commandbuffer must not be accessed from multiple threads at the same time
|
||||||
|
pub unsafe fn buffer(&self) -> vk::CommandBuffer {
|
||||||
self.buffer
|
self.buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//pub fn copy_buffer_to_image(&self, image: &Image2D, buffer: &Buffer, )
|
||||||
|
|
||||||
|
pub fn image_barrier(
|
||||||
|
&self,
|
||||||
|
image: vk::Image,
|
||||||
|
aspects: vk::ImageAspectFlags,
|
||||||
|
src_stage: vk::PipelineStageFlags2,
|
||||||
|
src_access: vk::AccessFlags2,
|
||||||
|
dst_stage: vk::PipelineStageFlags2,
|
||||||
|
dst_access: vk::AccessFlags2,
|
||||||
|
old_layout: vk::ImageLayout,
|
||||||
|
new_layout: vk::ImageLayout,
|
||||||
|
queue_ownership_op: Option<QueueOwnership>,
|
||||||
|
) {
|
||||||
|
let (src_family, dst_family) = queue_ownership_op
|
||||||
|
.map(|t| (t.src, t.dst))
|
||||||
|
.unwrap_or((vk::QUEUE_FAMILY_IGNORED, vk::QUEUE_FAMILY_IGNORED));
|
||||||
|
|
||||||
|
let barrier = vk::ImageMemoryBarrier2::default()
|
||||||
|
.image(image)
|
||||||
|
.subresource_range(
|
||||||
|
vk::ImageSubresourceRange::default()
|
||||||
|
.aspect_mask(aspects)
|
||||||
|
.base_mip_level(0)
|
||||||
|
.base_array_layer(0)
|
||||||
|
.level_count(vk::REMAINING_MIP_LEVELS)
|
||||||
|
.layer_count(vk::REMAINING_ARRAY_LAYERS),
|
||||||
|
)
|
||||||
|
.src_stage_mask(src_stage)
|
||||||
|
.src_access_mask(src_access)
|
||||||
|
.dst_stage_mask(dst_stage)
|
||||||
|
.dst_access_mask(dst_access)
|
||||||
|
.dst_queue_family_index(dst_family)
|
||||||
|
.src_queue_family_index(src_family)
|
||||||
|
.old_layout(old_layout)
|
||||||
|
.new_layout(new_layout);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
self.device.dev().cmd_pipeline_barrier2(
|
||||||
|
self.buffer,
|
||||||
|
&vk::DependencyInfo::default()
|
||||||
|
.dependency_flags(vk::DependencyFlags::BY_REGION)
|
||||||
|
.image_memory_barriers(core::slice::from_ref(&barrier)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clear_color_image(
|
||||||
|
&self,
|
||||||
|
image: vk::Image,
|
||||||
|
format: vk::Format,
|
||||||
|
layout: vk::ImageLayout,
|
||||||
|
color: crate::Rgba,
|
||||||
|
subresources: &[vk::ImageSubresourceRange],
|
||||||
|
) {
|
||||||
|
let clear_colors = match format.get_component_kind() {
|
||||||
|
crate::util::FormatComponentKind::Float => vk::ClearColorValue {
|
||||||
|
float32: color.into_f32(),
|
||||||
|
},
|
||||||
|
crate::util::FormatComponentKind::UInt => vk::ClearColorValue {
|
||||||
|
uint32: color.into_u32(),
|
||||||
|
},
|
||||||
|
crate::util::FormatComponentKind::SInt => vk::ClearColorValue {
|
||||||
|
int32: color.into_i32(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
self.device.dev().cmd_clear_color_image(
|
||||||
|
self.buffer,
|
||||||
|
image,
|
||||||
|
layout,
|
||||||
|
&clear_colors,
|
||||||
|
subresources,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn submit_fence(
|
pub fn submit_fence(
|
||||||
&self,
|
&self,
|
||||||
wait: Option<(vk::Semaphore, vk::PipelineStageFlags)>,
|
wait: Option<(vk::Semaphore, vk::PipelineStageFlags)>,
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use crate::buffers::Buffer;
|
||||||
|
|
||||||
use super::{Device, Queue};
|
use super::{Device, Queue};
|
||||||
use ash::{prelude::*, vk};
|
use ash::{prelude::*, vk};
|
||||||
use vk_mem::Alloc;
|
use vk_mem::Alloc;
|
||||||
|
@ -70,6 +72,16 @@ impl Image2D {
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn format(&self) -> vk::Format {
|
||||||
|
self.format
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn copy_from_buffer(&self, buffer: &Buffer) {
|
||||||
|
unsafe {
|
||||||
|
// self.device.dev().cmd_copy_buffer_to_image(command_buffer, src_buffer, dst_image, dst_image_layout, regions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn view(
|
pub fn view(
|
||||||
self: &Arc<Self>,
|
self: &Arc<Self>,
|
||||||
device: &Device,
|
device: &Device,
|
||||||
|
@ -121,8 +133,8 @@ impl Drop for ImageView2D {
|
||||||
impl ImageView2D {}
|
impl ImageView2D {}
|
||||||
|
|
||||||
pub struct QueueOwnership {
|
pub struct QueueOwnership {
|
||||||
src: u32,
|
pub src: u32,
|
||||||
dst: u32,
|
pub dst: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn image_barrier<'a>(
|
pub fn image_barrier<'a>(
|
||||||
|
@ -159,3 +171,12 @@ pub fn image_barrier<'a>(
|
||||||
.old_layout(old_layout)
|
.old_layout(old_layout)
|
||||||
.new_layout(new_layout)
|
.new_layout(new_layout)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const SUBRESOURCERANGE_COLOR_ALL: vk::ImageSubresourceRange =
|
||||||
|
vk::ImageSubresourceRange {
|
||||||
|
aspect_mask: vk::ImageAspectFlags::COLOR,
|
||||||
|
base_mip_level: 0,
|
||||||
|
level_count: vk::REMAINING_MIP_LEVELS,
|
||||||
|
base_array_layer: 0,
|
||||||
|
layer_count: vk::REMAINING_ARRAY_LAYERS,
|
||||||
|
};
|
||||||
|
|
|
@ -33,11 +33,14 @@ use raw_window_handle::{DisplayHandle, RawDisplayHandle};
|
||||||
use tinyvec::{array_vec, ArrayVec};
|
use tinyvec::{array_vec, ArrayVec};
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
|
|
||||||
|
mod buffers;
|
||||||
mod commands;
|
mod commands;
|
||||||
mod images;
|
mod images;
|
||||||
mod render_graph;
|
mod render_graph;
|
||||||
|
|
||||||
mod sync;
|
mod sync;
|
||||||
|
mod util;
|
||||||
|
|
||||||
|
use render_graph::Rgba;
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
@ -720,6 +723,7 @@ pub struct SwapchainFrame {
|
||||||
pub swapchain: Arc<Swapchain>,
|
pub swapchain: Arc<Swapchain>,
|
||||||
pub index: u32,
|
pub index: u32,
|
||||||
pub image: vk::Image,
|
pub image: vk::Image,
|
||||||
|
pub format: vk::Format,
|
||||||
pub view: vk::ImageView,
|
pub view: vk::ImageView,
|
||||||
pub acquire: vk::Semaphore,
|
pub acquire: vk::Semaphore,
|
||||||
pub release: vk::Semaphore,
|
pub release: vk::Semaphore,
|
||||||
|
@ -1042,6 +1046,7 @@ impl Swapchain {
|
||||||
SwapchainFrame {
|
SwapchainFrame {
|
||||||
index: idx as u32,
|
index: idx as u32,
|
||||||
swapchain: self.clone(),
|
swapchain: self.clone(),
|
||||||
|
format: self.format,
|
||||||
image,
|
image,
|
||||||
view,
|
view,
|
||||||
acquire,
|
acquire,
|
||||||
|
@ -2043,7 +2048,6 @@ impl<W> Renderer<W> {
|
||||||
|
|
||||||
if let Some(ctx) = self.window_contexts.get(window) {
|
if let Some(ctx) = self.window_contexts.get(window) {
|
||||||
let cmd = pool.alloc()?;
|
let cmd = pool.alloc()?;
|
||||||
let buffer = cmd.buffer();
|
|
||||||
|
|
||||||
let (frame, suboptimal) = smol::block_on(
|
let (frame, suboptimal) = smol::block_on(
|
||||||
ctx.current_swapchain.read().clone().acquire_image(),
|
ctx.current_swapchain.read().clone().acquire_image(),
|
||||||
|
@ -2074,6 +2078,7 @@ impl<W> Renderer<W> {
|
||||||
ctx.surface.surface.as_raw(),
|
ctx.surface.surface.as_raw(),
|
||||||
)
|
)
|
||||||
.gen::<[f32; 3]>();
|
.gen::<[f32; 3]>();
|
||||||
|
let clear_color = Rgba([r, g, b, 1.0]);
|
||||||
let clear_values = vk::ClearColorValue {
|
let clear_values = vk::ClearColorValue {
|
||||||
float32: [r, g, b, 1.0],
|
float32: [r, g, b, 1.0],
|
||||||
};
|
};
|
||||||
|
@ -2095,21 +2100,25 @@ impl<W> Renderer<W> {
|
||||||
.dependency_flags(vk::DependencyFlags::BY_REGION)
|
.dependency_flags(vk::DependencyFlags::BY_REGION)
|
||||||
.image_memory_barriers(&barriers);
|
.image_memory_barriers(&barriers);
|
||||||
|
|
||||||
dev.dev().cmd_pipeline_barrier2(buffer, &dependency_info);
|
cmd.image_barrier(
|
||||||
dev.dev().cmd_clear_color_image(
|
|
||||||
buffer,
|
|
||||||
frame.image,
|
frame.image,
|
||||||
|
vk::ImageAspectFlags::COLOR,
|
||||||
|
vk::PipelineStageFlags2::TRANSFER,
|
||||||
|
vk::AccessFlags2::empty(),
|
||||||
|
vk::PipelineStageFlags2::TRANSFER,
|
||||||
|
vk::AccessFlags2::TRANSFER_WRITE,
|
||||||
|
vk::ImageLayout::UNDEFINED,
|
||||||
vk::ImageLayout::TRANSFER_DST_OPTIMAL,
|
vk::ImageLayout::TRANSFER_DST_OPTIMAL,
|
||||||
&clear_values,
|
None,
|
||||||
&[vk::ImageSubresourceRange::default()
|
|
||||||
.aspect_mask(vk::ImageAspectFlags::COLOR)
|
|
||||||
.base_mip_level(0)
|
|
||||||
.base_array_layer(0)
|
|
||||||
.level_count(vk::REMAINING_MIP_LEVELS)
|
|
||||||
.layer_count(vk::REMAINING_ARRAY_LAYERS)],
|
|
||||||
);
|
);
|
||||||
|
cmd.clear_color_image(
|
||||||
let barriers = [images::image_barrier(
|
frame.image,
|
||||||
|
frame.format,
|
||||||
|
vk::ImageLayout::TRANSFER_DST_OPTIMAL,
|
||||||
|
clear_color,
|
||||||
|
&[images::SUBRESOURCERANGE_COLOR_ALL],
|
||||||
|
);
|
||||||
|
cmd.image_barrier(
|
||||||
frame.image,
|
frame.image,
|
||||||
vk::ImageAspectFlags::COLOR,
|
vk::ImageAspectFlags::COLOR,
|
||||||
vk::PipelineStageFlags2::TRANSFER,
|
vk::PipelineStageFlags2::TRANSFER,
|
||||||
|
@ -2119,16 +2128,10 @@ impl<W> Renderer<W> {
|
||||||
vk::ImageLayout::TRANSFER_DST_OPTIMAL,
|
vk::ImageLayout::TRANSFER_DST_OPTIMAL,
|
||||||
vk::ImageLayout::PRESENT_SRC_KHR,
|
vk::ImageLayout::PRESENT_SRC_KHR,
|
||||||
None,
|
None,
|
||||||
)];
|
);
|
||||||
|
|
||||||
let dependency_info = vk::DependencyInfo::default()
|
|
||||||
.dependency_flags(vk::DependencyFlags::BY_REGION)
|
|
||||||
.image_memory_barriers(&barriers);
|
|
||||||
|
|
||||||
dev.dev().cmd_pipeline_barrier2(buffer, &dependency_info);
|
|
||||||
|
|
||||||
let future = cmd.submit_async(
|
let future = cmd.submit_async(
|
||||||
Some((frame.acquire, vk::PipelineStageFlags::ALL_COMMANDS)),
|
Some((frame.acquire, vk::PipelineStageFlags::TRANSFER)),
|
||||||
Some(frame.release),
|
Some(frame.release),
|
||||||
Arc::new(sync::Fence::create(dev.clone())?),
|
Arc::new(sync::Fence::create(dev.clone())?),
|
||||||
)?;
|
)?;
|
||||||
|
|
|
@ -1,6 +1,44 @@
|
||||||
|
use std::hash::Hash;
|
||||||
|
|
||||||
use ash::vk;
|
use ash::vk;
|
||||||
|
|
||||||
struct Rgba([f32; 4]);
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub struct Rgba(pub [f32; 4]);
|
||||||
|
|
||||||
|
impl std::hash::Hash for Rgba {
|
||||||
|
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||||
|
fn hash_f32<H: std::hash::Hasher>(state: &mut H, f: f32) {
|
||||||
|
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),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.0.map(|f| hash_f32(state, f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Rgba {
|
||||||
|
pub fn new(r: f32, g: f32, b: f32, a: f32) -> Self {
|
||||||
|
Self([r, g, b, a])
|
||||||
|
}
|
||||||
|
pub fn into_u32(&self) -> [u32; 4] {
|
||||||
|
self.0.map(|f| (f.clamp(0.0, 1.0) * 255.0) as u32)
|
||||||
|
}
|
||||||
|
pub fn into_f32(&self) -> [f32; 4] {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
pub fn into_snorm(&self) -> [f32; 4] {
|
||||||
|
self.0.map(|f| (f - 0.5) * 2.0)
|
||||||
|
}
|
||||||
|
pub fn into_i32(&self) -> [i32; 4] {
|
||||||
|
self.0.map(|f| (f.clamp(0.0, 1.0) * 255.0) as i32 - 128)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
enum LoadOp {
|
enum LoadOp {
|
||||||
Clear(Rgba),
|
Clear(Rgba),
|
||||||
|
|
241
crates/renderer/src/util.rs
Normal file
241
crates/renderer/src/util.rs
Normal file
|
@ -0,0 +1,241 @@
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
|
use ash::vk;
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue