Add a lot of thing
Some checks failed
Build legacy Nix package on Ubuntu / build (push) Failing after 0s

This commit is contained in:
Florian RICHER 2024-11-15 13:59:19 +01:00
parent 09e109d6ef
commit fb4ac29c07
6 changed files with 255 additions and 43 deletions

View file

@ -1,9 +1,9 @@
use crate::display::window::Window;
use crate::vulkan::VkRenderContext;
use winit::application::ApplicationHandler;
use winit::event::WindowEvent;
use winit::event_loop::ActiveEventLoop;
use winit::window::{WindowId};
use crate::display::window::Window;
use crate::vulkan::VkRenderContext;
use winit::window::WindowId;
pub struct App {
window: Window,
@ -34,7 +34,29 @@ impl ApplicationHandler for App {
log::debug!("The close button was pressed; stopping");
event_loop.exit();
}
_ => self.window.window_event(event_loop, id, event),
WindowEvent::Resized(size) => {
match self.render_context.as_mut() {
Some(render_context) => {
if let Err(error) = render_context.update_resolution(size.width, size.height) {
log::error!("Failed to update resolution of render context : {}", error);
}
}
None => log::warn!("Window resized but no render context found")
};
}
WindowEvent::RedrawRequested => {
match self.render_context.as_mut() {
Some(render_context) => {
if let Err(error) = render_context.render() {
log::error!("Failed to render with render context : {}", error);
}
}
None => log::warn!("Window resized but no render context found")
};
self.window.request_redraw();
}
_ => {}
}
}
}

View file

