Use Arc to store reference and store dependencies for each vulkan types
Some checks failed
Build legacy Nix package on Ubuntu / build (push) Failing after 0s

Arc it's used because later, i can use on multi-threaded programs
This commit is contained in:
Florian RICHER 2024-11-15 22:40:36 +01:00
parent 1cb9309a56
commit 174e12591c
Signed by: florian.richer
GPG key ID: C73D37CBED7BFC77
5 changed files with 290 additions and 320 deletions

View file

@ -1,28 +1,26 @@
use std::sync::Arc;
use crate::vulkan::{VkDevice, VkInstance, VkPhysicalDevice, VkSurface, VkSwapchain};
use ash::vk;
use ash::vk::QueueFlags;
pub struct VkRenderContext {
instance: VkInstance,
surface: VkSurface,
device: VkDevice,
instance: Arc<VkInstance>,
surface: Arc<VkSurface>,
device: Arc<VkDevice>,
swapchain: VkSwapchain,
present_images: Vec<vk::Image>,
present_image_views: Vec<vk::ImageView>,
swapchain: Arc<VkSwapchain>,
present_queue: vk::Queue,
pool: vk::CommandPool,
setup_command_buffer: vk::CommandBuffer,
draw_command_buffer: vk::CommandBuffer,
draw_commands_reuse_fence: vk::Fence,
setup_commands_reuse_fence: vk::Fence,
present_complete_semaphore: vk::Semaphore,
rendering_complete_semaphore: vk::Semaphore,
// present_queue: vk::Queue,
//
// pool: vk::CommandPool,
//
// setup_command_buffer: vk::CommandBuffer,
// draw_command_buffer: vk::CommandBuffer,
//
// draw_commands_reuse_fence: vk::Fence,
// setup_commands_reuse_fence: vk::Fence,
//
// present_complete_semaphore: vk::Semaphore,
// rendering_complete_semaphore: vk::Semaphore,
}
impl VkRenderContext {
@ -30,75 +28,67 @@ impl VkRenderContext {
let required_extensions = window
.required_extensions()?;
let instance = VkInstance::new(&required_extensions);
let surface = instance.create_surface(&window)?;
let instance = Arc::new(VkInstance::new(&required_extensions));
let surface = Arc::new(VkSurface::new(
&window,
instance.clone()
)?);
let mut physical_devices = instance.get_physical_devices();
physical_devices.sort_by(|a, b| b.priority().cmp(&a.priority()));
let (physical_device, queue_family_index, _) = VkPhysicalDevice::pick_physical_device_and_queue_by(
&physical_devices,
Some(QueueFlags::GRAPHICS),
Some(vk::QueueFlags::GRAPHICS),
Some(&surface),
).expect("Unable to find physical device");
).ok_or_else(|| anyhow::anyhow!("Unable to find physical device"))?;
let device = VkDevice::new_graphics_device(&instance, &physical_device, queue_family_index)
.expect("Unable to create device");
let swapchain = surface.create_swapchain(
let device = Arc::new(VkDevice::new_graphics_device(instance.clone(), &physical_device, queue_family_index)?);
let swapchain = Arc::new(VkSwapchain::new(
&window,
&instance,
&device,
&physical_device,
).expect("Unable to create swapchain");
surface.clone(),
device.clone(),
&physical_device
)?);
let present_images = swapchain.get_swapchain_images()
.expect("Failed to get present images");
let present_image_views = present_images
.iter()
.map(|i| {
device.create_image_view(*i, swapchain.surface_format)
.expect("Failed to create image view")
})
.collect::<Vec<_>>();
let present_queue = device.get_device_queue(0);
let pool_create_info = vk::CommandPoolCreateInfo::default()
.flags(vk::CommandPoolCreateFlags::RESET_COMMAND_BUFFER);
let pool = device.create_command_pool(&pool_create_info)
.expect("Failed to create command pool");
let command_buffer_allocate_info = vk::CommandBufferAllocateInfo::default()
.command_buffer_count(2)
.command_pool(pool)
.level(vk::CommandBufferLevel::PRIMARY);
let command_buffers = device
.allocate_command_buffers(&command_buffer_allocate_info)
.expect("Failed to create command buffers");
let setup_command_buffer = command_buffers[0];
let draw_command_buffer = command_buffers[1];
let fence_create_info =
vk::FenceCreateInfo::default().flags(vk::FenceCreateFlags::SIGNALED);
let draw_commands_reuse_fence = device
.create_fence(&fence_create_info)
.expect("Failed to create draw commands fence");
let setup_commands_reuse_fence = device
.create_fence(&fence_create_info)
.expect("Failed to create setup commands fence");
let semaphore_create_info = vk::SemaphoreCreateInfo::default();
let present_complete_semaphore = device
.create_semaphore(&semaphore_create_info)
.expect("Failed to create present complete semaphore");
let rendering_complete_semaphore = device
.create_semaphore(&semaphore_create_info)
.expect("Failed to create rendering complete semaphore");
// let present_queue = device.get_device_queue(0);
//
// let pool_create_info = vk::CommandPoolCreateInfo::default()
// .flags(vk::CommandPoolCreateFlags::RESET_COMMAND_BUFFER);
//
// let pool = device.create_command_pool(&pool_create_info)
// .expect("Failed to create command pool");
//
// let command_buffer_allocate_info = vk::CommandBufferAllocateInfo::default()
// .command_buffer_count(2)
// .command_pool(pool)
// .level(vk::CommandBufferLevel::PRIMARY);
//
// let command_buffers = device
// .allocate_command_buffers(&command_buffer_allocate_info)
// .expect("Failed to create command buffers");
// let setup_command_buffer = command_buffers[0];
// let draw_command_buffer = command_buffers[1];
//
// let fence_create_info =
// vk::FenceCreateInfo::default().flags(vk::FenceCreateFlags::SIGNALED);
//
// let draw_commands_reuse_fence = device
// .create_fence(&fence_create_info)
// .expect("Failed to create draw commands fence");
// let setup_commands_reuse_fence = device
// .create_fence(&fence_create_info)
// .expect("Failed to create setup commands fence");
//
// let semaphore_create_info = vk::SemaphoreCreateInfo::default();
//
// let present_complete_semaphore = device
// .create_semaphore(&semaphore_create_info)
// .expect("Failed to create present complete semaphore");
// let rendering_complete_semaphore = device
// .create_semaphore(&semaphore_create_info)
// .expect("Failed to create rendering complete semaphore");
Ok(Self {
instance,
@ -106,72 +96,72 @@ impl VkRenderContext {
device,
swapchain,
present_images,
present_image_views,
present_queue,
pool,
setup_command_buffer,
draw_command_buffer,
present_complete_semaphore,
rendering_complete_semaphore,
draw_commands_reuse_fence,
setup_commands_reuse_fence,
// present_queue,
//
// pool,
//
// setup_command_buffer,
// draw_command_buffer,
//
// present_complete_semaphore,
// rendering_complete_semaphore,
//
// draw_commands_reuse_fence,
// setup_commands_reuse_fence,
})
}
pub fn render(&mut self) -> anyhow::Result<()> {
unsafe {
self.device.handle
.wait_for_fences(&[self.draw_commands_reuse_fence], true, u64::MAX)
.expect("Wait for fence failed.");
self.device.handle
.reset_fences(&[self.draw_commands_reuse_fence])
.expect("Reset fences failed.");
self.device.handle
.reset_command_buffer(
self.draw_command_buffer,
vk::CommandBufferResetFlags::RELEASE_RESOURCES,
)
.expect("Reset command buffer failed.");
let command_buffer_begin_info = vk::CommandBufferBeginInfo::default()
.flags(vk::CommandBufferUsageFlags::ONE_TIME_SUBMIT);
self.device.handle
.begin_command_buffer(self.draw_command_buffer, &command_buffer_begin_info)
.expect("Begin commandbuffer");
self.device.handle
.end_command_buffer(self.draw_command_buffer)
.expect("End commandbuffer");
let command_buffers = vec![self.draw_command_buffer];
let semaphores = vec![self.rendering_complete_semaphore];
let wait_mask = vec![vk::PipelineStageFlags::default()];
let submit_info = vk::SubmitInfo::default()
.wait_semaphores(&semaphores)
.wait_dst_stage_mask(&wait_mask)
.command_buffers(&command_buffers)
.signal_semaphores(&semaphores);
self.device.handle
.queue_submit(self.present_queue, &[submit_info], self.draw_commands_reuse_fence)
.expect("queue submit failed.");
}
// unsafe {
// self.device.handle
// .wait_for_fences(&[self.draw_commands_reuse_fence], true, u64::MAX)
// .expect("Wait for fence failed.");
//
// self.device.handle
// .reset_fences(&[self.draw_commands_reuse_fence])
// .expect("Reset fences failed.");
//
// self.device.handle
// .reset_command_buffer(
// self.draw_command_buffer,
// vk::CommandBufferResetFlags::RELEASE_RESOURCES,
// )
// .expect("Reset command buffer failed.");
//
// let command_buffer_begin_info = vk::CommandBufferBeginInfo::default()
// .flags(vk::CommandBufferUsageFlags::ONE_TIME_SUBMIT);
//
// self.device.handle
// .begin_command_buffer(self.draw_command_buffer, &command_buffer_begin_info)
// .expect("Begin commandbuffer");
//
// self.device.handle
// .end_command_buffer(self.draw_command_buffer)
// .expect("End commandbuffer");
//
// let command_buffers = vec![self.draw_command_buffer];
// let semaphores = vec![self.rendering_complete_semaphore];
// let wait_mask = vec![vk::PipelineStageFlags::default()];
//
// let submit_info = vk::SubmitInfo::default()
// .wait_semaphores(&semaphores)
// .wait_dst_stage_mask(&wait_mask)
// .command_buffers(&command_buffers)
// .signal_semaphores(&semaphores);
//
// self.device.handle
// .queue_submit(self.present_queue, &[submit_info], self.draw_commands_reuse_fence)
// .expect("queue submit failed.");
// }
Ok(())
}
pub fn update_resolution(&mut self, width: u32, height: u32) -> anyhow::Result<()> {
self.swapchain.update_resolution(&self.surface, width, height)?;
if let Some(swapchain) = Arc::get_mut(&mut self.swapchain) {
swapchain.update_resolution(width, height)?;
}
Ok(())
}