rendering blue background

This commit is contained in:
Janis 2024-12-15 01:59:19 +01:00
parent 052fdc4e3e
commit d9f302cb5a
2 changed files with 228 additions and 46 deletions

View file

@ -50,6 +50,7 @@ impl WindowState {
fn handle_draw_request(&mut self, window_id: WindowId) {
_ = window_id;
info!("TODO: implement draw request");
self.renderer.debug_draw().expect("drawing");
}
}
@ -71,7 +72,7 @@ impl ApplicationHandler for WindowState {
height: size.height,
};
self.renderer.new_window_context(
let _ = self.renderer.new_window_context(
extent,
window_id,
self.window

View file

@ -13,6 +13,12 @@ use dyn_clone::DynClone;
use tinyvec::{array_vec, ArrayVec};
use winit::raw_window_handle::DisplayHandle;
mod commands;
mod images;
mod sync;
type VkAllocator = Arc<vk_mem::Allocator>;
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error(transparent)]
@ -90,6 +96,15 @@ impl Queue {
device.get_device_queue(family, index)
})))
}
pub fn with_locked<T, F: FnOnce(vk::Queue) -> T>(&self, map: F) -> T {
let lock = self.0.lock().expect("mutex lock poison");
map(*lock)
}
pub fn lock(&self) -> std::sync::MutexGuard<'_, vk::Queue> {
self.0.lock().unwrap()
}
}
trait ExtendsDeviceFeatures2Debug:
@ -198,6 +213,21 @@ impl PhysicalDeviceFeatures {
}
}
fn with_extension2(mut self, ext: vk::ExtensionProperties) -> Self {
self.device_extensions.push(ext);
self
}
fn with_extensions2<I: IntoIterator<Item = vk::ExtensionProperties>>(
mut self,
exts: I,
) -> Self {
self.device_extensions.extend(exts);
self
}
fn with_extension<F>(
mut self,
ext: vk::ExtensionProperties,
@ -409,31 +439,45 @@ struct Device {
physical: PhysicalDevice,
device: ash::Device,
swapchain: khr::swapchain::Device,
main_queue: Queue,
compute_queue: Queue,
transfer_queue: Queue,
present_queue: Queue,
}
impl Device {
fn new(
device: ash::Device,
physical: PhysicalDevice,
swapchain: khr::swapchain::Device,
) -> Self {
Self {
device,
physical,
swapchain,
}
#[derive(Clone)]
struct Device2(Arc<Device>);
impl Device2 {
fn dev(&self) -> &ash::Device {
&self.0.device
}
fn swapchain(&self) -> &khr::swapchain::Device {
&self.0.swapchain
}
fn queue_families(&self) -> &DeviceQueueFamilies {
&self.0.physical.queue_families
}
fn phy(&self) -> &vk::PhysicalDevice {
&self.0.physical.pdev
}
fn graphics_queue(&self) -> &Queue {
&self.0.main_queue
}
fn present_queue(&self) -> &Queue {
&self.0.present_queue
}
}
impl AsRef<khr::swapchain::Device> for Device {
impl AsRef<khr::swapchain::Device> for Device2 {
fn as_ref(&self) -> &khr::swapchain::Device {
&self.swapchain
&self.0.swapchain
}
}
impl AsRef<ash::Device> for Device {
impl AsRef<ash::Device> for Device2 {
fn as_ref(&self) -> &ash::Device {
&self.device
&self.0.device
}
}
@ -560,8 +604,14 @@ impl Swapchain {
.cloned()
.expect("no surface format available!");
let image_count =
3u32.clamp(caps.min_image_count, caps.max_image_count);
let image_count = 3u32.clamp(
caps.min_image_count,
if caps.max_image_count == 0 {
u32::MAX
} else {
caps.max_image_count
},
);
let extent = current_extent_or_clamped(&caps, requested_extent);
@ -767,8 +817,8 @@ impl Drop for Surface {
pub struct Vulkan {
instance: Arc<Instance>,
device: DeviceAndQueues,
alloc: Arc<vk_mem::Allocator>,
device: Arc<Device>,
alloc: VkAllocator,
}
impl Vulkan {
@ -907,13 +957,13 @@ impl Vulkan {
)
.with_extension(
make_extention_properties(
ash::khr::index_type_uint8::NAME,
ash::khr::index_type_uint8::SPEC_VERSION,
ash::ext::index_type_uint8::NAME,
ash::ext::index_type_uint8::SPEC_VERSION,
),
vk::PhysicalDeviceIndexTypeUint8FeaturesKHR::default()
vk::PhysicalDeviceIndexTypeUint8FeaturesEXT::default()
.index_type_uint8(true),
)
.device_extensions(vec![
.with_extensions2([
make_extention_properties(
khr::swapchain::NAME,
khr::swapchain::SPEC_VERSION,
@ -938,19 +988,20 @@ impl Vulkan {
)?;
tracing::debug!("pdev: {pdev:?}");
let dev = Self::create_device(&instance, pdev, &mut features)?;
let device =
Arc::new(Self::create_device(&instance, pdev, &mut features)?);
let alloc_info = vk_mem::AllocatorCreateInfo::new(
&instance.instance,
dev.as_ref(),
dev.device.physical.pdev,
&device.device,
device.physical.pdev,
);
let alloc = Arc::new(unsafe { vk_mem::Allocator::new(alloc_info)? });
Ok(Self {
instance,
device: dev,
device,
alloc,
})
}
@ -1145,13 +1196,16 @@ impl Vulkan {
instance: &Instance,
pdev: PhysicalDevice,
features: &mut PhysicalDeviceFeatures,
) -> Result<DeviceAndQueues> {
) -> Result<Device> {
let mut unique_families = BTreeMap::<u32, u32>::new();
let mut helper = |family: u32| {
use std::collections::btree_map::Entry;
let index = match unique_families.entry(family) {
Entry::Vacant(vacant_entry) => *vacant_entry.insert(0),
Entry::Vacant(vacant_entry) => {
vacant_entry.insert(1);
0
}
Entry::Occupied(mut occupied_entry) => {
let idx = occupied_entry.get_mut();
*idx += 1;
@ -1162,6 +1216,8 @@ impl Vulkan {
(family, index)
};
eprintln!("queue families: {:?}", pdev.queue_families);
let graphics_family_and_index = helper(pdev.queue_families.graphics);
let compute_family_and_index =
pdev.queue_families.async_compute.map(|f| helper(f));
@ -1176,8 +1232,11 @@ impl Vulkan {
as usize
];
eprintln!("unique_families: {unique_families:?}");
let queue_infos = unique_families
.into_iter()
.filter(|&(_, count)| count > 0)
.map(|(family, queues)| {
vk::DeviceQueueCreateInfo::default()
.queue_family_index(family)
@ -1185,6 +1244,8 @@ impl Vulkan {
})
.collect::<Vec<_>>();
eprintln!("infos: {queue_infos:#?}");
let extensions = features
.device_extensions
.iter()
@ -1197,7 +1258,7 @@ impl Vulkan {
.enabled_extension_names(&extensions)
.push_next(&mut features2);
let device_and_queues = unsafe {
let device = unsafe {
let device = instance.instance.create_device(
pdev.pdev,
&device_info,
@ -1222,15 +1283,13 @@ impl Vulkan {
.map(|(f, i)| Queue::new(&device, f, i))
.unwrap_or(compute_queue.clone());
DeviceAndQueues {
device: Arc::new(Device {
device: device.clone(),
physical: pdev,
swapchain: khr::swapchain::Device::new(
&instance.instance,
&device,
),
}),
Device {
device: device.clone(),
physical: pdev,
swapchain: khr::swapchain::Device::new(
&instance.instance,
&device,
),
main_queue,
present_queue,
compute_queue,
@ -1238,7 +1297,7 @@ impl Vulkan {
}
};
Ok(device_and_queues)
Ok(device)
}
fn choose_physical_device(
@ -1417,7 +1476,7 @@ pub struct WindowContext {
}
impl WindowContext {
pub fn new(
fn new(
instance: Arc<Instance>,
device: Arc<Device>,
extent: vk::Extent2D,
@ -1468,11 +1527,133 @@ impl Renderer {
}
pub fn debug_draw(&mut self) -> Result<()> {
let dev = self.vulkan.device.device.clone();
let dev = Device2(self.vulkan.device.clone());
unsafe { dev.device.device_wait_idle()? };
unsafe { dev.dev().device_wait_idle()? };
todo!()
let pool = commands::SingleUseCommandPool::new(
dev.clone(),
dev.queue_families().graphics,
)?;
for ctx in self.window_contexts.values() {
let cmd =
commands::SingleUseCommand::new(dev.clone(), pool.pool())?;
let buffer = cmd.command_buffer();
let extent = ctx.current_swapchain.extent;
let ready_semaphore = sync::Semaphore::new(dev.clone())?;
let (swapchain_index, suboptimal) = unsafe {
dev.swapchain().acquire_next_image(
ctx.current_swapchain.swapchain,
u64::MAX,
ready_semaphore.semaphore(),
vk::Fence::null(),
)?
};
if suboptimal {
continue;
}
let image = ctx.current_swapchain.images.first().cloned().unwrap();
// let image = images::Image2D::new_exclusive(
// self.vulkan.alloc.clone(),
// extent,
// 1,
// 1,
// vk::Format::R8G8B8A8_UNORM,
// vk::ImageTiling::OPTIMAL,
// vk::ImageUsageFlags::TRANSFER_SRC,
// vk_mem::MemoryUsage::AutoPreferDevice,
// vk_mem::AllocationCreateFlags::empty(),
// )?;
// let view = image.view(&dev, vk::ImageAspectFlags::COLOR)?;
let clear_values = vk::ClearColorValue {
float32: [0.275, 0.769, 0.941, 1.0],
};
unsafe {
let barriers = [images::image_barrier(
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);
dev.dev().cmd_pipeline_barrier2(buffer, &dependency_info);
dev.dev().cmd_clear_color_image(
buffer,
image,
vk::ImageLayout::TRANSFER_DST_OPTIMAL,
&clear_values,
&[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)],
);
let barriers = [images::image_barrier(
image,
vk::ImageAspectFlags::COLOR,
vk::PipelineStageFlags2::TRANSFER,
vk::AccessFlags2::TRANSFER_WRITE,
vk::PipelineStageFlags2::BOTTOM_OF_PIPE,
vk::AccessFlags2::empty(),
vk::ImageLayout::TRANSFER_DST_OPTIMAL,
vk::ImageLayout::PRESENT_SRC_KHR,
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 signal_semaphore = sync::Semaphore::new(dev.clone())?;
let future = cmd.submit_async(
dev.graphics_queue().clone(),
Some((
ready_semaphore.semaphore(),
vk::PipelineStageFlags::TOP_OF_PIPE,
)),
Some(signal_semaphore.semaphore()),
)?;
let wait_semaphores = [signal_semaphore.semaphore()];
let swapchains = [ctx.current_swapchain.swapchain];
let indices = [swapchain_index];
let present_info = vk::PresentInfoKHR::default()
.image_indices(&indices)
.swapchains(&swapchains)
.wait_semaphores(&wait_semaphores);
dev.present_queue().with_locked(|queue| {
dev.swapchain().queue_present(queue, &present_info)
})?;
future.block_until()?;
}
}
//unsafe {dev.dev().}
Ok(())
}
pub fn new_window_context(
@ -1486,7 +1667,7 @@ impl Renderer {
Entry::Vacant(entry) => {
let ctx = WindowContext::new(
self.vulkan.instance.clone(),
self.vulkan.device.device.clone(),
self.vulkan.device.clone(),
extent,
window.as_raw(),
self.display,