@ -6,7 +6,7 @@ use winit::window::WindowId;
pub struct Window {
handle: Option<winit::window::Window>,
window_attributes: winit::window::WindowAttributes
window_attributes: winit::window::WindowAttributes,
}
impl Window {
@ -49,20 +49,15 @@ impl Window {
pub fn handle(&self) -> Option<&winit::window::Window> {
self.handle.as_ref()
}
pub fn size(&self) -> Option<winit::dpi::Size> {
self.window_attributes.inner_size
}
pub fn window_event(&mut self, _event_loop: &ActiveEventLoop, _id: WindowId, event: WindowEvent) {
match event {
WindowEvent::RedrawRequested => {
match self.handle.as_ref() {
Some(window) => window.request_redraw(),
None => log::warn!("Redraw requested but no window found")
}
}
_ => (),
pub fn request_redraw(&self) {
match self.handle.as_ref() {
Some(window) => window.request_redraw(),
None => log::warn!("Redraw requested but no window found")
}
}
}

View file

@ -10,12 +10,11 @@ fn main() {
let window_attributes = winit::window::Window::default_attributes()
.with_title("Rust ASH Test")
.with_visible(true)
.with_inner_size(winit::dpi::LogicalSize::new(
f64::from(800),
f64::from(600),
));
let window = display::Window::new(window_attributes);
let mut app = display::App::new(window);

View file

@ -1,13 +1,14 @@
use ash::vk;
use crate::vulkan::{VkInstance, VkPhysicalDevice};
use ash::prelude::VkResult;
use ash::vk;
pub struct VkDevice {
pub(crate) handle: ash::Device,
queue_family_index: u32
pub(super) handle: ash::Device,
queue_family_index: u32,
}
impl VkDevice {
pub fn new_graphics_device(
pub(super) fn new_graphics_device(
instance: &VkInstance,
physical_device: &VkPhysicalDevice,
queue_family_index: u32,
@ -37,15 +38,55 @@ impl VkDevice {
Ok(Self {
handle: device,
queue_family_index
queue_family_index,
})
}
pub fn get_device_queue(&self, queue_index: u32) -> vk::Queue {
pub(super) fn get_device_queue(&self, queue_index: u32) -> vk::Queue {
unsafe {
self.handle.get_device_queue(self.queue_family_index, queue_index)
}
}
pub(super) fn create_image_view(&self, image: vk::Image, surface_format: vk::SurfaceFormatKHR) -> VkResult<vk::ImageView> {
let create_view_info = vk::ImageViewCreateInfo::default()
.view_type(vk::ImageViewType::TYPE_2D)
.format(surface_format.format)
.components(vk::ComponentMapping {
r: vk::ComponentSwizzle::R,
g: vk::ComponentSwizzle::G,
b: vk::ComponentSwizzle::B,
a: vk::ComponentSwizzle::A,
})
.subresource_range(vk::ImageSubresourceRange {
aspect_mask: vk::ImageAspectFlags::COLOR,
base_mip_level: 0,
level_count: 1,
base_array_layer: 0,
layer_count: 1,
})
.image(image);
unsafe { self.handle.create_image_view(&create_view_info, None) }
}
pub(super) fn create_command_pool(&self, info: &vk::CommandPoolCreateInfo) -> VkResult<vk::CommandPool> {
let info = info.queue_family_index(self.queue_family_index);
unsafe { self.handle.create_command_pool(&info, None) }
}
pub(super) fn allocate_command_buffers(&self, info: &vk::CommandBufferAllocateInfo) -> VkResult<Vec<vk::CommandBuffer>> {
unsafe { self.handle.allocate_command_buffers(&info) }
}
pub(super) fn create_fence(&self, info: &vk::FenceCreateInfo) -> VkResult<vk::Fence> {
unsafe { self.handle.create_fence(&info, None) }
}
pub(super) fn create_semaphore(&self, info: &vk::SemaphoreCreateInfo) -> VkResult<vk::Semaphore> {
unsafe { self.handle.create_semaphore(&info, None) }
}
}
impl Drop for VkDevice {

View file

@ -1,11 +1,28 @@
use crate::vulkan::{VkDevice, VkInstance, VkPhysicalDevice, VkSurface, VkSwapchain};
use ash::vk;
use ash::vk::QueueFlags;
pub struct VkRenderContext {
instance: VkInstance,
surface: VkSurface,
device: VkDevice,
swapchain: VkSwapchain,
present_images: Vec<vk::Image>,
present_image_views: Vec<vk::ImageView>,
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 {
@ -28,20 +45,134 @@ impl VkRenderContext {
let device = VkDevice::new_graphics_device(&instance, &physical_device, queue_family_index)
.expect("Unable to create device");
let mut swapchain = surface.create_swapchain(
let swapchain = surface.create_swapchain(
&window,
&instance,
&device,
&physical_device,
).expect("Unable to create swapchain");
// let present_queue = device.get_device_queue(0);
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");
Ok(Self {
instance,
surface,
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,
})
}
}
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.");
}
Ok(())
}
pub fn update_resolution(&mut self, width: u32, height: u32) -> anyhow::Result<()> {
self.swapchain.update_resolution(&self.surface, width, height)?;
Ok(())
}
}

View file

@ -1,27 +1,26 @@
use crate::vulkan::{VkSurface, LOG_TARGET};
use ash::prelude::VkResult;
use ash::vk;
use ash::vk::{Extent2D, PresentModeKHR, SurfaceFormatKHR, SurfaceTransformFlagsKHR, SwapchainCreateInfoKHR, SwapchainKHR};
pub struct VkSwapchain {
swapchain_loader: ash::khr::swapchain::Device,
pub(super) swapchain_loader: ash::khr::swapchain::Device,
swapchain: Option<vk::SwapchainKHR>,
desired_image_count: u32,
surface_format: SurfaceFormatKHR,
surface_resolution: Extent2D,
present_mode: PresentModeKHR,
pre_transform: SurfaceTransformFlagsKHR,
pub(super) desired_image_count: u32,
pub(super) surface_format: vk::SurfaceFormatKHR,
pub(super) surface_resolution: vk::Extent2D,
pub(super) present_mode: vk::PresentModeKHR,
pub(super) pre_transform: vk::SurfaceTransformFlagsKHR,
}
impl VkSwapchain {
pub fn new(
pub(super) fn new(
swapchain_loader: ash::khr::swapchain::Device,
desired_image_count: u32,
surface_format: SurfaceFormatKHR,
surface_resolution: Extent2D,
present_mode: PresentModeKHR,
pre_transform: SurfaceTransformFlagsKHR,
surface_format: vk::SurfaceFormatKHR,
surface_resolution: vk::Extent2D,
present_mode: vk::PresentModeKHR,
pre_transform: vk::SurfaceTransformFlagsKHR,
) -> Self {
Self {
swapchain_loader,
@ -34,7 +33,7 @@ impl VkSwapchain {
}
}
pub fn create_swapchain(&mut self, surface: &VkSurface) -> VkResult<()> {
pub(super) fn create_swapchain(&mut self, surface: &VkSurface) -> VkResult<()> {
let mut swapchain_create_info = self.create_swapchain_info(surface);
if let Some(old_swapchain) = self.swapchain {
@ -44,15 +43,40 @@ impl VkSwapchain {
let swapchain = unsafe {
self.swapchain_loader.create_swapchain(&swapchain_create_info, None)?
};
log::debug!(target: LOG_TARGET, "Swapchain created : {swapchain_create_info:#?}");
match self.swapchain {
Some(_) => log::debug!(target: LOG_TARGET, "Swapchain created : {swapchain_create_info:#?}"),
None => log::debug!(target: LOG_TARGET, "Swapchain updated : {swapchain_create_info:#?}")
}
self.swapchain = Some(swapchain);
Ok(())
}
fn create_swapchain_info(&self, surface: &VkSurface) -> SwapchainCreateInfoKHR {
SwapchainCreateInfoKHR::default()
pub(super) fn update_resolution(&mut self, surface: &VkSurface, width: u32, height: u32) -> VkResult<()> {
log::debug!(target: LOG_TARGET, "New resolution requested for swapchain {width}x{height}");
self.surface_resolution = vk::Extent2D {
width,
height,
};
self.create_swapchain(surface)?;
Ok(())
}
pub(super) fn get_swapchain_images(&self) -> anyhow::Result<Vec<vk::Image>> {
let swapchain = self.swapchain
.ok_or_else(|| anyhow::anyhow!("Can't get swapchain images : Swapchain is not set"))?;
let images = unsafe { self.swapchain_loader.get_swapchain_images(swapchain)? };
Ok(images)
}
fn create_swapchain_info(&self, surface: &VkSurface) -> vk::SwapchainCreateInfoKHR {
vk::SwapchainCreateInfoKHR::default()
.surface(surface.surface)
.min_image_count(self.desired_image_count)
.image_color_space(self.surface_format.color_space)