rendering blue background
This commit is contained in:
parent
052fdc4e3e
commit
d9f302cb5a
|
@ -50,6 +50,7 @@ impl WindowState {
|
||||||
fn handle_draw_request(&mut self, window_id: WindowId) {
|
fn handle_draw_request(&mut self, window_id: WindowId) {
|
||||||
_ = window_id;
|
_ = window_id;
|
||||||
info!("TODO: implement draw request");
|
info!("TODO: implement draw request");
|
||||||
|
self.renderer.debug_draw().expect("drawing");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +72,7 @@ impl ApplicationHandler for WindowState {
|
||||||
height: size.height,
|
height: size.height,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.renderer.new_window_context(
|
let _ = self.renderer.new_window_context(
|
||||||
extent,
|
extent,
|
||||||
window_id,
|
window_id,
|
||||||
self.window
|
self.window
|
||||||
|
|
|
@ -13,6 +13,12 @@ use dyn_clone::DynClone;
|
||||||
use tinyvec::{array_vec, ArrayVec};
|
use tinyvec::{array_vec, ArrayVec};
|
||||||
use winit::raw_window_handle::DisplayHandle;
|
use winit::raw_window_handle::DisplayHandle;
|
||||||
|
|
||||||
|
mod commands;
|
||||||
|
mod images;
|
||||||
|
mod sync;
|
||||||
|
|
||||||
|
type VkAllocator = Arc<vk_mem::Allocator>;
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
|
@ -90,6 +96,15 @@ impl Queue {
|
||||||
device.get_device_queue(family, index)
|
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:
|
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>(
|
fn with_extension<F>(
|
||||||
mut self,
|
mut self,
|
||||||
ext: vk::ExtensionProperties,
|
ext: vk::ExtensionProperties,
|
||||||
|
@ -409,31 +439,45 @@ struct Device {
|
||||||
physical: PhysicalDevice,
|
physical: PhysicalDevice,
|
||||||
device: ash::Device,
|
device: ash::Device,
|
||||||
swapchain: khr::swapchain::Device,
|
swapchain: khr::swapchain::Device,
|
||||||
|
main_queue: Queue,
|
||||||
|
compute_queue: Queue,
|
||||||
|
transfer_queue: Queue,
|
||||||
|
present_queue: Queue,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Device {
|
#[derive(Clone)]
|
||||||
fn new(
|
struct Device2(Arc<Device>);
|
||||||
device: ash::Device,
|
|
||||||
physical: PhysicalDevice,
|
impl Device2 {
|
||||||
swapchain: khr::swapchain::Device,
|
fn dev(&self) -> &ash::Device {
|
||||||
) -> Self {
|
&self.0.device
|
||||||
Self {
|
}
|
||||||
device,
|
fn swapchain(&self) -> &khr::swapchain::Device {
|
||||||
physical,
|
&self.0.swapchain
|
||||||
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 {
|
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 {
|
fn as_ref(&self) -> &ash::Device {
|
||||||
&self.device
|
&self.0.device
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -560,8 +604,14 @@ impl Swapchain {
|
||||||
.cloned()
|
.cloned()
|
||||||
.expect("no surface format available!");
|
.expect("no surface format available!");
|
||||||
|
|
||||||
let image_count =
|
let image_count = 3u32.clamp(
|
||||||
3u32.clamp(caps.min_image_count, caps.max_image_count);
|
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);
|
let extent = current_extent_or_clamped(&caps, requested_extent);
|
||||||
|
|
||||||
|
@ -767,8 +817,8 @@ impl Drop for Surface {
|
||||||
|
|
||||||
pub struct Vulkan {
|
pub struct Vulkan {
|
||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
device: DeviceAndQueues,
|
device: Arc<Device>,
|
||||||
alloc: Arc<vk_mem::Allocator>,
|
alloc: VkAllocator,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Vulkan {
|
impl Vulkan {
|
||||||
|
@ -907,13 +957,13 @@ impl Vulkan {
|
||||||
)
|
)
|
||||||
.with_extension(
|
.with_extension(
|
||||||
make_extention_properties(
|
make_extention_properties(
|
||||||
ash::khr::index_type_uint8::NAME,
|
ash::ext::index_type_uint8::NAME,
|
||||||
ash::khr::index_type_uint8::SPEC_VERSION,
|
ash::ext::index_type_uint8::SPEC_VERSION,
|
||||||
),
|
),
|
||||||
vk::PhysicalDeviceIndexTypeUint8FeaturesKHR::default()
|
vk::PhysicalDeviceIndexTypeUint8FeaturesEXT::default()
|
||||||
.index_type_uint8(true),
|
.index_type_uint8(true),
|
||||||
)
|
)
|
||||||
.device_extensions(vec![
|
.with_extensions2([
|
||||||
make_extention_properties(
|
make_extention_properties(
|
||||||
khr::swapchain::NAME,
|
khr::swapchain::NAME,
|
||||||
khr::swapchain::SPEC_VERSION,
|
khr::swapchain::SPEC_VERSION,
|
||||||
|
@ -938,19 +988,20 @@ impl Vulkan {
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
tracing::debug!("pdev: {pdev:?}");
|
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(
|
let alloc_info = vk_mem::AllocatorCreateInfo::new(
|
||||||
&instance.instance,
|
&instance.instance,
|
||||||
dev.as_ref(),
|
&device.device,
|
||||||
dev.device.physical.pdev,
|
device.physical.pdev,
|
||||||
);
|
);
|
||||||
|
|
||||||
let alloc = Arc::new(unsafe { vk_mem::Allocator::new(alloc_info)? });
|
let alloc = Arc::new(unsafe { vk_mem::Allocator::new(alloc_info)? });
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
instance,
|
instance,
|
||||||
device: dev,
|
device,
|
||||||
alloc,
|
alloc,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1145,13 +1196,16 @@ impl Vulkan {
|
||||||
instance: &Instance,
|
instance: &Instance,
|
||||||
pdev: PhysicalDevice,
|
pdev: PhysicalDevice,
|
||||||
features: &mut PhysicalDeviceFeatures,
|
features: &mut PhysicalDeviceFeatures,
|
||||||
) -> Result<DeviceAndQueues> {
|
) -> Result<Device> {
|
||||||
let mut unique_families = BTreeMap::<u32, u32>::new();
|
let mut unique_families = BTreeMap::<u32, u32>::new();
|
||||||
|
|
||||||
let mut helper = |family: u32| {
|
let mut helper = |family: u32| {
|
||||||
use std::collections::btree_map::Entry;
|
use std::collections::btree_map::Entry;
|
||||||
let index = match unique_families.entry(family) {
|
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) => {
|
Entry::Occupied(mut occupied_entry) => {
|
||||||
let idx = occupied_entry.get_mut();
|
let idx = occupied_entry.get_mut();
|
||||||
*idx += 1;
|
*idx += 1;
|
||||||
|
@ -1162,6 +1216,8 @@ impl Vulkan {
|
||||||
(family, index)
|
(family, index)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
eprintln!("queue families: {:?}", pdev.queue_families);
|
||||||
|
|
||||||
let graphics_family_and_index = helper(pdev.queue_families.graphics);
|
let graphics_family_and_index = helper(pdev.queue_families.graphics);
|
||||||
let compute_family_and_index =
|
let compute_family_and_index =
|
||||||
pdev.queue_families.async_compute.map(|f| helper(f));
|
pdev.queue_families.async_compute.map(|f| helper(f));
|
||||||
|
@ -1176,8 +1232,11 @@ impl Vulkan {
|
||||||
as usize
|
as usize
|
||||||
];
|
];
|
||||||
|
|
||||||
|
eprintln!("unique_families: {unique_families:?}");
|
||||||
|
|
||||||
let queue_infos = unique_families
|
let queue_infos = unique_families
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
.filter(|&(_, count)| count > 0)
|
||||||
.map(|(family, queues)| {
|
.map(|(family, queues)| {
|
||||||
vk::DeviceQueueCreateInfo::default()
|
vk::DeviceQueueCreateInfo::default()
|
||||||
.queue_family_index(family)
|
.queue_family_index(family)
|
||||||
|
@ -1185,6 +1244,8 @@ impl Vulkan {
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
eprintln!("infos: {queue_infos:#?}");
|
||||||
|
|
||||||
let extensions = features
|
let extensions = features
|
||||||
.device_extensions
|
.device_extensions
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -1197,7 +1258,7 @@ impl Vulkan {
|
||||||
.enabled_extension_names(&extensions)
|
.enabled_extension_names(&extensions)
|
||||||
.push_next(&mut features2);
|
.push_next(&mut features2);
|
||||||
|
|
||||||
let device_and_queues = unsafe {
|
let device = unsafe {
|
||||||
let device = instance.instance.create_device(
|
let device = instance.instance.create_device(
|
||||||
pdev.pdev,
|
pdev.pdev,
|
||||||
&device_info,
|
&device_info,
|
||||||
|
@ -1222,15 +1283,13 @@ impl Vulkan {
|
||||||
.map(|(f, i)| Queue::new(&device, f, i))
|
.map(|(f, i)| Queue::new(&device, f, i))
|
||||||
.unwrap_or(compute_queue.clone());
|
.unwrap_or(compute_queue.clone());
|
||||||
|
|
||||||
DeviceAndQueues {
|
Device {
|
||||||
device: Arc::new(Device {
|
device: device.clone(),
|
||||||
device: device.clone(),
|
physical: pdev,
|
||||||
physical: pdev,
|
swapchain: khr::swapchain::Device::new(
|
||||||
swapchain: khr::swapchain::Device::new(
|
&instance.instance,
|
||||||
&instance.instance,
|
&device,
|
||||||
&device,
|
),
|
||||||
),
|
|
||||||
}),
|
|
||||||
main_queue,
|
main_queue,
|
||||||
present_queue,
|
present_queue,
|
||||||
compute_queue,
|
compute_queue,
|
||||||
|
@ -1238,7 +1297,7 @@ impl Vulkan {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(device_and_queues)
|
Ok(device)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn choose_physical_device(
|
fn choose_physical_device(
|
||||||
|
@ -1417,7 +1476,7 @@ pub struct WindowContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WindowContext {
|
impl WindowContext {
|
||||||
pub fn new(
|
fn new(
|
||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
extent: vk::Extent2D,
|
extent: vk::Extent2D,
|
||||||
|
@ -1468,11 +1527,133 @@ impl Renderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn debug_draw(&mut self) -> Result<()> {
|
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(
|
pub fn new_window_context(
|
||||||
|
@ -1486,7 +1667,7 @@ impl Renderer {
|
||||||
Entry::Vacant(entry) => {
|
Entry::Vacant(entry) => {
|
||||||
let ctx = WindowContext::new(
|
let ctx = WindowContext::new(
|
||||||
self.vulkan.instance.clone(),
|
self.vulkan.instance.clone(),
|
||||||
self.vulkan.device.device.clone(),
|
self.vulkan.device.clone(),
|
||||||
extent,
|
extent,
|
||||||
window.as_raw(),
|
window.as_raw(),
|
||||||
self.display,
|
self.display,
|
||||||
|
|
Loading…
Reference in a new issue