From ab70c418507e1767f03a36627f88e80e41eddd05 Mon Sep 17 00:00:00 2001 From: ilyas-taouaou Date: Wed, 30 Oct 2024 21:33:58 +0100 Subject: [PATCH] Fix some best practices warnings and add optional allocation priority extension --- README.md | 10 ++++- engine/devres/shaders/shader.vert | 3 +- engine/src/buffer.rs | 9 ++++ engine/src/image.rs | 16 +++++++- engine/src/renderer/geometry.rs | 2 + engine/src/renderer/mod.rs | 4 ++ engine/src/renderer/staging_belt.rs | 1 + engine/src/renderer/swapchain.rs | 3 +- engine/src/rendering_context.rs | 64 ++++++++++++++++++++++++++--- src/app/mod.rs | 4 +- 10 files changed, 103 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 30b6f44..182154e 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ Features: - Multi window support. - Resolution scaling. +- Automatic shader compilation with include support. ## Compatibility @@ -17,10 +18,15 @@ Windows or Linux with Vulkan API 1.3 capable GPU driver with the following featu - dynamic_rendering - synchronization2 - buffer_device_address -- buffer_device_address_capture_replay (debug only) - descriptor_indexing - scalar_block_layout +Optional extensions: + +- debug_utils (debug only) +- buffer_device_address_capture_replay (debug only) +- memory_priority and pageable_device_local_memory + ## Contributions -Contributions are welcome especially bug fixes, will reviewed in the next live streams. +Contributions are welcome especially bug fixes. \ No newline at end of file diff --git a/engine/devres/shaders/shader.vert b/engine/devres/shaders/shader.vert index b76c2cb..714f690 100644 --- a/engine/devres/shaders/shader.vert +++ b/engine/devres/shaders/shader.vert @@ -8,8 +8,7 @@ void main() { Instance instance = pushConstants.instanceBuffer.instances[gl_InstanceIndex]; Camera camera = pushConstants.cameraBuffer.cameras[0]; - vec3 position = vertex.position; mat4 mvp = camera.projection * camera.view * instance.model; - gl_Position = mvp * vec4(position, 1.0); + gl_Position = mvp * vec4(vertex.position, 1.0); fragColor = vertex.color; } \ No newline at end of file diff --git a/engine/src/buffer.rs b/engine/src/buffer.rs index c799dce..f931070 100644 --- a/engine/src/buffer.rs +++ b/engine/src/buffer.rs @@ -12,6 +12,7 @@ pub struct BufferAttributes { pub usage: vk::BufferUsageFlags, pub location: MemoryLocation, pub allocation_scheme: AllocationScheme, + pub allocation_priority: f32, } pub struct Buffer { @@ -60,6 +61,14 @@ impl Buffer { allocation_scheme: attributes.allocation_scheme, })?; + if let Some(ref extension) = attributes.context.pageable_device_local_memory_extension { + (extension.fp().set_device_memory_priority_ext)( + attributes.context.device.handle(), + allocation.memory(), + attributes.allocation_priority, + ); + } + attributes.context.device.bind_buffer_memory( handle, allocation.memory(), diff --git a/engine/src/image.rs b/engine/src/image.rs index ddf1a5e..c55f19d 100644 --- a/engine/src/image.rs +++ b/engine/src/image.rs @@ -9,6 +9,7 @@ use std::sync::Arc; pub struct ImageAttributes { pub location: MemoryLocation, pub allocation_scheme: AllocationScheme, + pub allocation_priority: f32, pub linear: bool, pub extent: vk::Extent3D, pub format: vk::Format, @@ -86,6 +87,16 @@ impl Image { allocation_scheme: attributes.allocation_scheme, })?; + if let Some(ref extension) = context.pageable_device_local_memory_extension { + unsafe { + (extension.fp().set_device_memory_priority_ext)( + context.device.handle(), + allocation.memory(), + attributes.allocation_priority, + ); + } + } + unsafe { context .device @@ -115,6 +126,7 @@ impl Image { name: &str, extent: vk::Extent2D, format: vk::Format, + allocation_priority: f32, ) -> Result { Image::new( context, @@ -131,6 +143,7 @@ impl Image { .aspect_mask(vk::ImageAspectFlags::COLOR) .level_count(1) .layer_count(1), + allocation_priority, }, ) } @@ -157,6 +170,7 @@ impl Image { .aspect_mask(vk::ImageAspectFlags::DEPTH) .level_count(1) .layer_count(1), + allocation_priority: 1.0, }, ) } @@ -245,7 +259,7 @@ impl ImageLayoutState { pub fn present() -> Self { Self { - access: vk::AccessFlags2::TRANSFER_READ, + access: vk::AccessFlags2::empty(), layout: vk::ImageLayout::PRESENT_SRC_KHR, stage: vk::PipelineStageFlags2::TRANSFER, queue_family: QUEUE_FAMILY_IGNORED, diff --git a/engine/src/renderer/geometry.rs b/engine/src/renderer/geometry.rs index abc7ad9..c2c2a9c 100644 --- a/engine/src/renderer/geometry.rs +++ b/engine/src/renderer/geometry.rs @@ -174,6 +174,7 @@ impl Geometry { | vk::BufferUsageFlags::TRANSFER_DST, location: MemoryLocation::GpuOnly, allocation_scheme: AllocationScheme::GpuAllocatorManaged, + allocation_priority: 1.0, }, )?; @@ -186,6 +187,7 @@ impl Geometry { usage: vk::BufferUsageFlags::INDEX_BUFFER | vk::BufferUsageFlags::TRANSFER_DST, location: MemoryLocation::GpuOnly, allocation_scheme: AllocationScheme::GpuAllocatorManaged, + allocation_priority: 1.0, }, )?; diff --git a/engine/src/renderer/mod.rs b/engine/src/renderer/mod.rs index 5619a70..b828079 100644 --- a/engine/src/renderer/mod.rs +++ b/engine/src/renderer/mod.rs @@ -148,6 +148,7 @@ impl Renderer { "render_target", attributes.extent, attributes.format, + 1.0, ) }) .collect::>>()?; @@ -229,6 +230,7 @@ impl Renderer { | vk::BufferUsageFlags::TRANSFER_DST, location: MemoryLocation::GpuOnly, allocation_scheme: AllocationScheme::GpuAllocatorManaged, + allocation_priority: 1.0, }, )?; @@ -268,6 +270,7 @@ impl Renderer { | vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS, location: MemoryLocation::CpuToGpu, allocation_scheme: AllocationScheme::GpuAllocatorManaged, + allocation_priority: 1.0, }, )?; camera_buffer.write(&gpu_cameras, 0)?; @@ -302,6 +305,7 @@ impl Renderer { "render_target", resolution, self.attributes.format, + 1.0, )?; frame.depth_buffer = Image::new_depth_buffer( self.context.clone(), diff --git a/engine/src/renderer/staging_belt.rs b/engine/src/renderer/staging_belt.rs index d706a6f..e07594d 100644 --- a/engine/src/renderer/staging_belt.rs +++ b/engine/src/renderer/staging_belt.rs @@ -29,6 +29,7 @@ impl StagingBelt { usage: vk::BufferUsageFlags::TRANSFER_SRC, location: MemoryLocation::CpuToGpu, allocation_scheme: AllocationScheme::GpuAllocatorManaged, + allocation_priority: 1.0, }, )?; Ok(Self { diff --git a/engine/src/renderer/swapchain.rs b/engine/src/renderer/swapchain.rs index f16617e..cf6e912 100644 --- a/engine/src/renderer/swapchain.rs +++ b/engine/src/renderer/swapchain.rs @@ -82,7 +82,7 @@ impl Swapchain { .image_sharing_mode(vk::SharingMode::EXCLUSIVE) .pre_transform(vk::SurfaceTransformFlagsKHR::IDENTITY) .composite_alpha(vk::CompositeAlphaFlagsKHR::OPAQUE) - .present_mode(vk::PresentModeKHR::MAILBOX) + .present_mode(vk::PresentModeKHR::FIFO) .clipped(true) .old_swapchain(self.handle), None, @@ -116,6 +116,7 @@ impl Swapchain { .aspect_mask(vk::ImageAspectFlags::COLOR) .level_count(1) .layer_count(1), + allocation_priority: 1.0, }, )?) }) diff --git a/engine/src/rendering_context.rs b/engine/src/rendering_context.rs index cfd26a7..e82ceaf 100644 --- a/engine/src/rendering_context.rs +++ b/engine/src/rendering_context.rs @@ -16,6 +16,8 @@ use winit::window::Window; pub struct RenderingContext { pub queues: Vec, + pub pageable_device_local_memory_extension: + Option, pub swapchain_extension: ash::khr::swapchain::Device, pub device: ash::Device, pub queue_family_indices: HashSet, @@ -39,6 +41,8 @@ pub struct PhysicalDevice { pub features: vk::PhysicalDeviceFeatures, pub vulkan12_features: vk::PhysicalDeviceVulkan12Features<'static>, pub vulkan13_features: vk::PhysicalDeviceVulkan13Features<'static>, + pub pageable_device_local_memory_features: + vk::PhysicalDevicePageableDeviceLocalMemoryFeaturesEXT<'static>, pub memory_properties: vk::PhysicalDeviceMemoryProperties, pub queue_families: Vec, } @@ -113,14 +117,33 @@ impl RenderingContext { let raw_display_handle = attributes.compatibility_window.display_handle()?.as_raw(); let raw_window_handle = attributes.compatibility_window.window_handle()?.as_raw(); + let available_extensions = entry + .enumerate_instance_extension_properties(None)? + .into_iter() + .map(|extension| { + let name = extension.extension_name; + std::ffi::CStr::from_ptr(name.as_ptr()) + .to_str() + .unwrap() + .to_string() + }) + .collect::>(); + + let mut extensions = + ash_window::enumerate_required_extensions(raw_display_handle)?.to_vec(); + + if cfg!(debug_assertions) { + if available_extensions.contains(ash::ext::debug_utils::NAME.to_str()?) { + extensions.push(ash::ext::debug_utils::NAME.as_ptr()); + } + } + let instance = entry.create_instance( &vk::InstanceCreateInfo::default() .application_info( &vk::ApplicationInfo::default().api_version(vk::API_VERSION_1_3), ) - .enabled_extension_names(ash_window::enumerate_required_extensions( - raw_display_handle, - )?), + .enabled_extension_names(&extensions), None, )?; @@ -141,9 +164,12 @@ impl RenderingContext { let properties = instance.get_physical_device_properties(handle); let mut vulkan12_features = vk::PhysicalDeviceVulkan12Features::default(); let mut vulkan13_features = vk::PhysicalDeviceVulkan13Features::default(); + let mut pageable_device_local_memory_features = + vk::PhysicalDevicePageableDeviceLocalMemoryFeaturesEXT::default(); let mut features = vk::PhysicalDeviceFeatures2::default() .push_next(&mut vulkan12_features) - .push_next(&mut vulkan13_features); + .push_next(&mut vulkan13_features) + .push_next(&mut pageable_device_local_memory_features); instance.get_physical_device_features2(handle, &mut features); let features = features.features; let memory_properties = instance.get_physical_device_memory_properties(handle); @@ -165,6 +191,7 @@ impl RenderingContext { features, vulkan12_features, vulkan13_features, + pageable_device_local_memory_features, memory_properties, queue_families, } @@ -215,11 +242,25 @@ impl RenderingContext { .buffer_device_address_capture_replay == vk::TRUE; + let is_pageable_device_local_memory_supported = physical_device + .pageable_device_local_memory_features + .pageable_device_local_memory + == vk::TRUE; + + let mut device_extensions = vec![ash::khr::swapchain::NAME.as_ptr()]; + + let mut pageable_device_local_memory_extension = None; + + if is_pageable_device_local_memory_supported { + device_extensions.push(ash::ext::memory_priority::NAME.as_ptr()); + device_extensions.push(ash::ext::pageable_device_local_memory::NAME.as_ptr()); + } + let device = instance.create_device( physical_device.handle, &vk::DeviceCreateInfo::default() .queue_create_infos(&queue_create_infos) - .enabled_extension_names(&[ash::khr::swapchain::NAME.as_ptr()]) + .enabled_extension_names(&device_extensions) .push_next( &mut vk::PhysicalDeviceVulkan12Features::default() .buffer_device_address(true) @@ -233,10 +274,22 @@ impl RenderingContext { &mut vk::PhysicalDeviceVulkan13Features::default() .dynamic_rendering(true) .synchronization2(true), + ) + .push_next( + &mut vk::PhysicalDevicePageableDeviceLocalMemoryFeaturesEXT::default() + .pageable_device_local_memory( + is_pageable_device_local_memory_supported, + ), ), None, )?; + if is_pageable_device_local_memory_supported { + pageable_device_local_memory_extension = Some( + ash::ext::pageable_device_local_memory::Device::new(&instance, &device), + ); + } + let swapchain_extension = ash::khr::swapchain::Device::new(&instance, &device); let queues = queue_family_indices @@ -257,6 +310,7 @@ impl RenderingContext { instance, entry, swapchain_extension, + pageable_device_local_memory_extension, }) } } diff --git a/src/app/mod.rs b/src/app/mod.rs index 9489a7e..92c3c2e 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -16,7 +16,7 @@ impl ApplicationHandler for App { let primary_window_attributes = WindowAttributes::default().with_title("Primary window"); let primary_window_renderer_attributes = WindowRendererAttributes { format: vk::Format::R16G16B16A16_SFLOAT, - depth_format: vk::Format::D32_SFLOAT, + depth_format: vk::Format::D16_UNORM, clear_color: vk::ClearColorValue { float32: [0.0, 0.0, 0.0, 1.0], }, @@ -29,7 +29,7 @@ impl ApplicationHandler for App { WindowAttributes::default().with_title("Secondary window"); let secondary_window_renderer_attributes = WindowRendererAttributes { format: vk::Format::R16G16B16A16_SFLOAT, - depth_format: vk::Format::D32_SFLOAT, + depth_format: vk::Format::D16_UNORM, clear_color: vk::ClearColorValue { float32: [0.0, 0.0, 0.0, 1.0], },