warning cleanup

This commit is contained in:
Janis 2025-01-01 02:00:23 +01:00
parent ea3c24ec46
commit e76bf29840
9 changed files with 323 additions and 321 deletions

View file

@ -12,7 +12,6 @@ define_device_owned_handle! {
#[derive(Debug)]
pub Buffer(vk::Buffer) {
alloc: vk_mem::Allocation,
usage: vk::BufferUsageFlags,
size: u64,
} => |this| unsafe {
this.device().clone().alloc().destroy_buffer(this.handle(), &mut this.alloc);
@ -55,7 +54,6 @@ impl Buffer {
buffer,
name,
allocation,
usage,
size as u64,
)?))
}

View file

@ -1,9 +1,8 @@
use std::{future::Future, marker::PhantomData, sync::Arc};
use std::sync::Arc;
use crate::{
buffers::Buffer,
device::DeviceOwned,
images::{Image2D, QueueOwnership},
images::{Image, QueueOwnership},
pipeline::{Pipeline, PipelineLayout},
sync::{self, FenceFuture},
util::{self, FormatExt, MutexExt},
@ -154,9 +153,9 @@ impl SingleUseCommand {
pub fn blit_images(
&self,
src: &Image2D,
src: &Image,
src_region: util::Rect2D,
dst: &Image2D,
dst: &Image,
dst_region: util::Rect2D,
) {
unsafe {
@ -318,6 +317,8 @@ impl SingleUseCommand {
);
}
}
#[allow(dead_code)]
pub fn draw_indexed(
&self,
indices: u32,
@ -398,12 +399,12 @@ impl SingleUseCommand {
signal: Option<vk::Semaphore>,
fence: Arc<sync::Fence>,
) -> VkResult<FenceFuture<'a>> {
let device = self.device.clone();
self.submit_fence(wait, signal, Some(fence.fence()))?;
Ok(unsafe { FenceFuture::new(fence) })
Ok(FenceFuture::new(fence))
}
#[allow(dead_code)]
pub fn submit_blocking(
self,
wait: Option<(vk::Semaphore, vk::PipelineStageFlags)>,
@ -411,22 +412,7 @@ impl SingleUseCommand {
) -> VkResult<()> {
let fence = Arc::new(sync::Fence::create(self.device.clone())?);
let future = self.submit_async(wait, signal, fence)?;
future.block();
future.block()?;
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;
}
}

View file

@ -1,16 +1,10 @@
use std::{
borrow::Cow,
collections::{BTreeMap, HashMap},
ops::Deref,
sync::Arc,
};
use std::{borrow::Cow, collections::BTreeMap, ops::Deref, sync::Arc};
use ash::{
khr,
prelude::VkResult,
vk::{self, Handle},
};
use parking_lot::Mutex;
use tinyvec::{array_vec, ArrayVec};
use crate::{sync, Instance, PhysicalDevice, Queue};
@ -68,6 +62,7 @@ impl Drop for DeviceWrapper {
}
}
#[allow(unused)]
pub struct DeviceInner {
alloc: vk_mem::Allocator,
device: DeviceWrapper,
@ -158,7 +153,7 @@ impl Device {
let alloc_info =
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 {
device: DeviceWrapper(device.clone()),
@ -276,6 +271,7 @@ impl AsRef<ash::Device> for Device {
}
}
#[allow(dead_code)]
pub struct DeviceAndQueues {
pub(crate) device: Device,
pub(crate) main_queue: Queue,
@ -299,18 +295,25 @@ impl AsRef<ash::khr::swapchain::Device> for DeviceAndQueues {
pub struct DeviceOwnedDebugObject<T> {
device: Device,
object: T,
#[cfg(debug_assertions)]
name: Option<Cow<'static, str>>,
}
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 {
f.debug_struct(core::any::type_name::<T>())
.field_with("device", |f| {
write!(f, "0x{:x}", self.device.0.device.handle().as_raw())
})
.field_with("handle", |f| write!(f, "0x{:x}", &self.object.as_raw()))
.field("name", &self.name)
.finish()
let mut fmt = f.debug_struct(core::any::type_name::<T>());
fmt.field_with("device", |f| {
write!(f, "0x{:x}", self.device.0.device.handle().as_raw())
})
.field_with("handle", |f| write!(f, "0x{:x}", &self.object.as_raw()));
#[cfg(debug_assertions)]
{
fmt.field("name", &self.name);
}
fmt.finish()
}
}
@ -324,7 +327,7 @@ impl<T> DeviceOwnedDebugObject<T> {
T: vk::Handle + Copy,
{
if let Some(name) = name.as_ref() {
device.debug_name_object(object, name);
device.debug_name_object(object, name)?;
}
Ok(Self {
@ -395,6 +398,7 @@ macro_rules! define_device_owned_handle {
$(
impl Drop for $ty {
fn drop(&mut self) {
#[allow(unused_mut)]
let mut $this = self;
$dtor
}

View file

@ -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 itertools::Itertools;
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)]
pub struct ImageViewDesc {
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! {
#[derive(Debug)]
pub ImageView(vk::ImageView) {} => |this| unsafe {
@ -230,41 +279,6 @@ pub struct QueueOwnership {
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 {
aspect_mask: vk::ImageAspectFlags::COLOR,
base_mip_level: 0,

View file

@ -6,23 +6,20 @@
map_try_insert,
debug_closure_helpers
)]
#![allow(unused)]
use std::{
borrow::Borrow,
collections::{BTreeMap, BTreeSet, HashMap},
ffi::{CStr, CString},
fmt::Debug,
hash::Hash,
hint::black_box,
marker::PhantomData,
ops::Deref,
sync::{
atomic::{AtomicU32, AtomicU64},
Arc,
},
};
use bytemuck::Contiguous;
use egui::Color32;
use indexmap::IndexMap;
use parking_lot::{Mutex, MutexGuard, RwLock};
@ -35,8 +32,7 @@ use ash::{
};
use dyn_clone::DynClone;
use rand::{Rng, SeedableRng};
use raw_window_handle::{DisplayHandle, RawDisplayHandle};
use tinyvec::{array_vec, ArrayVec};
use raw_window_handle::RawDisplayHandle;
use tracing::info;
mod buffers;
@ -48,7 +44,7 @@ mod render_graph;
mod sync;
mod util;
use device::{Device, DeviceAndQueues, DeviceOwned, DeviceQueueFamilies, WeakDevice};
use device::{Device, DeviceOwned, DeviceQueueFamilies};
mod texture {
use std::{
@ -61,7 +57,7 @@ mod texture {
use crate::{
def_monotonic_id,
images::{Image2D, ImageView},
images::{Image, ImageView},
Device,
};
@ -69,12 +65,15 @@ mod texture {
pub struct Texture {
id: TextureId,
image: Arc<Image2D>,
image: Arc<Image>,
views: Mutex<HashMap<crate::images::ImageViewDesc, Arc<ImageView>>>,
}
impl Texture {
pub fn image(&self) -> Arc<Image2D> {
pub fn id(&self) -> TextureId {
self.id
}
pub fn image(&self) -> Arc<Image> {
self.image.clone()
}
pub fn view(&self, desc: crate::images::ImageViewDesc) -> VkResult<Arc<ImageView>> {
@ -93,6 +92,7 @@ mod texture {
pub struct TextureManager {
pub textures: BTreeMap<TextureId, Arc<Texture>>,
#[allow(unused)]
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(
id,
Arc::new(Texture {
@ -164,6 +164,7 @@ impl<'a> VkNameList<'a> {
}
#[derive(Debug, Clone)]
#[allow(dead_code)]
struct DeviceExtension<'a> {
name: &'a core::ffi::CStr,
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
/// than or equal to rhs spec_version
#[allow(dead_code)]
fn compatible_extension_properties(
lhs: &vk::ExtensionProperties,
rhs: &vk::ExtensionProperties,
@ -197,7 +199,7 @@ fn compatible_extension_properties(
}
#[derive(Clone, Debug)]
struct Queue(Arc<Mutex<vk::Queue>>, u32);
pub struct Queue(Arc<Mutex<vk::Queue>>, u32);
impl Queue {
fn new(device: &ash::Device, family: u32, index: u32) -> Self {
@ -223,8 +225,11 @@ impl Queue {
}
}
trait ExtendsDeviceFeatures2Debug: vk::ExtendsPhysicalDeviceFeatures2 + Debug + Send + Sync {}
trait ExtendsDeviceProperties2Debug:
pub trait ExtendsDeviceFeatures2Debug:
vk::ExtendsPhysicalDeviceFeatures2 + Debug + Send + Sync
{
}
pub trait ExtendsDeviceProperties2Debug:
vk::ExtendsPhysicalDeviceProperties2 + Debug + DynClone + Send + Sync
{
}
@ -239,7 +244,7 @@ impl<T: vk::ExtendsPhysicalDeviceProperties2 + Debug + DynClone + Send + Sync>
}
#[derive(Default, Debug)]
struct PhysicalDeviceFeatures {
pub struct PhysicalDeviceFeatures {
pub version: u32,
pub physical_features_10: vk::PhysicalDeviceFeatures,
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 {
self.device_extensions.push(ext);
@ -442,6 +448,7 @@ impl PhysicalDeviceProperties {
self
}
#[allow(dead_code)]
fn with_properties<F>(mut self, properties: F) -> Self
where
F: ExtendsDeviceProperties2Debug + 'static,
@ -467,13 +474,13 @@ impl PhysicalDeviceProperties {
}
#[derive(Debug)]
struct PhysicalDevice {
pub struct PhysicalDevice {
pdev: vk::PhysicalDevice,
queue_families: DeviceQueueFamilies,
properties: PhysicalDeviceProperties,
}
struct Instance {
pub struct Instance {
entry: Entry,
instance: ash::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)]
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
surface: Arc<Surface>,
swapchain: SwapchainHandle,
#[allow(unused)]
present_mode: vk::PresentModeKHR,
#[allow(unused)]
color_space: vk::ColorSpaceKHR,
format: vk::Format,
images: Vec<vk::Image>,
@ -555,7 +560,7 @@ pub struct Swapchain {
impl Drop for Swapchain {
fn drop(&mut self) {
unsafe {
self.device.wait_queue_idle(self.device.present_queue());
_ = self.device.wait_queue_idle(self.device.present_queue());
info!("dropping swapchain {:?}", self.swapchain);
for view in &self.image_views {
self.device.dev().destroy_image_view(*view, None);
@ -570,9 +575,7 @@ impl Drop for Swapchain {
.iter()
.chain(&self.release_semaphores)
{
unsafe {
self.device.dev().destroy_semaphore(semaphore, None);
}
self.device.dev().destroy_semaphore(semaphore, None);
}
}
}
@ -620,8 +623,8 @@ pub struct SwapchainFrame {
}
impl SwapchainFrame {
fn present(self) {
self.swapchain.clone().present(self);
fn present(self) -> Result<()> {
self.swapchain.clone().present(self)
}
}
@ -773,13 +776,11 @@ impl Swapchain {
swapchain.0.lock().as_raw()
))
.unwrap();
unsafe {
device.debug_utils().set_debug_utils_object_name(
&vk::DebugUtilsObjectNameInfoEXT::default()
.object_handle(*r)
.object_name(&name),
);
}
_ = device.debug_utils().set_debug_utils_object_name(
&vk::DebugUtilsObjectNameInfoEXT::default()
.object_handle(*r)
.object_name(&name),
);
}
})
})
@ -800,13 +801,11 @@ impl Swapchain {
swapchain.0.lock().as_raw()
))
.unwrap();
unsafe {
device.debug_utils().set_debug_utils_object_name(
&vk::DebugUtilsObjectNameInfoEXT::default()
.object_handle(*r)
.object_name(&name),
);
}
_ = device.debug_utils().set_debug_utils_object_name(
&vk::DebugUtilsObjectNameInfoEXT::default()
.object_handle(*r)
.object_name(&name),
);
}
})
})
@ -826,7 +825,7 @@ impl Swapchain {
))
.unwrap();
unsafe {
device.debug_utils().set_debug_utils_object_name(
_ = device.debug_utils().set_debug_utils_object_name(
&vk::DebugUtilsObjectNameInfoEXT::default()
.object_handle(r.fence())
.object_name(&name),
@ -1011,7 +1010,7 @@ impl Swapchain {
SWAPCHAIN_COUNT.fetch_add(1, std::sync::atomic::Ordering::Relaxed)
))
.unwrap();
device.debug_utils().set_debug_utils_object_name(
_ = device.debug_utils().set_debug_utils_object_name(
&vk::DebugUtilsObjectNameInfoEXT::default()
.object_handle(swapchain)
.object_name(&name),
@ -1028,12 +1027,13 @@ impl Swapchain {
}
static SWAPCHAIN_COUNT: AtomicU64 = AtomicU64::new(0);
struct Surface {
pub struct Surface {
instance: Arc<Instance>,
surface: vk::SurfaceKHR,
}
impl Surface {
#[allow(dead_code)]
fn headless(instance: Arc<Instance>) -> Result<Self> {
unsafe {
let headless_instance =
@ -1109,7 +1109,7 @@ pub struct Vulkan {
impl Drop for Vulkan {
fn drop(&mut self) {
unsafe {
self.device.dev().device_wait_idle();
_ = self.device.dev().device_wait_idle();
}
}
}
@ -1211,7 +1211,7 @@ impl Vulkan {
entry,
});
let mut features = PhysicalDeviceFeatures::all_default()
let features = PhysicalDeviceFeatures::all_default()
.version(vk::make_api_version(0, 1, 3, 0))
.features10(
vk::PhysicalDeviceFeatures::default()
@ -1355,6 +1355,7 @@ impl Vulkan {
}
impl QueueFamily {
#[allow(dead_code)]
fn is_graphics_and_compute(&self) -> bool {
self.is_compute && self.is_graphics
}
@ -1675,7 +1676,8 @@ pub struct WindowContext {
impl Drop for WindowContext {
fn drop(&mut self) {
unsafe {
self.current_swapchain
_ = self
.current_swapchain
.read()
.device
.dev()
@ -1747,7 +1749,6 @@ impl WindowContext {
.await
.expect("channel closed on swapchain acquiring frame");
}
Result::Ok(())
});
(rx, task)
@ -1779,8 +1780,10 @@ impl WindowContext {
#[derive(Debug)]
pub struct EguiState {
textures: HashMap<egui::TextureId, EguiTextureInfo>,
#[allow(unused)]
descriptor_pool: pipeline::DescriptorPool,
descriptor_set: vk::DescriptorSet,
#[allow(unused)]
descriptor_layout: pipeline::DescriptorSetLayout,
pipeline_layout: pipeline::PipelineLayout,
pipeline: pipeline::Pipeline,
@ -2113,23 +2116,25 @@ impl<W> Renderer<W> {
} else {
vk::ImageUsageFlags::TRANSFER_SRC
};
let extent = vk::Extent2D {
width: delta.image.width() as u32,
height: delta.image.height() as u32,
};
let texture = images::Image2D::new_exclusive(
&self.vulkan.device,
extent,
1,
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");
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,
height: delta.image.height() as u32,
depth: 1,
},
usage: sampled | vk::ImageUsageFlags::TRANSFER_DST,
mem_usage: vk_mem::MemoryUsage::AutoPreferDevice,
..Default::default()
},
)
.expect("image creation"),
);
cmd.image_barrier(
texture.image(),
@ -2492,7 +2497,7 @@ impl<W> Renderer<W> {
let fence = Arc::new(sync::Fence::create(device.clone()).unwrap());
let future = cmd.submit_async(None, None, fence).unwrap();
future.block();
future.block()?;
black_box((cmd_objects, draw_staging));
// 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())
.gen::<[f32; 3]>();
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(
frame.image,
vk::ImageAspectFlags::COLOR,
@ -2593,6 +2579,8 @@ impl<W> Renderer<W> {
let egui_ctx = self.egui_state.render_state.take();
if let Some(ctx) = egui_ctx.as_ref() {
_ = &ctx.texture_ids;
let color_attachment = &vk::RenderingAttachmentInfo::default()
.image_layout(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL)
.image_view(frame.view)
@ -2669,9 +2657,15 @@ impl<W> Renderer<W> {
// call pre_present_notify
pre_present_cb();
frame.present();
frame.present()?;
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.
// dev.dev().device_wait_idle();
}
@ -3330,19 +3324,19 @@ mod test_swapchain {
#[tracing_test::traced_test]
#[test]
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 (rx, handle) = ctx.images();
let mut count = 0;
loop {
let mut now = std::time::Instant::now();
let now = std::time::Instant::now();
let frame = rx.recv_blocking().expect("recv");
frame.present();
_ = frame.present();
tracing::info!("mspf: {}ms", now.elapsed().as_secs_f64() / 1000.0);
count += 1;
if count > 1000 {
handle.cancel();
smol::block_on(handle.cancel());
break;
}
}

View file

@ -45,15 +45,6 @@ pub enum PipelineDesc<'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)]
pub struct ComputePipelineDesc<'a> {
pub flags: vk::PipelineCreateFlags,
@ -261,10 +252,17 @@ impl DescriptorPool {
.set_layouts(&layouts);
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)
}
// pub fn free(&self) {}
#[allow(dead_code)]
pub fn reset(&self) -> VkResult<()> {
unsafe {
self.device()
@ -511,7 +509,13 @@ impl Pipeline {
name = desc.name;
bind_point = vk::PipelineBindPoint::COMPUTE;
let info = &vk::ComputePipelineCreateInfo::default()
.flags(desc.flags)
.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());
unsafe {
@ -581,11 +585,12 @@ impl Pipeline {
});
let multisample = desc.multisample.map(|state| {
let mut info = vk::PipelineMultisampleStateCreateInfo::default()
let info = vk::PipelineMultisampleStateCreateInfo::default()
.flags(state.flags)
.min_sample_shading(state.min_sample_shading)
.rasterization_samples(state.rasterization_samples)
.sample_mask(state.sample_mask)
.sample_shading_enable(state.sample_shading_enable)
.alpha_to_coverage_enable(state.alpha_to_coverage_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 mut info = vk::PipelineColorBlendStateCreateInfo::default()
let info = vk::PipelineColorBlendStateCreateInfo::default()
.flags(state.flags)
.attachments(state.attachments)
.blend_constants(state.blend_constants)
@ -631,7 +636,7 @@ impl Pipeline {
});
let dynamic = desc.dynamic.map(|state| {
let mut info = vk::PipelineDynamicStateCreateInfo::default()
let info = vk::PipelineDynamicStateCreateInfo::default()
.flags(state.flags)
.dynamic_states(state.dynamic_states);
@ -639,7 +644,7 @@ impl Pipeline {
});
let mut rendering = desc.rendering.map(|state| {
let mut info = vk::PipelineRenderingCreateInfo::default()
let info = vk::PipelineRenderingCreateInfo::default()
.color_attachment_formats(state.color_formats)
.depth_attachment_format(state.depth_format.unwrap_or_default())
.stencil_attachment_format(state.stencil_format.unwrap_or_default());

View file

@ -1,4 +1,4 @@
use std::hash::Hash;
#![allow(dead_code)]
use crate::util::hash_f32;
use ash::vk;

View file

@ -24,7 +24,7 @@ enum SyncPrimitive {
Fence(Arc<Fence>),
// actually, I think this is an awful idea because I would have to hold a
// lock on all queues.
DeviceIdle(Device),
// DeviceIdle(Device),
}
impl SyncThreadpool {
@ -72,8 +72,7 @@ impl SyncThreadpool {
let wait_result = match &sync {
SyncPrimitive::Fence(fence) => {
fence.wait_on(Some(self.timeout))
}
SyncPrimitive::DeviceIdle(device) => device.wait_idle(),
} // SyncPrimitive::DeviceIdle(device) => device.wait_idle(),
};
match wait_result {
@ -105,14 +104,15 @@ impl SyncThreadpool {
};
let barrier = Arc::new(std::sync::Barrier::new(2));
std::thread::Builder::new()
let _ = std::thread::Builder::new()
.name(format!("fence-waiter-{tid}"))
.spawn({
let barrier = barrier.clone();
move || {
thread.run(barrier);
}
});
})
.expect("sync-threadpool waiter thread failed to spawn.");
barrier.wait();
Some(())
}
@ -127,8 +127,6 @@ impl SyncThreadpool {
}
fn spawn_waiter(&self, fence: Arc<Fence>, waker: std::task::Waker) {
use std::sync::atomic::Ordering;
let mut msg = (SyncPrimitive::Fence(fence), waker);
while let Err(err) = self.channel.0.try_send(msg) {
match err {
@ -137,7 +135,7 @@ impl SyncThreadpool {
self.try_spawn_thread();
}
crossbeam::channel::TrySendError::Disconnected(_) => {
//tracing::error!("sync-threadpool channel disconnected?");
tracing::error!("sync-threadpool channel disconnected?");
unreachable!()
}
}
@ -182,6 +180,7 @@ impl Fence {
))
}
}
#[allow(dead_code)]
pub fn create_signaled(dev: Device) -> VkResult<Fence> {
unsafe {
Ok(Self::new(
@ -221,6 +220,7 @@ impl AsRef<vk::Fence> for Fence {
}
}
#[allow(dead_code)]
impl Semaphore {
pub fn new(device: Device) -> VkResult<Self> {
let mut type_info =
@ -260,6 +260,7 @@ pub struct FenceFuture<'a> {
impl FenceFuture<'_> {
/// 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 {
Self {
fence: Arc::new(Fence::new(device, fence)),

View file

@ -1,4 +1,4 @@
use std::{borrow::Cow, ops::Deref};
use std::ops::Deref;
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 {
fn get_component_kind(&self) -> FormatComponentKind;
fn is_f32(&self) -> bool;
@ -280,7 +281,6 @@ impl Rect2D {
}
}
pub fn new_from_size(pos: glam::IVec2, size: glam::IVec2) -> Self {
use glam::ivec2;
Self {
top_left: pos,
bottom_right: pos + size,