warning cleanup
This commit is contained in:
parent
ea3c24ec46
commit
e76bf29840
|
@ -12,7 +12,6 @@ define_device_owned_handle! {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub Buffer(vk::Buffer) {
|
pub Buffer(vk::Buffer) {
|
||||||
alloc: vk_mem::Allocation,
|
alloc: vk_mem::Allocation,
|
||||||
usage: vk::BufferUsageFlags,
|
|
||||||
size: u64,
|
size: u64,
|
||||||
} => |this| unsafe {
|
} => |this| unsafe {
|
||||||
this.device().clone().alloc().destroy_buffer(this.handle(), &mut this.alloc);
|
this.device().clone().alloc().destroy_buffer(this.handle(), &mut this.alloc);
|
||||||
|
@ -55,7 +54,6 @@ impl Buffer {
|
||||||
buffer,
|
buffer,
|
||||||
name,
|
name,
|
||||||
allocation,
|
allocation,
|
||||||
usage,
|
|
||||||
size as u64,
|
size as u64,
|
||||||
)?))
|
)?))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
use std::{future::Future, marker::PhantomData, sync::Arc};
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
buffers::Buffer,
|
|
||||||
device::DeviceOwned,
|
device::DeviceOwned,
|
||||||
images::{Image2D, QueueOwnership},
|
images::{Image, QueueOwnership},
|
||||||
pipeline::{Pipeline, PipelineLayout},
|
pipeline::{Pipeline, PipelineLayout},
|
||||||
sync::{self, FenceFuture},
|
sync::{self, FenceFuture},
|
||||||
util::{self, FormatExt, MutexExt},
|
util::{self, FormatExt, MutexExt},
|
||||||
|
@ -154,9 +153,9 @@ impl SingleUseCommand {
|
||||||
|
|
||||||
pub fn blit_images(
|
pub fn blit_images(
|
||||||
&self,
|
&self,
|
||||||
src: &Image2D,
|
src: &Image,
|
||||||
src_region: util::Rect2D,
|
src_region: util::Rect2D,
|
||||||
dst: &Image2D,
|
dst: &Image,
|
||||||
dst_region: util::Rect2D,
|
dst_region: util::Rect2D,
|
||||||
) {
|
) {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -318,6 +317,8 @@ impl SingleUseCommand {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn draw_indexed(
|
pub fn draw_indexed(
|
||||||
&self,
|
&self,
|
||||||
indices: u32,
|
indices: u32,
|
||||||
|
@ -398,12 +399,12 @@ impl SingleUseCommand {
|
||||||
signal: Option<vk::Semaphore>,
|
signal: Option<vk::Semaphore>,
|
||||||
fence: Arc<sync::Fence>,
|
fence: Arc<sync::Fence>,
|
||||||
) -> VkResult<FenceFuture<'a>> {
|
) -> VkResult<FenceFuture<'a>> {
|
||||||
let device = self.device.clone();
|
|
||||||
self.submit_fence(wait, signal, Some(fence.fence()))?;
|
self.submit_fence(wait, signal, Some(fence.fence()))?;
|
||||||
|
|
||||||
Ok(unsafe { FenceFuture::new(fence) })
|
Ok(FenceFuture::new(fence))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn submit_blocking(
|
pub fn submit_blocking(
|
||||||
self,
|
self,
|
||||||
wait: Option<(vk::Semaphore, vk::PipelineStageFlags)>,
|
wait: Option<(vk::Semaphore, vk::PipelineStageFlags)>,
|
||||||
|
@ -411,22 +412,7 @@ impl SingleUseCommand {
|
||||||
) -> VkResult<()> {
|
) -> VkResult<()> {
|
||||||
let fence = Arc::new(sync::Fence::create(self.device.clone())?);
|
let fence = Arc::new(sync::Fence::create(self.device.clone())?);
|
||||||
let future = self.submit_async(wait, signal, fence)?;
|
let future = self.submit_async(wait, signal, fence)?;
|
||||||
future.block();
|
future.block()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
async fn async_submit(cmd: SingleUseCommand, queue: Queue) {
|
|
||||||
cmd.submit_async(
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
Arc::new(sync::Fence::create(cmd.device.clone()).unwrap()),
|
|
||||||
)
|
|
||||||
.unwrap()
|
|
||||||
.await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,16 +1,10 @@
|
||||||
use std::{
|
use std::{borrow::Cow, collections::BTreeMap, ops::Deref, sync::Arc};
|
||||||
borrow::Cow,
|
|
||||||
collections::{BTreeMap, HashMap},
|
|
||||||
ops::Deref,
|
|
||||||
sync::Arc,
|
|
||||||
};
|
|
||||||
|
|
||||||
use ash::{
|
use ash::{
|
||||||
khr,
|
khr,
|
||||||
prelude::VkResult,
|
prelude::VkResult,
|
||||||
vk::{self, Handle},
|
vk::{self, Handle},
|
||||||
};
|
};
|
||||||
use parking_lot::Mutex;
|
|
||||||
use tinyvec::{array_vec, ArrayVec};
|
use tinyvec::{array_vec, ArrayVec};
|
||||||
|
|
||||||
use crate::{sync, Instance, PhysicalDevice, Queue};
|
use crate::{sync, Instance, PhysicalDevice, Queue};
|
||||||
|
@ -68,6 +62,7 @@ impl Drop for DeviceWrapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
pub struct DeviceInner {
|
pub struct DeviceInner {
|
||||||
alloc: vk_mem::Allocator,
|
alloc: vk_mem::Allocator,
|
||||||
device: DeviceWrapper,
|
device: DeviceWrapper,
|
||||||
|
@ -158,7 +153,7 @@ impl Device {
|
||||||
let alloc_info =
|
let alloc_info =
|
||||||
vk_mem::AllocatorCreateInfo::new(&instance.instance, &device, physical.pdev);
|
vk_mem::AllocatorCreateInfo::new(&instance.instance, &device, physical.pdev);
|
||||||
|
|
||||||
let alloc = unsafe { vk_mem::Allocator::new(alloc_info)? };
|
let alloc = vk_mem::Allocator::new(alloc_info)?;
|
||||||
|
|
||||||
DeviceInner {
|
DeviceInner {
|
||||||
device: DeviceWrapper(device.clone()),
|
device: DeviceWrapper(device.clone()),
|
||||||
|
@ -276,6 +271,7 @@ impl AsRef<ash::Device> for Device {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub struct DeviceAndQueues {
|
pub struct DeviceAndQueues {
|
||||||
pub(crate) device: Device,
|
pub(crate) device: Device,
|
||||||
pub(crate) main_queue: Queue,
|
pub(crate) main_queue: Queue,
|
||||||
|
@ -299,18 +295,25 @@ impl AsRef<ash::khr::swapchain::Device> for DeviceAndQueues {
|
||||||
pub struct DeviceOwnedDebugObject<T> {
|
pub struct DeviceOwnedDebugObject<T> {
|
||||||
device: Device,
|
device: Device,
|
||||||
object: T,
|
object: T,
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
name: Option<Cow<'static, str>>,
|
name: Option<Cow<'static, str>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: std::fmt::Debug + vk::Handle + Copy> std::fmt::Debug for DeviceOwnedDebugObject<T> {
|
impl<T: std::fmt::Debug + vk::Handle + Copy> std::fmt::Debug for DeviceOwnedDebugObject<T> {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
f.debug_struct(core::any::type_name::<T>())
|
let mut fmt = f.debug_struct(core::any::type_name::<T>());
|
||||||
.field_with("device", |f| {
|
|
||||||
|
fmt.field_with("device", |f| {
|
||||||
write!(f, "0x{:x}", self.device.0.device.handle().as_raw())
|
write!(f, "0x{:x}", self.device.0.device.handle().as_raw())
|
||||||
})
|
})
|
||||||
.field_with("handle", |f| write!(f, "0x{:x}", &self.object.as_raw()))
|
.field_with("handle", |f| write!(f, "0x{:x}", &self.object.as_raw()));
|
||||||
.field("name", &self.name)
|
|
||||||
.finish()
|
#[cfg(debug_assertions)]
|
||||||
|
{
|
||||||
|
fmt.field("name", &self.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,7 +327,7 @@ impl<T> DeviceOwnedDebugObject<T> {
|
||||||
T: vk::Handle + Copy,
|
T: vk::Handle + Copy,
|
||||||
{
|
{
|
||||||
if let Some(name) = name.as_ref() {
|
if let Some(name) = name.as_ref() {
|
||||||
device.debug_name_object(object, name);
|
device.debug_name_object(object, name)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
|
@ -395,6 +398,7 @@ macro_rules! define_device_owned_handle {
|
||||||
$(
|
$(
|
||||||
impl Drop for $ty {
|
impl Drop for $ty {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
|
#[allow(unused_mut)]
|
||||||
let mut $this = self;
|
let mut $this = self;
|
||||||
$dtor
|
$dtor
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,187 @@
|
||||||
use std::{borrow::Cow, sync::Arc};
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use crate::{buffers::Buffer, define_device_owned_handle, device::DeviceOwned};
|
use crate::{define_device_owned_handle, device::DeviceOwned};
|
||||||
|
|
||||||
use super::{Device, Queue};
|
use super::Device;
|
||||||
use ash::{prelude::*, vk};
|
use ash::{prelude::*, vk};
|
||||||
|
use itertools::Itertools;
|
||||||
use vk_mem::Alloc;
|
use vk_mem::Alloc;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct ImageDesc<'a> {
|
||||||
|
pub flags: vk::ImageCreateFlags,
|
||||||
|
pub name: Option<Cow<'static, str>>,
|
||||||
|
pub format: vk::Format,
|
||||||
|
pub kind: vk::ImageType,
|
||||||
|
pub mip_levels: u32,
|
||||||
|
pub array_layers: u32,
|
||||||
|
pub samples: vk::SampleCountFlags,
|
||||||
|
pub extent: vk::Extent3D,
|
||||||
|
pub tiling: vk::ImageTiling,
|
||||||
|
pub usage: vk::ImageUsageFlags,
|
||||||
|
pub queue_families: &'a [u32],
|
||||||
|
pub layout: vk::ImageLayout,
|
||||||
|
|
||||||
|
pub mem_usage: vk_mem::MemoryUsage,
|
||||||
|
pub alloc_flags: vk_mem::AllocationCreateFlags,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> std::fmt::Debug for ImageDesc<'a> {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_struct("ImageDesc")
|
||||||
|
.field("flags", &self.flags)
|
||||||
|
.field("name", &self.name)
|
||||||
|
.field("format", &self.format)
|
||||||
|
.field("kind", &self.kind)
|
||||||
|
.field("mip_levels", &self.mip_levels)
|
||||||
|
.field("array_layers", &self.array_layers)
|
||||||
|
.field("samples", &self.samples)
|
||||||
|
.field("extent", &self.extent)
|
||||||
|
.field("tiling", &self.tiling)
|
||||||
|
.field("usage", &self.usage)
|
||||||
|
.field("queue_families", &self.queue_families)
|
||||||
|
.field("layout", &self.layout)
|
||||||
|
.field("mem_usage", &self.mem_usage)
|
||||||
|
.field_with("alloc_flags", |f| {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"{}",
|
||||||
|
self.alloc_flags
|
||||||
|
.iter_names()
|
||||||
|
.map(|(name, _)| name)
|
||||||
|
.format(" | ")
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Default for ImageDesc<'a> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
flags: Default::default(),
|
||||||
|
name: Default::default(),
|
||||||
|
format: Default::default(),
|
||||||
|
kind: vk::ImageType::TYPE_2D,
|
||||||
|
samples: vk::SampleCountFlags::TYPE_1,
|
||||||
|
mip_levels: 1,
|
||||||
|
array_layers: 1,
|
||||||
|
extent: Default::default(),
|
||||||
|
tiling: vk::ImageTiling::OPTIMAL,
|
||||||
|
usage: Default::default(),
|
||||||
|
queue_families: &[],
|
||||||
|
layout: vk::ImageLayout::UNDEFINED,
|
||||||
|
alloc_flags: vk_mem::AllocationCreateFlags::empty(),
|
||||||
|
mem_usage: vk_mem::MemoryUsage::Auto,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
define_device_owned_handle! {
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub Image(vk::Image) {
|
||||||
|
alloc: vk_mem::Allocation,
|
||||||
|
size: vk::Extent3D,
|
||||||
|
format: vk::Format,
|
||||||
|
} => |this| unsafe {
|
||||||
|
this.inner.dev().alloc().destroy_image(this.handle(), &mut this.alloc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Image {
|
||||||
|
pub fn new(device: Device, desc: ImageDesc) -> VkResult<Self> {
|
||||||
|
let ImageDesc {
|
||||||
|
flags,
|
||||||
|
name,
|
||||||
|
format,
|
||||||
|
kind,
|
||||||
|
mip_levels,
|
||||||
|
array_layers,
|
||||||
|
samples,
|
||||||
|
extent,
|
||||||
|
tiling,
|
||||||
|
usage,
|
||||||
|
queue_families,
|
||||||
|
layout,
|
||||||
|
mem_usage,
|
||||||
|
alloc_flags,
|
||||||
|
} = desc;
|
||||||
|
let info = &vk::ImageCreateInfo::default()
|
||||||
|
.flags(flags)
|
||||||
|
.image_type(kind)
|
||||||
|
.format(format)
|
||||||
|
.extent(extent)
|
||||||
|
.samples(samples)
|
||||||
|
.initial_layout(layout)
|
||||||
|
.tiling(tiling)
|
||||||
|
.usage(usage)
|
||||||
|
.sharing_mode(if queue_families.len() > 1 {
|
||||||
|
vk::SharingMode::CONCURRENT
|
||||||
|
} else {
|
||||||
|
vk::SharingMode::EXCLUSIVE
|
||||||
|
})
|
||||||
|
.queue_family_indices(queue_families)
|
||||||
|
.array_layers(array_layers)
|
||||||
|
.mip_levels(mip_levels);
|
||||||
|
|
||||||
|
let alloc_info = &vk_mem::AllocationCreateInfo {
|
||||||
|
usage: mem_usage,
|
||||||
|
flags: alloc_flags,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let (handle, alloc) = unsafe { device.alloc().create_image(info, alloc_info)? };
|
||||||
|
|
||||||
|
Self::construct(device, handle, name, alloc, extent, format)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn format(&self) -> vk::Format {
|
||||||
|
self.format
|
||||||
|
}
|
||||||
|
pub fn image(&self) -> vk::Image {
|
||||||
|
self.handle()
|
||||||
|
}
|
||||||
|
pub fn size(&self) -> vk::Extent3D {
|
||||||
|
self.size
|
||||||
|
}
|
||||||
|
pub fn extent_2d(&self) -> vk::Extent2D {
|
||||||
|
vk::Extent2D {
|
||||||
|
width: self.size.width,
|
||||||
|
height: self.size.height,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn width(&self) -> u32 {
|
||||||
|
self.size.width
|
||||||
|
}
|
||||||
|
pub fn height(&self) -> u32 {
|
||||||
|
self.size.height
|
||||||
|
}
|
||||||
|
pub fn depth(&self) -> u32 {
|
||||||
|
self.size.depth
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn view(&self, desc: ImageViewDesc) -> VkResult<ImageView> {
|
||||||
|
let create_info = vk::ImageViewCreateInfo::default()
|
||||||
|
.flags(desc.flags)
|
||||||
|
.image(self.image())
|
||||||
|
.view_type(vk::ImageViewType::TYPE_2D)
|
||||||
|
.format(desc.format)
|
||||||
|
.components(desc.components)
|
||||||
|
.subresource_range(
|
||||||
|
vk::ImageSubresourceRange::default()
|
||||||
|
.aspect_mask(desc.aspect)
|
||||||
|
.base_mip_level(desc.mip_range.0)
|
||||||
|
.level_count(desc.mip_range.count())
|
||||||
|
.base_array_layer(desc.layer_range.0)
|
||||||
|
.layer_count(desc.layer_range.count()),
|
||||||
|
);
|
||||||
|
|
||||||
|
let view = unsafe { self.device().dev().create_image_view(&create_info, None)? };
|
||||||
|
|
||||||
|
ImageView::construct(self.device().clone(), view, desc.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone)]
|
#[derive(Debug, Default, Clone)]
|
||||||
pub struct ImageViewDesc {
|
pub struct ImageViewDesc {
|
||||||
pub flags: vk::ImageViewCreateFlags,
|
pub flags: vk::ImageViewCreateFlags,
|
||||||
|
@ -91,133 +267,6 @@ impl PartialEq for ImageViewDesc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Image2D {
|
|
||||||
device: Device,
|
|
||||||
size: vk::Extent2D,
|
|
||||||
mip_levels: u32,
|
|
||||||
format: vk::Format,
|
|
||||||
image: vk::Image,
|
|
||||||
allocation: vk_mem::Allocation,
|
|
||||||
name: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for Image2D {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
tracing::debug!("destroying image {:?}", self);
|
|
||||||
unsafe {
|
|
||||||
self.device
|
|
||||||
.alloc()
|
|
||||||
.destroy_image(self.image, &mut self.allocation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Image2D {
|
|
||||||
pub fn new_exclusive(
|
|
||||||
device: &Device,
|
|
||||||
extent: vk::Extent2D,
|
|
||||||
mip_levels: u32,
|
|
||||||
array_layers: u32,
|
|
||||||
format: vk::Format,
|
|
||||||
tiling: vk::ImageTiling,
|
|
||||||
usage: vk::ImageUsageFlags,
|
|
||||||
memory_usage: vk_mem::MemoryUsage,
|
|
||||||
alloc_flags: vk_mem::AllocationCreateFlags,
|
|
||||||
name: Option<&str>,
|
|
||||||
) -> VkResult<Arc<Self>> {
|
|
||||||
let create_info = vk::ImageCreateInfo::default()
|
|
||||||
.array_layers(array_layers)
|
|
||||||
.mip_levels(mip_levels)
|
|
||||||
.extent(vk::Extent3D {
|
|
||||||
width: extent.width,
|
|
||||||
height: extent.height,
|
|
||||||
depth: 1,
|
|
||||||
})
|
|
||||||
.image_type(vk::ImageType::TYPE_2D)
|
|
||||||
.format(format)
|
|
||||||
.tiling(tiling)
|
|
||||||
.initial_layout(vk::ImageLayout::UNDEFINED)
|
|
||||||
.usage(usage)
|
|
||||||
.sharing_mode(vk::SharingMode::EXCLUSIVE)
|
|
||||||
.samples(vk::SampleCountFlags::TYPE_1);
|
|
||||||
|
|
||||||
let alloc_info = vk_mem::AllocationCreateInfo {
|
|
||||||
usage: memory_usage,
|
|
||||||
flags: alloc_flags,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
let (image, allocation) =
|
|
||||||
unsafe { device.alloc().create_image(&create_info, &alloc_info)? };
|
|
||||||
|
|
||||||
if let Some(name) = name {
|
|
||||||
let info = device.alloc().get_allocation_info(&allocation);
|
|
||||||
|
|
||||||
let name = std::ffi::CString::new(name).unwrap_or(c"invalid name".to_owned());
|
|
||||||
unsafe {
|
|
||||||
device.debug_utils().set_debug_utils_object_name(
|
|
||||||
&vk::DebugUtilsObjectNameInfoEXT::default()
|
|
||||||
.object_handle(info.device_memory)
|
|
||||||
.object_name(&name),
|
|
||||||
)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(Arc::new(Self {
|
|
||||||
size: extent,
|
|
||||||
mip_levels,
|
|
||||||
format,
|
|
||||||
device: device.clone(),
|
|
||||||
image,
|
|
||||||
allocation,
|
|
||||||
name: name.map(|s| s.to_owned()),
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn format(&self) -> vk::Format {
|
|
||||||
self.format
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn device(&self) -> Device {
|
|
||||||
self.device.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn view(&self, desc: ImageViewDesc) -> VkResult<ImageView> {
|
|
||||||
let create_info = vk::ImageViewCreateInfo::default()
|
|
||||||
.flags(desc.flags)
|
|
||||||
.image(self.image())
|
|
||||||
.view_type(vk::ImageViewType::TYPE_2D)
|
|
||||||
.format(desc.format)
|
|
||||||
.components(desc.components)
|
|
||||||
.subresource_range(
|
|
||||||
vk::ImageSubresourceRange::default()
|
|
||||||
.aspect_mask(desc.aspect)
|
|
||||||
.base_mip_level(desc.mip_range.0)
|
|
||||||
.level_count(desc.mip_range.count())
|
|
||||||
.base_array_layer(desc.layer_range.0)
|
|
||||||
.layer_count(desc.layer_range.count()),
|
|
||||||
);
|
|
||||||
|
|
||||||
let view = unsafe { self.device.dev().create_image_view(&create_info, None)? };
|
|
||||||
|
|
||||||
ImageView::construct(self.device.clone(), view, desc.name)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn image(&self) -> vk::Image {
|
|
||||||
self.image
|
|
||||||
}
|
|
||||||
pub fn size(&self) -> vk::Extent2D {
|
|
||||||
self.size
|
|
||||||
}
|
|
||||||
pub fn width(&self) -> u32 {
|
|
||||||
self.size.width
|
|
||||||
}
|
|
||||||
pub fn height(&self) -> u32 {
|
|
||||||
self.size.height
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_device_owned_handle! {
|
define_device_owned_handle! {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub ImageView(vk::ImageView) {} => |this| unsafe {
|
pub ImageView(vk::ImageView) {} => |this| unsafe {
|
||||||
|
@ -230,41 +279,6 @@ pub struct QueueOwnership {
|
||||||
pub dst: u32,
|
pub dst: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn image_barrier<'a>(
|
|
||||||
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>,
|
|
||||||
) -> vk::ImageMemoryBarrier2<'a> {
|
|
||||||
let (src_family, dst_family) = queue_ownership_op
|
|
||||||
.map(|t| (t.src, t.dst))
|
|
||||||
.unwrap_or((vk::QUEUE_FAMILY_IGNORED, vk::QUEUE_FAMILY_IGNORED));
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const SUBRESOURCERANGE_COLOR_ALL: vk::ImageSubresourceRange = vk::ImageSubresourceRange {
|
pub const SUBRESOURCERANGE_COLOR_ALL: vk::ImageSubresourceRange = vk::ImageSubresourceRange {
|
||||||
aspect_mask: vk::ImageAspectFlags::COLOR,
|
aspect_mask: vk::ImageAspectFlags::COLOR,
|
||||||
base_mip_level: 0,
|
base_mip_level: 0,
|
||||||
|
|
|
@ -6,23 +6,20 @@
|
||||||
map_try_insert,
|
map_try_insert,
|
||||||
debug_closure_helpers
|
debug_closure_helpers
|
||||||
)]
|
)]
|
||||||
#![allow(unused)]
|
|
||||||
use std::{
|
use std::{
|
||||||
borrow::Borrow,
|
borrow::Borrow,
|
||||||
collections::{BTreeMap, BTreeSet, HashMap},
|
collections::{BTreeMap, BTreeSet, HashMap},
|
||||||
ffi::{CStr, CString},
|
ffi::{CStr, CString},
|
||||||
fmt::Debug,
|
fmt::Debug,
|
||||||
hash::Hash,
|
|
||||||
hint::black_box,
|
hint::black_box,
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
ops::Deref,
|
|
||||||
sync::{
|
sync::{
|
||||||
atomic::{AtomicU32, AtomicU64},
|
atomic::{AtomicU32, AtomicU64},
|
||||||
Arc,
|
Arc,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use bytemuck::Contiguous;
|
|
||||||
use egui::Color32;
|
use egui::Color32;
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use parking_lot::{Mutex, MutexGuard, RwLock};
|
use parking_lot::{Mutex, MutexGuard, RwLock};
|
||||||
|
@ -35,8 +32,7 @@ use ash::{
|
||||||
};
|
};
|
||||||
use dyn_clone::DynClone;
|
use dyn_clone::DynClone;
|
||||||
use rand::{Rng, SeedableRng};
|
use rand::{Rng, SeedableRng};
|
||||||
use raw_window_handle::{DisplayHandle, RawDisplayHandle};
|
use raw_window_handle::RawDisplayHandle;
|
||||||
use tinyvec::{array_vec, ArrayVec};
|
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
|
|
||||||
mod buffers;
|
mod buffers;
|
||||||
|
@ -48,7 +44,7 @@ mod render_graph;
|
||||||
mod sync;
|
mod sync;
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
use device::{Device, DeviceAndQueues, DeviceOwned, DeviceQueueFamilies, WeakDevice};
|
use device::{Device, DeviceOwned, DeviceQueueFamilies};
|
||||||
|
|
||||||
mod texture {
|
mod texture {
|
||||||
use std::{
|
use std::{
|
||||||
|
@ -61,7 +57,7 @@ mod texture {
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
def_monotonic_id,
|
def_monotonic_id,
|
||||||
images::{Image2D, ImageView},
|
images::{Image, ImageView},
|
||||||
Device,
|
Device,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -69,12 +65,15 @@ mod texture {
|
||||||
|
|
||||||
pub struct Texture {
|
pub struct Texture {
|
||||||
id: TextureId,
|
id: TextureId,
|
||||||
image: Arc<Image2D>,
|
image: Arc<Image>,
|
||||||
views: Mutex<HashMap<crate::images::ImageViewDesc, Arc<ImageView>>>,
|
views: Mutex<HashMap<crate::images::ImageViewDesc, Arc<ImageView>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Texture {
|
impl Texture {
|
||||||
pub fn image(&self) -> Arc<Image2D> {
|
pub fn id(&self) -> TextureId {
|
||||||
|
self.id
|
||||||
|
}
|
||||||
|
pub fn image(&self) -> Arc<Image> {
|
||||||
self.image.clone()
|
self.image.clone()
|
||||||
}
|
}
|
||||||
pub fn view(&self, desc: crate::images::ImageViewDesc) -> VkResult<Arc<ImageView>> {
|
pub fn view(&self, desc: crate::images::ImageViewDesc) -> VkResult<Arc<ImageView>> {
|
||||||
|
@ -93,6 +92,7 @@ mod texture {
|
||||||
|
|
||||||
pub struct TextureManager {
|
pub struct TextureManager {
|
||||||
pub textures: BTreeMap<TextureId, Arc<Texture>>,
|
pub textures: BTreeMap<TextureId, Arc<Texture>>,
|
||||||
|
#[allow(unused)]
|
||||||
dev: Device,
|
dev: Device,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +104,7 @@ mod texture {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_image_with_id(&mut self, id: TextureId, image: Arc<Image2D>) {
|
pub fn insert_image_with_id(&mut self, id: TextureId, image: Arc<Image>) {
|
||||||
self.textures.insert(
|
self.textures.insert(
|
||||||
id,
|
id,
|
||||||
Arc::new(Texture {
|
Arc::new(Texture {
|
||||||
|
@ -164,6 +164,7 @@ impl<'a> VkNameList<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
#[allow(dead_code)]
|
||||||
struct DeviceExtension<'a> {
|
struct DeviceExtension<'a> {
|
||||||
name: &'a core::ffi::CStr,
|
name: &'a core::ffi::CStr,
|
||||||
version: u32,
|
version: u32,
|
||||||
|
@ -178,6 +179,7 @@ fn make_extention_properties(name: &CStr, version: u32) -> vk::ExtensionProperti
|
||||||
|
|
||||||
/// returns true if lhs and rhs have the same name and lhs spec_version is less
|
/// returns true if lhs and rhs have the same name and lhs spec_version is less
|
||||||
/// than or equal to rhs spec_version
|
/// than or equal to rhs spec_version
|
||||||
|
#[allow(dead_code)]
|
||||||
fn compatible_extension_properties(
|
fn compatible_extension_properties(
|
||||||
lhs: &vk::ExtensionProperties,
|
lhs: &vk::ExtensionProperties,
|
||||||
rhs: &vk::ExtensionProperties,
|
rhs: &vk::ExtensionProperties,
|
||||||
|
@ -197,7 +199,7 @@ fn compatible_extension_properties(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
struct Queue(Arc<Mutex<vk::Queue>>, u32);
|
pub struct Queue(Arc<Mutex<vk::Queue>>, u32);
|
||||||
|
|
||||||
impl Queue {
|
impl Queue {
|
||||||
fn new(device: &ash::Device, family: u32, index: u32) -> Self {
|
fn new(device: &ash::Device, family: u32, index: u32) -> Self {
|
||||||
|
@ -223,8 +225,11 @@ impl Queue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trait ExtendsDeviceFeatures2Debug: vk::ExtendsPhysicalDeviceFeatures2 + Debug + Send + Sync {}
|
pub trait ExtendsDeviceFeatures2Debug:
|
||||||
trait ExtendsDeviceProperties2Debug:
|
vk::ExtendsPhysicalDeviceFeatures2 + Debug + Send + Sync
|
||||||
|
{
|
||||||
|
}
|
||||||
|
pub trait ExtendsDeviceProperties2Debug:
|
||||||
vk::ExtendsPhysicalDeviceProperties2 + Debug + DynClone + Send + Sync
|
vk::ExtendsPhysicalDeviceProperties2 + Debug + DynClone + Send + Sync
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -239,7 +244,7 @@ impl<T: vk::ExtendsPhysicalDeviceProperties2 + Debug + DynClone + Send + Sync>
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
struct PhysicalDeviceFeatures {
|
pub struct PhysicalDeviceFeatures {
|
||||||
pub version: u32,
|
pub version: u32,
|
||||||
pub physical_features_10: vk::PhysicalDeviceFeatures,
|
pub physical_features_10: vk::PhysicalDeviceFeatures,
|
||||||
pub physical_features_11: Option<vk::PhysicalDeviceVulkan11Features<'static>>,
|
pub physical_features_11: Option<vk::PhysicalDeviceVulkan11Features<'static>>,
|
||||||
|
@ -307,6 +312,7 @@ impl PhysicalDeviceFeatures {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
fn with_extension2(mut self, ext: vk::ExtensionProperties) -> Self {
|
fn with_extension2(mut self, ext: vk::ExtensionProperties) -> Self {
|
||||||
self.device_extensions.push(ext);
|
self.device_extensions.push(ext);
|
||||||
|
|
||||||
|
@ -442,6 +448,7 @@ impl PhysicalDeviceProperties {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
fn with_properties<F>(mut self, properties: F) -> Self
|
fn with_properties<F>(mut self, properties: F) -> Self
|
||||||
where
|
where
|
||||||
F: ExtendsDeviceProperties2Debug + 'static,
|
F: ExtendsDeviceProperties2Debug + 'static,
|
||||||
|
@ -467,13 +474,13 @@ impl PhysicalDeviceProperties {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct PhysicalDevice {
|
pub struct PhysicalDevice {
|
||||||
pdev: vk::PhysicalDevice,
|
pdev: vk::PhysicalDevice,
|
||||||
queue_families: DeviceQueueFamilies,
|
queue_families: DeviceQueueFamilies,
|
||||||
properties: PhysicalDeviceProperties,
|
properties: PhysicalDeviceProperties,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Instance {
|
pub struct Instance {
|
||||||
entry: Entry,
|
entry: Entry,
|
||||||
instance: ash::Instance,
|
instance: ash::Instance,
|
||||||
debug_utils: ash::ext::debug_utils::Instance,
|
debug_utils: ash::ext::debug_utils::Instance,
|
||||||
|
@ -501,10 +508,6 @@ impl AsRef<ash::khr::surface::Instance> for Instance {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RawSwapchain(vk::SwapchainKHR);
|
|
||||||
|
|
||||||
impl !Sync for RawSwapchain {}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct SwapchainHandle(Mutex<vk::SwapchainKHR>);
|
struct SwapchainHandle(Mutex<vk::SwapchainKHR>);
|
||||||
|
|
||||||
|
@ -529,7 +532,9 @@ pub struct Swapchain {
|
||||||
// has a strong ref to the surface because the surface may not outlive the swapchain
|
// has a strong ref to the surface because the surface may not outlive the swapchain
|
||||||
surface: Arc<Surface>,
|
surface: Arc<Surface>,
|
||||||
swapchain: SwapchainHandle,
|
swapchain: SwapchainHandle,
|
||||||
|
#[allow(unused)]
|
||||||
present_mode: vk::PresentModeKHR,
|
present_mode: vk::PresentModeKHR,
|
||||||
|
#[allow(unused)]
|
||||||
color_space: vk::ColorSpaceKHR,
|
color_space: vk::ColorSpaceKHR,
|
||||||
format: vk::Format,
|
format: vk::Format,
|
||||||
images: Vec<vk::Image>,
|
images: Vec<vk::Image>,
|
||||||
|
@ -555,7 +560,7 @@ pub struct Swapchain {
|
||||||
impl Drop for Swapchain {
|
impl Drop for Swapchain {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.device.wait_queue_idle(self.device.present_queue());
|
_ = self.device.wait_queue_idle(self.device.present_queue());
|
||||||
info!("dropping swapchain {:?}", self.swapchain);
|
info!("dropping swapchain {:?}", self.swapchain);
|
||||||
for view in &self.image_views {
|
for view in &self.image_views {
|
||||||
self.device.dev().destroy_image_view(*view, None);
|
self.device.dev().destroy_image_view(*view, None);
|
||||||
|
@ -570,12 +575,10 @@ impl Drop for Swapchain {
|
||||||
.iter()
|
.iter()
|
||||||
.chain(&self.release_semaphores)
|
.chain(&self.release_semaphores)
|
||||||
{
|
{
|
||||||
unsafe {
|
|
||||||
self.device.dev().destroy_semaphore(semaphore, None);
|
self.device.dev().destroy_semaphore(semaphore, None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn current_extent_or_clamped(
|
fn current_extent_or_clamped(
|
||||||
|
@ -620,8 +623,8 @@ pub struct SwapchainFrame {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SwapchainFrame {
|
impl SwapchainFrame {
|
||||||
fn present(self) {
|
fn present(self) -> Result<()> {
|
||||||
self.swapchain.clone().present(self);
|
self.swapchain.clone().present(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -773,14 +776,12 @@ impl Swapchain {
|
||||||
swapchain.0.lock().as_raw()
|
swapchain.0.lock().as_raw()
|
||||||
))
|
))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
unsafe {
|
_ = device.debug_utils().set_debug_utils_object_name(
|
||||||
device.debug_utils().set_debug_utils_object_name(
|
|
||||||
&vk::DebugUtilsObjectNameInfoEXT::default()
|
&vk::DebugUtilsObjectNameInfoEXT::default()
|
||||||
.object_handle(*r)
|
.object_handle(*r)
|
||||||
.object_name(&name),
|
.object_name(&name),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.collect::<VkResult<Vec<_>>>()?
|
.collect::<VkResult<Vec<_>>>()?
|
||||||
|
@ -800,14 +801,12 @@ impl Swapchain {
|
||||||
swapchain.0.lock().as_raw()
|
swapchain.0.lock().as_raw()
|
||||||
))
|
))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
unsafe {
|
_ = device.debug_utils().set_debug_utils_object_name(
|
||||||
device.debug_utils().set_debug_utils_object_name(
|
|
||||||
&vk::DebugUtilsObjectNameInfoEXT::default()
|
&vk::DebugUtilsObjectNameInfoEXT::default()
|
||||||
.object_handle(*r)
|
.object_handle(*r)
|
||||||
.object_name(&name),
|
.object_name(&name),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.collect::<VkResult<Vec<_>>>()?
|
.collect::<VkResult<Vec<_>>>()?
|
||||||
|
@ -826,7 +825,7 @@ impl Swapchain {
|
||||||
))
|
))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
unsafe {
|
unsafe {
|
||||||
device.debug_utils().set_debug_utils_object_name(
|
_ = device.debug_utils().set_debug_utils_object_name(
|
||||||
&vk::DebugUtilsObjectNameInfoEXT::default()
|
&vk::DebugUtilsObjectNameInfoEXT::default()
|
||||||
.object_handle(r.fence())
|
.object_handle(r.fence())
|
||||||
.object_name(&name),
|
.object_name(&name),
|
||||||
|
@ -1011,7 +1010,7 @@ impl Swapchain {
|
||||||
SWAPCHAIN_COUNT.fetch_add(1, std::sync::atomic::Ordering::Relaxed)
|
SWAPCHAIN_COUNT.fetch_add(1, std::sync::atomic::Ordering::Relaxed)
|
||||||
))
|
))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
device.debug_utils().set_debug_utils_object_name(
|
_ = device.debug_utils().set_debug_utils_object_name(
|
||||||
&vk::DebugUtilsObjectNameInfoEXT::default()
|
&vk::DebugUtilsObjectNameInfoEXT::default()
|
||||||
.object_handle(swapchain)
|
.object_handle(swapchain)
|
||||||
.object_name(&name),
|
.object_name(&name),
|
||||||
|
@ -1028,12 +1027,13 @@ impl Swapchain {
|
||||||
}
|
}
|
||||||
static SWAPCHAIN_COUNT: AtomicU64 = AtomicU64::new(0);
|
static SWAPCHAIN_COUNT: AtomicU64 = AtomicU64::new(0);
|
||||||
|
|
||||||
struct Surface {
|
pub struct Surface {
|
||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
surface: vk::SurfaceKHR,
|
surface: vk::SurfaceKHR,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Surface {
|
impl Surface {
|
||||||
|
#[allow(dead_code)]
|
||||||
fn headless(instance: Arc<Instance>) -> Result<Self> {
|
fn headless(instance: Arc<Instance>) -> Result<Self> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let headless_instance =
|
let headless_instance =
|
||||||
|
@ -1109,7 +1109,7 @@ pub struct Vulkan {
|
||||||
impl Drop for Vulkan {
|
impl Drop for Vulkan {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.device.dev().device_wait_idle();
|
_ = self.device.dev().device_wait_idle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1211,7 +1211,7 @@ impl Vulkan {
|
||||||
entry,
|
entry,
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut features = PhysicalDeviceFeatures::all_default()
|
let features = PhysicalDeviceFeatures::all_default()
|
||||||
.version(vk::make_api_version(0, 1, 3, 0))
|
.version(vk::make_api_version(0, 1, 3, 0))
|
||||||
.features10(
|
.features10(
|
||||||
vk::PhysicalDeviceFeatures::default()
|
vk::PhysicalDeviceFeatures::default()
|
||||||
|
@ -1355,6 +1355,7 @@ impl Vulkan {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl QueueFamily {
|
impl QueueFamily {
|
||||||
|
#[allow(dead_code)]
|
||||||
fn is_graphics_and_compute(&self) -> bool {
|
fn is_graphics_and_compute(&self) -> bool {
|
||||||
self.is_compute && self.is_graphics
|
self.is_compute && self.is_graphics
|
||||||
}
|
}
|
||||||
|
@ -1675,7 +1676,8 @@ pub struct WindowContext {
|
||||||
impl Drop for WindowContext {
|
impl Drop for WindowContext {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.current_swapchain
|
_ = self
|
||||||
|
.current_swapchain
|
||||||
.read()
|
.read()
|
||||||
.device
|
.device
|
||||||
.dev()
|
.dev()
|
||||||
|
@ -1747,7 +1749,6 @@ impl WindowContext {
|
||||||
.await
|
.await
|
||||||
.expect("channel closed on swapchain acquiring frame");
|
.expect("channel closed on swapchain acquiring frame");
|
||||||
}
|
}
|
||||||
Result::Ok(())
|
|
||||||
});
|
});
|
||||||
|
|
||||||
(rx, task)
|
(rx, task)
|
||||||
|
@ -1779,8 +1780,10 @@ impl WindowContext {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct EguiState {
|
pub struct EguiState {
|
||||||
textures: HashMap<egui::TextureId, EguiTextureInfo>,
|
textures: HashMap<egui::TextureId, EguiTextureInfo>,
|
||||||
|
#[allow(unused)]
|
||||||
descriptor_pool: pipeline::DescriptorPool,
|
descriptor_pool: pipeline::DescriptorPool,
|
||||||
descriptor_set: vk::DescriptorSet,
|
descriptor_set: vk::DescriptorSet,
|
||||||
|
#[allow(unused)]
|
||||||
descriptor_layout: pipeline::DescriptorSetLayout,
|
descriptor_layout: pipeline::DescriptorSetLayout,
|
||||||
pipeline_layout: pipeline::PipelineLayout,
|
pipeline_layout: pipeline::PipelineLayout,
|
||||||
pipeline: pipeline::Pipeline,
|
pipeline: pipeline::Pipeline,
|
||||||
|
@ -2113,23 +2116,25 @@ impl<W> Renderer<W> {
|
||||||
} else {
|
} else {
|
||||||
vk::ImageUsageFlags::TRANSFER_SRC
|
vk::ImageUsageFlags::TRANSFER_SRC
|
||||||
};
|
};
|
||||||
let extent = vk::Extent2D {
|
|
||||||
|
let texture = Arc::new(
|
||||||
|
images::Image::new(
|
||||||
|
self.vulkan.device.clone(),
|
||||||
|
images::ImageDesc {
|
||||||
|
name: Some(format!("egui-texture-{egui_id:?}").into()),
|
||||||
|
format: vk::Format::R8G8B8A8_UNORM,
|
||||||
|
extent: vk::Extent3D {
|
||||||
width: delta.image.width() as u32,
|
width: delta.image.width() as u32,
|
||||||
height: delta.image.height() as u32,
|
height: delta.image.height() as u32,
|
||||||
};
|
depth: 1,
|
||||||
let texture = images::Image2D::new_exclusive(
|
},
|
||||||
&self.vulkan.device,
|
usage: sampled | vk::ImageUsageFlags::TRANSFER_DST,
|
||||||
extent,
|
mem_usage: vk_mem::MemoryUsage::AutoPreferDevice,
|
||||||
1,
|
..Default::default()
|
||||||
1,
|
},
|
||||||
vk::Format::R8G8B8A8_UNORM,
|
|
||||||
vk::ImageTiling::OPTIMAL,
|
|
||||||
sampled | vk::ImageUsageFlags::TRANSFER_DST,
|
|
||||||
vk_mem::MemoryUsage::AutoPreferDevice,
|
|
||||||
vk_mem::AllocationCreateFlags::empty(),
|
|
||||||
Some(&format!("egui-texture-{egui_id:?}")),
|
|
||||||
)
|
)
|
||||||
.expect("image creation");
|
.expect("image creation"),
|
||||||
|
);
|
||||||
|
|
||||||
cmd.image_barrier(
|
cmd.image_barrier(
|
||||||
texture.image(),
|
texture.image(),
|
||||||
|
@ -2492,7 +2497,7 @@ impl<W> Renderer<W> {
|
||||||
let fence = Arc::new(sync::Fence::create(device.clone()).unwrap());
|
let fence = Arc::new(sync::Fence::create(device.clone()).unwrap());
|
||||||
let future = cmd.submit_async(None, None, fence).unwrap();
|
let future = cmd.submit_async(None, None, fence).unwrap();
|
||||||
|
|
||||||
future.block();
|
future.block()?;
|
||||||
|
|
||||||
black_box((cmd_objects, draw_staging));
|
black_box((cmd_objects, draw_staging));
|
||||||
// free after drawing
|
// free after drawing
|
||||||
|
@ -2540,27 +2545,8 @@ impl<W> Renderer<W> {
|
||||||
let [r, g, b] = rand::prelude::StdRng::seed_from_u64(ctx.surface.surface.as_raw())
|
let [r, g, b] = rand::prelude::StdRng::seed_from_u64(ctx.surface.surface.as_raw())
|
||||||
.gen::<[f32; 3]>();
|
.gen::<[f32; 3]>();
|
||||||
let clear_color = Rgba([r, g, b, 1.0]);
|
let clear_color = Rgba([r, g, b, 1.0]);
|
||||||
let clear_values = vk::ClearColorValue {
|
|
||||||
float32: [r, g, b, 1.0],
|
|
||||||
};
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
let barriers = [images::image_barrier(
|
|
||||||
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,
|
|
||||||
None,
|
|
||||||
)];
|
|
||||||
|
|
||||||
let dependency_info = vk::DependencyInfo::default()
|
|
||||||
.dependency_flags(vk::DependencyFlags::BY_REGION)
|
|
||||||
.image_memory_barriers(&barriers);
|
|
||||||
|
|
||||||
|
{
|
||||||
cmd.image_barrier(
|
cmd.image_barrier(
|
||||||
frame.image,
|
frame.image,
|
||||||
vk::ImageAspectFlags::COLOR,
|
vk::ImageAspectFlags::COLOR,
|
||||||
|
@ -2593,6 +2579,8 @@ impl<W> Renderer<W> {
|
||||||
|
|
||||||
let egui_ctx = self.egui_state.render_state.take();
|
let egui_ctx = self.egui_state.render_state.take();
|
||||||
if let Some(ctx) = egui_ctx.as_ref() {
|
if let Some(ctx) = egui_ctx.as_ref() {
|
||||||
|
_ = &ctx.texture_ids;
|
||||||
|
|
||||||
let color_attachment = &vk::RenderingAttachmentInfo::default()
|
let color_attachment = &vk::RenderingAttachmentInfo::default()
|
||||||
.image_layout(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL)
|
.image_layout(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL)
|
||||||
.image_view(frame.view)
|
.image_view(frame.view)
|
||||||
|
@ -2669,9 +2657,15 @@ impl<W> Renderer<W> {
|
||||||
// call pre_present_notify
|
// call pre_present_notify
|
||||||
pre_present_cb();
|
pre_present_cb();
|
||||||
|
|
||||||
frame.present();
|
frame.present()?;
|
||||||
future.block()?;
|
future.block()?;
|
||||||
|
|
||||||
|
egui_ctx.map(|ctx| {
|
||||||
|
for id in ctx.textures_to_free {
|
||||||
|
self.texture_handler.remove_texture(id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// wait for idle here is unnecessary.
|
// wait for idle here is unnecessary.
|
||||||
// dev.dev().device_wait_idle();
|
// dev.dev().device_wait_idle();
|
||||||
}
|
}
|
||||||
|
@ -3330,19 +3324,19 @@ mod test_swapchain {
|
||||||
#[tracing_test::traced_test]
|
#[tracing_test::traced_test]
|
||||||
#[test]
|
#[test]
|
||||||
fn async_swapchain_acquiring() {
|
fn async_swapchain_acquiring() {
|
||||||
let (vk, ctx) = create_headless_vk().expect("init");
|
let (_vk, ctx) = create_headless_vk().expect("init");
|
||||||
let ctx = Arc::new(ctx);
|
let ctx = Arc::new(ctx);
|
||||||
let (rx, handle) = ctx.images();
|
let (rx, handle) = ctx.images();
|
||||||
|
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
loop {
|
loop {
|
||||||
let mut now = std::time::Instant::now();
|
let now = std::time::Instant::now();
|
||||||
let frame = rx.recv_blocking().expect("recv");
|
let frame = rx.recv_blocking().expect("recv");
|
||||||
frame.present();
|
_ = frame.present();
|
||||||
tracing::info!("mspf: {}ms", now.elapsed().as_secs_f64() / 1000.0);
|
tracing::info!("mspf: {}ms", now.elapsed().as_secs_f64() / 1000.0);
|
||||||
count += 1;
|
count += 1;
|
||||||
if count > 1000 {
|
if count > 1000 {
|
||||||
handle.cancel();
|
smol::block_on(handle.cancel());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,15 +45,6 @@ pub enum PipelineDesc<'a> {
|
||||||
Graphics(GraphicsPipelineDesc<'a>),
|
Graphics(GraphicsPipelineDesc<'a>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PipelineDesc<'_> {
|
|
||||||
fn name(self) -> Option<Cow<'static, str>> {
|
|
||||||
match self {
|
|
||||||
PipelineDesc::Compute(desc) => desc.name,
|
|
||||||
PipelineDesc::Graphics(desc) => desc.name,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ComputePipelineDesc<'a> {
|
pub struct ComputePipelineDesc<'a> {
|
||||||
pub flags: vk::PipelineCreateFlags,
|
pub flags: vk::PipelineCreateFlags,
|
||||||
|
@ -261,10 +252,17 @@ impl DescriptorPool {
|
||||||
.set_layouts(&layouts);
|
.set_layouts(&layouts);
|
||||||
let sets = unsafe { self.device().dev().allocate_descriptor_sets(&info)? };
|
let sets = unsafe { self.device().dev().allocate_descriptor_sets(&info)? };
|
||||||
|
|
||||||
|
for (&set, desc) in sets.iter().zip(descs) {
|
||||||
|
if let Some(name) = desc.name.as_ref() {
|
||||||
|
self.device().debug_name_object(set, &name)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(sets)
|
Ok(sets)
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub fn free(&self) {}
|
// pub fn free(&self) {}
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn reset(&self) -> VkResult<()> {
|
pub fn reset(&self) -> VkResult<()> {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.device()
|
self.device()
|
||||||
|
@ -511,7 +509,13 @@ impl Pipeline {
|
||||||
name = desc.name;
|
name = desc.name;
|
||||||
bind_point = vk::PipelineBindPoint::COMPUTE;
|
bind_point = vk::PipelineBindPoint::COMPUTE;
|
||||||
let info = &vk::ComputePipelineCreateInfo::default()
|
let info = &vk::ComputePipelineCreateInfo::default()
|
||||||
|
.flags(desc.flags)
|
||||||
.layout(desc.layout.handle())
|
.layout(desc.layout.handle())
|
||||||
|
.base_pipeline_handle(
|
||||||
|
desc.base_pipeline
|
||||||
|
.map(|p| p.handle())
|
||||||
|
.unwrap_or(vk::Pipeline::null()),
|
||||||
|
)
|
||||||
.stage(desc.shader_stage.into_create_info());
|
.stage(desc.shader_stage.into_create_info());
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -581,11 +585,12 @@ impl Pipeline {
|
||||||
});
|
});
|
||||||
|
|
||||||
let multisample = desc.multisample.map(|state| {
|
let multisample = desc.multisample.map(|state| {
|
||||||
let mut info = vk::PipelineMultisampleStateCreateInfo::default()
|
let info = vk::PipelineMultisampleStateCreateInfo::default()
|
||||||
.flags(state.flags)
|
.flags(state.flags)
|
||||||
.min_sample_shading(state.min_sample_shading)
|
.min_sample_shading(state.min_sample_shading)
|
||||||
.rasterization_samples(state.rasterization_samples)
|
.rasterization_samples(state.rasterization_samples)
|
||||||
.sample_mask(state.sample_mask)
|
.sample_mask(state.sample_mask)
|
||||||
|
.sample_shading_enable(state.sample_shading_enable)
|
||||||
.alpha_to_coverage_enable(state.alpha_to_coverage_enable)
|
.alpha_to_coverage_enable(state.alpha_to_coverage_enable)
|
||||||
.alpha_to_one_enable(state.alpha_to_one_enable);
|
.alpha_to_one_enable(state.alpha_to_one_enable);
|
||||||
|
|
||||||
|
@ -593,7 +598,7 @@ impl Pipeline {
|
||||||
});
|
});
|
||||||
|
|
||||||
let color_blend = desc.color_blend.map(|state| {
|
let color_blend = desc.color_blend.map(|state| {
|
||||||
let mut info = vk::PipelineColorBlendStateCreateInfo::default()
|
let info = vk::PipelineColorBlendStateCreateInfo::default()
|
||||||
.flags(state.flags)
|
.flags(state.flags)
|
||||||
.attachments(state.attachments)
|
.attachments(state.attachments)
|
||||||
.blend_constants(state.blend_constants)
|
.blend_constants(state.blend_constants)
|
||||||
|
@ -631,7 +636,7 @@ impl Pipeline {
|
||||||
});
|
});
|
||||||
|
|
||||||
let dynamic = desc.dynamic.map(|state| {
|
let dynamic = desc.dynamic.map(|state| {
|
||||||
let mut info = vk::PipelineDynamicStateCreateInfo::default()
|
let info = vk::PipelineDynamicStateCreateInfo::default()
|
||||||
.flags(state.flags)
|
.flags(state.flags)
|
||||||
.dynamic_states(state.dynamic_states);
|
.dynamic_states(state.dynamic_states);
|
||||||
|
|
||||||
|
@ -639,7 +644,7 @@ impl Pipeline {
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut rendering = desc.rendering.map(|state| {
|
let mut rendering = desc.rendering.map(|state| {
|
||||||
let mut info = vk::PipelineRenderingCreateInfo::default()
|
let info = vk::PipelineRenderingCreateInfo::default()
|
||||||
.color_attachment_formats(state.color_formats)
|
.color_attachment_formats(state.color_formats)
|
||||||
.depth_attachment_format(state.depth_format.unwrap_or_default())
|
.depth_attachment_format(state.depth_format.unwrap_or_default())
|
||||||
.stencil_attachment_format(state.stencil_format.unwrap_or_default());
|
.stencil_attachment_format(state.stencil_format.unwrap_or_default());
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::hash::Hash;
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use crate::util::hash_f32;
|
use crate::util::hash_f32;
|
||||||
use ash::vk;
|
use ash::vk;
|
||||||
|
|
|
@ -24,7 +24,7 @@ enum SyncPrimitive {
|
||||||
Fence(Arc<Fence>),
|
Fence(Arc<Fence>),
|
||||||
// actually, I think this is an awful idea because I would have to hold a
|
// actually, I think this is an awful idea because I would have to hold a
|
||||||
// lock on all queues.
|
// lock on all queues.
|
||||||
DeviceIdle(Device),
|
// DeviceIdle(Device),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SyncThreadpool {
|
impl SyncThreadpool {
|
||||||
|
@ -72,8 +72,7 @@ impl SyncThreadpool {
|
||||||
let wait_result = match &sync {
|
let wait_result = match &sync {
|
||||||
SyncPrimitive::Fence(fence) => {
|
SyncPrimitive::Fence(fence) => {
|
||||||
fence.wait_on(Some(self.timeout))
|
fence.wait_on(Some(self.timeout))
|
||||||
}
|
} // SyncPrimitive::DeviceIdle(device) => device.wait_idle(),
|
||||||
SyncPrimitive::DeviceIdle(device) => device.wait_idle(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
match wait_result {
|
match wait_result {
|
||||||
|
@ -105,14 +104,15 @@ impl SyncThreadpool {
|
||||||
};
|
};
|
||||||
|
|
||||||
let barrier = Arc::new(std::sync::Barrier::new(2));
|
let barrier = Arc::new(std::sync::Barrier::new(2));
|
||||||
std::thread::Builder::new()
|
let _ = std::thread::Builder::new()
|
||||||
.name(format!("fence-waiter-{tid}"))
|
.name(format!("fence-waiter-{tid}"))
|
||||||
.spawn({
|
.spawn({
|
||||||
let barrier = barrier.clone();
|
let barrier = barrier.clone();
|
||||||
move || {
|
move || {
|
||||||
thread.run(barrier);
|
thread.run(barrier);
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
.expect("sync-threadpool waiter thread failed to spawn.");
|
||||||
barrier.wait();
|
barrier.wait();
|
||||||
Some(())
|
Some(())
|
||||||
}
|
}
|
||||||
|
@ -127,8 +127,6 @@ impl SyncThreadpool {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn spawn_waiter(&self, fence: Arc<Fence>, waker: std::task::Waker) {
|
fn spawn_waiter(&self, fence: Arc<Fence>, waker: std::task::Waker) {
|
||||||
use std::sync::atomic::Ordering;
|
|
||||||
|
|
||||||
let mut msg = (SyncPrimitive::Fence(fence), waker);
|
let mut msg = (SyncPrimitive::Fence(fence), waker);
|
||||||
while let Err(err) = self.channel.0.try_send(msg) {
|
while let Err(err) = self.channel.0.try_send(msg) {
|
||||||
match err {
|
match err {
|
||||||
|
@ -137,7 +135,7 @@ impl SyncThreadpool {
|
||||||
self.try_spawn_thread();
|
self.try_spawn_thread();
|
||||||
}
|
}
|
||||||
crossbeam::channel::TrySendError::Disconnected(_) => {
|
crossbeam::channel::TrySendError::Disconnected(_) => {
|
||||||
//tracing::error!("sync-threadpool channel disconnected?");
|
tracing::error!("sync-threadpool channel disconnected?");
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -182,6 +180,7 @@ impl Fence {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn create_signaled(dev: Device) -> VkResult<Fence> {
|
pub fn create_signaled(dev: Device) -> VkResult<Fence> {
|
||||||
unsafe {
|
unsafe {
|
||||||
Ok(Self::new(
|
Ok(Self::new(
|
||||||
|
@ -221,6 +220,7 @@ impl AsRef<vk::Fence> for Fence {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
impl Semaphore {
|
impl Semaphore {
|
||||||
pub fn new(device: Device) -> VkResult<Self> {
|
pub fn new(device: Device) -> VkResult<Self> {
|
||||||
let mut type_info =
|
let mut type_info =
|
||||||
|
@ -260,6 +260,7 @@ pub struct FenceFuture<'a> {
|
||||||
|
|
||||||
impl FenceFuture<'_> {
|
impl FenceFuture<'_> {
|
||||||
/// Unsafe because `fence` must not be destroyed while this future is live.
|
/// Unsafe because `fence` must not be destroyed while this future is live.
|
||||||
|
#[allow(dead_code)]
|
||||||
pub unsafe fn from_fence(device: Device, fence: vk::Fence) -> Self {
|
pub unsafe fn from_fence(device: Device, fence: vk::Fence) -> Self {
|
||||||
Self {
|
Self {
|
||||||
fence: Arc::new(Fence::new(device, fence)),
|
fence: Arc::new(Fence::new(device, fence)),
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::{borrow::Cow, ops::Deref};
|
use std::ops::Deref;
|
||||||
|
|
||||||
use ash::vk;
|
use ash::vk;
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@ impl<'a, T: 'a> MutexExt<'a, T> for parking_lot::Mutex<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub trait FormatExt {
|
pub trait FormatExt {
|
||||||
fn get_component_kind(&self) -> FormatComponentKind;
|
fn get_component_kind(&self) -> FormatComponentKind;
|
||||||
fn is_f32(&self) -> bool;
|
fn is_f32(&self) -> bool;
|
||||||
|
@ -280,7 +281,6 @@ impl Rect2D {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn new_from_size(pos: glam::IVec2, size: glam::IVec2) -> Self {
|
pub fn new_from_size(pos: glam::IVec2, size: glam::IVec2) -> Self {
|
||||||
use glam::ivec2;
|
|
||||||
Self {
|
Self {
|
||||||
top_left: pos,
|
top_left: pos,
|
||||||
bottom_right: pos + size,
|
bottom_right: pos + size,
|
||||||
|
|
Loading…
Reference in a new issue