librashader/librashader-runtime-vk/tests/hello_triangle/vulkan_base.rs
2024-08-01 08:37:40 -04:00

173 lines
5.6 KiB
Rust

use ash::vk;
use crate::hello_triangle::physicaldevice::{find_queue_family, pick_physical_device};
use crate::hello_triangle::util;
use ash::prelude::VkResult;
use gpu_allocator::vulkan::Allocator;
use librashader_runtime_vk::error::FilterChainError;
use librashader_runtime_vk::VulkanObjects;
use parking_lot::Mutex;
use std::ffi::CStr;
use std::sync::Arc;
const WINDOW_TITLE: &[u8] = b"librashader Vulkan\0";
const KHRONOS_VALIDATION: &[u8] = b"VK_LAYER_KHRONOS_validation\0";
pub struct VulkanBase {
pub entry: ash::Entry,
pub instance: ash::Instance,
pub device: Arc<ash::Device>,
pub graphics_queue: vk::Queue,
// pub debug: VulkanDebug,
pub physical_device: vk::PhysicalDevice,
pub mem_props: vk::PhysicalDeviceMemoryProperties,
pub allocator: Arc<Mutex<Allocator>>,
}
impl VulkanBase {
pub fn new(entry: ash::Entry) -> VkResult<VulkanBase> {
let app_info = vk::ApplicationInfo::default()
.application_name(unsafe { CStr::from_bytes_with_nul_unchecked(WINDOW_TITLE) })
.engine_name(unsafe { CStr::from_bytes_with_nul_unchecked(WINDOW_TITLE) })
.engine_version(0)
.application_version(0)
.api_version(vk::make_api_version(0, 1, 3, 0));
dbg!("entry");
// todo: make this xplat
let extensions = [
ash::khr::surface::NAME.as_ptr(),
ash::khr::win32_surface::NAME.as_ptr(),
ash::ext::debug_utils::NAME.as_ptr(),
];
let layers = [KHRONOS_VALIDATION.as_ptr().cast()];
let create_info = vk::InstanceCreateInfo::default()
.application_info(&app_info)
.enabled_layer_names(&layers)
.enabled_extension_names(&extensions);
let instance = unsafe { entry.create_instance(&create_info, None)? };
// let debug = VulkanDebug::new(&entry, &instance, Some(vulkan_debug_callback))?;
let physical_device = pick_physical_device(&instance);
dbg!("picked physdev");
let (device, queue) = VulkanBase::create_device(&instance, &physical_device)?;
dbg!("created device");
let mem_props = unsafe { instance.get_physical_device_memory_properties(physical_device) };
dbg!("got memprops");
let alloc =
util::create_allocator(device.clone(), instance.clone(), physical_device.clone());
Ok(VulkanBase {
entry,
instance,
device: Arc::new(device),
graphics_queue: queue,
physical_device,
mem_props,
// debug,
allocator: alloc,
})
}
fn create_device(
instance: &ash::Instance,
physical_device: &vk::PhysicalDevice,
) -> VkResult<(ash::Device, vk::Queue)> {
let _debug = [unsafe { CStr::from_bytes_with_nul_unchecked(KHRONOS_VALIDATION).as_ptr() }];
let indices = find_queue_family(instance, *physical_device);
let queue_info = [vk::DeviceQueueCreateInfo::default()
.queue_family_index(indices.graphics_family())
.queue_priorities(&[1.0f32])];
// let physical_device_features = vk::PhysicalDeviceFeatures::default();
let mut physical_device_features =
vk::PhysicalDeviceVulkan13Features::default().dynamic_rendering(true);
// let mut physical_device_features =
// vk::PhysicalDeviceFeatures2::default().push_next(&mut physical_device_features)
// ;
let extensions = [
ash::khr::swapchain::NAME.as_ptr(),
ash::khr::dynamic_rendering::NAME.as_ptr(),
];
let device_create_info = vk::DeviceCreateInfo::default()
.queue_create_infos(&queue_info)
// .enabled_layer_names(&debug)
.enabled_extension_names(&extensions)
.push_next(&mut physical_device_features)
// .enabled_features(&physical_device_features)
;
let device =
unsafe { instance.create_device(*physical_device, &device_create_info, None)? };
let queue = unsafe { device.get_device_queue(indices.graphics_family(), 0) };
Ok((device, queue))
}
}
#[allow(unused)]
unsafe extern "system" fn vulkan_debug_callback(
_message_severity: vk::DebugUtilsMessageSeverityFlagsEXT,
_message_type: vk::DebugUtilsMessageTypeFlagsEXT,
_p_callback_data: *const vk::DebugUtilsMessengerCallbackDataEXT,
_user_data: *mut std::os::raw::c_void,
) -> vk::Bool32 {
// let callback_data = *p_callback_data;
// let message_id_number: i32 = callback_data.message_id_number as i32;
//
// let message_id_name = if callback_data.p_message_id_name.is_null() {
// Cow::from("")
// } else {
// CStr::from_ptr(callback_data.p_message_id_name).to_string_lossy()
// };
//
// let message = if callback_data.p_message.is_null() {
// Cow::from("")
// } else {
// CStr::from_ptr(callback_data.p_message).to_string_lossy()
// };
//
// println!(
// "{:?}:\n{:?} [{} ({})] : {}\n",
// message_severity,
// message_type,
// message_id_name,
// &message_id_number.to_string(),
// message,
// );
vk::FALSE
}
impl Drop for VulkanBase {
fn drop(&mut self) {
unsafe {
self.device.destroy_device(None);
}
}
}
impl TryFrom<&VulkanBase> for VulkanObjects {
type Error = FilterChainError;
fn try_from(value: &VulkanBase) -> Result<Self, Self::Error> {
let device = (*value.device).clone();
VulkanObjects::try_from((value.physical_device, value.instance.clone(), device))
}
}