| // Copyright 2022 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| use ash::extensions::{ |
| ext::DebugUtils, |
| // // khr::{Surface, Swapchain}, |
| }; |
| use ash::{self, vk}; |
| use std::borrow::Cow; |
| // use std::cell::RefCell; |
| // use std::default::Default; |
| use std::ffi::CStr; |
| // use std::ops::Drop; |
| use std::os::raw::c_char; |
| |
| use anyhow::Error; |
| // use std::default::Default; |
| // use std::ffi::CStr; |
| // use std::io::Cursor; |
| // use std::mem; |
| // use std::mem::align_of; |
| |
| // macro_rules! cstr { |
| // ( $bytes:expr ) => { |
| // CStr::from_bytes_with_nul($bytes).expect("CStr must end with '\\0'") |
| // }; |
| // } |
| |
| // macro_rules! vulkan_version { |
| // ( $major:expr, $minor:expr, $patch:expr ) => { |
| // ($major as u32) << 22 | ($minor as u32) << 12 | ($patch as u32) |
| // }; |
| // } |
| |
| // unsafe fn create_from<T>(f: impl FnOnce(*mut T)) -> T { |
| // let mut value = MaybeUninit::uninit(); |
| // f(value.as_mut_ptr()); |
| // value.assume_init() |
| // } |
| |
| // fn create_vk_instance() -> Result<vk::Instance, Error> { |
| // let entry_points = fvk::entry_points(); |
| // let mut instance: vk::Instance = 0; |
| // let create_instance_result = unsafe { |
| // entry_points.CreateInstance( |
| // &vk::InstanceCreateInfo { |
| // sType: vk::STRUCTURE_TYPE_INSTANCE_CREATE_INFO, |
| // pNext: ptr::null(), |
| // flags: 0, |
| // pApplicationInfo: &vk::ApplicationInfo { |
| // sType: vk::STRUCTURE_TYPE_APPLICATION_INFO, |
| // pNext: ptr::null(), |
| // pApplicationName: cstr!(b"flatland-view-provider\0").as_ptr(), |
| // applicationVersion: 0, |
| // pEngineName: ptr::null(), |
| // engineVersion: 0, |
| // apiVersion: vulkan_version!(1, 1, 0), |
| // }, |
| // enabledLayerCount: 0, |
| // ppEnabledLayerNames: ptr::null(), |
| // enabledExtensionCount: 0, |
| // ppEnabledExtensionNames: ptr::null(), |
| // }, |
| // ptr::null(), |
| // &mut instance as *mut vk::Instance, |
| // ) |
| // }; |
| // if create_instance_result != vk::SUCCESS { |
| // return Err(anyhow!("Failed to create vk::Instance")); |
| // } |
| // Ok(instance) |
| // } |
| |
| // fn get_vk_physical_device(instance: vk::Instance) -> Option<vk::PhysicalDevice> { |
| // let instance_pointers = fvk::instance_pointers(instance); |
| // let physical_devices = { |
| // let mut len = unsafe { |
| // create_from(|ptr| { |
| // instance_pointers.EnumeratePhysicalDevices(instance, ptr, ptr::null_mut()); |
| // }) |
| // }; |
| // let mut physical_devices: Vec<vk::PhysicalDevice> = Vec::with_capacity(len as usize); |
| // unsafe { |
| // let enumerate_result = instance_pointers.EnumeratePhysicalDevices( |
| // instance, |
| // &mut len, |
| // physical_devices.as_mut_ptr(), |
| // ); |
| // assert!(enumerate_result == vk::SUCCESS); |
| // physical_devices.set_len(len as usize); |
| // } |
| // physical_devices |
| // }; |
| // physical_devices.get(0).map(|val| *val) |
| // } |
| |
| // fn create_vk_device( |
| // instance: vk::Instance, |
| // extension_names: Vec<*const c_char>, |
| // ) -> Result<vk::Device, Error> { |
| // let instance_pointers = fvk::instance_pointers(instance); |
| // let physical_device = match get_vk_physical_device(instance)?; |
| |
| // let mut queue_family_count = unsafe { |
| // create_from(|ptr| { |
| // vk_i.GetPhysicalDeviceQueueFamilyProperties(physical_device, ptr, ptr::null_mut()) |
| // }) |
| // }; |
| // let mut queue_family_properties = Vec::with_capacity(queue_family_count as usize); |
| // unsafe { |
| // vk_i.GetPhysicalDeviceQueueFamilyProperties( |
| // physical_device, |
| // &mut queue_family_count, |
| // queue_family_properties.as_mut_ptr(), |
| // ); |
| // queue_family_properties.set_len(queue_family_count as usize); |
| // } |
| // if queue_family_count == 0 { |
| // println!("no queue family available!"); |
| // return None; |
| // } |
| |
| // let queue_priority: f32 = 1.0; |
| // let queue_create_info = vk::DeviceQueueCreateInfo { |
| // sType: vk::STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, |
| // pNext: ptr::null(), |
| // flags: 0, |
| // queueFamilyIndex: 0, |
| // queueCount: 1, |
| // pQueuePriorities: &queue_priority as *const f32, |
| // }; |
| |
| // let device = unsafe { |
| // init(|ptr| { |
| // let create_device_result = vk_i.CreateDevice( |
| // physical_device, |
| // &vk::DeviceCreateInfo { |
| // sType: vk::STRUCTURE_TYPE_DEVICE_CREATE_INFO, |
| // pNext: ptr::null(), |
| // flags: 0, |
| // queueCreateInfoCount: 1, |
| // pQueueCreateInfos: &queue_create_info as *const _, |
| // enabledLayerCount: 0, |
| // ppEnabledLayerNames: ptr::null(), |
| // enabledExtensionCount: extension_names.len() as u32, |
| // ppEnabledExtensionNames: extension_names.as_ptr(), |
| // pEnabledFeatures: ptr::null(), |
| // }, |
| // ptr::null(), |
| // ptr, |
| // ); |
| // assert!(create_device_result == vk::SUCCESS); |
| // }) |
| // }; |
| // Some(device) |
| // } |
| |
| // fn destroy_vk_device(instance: vk::Instance, device: vk::Device) { |
| // let vk_i = super::instance_pointers(instance); |
| // let vk_d = super::device_pointers(&vk_i, device); |
| // unsafe { |
| // vk_d.DestroyDevice(device, ptr::null()); |
| // } |
| // } |
| /* |
| // Simple offset_of macro akin to C++ offsetof |
| macro_rules! offset_of { |
| ($base:path, $field:ident) => {{ |
| #[allow(unused_unsafe)] |
| unsafe { |
| let b: $base = mem::zeroed(); |
| (&b.$field as *const _ as isize) - (&b as *const _ as isize) |
| } |
| }}; |
| } |
| |
| /// Helper function for submitting command buffers. Immediately waits for the fence before the command buffer |
| /// is executed. That way we can delay the waiting for the fences by 1 frame which is good for performance. |
| /// Make sure to create the fence in a signaled state on the first use. |
| #[allow(clippy::too_many_arguments)] |
| pub fn record_submit_commandbuffer<F: FnOnce(&Device, vk::CommandBuffer)>( |
| device: &Device, |
| command_buffer: vk::CommandBuffer, |
| command_buffer_reuse_fence: vk::Fence, |
| submit_queue: vk::Queue, |
| wait_mask: &[vk::PipelineStageFlags], |
| wait_semaphores: &[vk::Semaphore], |
| signal_semaphores: &[vk::Semaphore], |
| f: F, |
| ) { |
| unsafe { |
| device |
| .wait_for_fences(&[command_buffer_reuse_fence], true, std::u64::MAX) |
| .expect("Wait for fence failed."); |
| |
| device |
| .reset_fences(&[command_buffer_reuse_fence]) |
| .expect("Reset fences failed."); |
| |
| device |
| .reset_command_buffer( |
| 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); |
| |
| device |
| .begin_command_buffer(command_buffer, &command_buffer_begin_info) |
| .expect("Begin commandbuffer"); |
| f(device, command_buffer); |
| device |
| .end_command_buffer(command_buffer) |
| .expect("End commandbuffer"); |
| |
| let command_buffers = vec![command_buffer]; |
| |
| let submit_info = vk::SubmitInfo::default() |
| .wait_semaphores(wait_semaphores) |
| .wait_dst_stage_mask(wait_mask) |
| .command_buffers(&command_buffers) |
| .signal_semaphores(signal_semaphores); |
| |
| device |
| .queue_submit(submit_queue, &[submit_info], command_buffer_reuse_fence) |
| .expect("queue submit failed."); |
| } |
| } |
| |
| */ |
| |
| 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 |
| } |
| |
| // pub fn find_memorytype_index( |
| // memory_req: &vk::MemoryRequirements, |
| // memory_prop: &vk::PhysicalDeviceMemoryProperties, |
| // flags: vk::MemoryPropertyFlags, |
| // ) -> Option<u32> { |
| // memory_prop.memory_types[..memory_prop.memory_type_count as _] |
| // .iter() |
| // .enumerate() |
| // .find(|(index, memory_type)| { |
| // (1 << index) & memory_req.memory_type_bits != 0 |
| // && memory_type.property_flags & flags == flags |
| // }) |
| // .map(|(index, _memory_type)| index as _) |
| // } |
| |
| pub struct VkRender { |
| pub entry: ash::Entry, |
| pub instance: ash::Instance, |
| pub device: ash::Device, |
| // pub surface_loader: Surface, |
| // pub swapchain_loader: Swapchain, |
| // pub debug_utils_loader: DebugUtils, |
| // pub debug_call_back: vk::DebugUtilsMessengerEXT, |
| |
| // pub pdevice: vk::PhysicalDevice, |
| // pub device_memory_properties: vk::PhysicalDeviceMemoryProperties, |
| // pub queue_family_index: u32, |
| // pub present_queue: vk::Queue, |
| |
| // pub surface: vk::SurfaceKHR, |
| // pub surface_format: vk::SurfaceFormatKHR, |
| // pub surface_resolution: vk::Extent2D, |
| |
| // pub swapchain: vk::SwapchainKHR, |
| // pub present_images: Vec<vk::Image>, |
| // pub present_image_views: Vec<vk::ImageView>, |
| |
| // pub pool: vk::CommandPool, |
| // pub draw_command_buffer: vk::CommandBuffer, |
| // pub setup_command_buffer: vk::CommandBuffer, |
| |
| // pub depth_image: vk::Image, |
| // pub depth_image_view: vk::ImageView, |
| // pub depth_image_memory: vk::DeviceMemory, |
| |
| // pub present_complete_semaphore: vk::Semaphore, |
| // pub rendering_complete_semaphore: vk::Semaphore, |
| |
| // pub draw_commands_reuse_fence: vk::Fence, |
| // pub setup_commands_reuse_fence: vk::Fence, |
| } |
| |
| impl VkRender { |
| // pub fn render_loop<F: Fn()>(&self, f: F) { |
| // self.event_loop |
| // .borrow_mut() |
| // .run_return(|event, _, control_flow| { |
| // *control_flow = ControlFlow::Poll; |
| // match event { |
| // Event::WindowEvent { |
| // event: |
| // WindowEvent::CloseRequested |
| // | WindowEvent::KeyboardInput { |
| // input: |
| // KeyboardInput { |
| // state: ElementState::Pressed, |
| // virtual_keycode: Some(VirtualKeyCode::Escape), |
| // .. |
| // }, |
| // .. |
| // }, |
| // .. |
| // } => *control_flow = ControlFlow::Exit, |
| // Event::MainEventsCleared => f(), |
| // _ => (), |
| // } |
| // }); |
| // } |
| |
| pub fn new(_window_width: u32, _window_height: u32) -> Result<(), Error> { |
| unsafe { |
| // let event_loop = EventLoop::new(); |
| // let window = WindowBuilder::new() |
| // .with_title("Ash - Example") |
| // .with_inner_size(winit::dpi::LogicalSize::new( |
| // f64::from(window_width), |
| // f64::from(window_height), |
| // )) |
| // .build(&event_loop) |
| // .unwrap(); |
| let entry = ash::Entry::load()?; |
| let app_name = CStr::from_bytes_with_nul_unchecked(b"flatland-view-provider\0"); |
| |
| let layer_names = [CStr::from_bytes_with_nul_unchecked( |
| b"VK_LAYER_KHRONOS_validation\0", |
| )]; |
| let layers_names_raw: Vec<*const c_char> = layer_names |
| .iter() |
| .map(|raw_name| raw_name.as_ptr()) |
| .collect(); |
| |
| let extension_names = vec![DebugUtils::name().as_ptr()]; |
| |
| let appinfo = vk::ApplicationInfo::builder() |
| .application_name(app_name) |
| .application_version(0) |
| .engine_name(app_name) |
| .engine_version(0) |
| .api_version(vk::make_api_version(0, 1, 0, 0)) |
| .build(); |
| |
| let create_info = vk::InstanceCreateInfo::builder() |
| .application_info(&appinfo) |
| .enabled_layer_names(&layers_names_raw) |
| .enabled_extension_names(&extension_names) |
| .build(); |
| |
| let instance: ash::Instance = entry |
| .create_instance(&create_info, None) |
| .expect("Instance creation error"); |
| |
| let debug_info = vk::DebugUtilsMessengerCreateInfoEXT::builder() |
| .message_severity( |
| vk::DebugUtilsMessageSeverityFlagsEXT::ERROR |
| | vk::DebugUtilsMessageSeverityFlagsEXT::WARNING |
| | vk::DebugUtilsMessageSeverityFlagsEXT::INFO, |
| ) |
| .message_type( |
| vk::DebugUtilsMessageTypeFlagsEXT::GENERAL |
| | vk::DebugUtilsMessageTypeFlagsEXT::VALIDATION |
| | vk::DebugUtilsMessageTypeFlagsEXT::PERFORMANCE, |
| ) |
| .pfn_user_callback(Some(vulkan_debug_callback)); |
| |
| let debug_utils_loader = DebugUtils::new(&entry, &instance); |
| let _debug_call_back = debug_utils_loader |
| .create_debug_utils_messenger(&debug_info, None) |
| .unwrap(); |
| // let surface = ash_window::create_surface(&entry, &instance, &window, None).unwrap(); |
| let pdevices = instance |
| .enumerate_physical_devices() |
| .expect("Physical device error"); |
| assert!(pdevices.len() > 0); |
| let pdevice_index = 0; |
| let pdevice = pdevices[pdevice_index]; |
| // let surface_loader = Surface::new(&entry, &instance); |
| // let (pdevice, queue_family_index) = pdevices |
| // .iter() |
| // .find_map(|pdevice| { |
| // instance |
| // .get_physical_device_queue_family_properties(*pdevice) |
| // .iter() |
| // .enumerate() |
| // .find_map(|(index, info)| { |
| // let supports_graphic_and_surface = |
| // info.queue_flags.contains(vk::QueueFlags::GRAPHICS) |
| // && surface_loader |
| // .get_physical_device_surface_support( |
| // *pdevice, |
| // index as u32, |
| // surface, |
| // ) |
| // .unwrap(); |
| // if supports_graphic_and_surface { |
| // Some((*pdevice, index)) |
| // } else { |
| // None |
| // } |
| // }) |
| // }) |
| // .expect("Couldn't find suitable device."); |
| // let queue_family_index = queue_family_index as u32; |
| let queue_family_index = 0; |
| // let device_extension_names_raw = [Swapchain::name().as_ptr()]; |
| let features = vk::PhysicalDeviceFeatures::builder() |
| .shader_clip_distance(true). |
| build(); |
| // shader_clip_distance: 1, |
| // ..Default::default() |
| // }; |
| let priorities = [1.0]; |
| |
| let queue_info = vk::DeviceQueueCreateInfo::builder() |
| .queue_family_index(queue_family_index) |
| .queue_priorities(&priorities) |
| .build(); |
| |
| let device_create_info = vk::DeviceCreateInfo::builder() |
| .queue_create_infos(std::slice::from_ref(&queue_info)) |
| // .enabled_extension_names(&device_extension_names_raw) |
| .enabled_features(&features) |
| .build(); |
| |
| let _device = instance |
| .create_device(pdevice, &device_create_info, None)?; |
| |
| // let present_queue = device.get_device_queue(queue_family_index as u32, 0); |
| |
| // let surface_format = surface_loader |
| // .get_physical_device_surface_formats(pdevice, surface) |
| // .unwrap()[0]; |
| |
| // let surface_capabilities = surface_loader |
| // .get_physical_device_surface_capabilities(pdevice, surface) |
| // .unwrap(); |
| // let mut desired_image_count = surface_capabilities.min_image_count + 1; |
| // if surface_capabilities.max_image_count > 0 |
| // && desired_image_count > surface_capabilities.max_image_count |
| // { |
| // desired_image_count = surface_capabilities.max_image_count; |
| // } |
| // let surface_resolution = match surface_capabilities.current_extent.width { |
| // std::u32::MAX => vk::Extent2D { |
| // width: window_width, |
| // height: window_height, |
| // }, |
| // _ => surface_capabilities.current_extent, |
| // }; |
| // let pre_transform = if surface_capabilities |
| // .supported_transforms |
| // .contains(vk::SurfaceTransformFlagsKHR::IDENTITY) |
| // { |
| // vk::SurfaceTransformFlagsKHR::IDENTITY |
| // } else { |
| // surface_capabilities.current_transform |
| // }; |
| // let present_modes = surface_loader |
| // .get_physical_device_surface_present_modes(pdevice, surface) |
| // .unwrap(); |
| // let present_mode = present_modes |
| // .iter() |
| // .cloned() |
| // .find(|&mode| mode == vk::PresentModeKHR::MAILBOX) |
| // .unwrap_or(vk::PresentModeKHR::FIFO); |
| // let swapchain_loader = Swapchain::new(&instance, &device); |
| |
| // let swapchain_create_info = vk::SwapchainCreateInfoKHR::default() |
| // .surface(surface) |
| // .min_image_count(desired_image_count) |
| // .image_color_space(surface_format.color_space) |
| // .image_format(surface_format.format) |
| // .image_extent(surface_resolution) |
| // .image_usage(vk::ImageUsageFlags::COLOR_ATTACHMENT) |
| // .image_sharing_mode(vk::SharingMode::EXCLUSIVE) |
| // .pre_transform(pre_transform) |
| // .composite_alpha(vk::CompositeAlphaFlagsKHR::OPAQUE) |
| // .present_mode(present_mode) |
| // .clipped(true) |
| // .image_array_layers(1); |
| |
| // let swapchain = swapchain_loader |
| // .create_swapchain(&swapchain_create_info, None) |
| // .unwrap(); |
| |
| // let pool_create_info = vk::CommandPoolCreateInfo::default() |
| // .flags(vk::CommandPoolCreateFlags::RESET_COMMAND_BUFFER) |
| // .queue_family_index(queue_family_index); |
| |
| // let pool = device.create_command_pool(&pool_create_info, None).unwrap(); |
| |
| // 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) |
| // .unwrap(); |
| // let setup_command_buffer = command_buffers[0]; |
| // let draw_command_buffer = command_buffers[1]; |
| |
| // let present_images = swapchain_loader.get_swapchain_images(swapchain).unwrap(); |
| // let present_image_views: Vec<vk::ImageView> = present_images |
| // .iter() |
| // .map(|&image| { |
| // 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); |
| // device.create_image_view(&create_view_info, None).unwrap() |
| // }) |
| // .collect(); |
| // let device_memory_properties = instance.get_physical_device_memory_properties(pdevice); |
| // let depth_image_create_info = vk::ImageCreateInfo::default() |
| // .image_type(vk::ImageType::TYPE_2D) |
| // .format(vk::Format::D16_UNORM) |
| // .extent(surface_resolution.into()) |
| // .mip_levels(1) |
| // .array_layers(1) |
| // .samples(vk::SampleCountFlags::TYPE_1) |
| // .tiling(vk::ImageTiling::OPTIMAL) |
| // .usage(vk::ImageUsageFlags::DEPTH_STENCIL_ATTACHMENT) |
| // .sharing_mode(vk::SharingMode::EXCLUSIVE); |
| |
| // let depth_image = device.create_image(&depth_image_create_info, None).unwrap(); |
| // let depth_image_memory_req = device.get_image_memory_requirements(depth_image); |
| // let depth_image_memory_index = find_memorytype_index( |
| // &depth_image_memory_req, |
| // &device_memory_properties, |
| // vk::MemoryPropertyFlags::DEVICE_LOCAL, |
| // ) |
| // .expect("Unable to find suitable memory index for depth image."); |
| |
| // let depth_image_allocate_info = vk::MemoryAllocateInfo::default() |
| // .allocation_size(depth_image_memory_req.size) |
| // .memory_type_index(depth_image_memory_index); |
| |
| // let depth_image_memory = device |
| // .allocate_memory(&depth_image_allocate_info, None) |
| // .unwrap(); |
| |
| // device |
| // .bind_image_memory(depth_image, depth_image_memory, 0) |
| // .expect("Unable to bind depth image memory"); |
| |
| // let fence_create_info = |
| // vk::FenceCreateInfo::default().flags(vk::FenceCreateFlags::SIGNALED); |
| |
| // let draw_commands_reuse_fence = device |
| // .create_fence(&fence_create_info, None) |
| // .expect("Create fence failed."); |
| // let setup_commands_reuse_fence = device |
| // .create_fence(&fence_create_info, None) |
| // .expect("Create fence failed."); |
| |
| // record_submit_commandbuffer( |
| // &device, |
| // setup_command_buffer, |
| // setup_commands_reuse_fence, |
| // present_queue, |
| // &[], |
| // &[], |
| // &[], |
| // |device, setup_command_buffer| { |
| // let layout_transition_barriers = vk::ImageMemoryBarrier::default() |
| // .image(depth_image) |
| // .dst_access_mask( |
| // vk::AccessFlags::DEPTH_STENCIL_ATTACHMENT_READ |
| // | vk::AccessFlags::DEPTH_STENCIL_ATTACHMENT_WRITE, |
| // ) |
| // .new_layout(vk::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL) |
| // .old_layout(vk::ImageLayout::UNDEFINED) |
| // .subresource_range( |
| // vk::ImageSubresourceRange::default() |
| // .aspect_mask(vk::ImageAspectFlags::DEPTH) |
| // .layer_count(1) |
| // .level_count(1), |
| // ); |
| |
| // device.cmd_pipeline_barrier( |
| // setup_command_buffer, |
| // vk::PipelineStageFlags::BOTTOM_OF_PIPE, |
| // vk::PipelineStageFlags::LATE_FRAGMENT_TESTS, |
| // vk::DependencyFlags::empty(), |
| // &[], |
| // &[], |
| // &[layout_transition_barriers], |
| // ); |
| // }, |
| // ); |
| |
| // let depth_image_view_info = vk::ImageViewCreateInfo::default() |
| // .subresource_range( |
| // vk::ImageSubresourceRange::default() |
| // .aspect_mask(vk::ImageAspectFlags::DEPTH) |
| // .level_count(1) |
| // .layer_count(1), |
| // ) |
| // .image(depth_image) |
| // .format(depth_image_create_info.format) |
| // .view_type(vk::ImageViewType::TYPE_2D); |
| |
| // let depth_image_view = device |
| // .create_image_view(&depth_image_view_info, None) |
| // .unwrap(); |
| |
| // let semaphore_create_info = vk::SemaphoreCreateInfo::default(); |
| |
| // let present_complete_semaphore = device |
| // .create_semaphore(&semaphore_create_info, None) |
| // .unwrap(); |
| // let rendering_complete_semaphore = device |
| // .create_semaphore(&semaphore_create_info, None) |
| // .unwrap(); |
| |
| // VkRender { |
| // event_loop: RefCell::new(event_loop), |
| // entry, |
| // instance, |
| // device, |
| // queue_family_index, |
| // pdevice, |
| // device_memory_properties, |
| // window, |
| // surface_loader, |
| // surface_format, |
| // present_queue, |
| // surface_resolution, |
| // swapchain_loader, |
| // swapchain, |
| // present_images, |
| // present_image_views, |
| // pool, |
| // draw_command_buffer, |
| // setup_command_buffer, |
| // depth_image, |
| // depth_image_view, |
| // present_complete_semaphore, |
| // rendering_complete_semaphore, |
| // draw_commands_reuse_fence, |
| // setup_commands_reuse_fence, |
| // surface, |
| // debug_call_back, |
| // debug_utils_loader, |
| // depth_image_memory, |
| // } |
| } |
| Ok(()) |
| } |
| } |
| |
| impl std::ops::Drop for VkRender { |
| fn drop(&mut self) { |
| // unsafe { |
| // self.device.device_wait_idle().unwrap(); |
| // self.device |
| // .destroy_semaphore(self.present_complete_semaphore, None); |
| // self.device |
| // .destroy_semaphore(self.rendering_complete_semaphore, None); |
| // self.device |
| // .destroy_fence(self.draw_commands_reuse_fence, None); |
| // self.device |
| // .destroy_fence(self.setup_commands_reuse_fence, None); |
| // self.device.free_memory(self.depth_image_memory, None); |
| // self.device.destroy_image_view(self.depth_image_view, None); |
| // self.device.destroy_image(self.depth_image, None); |
| // for &image_view in self.present_image_views.iter() { |
| // self.device.destroy_image_view(image_view, None); |
| // } |
| // self.device.destroy_command_pool(self.pool, None); |
| // self.swapchain_loader |
| // .destroy_swapchain(self.swapchain, None); |
| // self.device.destroy_device(None); |
| // self.surface_loader.destroy_surface(self.surface, None); |
| // self.debug_utils_loader |
| // .destroy_debug_utils_messenger(self.debug_call_back, None); |
| // self.instance.destroy_instance(None); |
| // } |
| } |
| } |
| |
| |
| // #[derive(Clone, Debug, Copy)] |
| // struct Vertex { |
| // pos: [f32; 4], |
| // color: [f32; 4], |
| // } |
| |
| |
| fn render() { |
| // unsafe { |
| VkRender::new(1920, 1080).expect("failed to create VkRenderer"); |
| // let renderpass_attachments = [ |
| // vk::AttachmentDescription { |
| // format: base.surface_format.format, |
| // samples: vk::SampleCountFlags::TYPE_1, |
| // load_op: vk::AttachmentLoadOp::CLEAR, |
| // store_op: vk::AttachmentStoreOp::STORE, |
| // final_layout: vk::ImageLayout::PRESENT_SRC_KHR, |
| // ..Default::default() |
| // }, |
| // vk::AttachmentDescription { |
| // format: vk::Format::D16_UNORM, |
| // samples: vk::SampleCountFlags::TYPE_1, |
| // load_op: vk::AttachmentLoadOp::CLEAR, |
| // initial_layout: vk::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL, |
| // final_layout: vk::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL, |
| // ..Default::default() |
| // }, |
| // ]; |
| // let color_attachment_refs = [vk::AttachmentReference { |
| // attachment: 0, |
| // layout: vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL, |
| // }]; |
| // let depth_attachment_ref = vk::AttachmentReference { |
| // attachment: 1, |
| // layout: vk::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL, |
| // }; |
| // let dependencies = [vk::SubpassDependency { |
| // src_subpass: vk::SUBPASS_EXTERNAL, |
| // src_stage_mask: vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT, |
| // dst_access_mask: vk::AccessFlags::COLOR_ATTACHMENT_READ |
| // | vk::AccessFlags::COLOR_ATTACHMENT_WRITE, |
| // dst_stage_mask: vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT, |
| // ..Default::default() |
| // }]; |
| |
| // let subpass = vk::SubpassDescription::default() |
| // .color_attachments(&color_attachment_refs) |
| // .depth_stencil_attachment(&depth_attachment_ref) |
| // .pipeline_bind_point(vk::PipelineBindPoint::GRAPHICS); |
| |
| // let renderpass_create_info = vk::RenderPassCreateInfo::default() |
| // .attachments(&renderpass_attachments) |
| // .subpasses(std::slice::from_ref(&subpass)) |
| // .dependencies(&dependencies); |
| |
| // let renderpass = base |
| // .device |
| // .create_render_pass(&renderpass_create_info, None) |
| // .unwrap(); |
| |
| // let framebuffers: Vec<vk::Framebuffer> = base |
| // .present_image_views |
| // .iter() |
| // .map(|&present_image_view| { |
| // let framebuffer_attachments = [present_image_view, base.depth_image_view]; |
| // let frame_buffer_create_info = vk::FramebufferCreateInfo::default() |
| // .render_pass(renderpass) |
| // .attachments(&framebuffer_attachments) |
| // .width(base.surface_resolution.width) |
| // .height(base.surface_resolution.height) |
| // .layers(1); |
| |
| // base.device |
| // .create_framebuffer(&frame_buffer_create_info, None) |
| // .unwrap() |
| // }) |
| // .collect(); |
| |
| // let index_buffer_data = [0u32, 1, 2]; |
| // let index_buffer_info = vk::BufferCreateInfo::default() |
| // .size(std::mem::size_of_val(&index_buffer_data) as u64) |
| // .usage(vk::BufferUsageFlags::INDEX_BUFFER) |
| // .sharing_mode(vk::SharingMode::EXCLUSIVE); |
| |
| // let index_buffer = base.device.create_buffer(&index_buffer_info, None).unwrap(); |
| // let index_buffer_memory_req = base.device.get_buffer_memory_requirements(index_buffer); |
| // let index_buffer_memory_index = find_memorytype_index( |
| // &index_buffer_memory_req, |
| // &base.device_memory_properties, |
| // vk::MemoryPropertyFlags::HOST_VISIBLE | vk::MemoryPropertyFlags::HOST_COHERENT, |
| // ) |
| // .expect("Unable to find suitable memorytype for the index buffer."); |
| |
| // let index_allocate_info = vk::MemoryAllocateInfo { |
| // allocation_size: index_buffer_memory_req.size, |
| // memory_type_index: index_buffer_memory_index, |
| // ..Default::default() |
| // }; |
| // let index_buffer_memory = base |
| // .device |
| // .allocate_memory(&index_allocate_info, None) |
| // .unwrap(); |
| // let index_ptr = base |
| // .device |
| // .map_memory( |
| // index_buffer_memory, |
| // 0, |
| // index_buffer_memory_req.size, |
| // vk::MemoryMapFlags::empty(), |
| // ) |
| // .unwrap(); |
| // let mut index_slice = Align::new( |
| // index_ptr, |
| // align_of::<u32>() as u64, |
| // index_buffer_memory_req.size, |
| // ); |
| // index_slice.copy_from_slice(&index_buffer_data); |
| // base.device.unmap_memory(index_buffer_memory); |
| // base.device |
| // .bind_buffer_memory(index_buffer, index_buffer_memory, 0) |
| // .unwrap(); |
| |
| // let vertex_input_buffer_info = vk::BufferCreateInfo { |
| // size: 3 * std::mem::size_of::<Vertex>() as u64, |
| // usage: vk::BufferUsageFlags::VERTEX_BUFFER, |
| // sharing_mode: vk::SharingMode::EXCLUSIVE, |
| // ..Default::default() |
| // }; |
| |
| // let vertex_input_buffer = base |
| // .device |
| // .create_buffer(&vertex_input_buffer_info, None) |
| // .unwrap(); |
| |
| // let vertex_input_buffer_memory_req = base |
| // .device |
| // .get_buffer_memory_requirements(vertex_input_buffer); |
| |
| // let vertex_input_buffer_memory_index = find_memorytype_index( |
| // &vertex_input_buffer_memory_req, |
| // &base.device_memory_properties, |
| // vk::MemoryPropertyFlags::HOST_VISIBLE | vk::MemoryPropertyFlags::HOST_COHERENT, |
| // ) |
| // .expect("Unable to find suitable memorytype for the vertex buffer."); |
| |
| // let vertex_buffer_allocate_info = vk::MemoryAllocateInfo { |
| // allocation_size: vertex_input_buffer_memory_req.size, |
| // memory_type_index: vertex_input_buffer_memory_index, |
| // ..Default::default() |
| // }; |
| |
| // let vertex_input_buffer_memory = base |
| // .device |
| // .allocate_memory(&vertex_buffer_allocate_info, None) |
| // .unwrap(); |
| |
| // let vertices = [ |
| // Vertex { |
| // pos: [-1.0, 1.0, 0.0, 1.0], |
| // color: [0.0, 1.0, 0.0, 1.0], |
| // }, |
| // Vertex { |
| // pos: [1.0, 1.0, 0.0, 1.0], |
| // color: [0.0, 0.0, 1.0, 1.0], |
| // }, |
| // Vertex { |
| // pos: [0.0, -1.0, 0.0, 1.0], |
| // color: [1.0, 0.0, 0.0, 1.0], |
| // }, |
| // ]; |
| |
| // let vert_ptr = base |
| // .device |
| // .map_memory( |
| // vertex_input_buffer_memory, |
| // 0, |
| // vertex_input_buffer_memory_req.size, |
| // vk::MemoryMapFlags::empty(), |
| // ) |
| // .unwrap(); |
| |
| // let mut vert_align = Align::new( |
| // vert_ptr, |
| // align_of::<Vertex>() as u64, |
| // vertex_input_buffer_memory_req.size, |
| // ); |
| // vert_align.copy_from_slice(&vertices); |
| // base.device.unmap_memory(vertex_input_buffer_memory); |
| // base.device |
| // .bind_buffer_memory(vertex_input_buffer, vertex_input_buffer_memory, 0) |
| // .unwrap(); |
| // let mut vertex_spv_file = |
| // Cursor::new(&include_bytes!("../../shader/triangle/vert.spv")[..]); |
| // let mut frag_spv_file = Cursor::new(&include_bytes!("../../shader/triangle/frag.spv")[..]); |
| |
| // let vertex_code = |
| // read_spv(&mut vertex_spv_file).expect("Failed to read vertex shader spv file"); |
| // let vertex_shader_info = vk::ShaderModuleCreateInfo::default().code(&vertex_code); |
| |
| // let frag_code = |
| // read_spv(&mut frag_spv_file).expect("Failed to read fragment shader spv file"); |
| // let frag_shader_info = vk::ShaderModuleCreateInfo::default().code(&frag_code); |
| |
| // let vertex_shader_module = base |
| // .device |
| // .create_shader_module(&vertex_shader_info, None) |
| // .expect("Vertex shader module error"); |
| |
| // let fragment_shader_module = base |
| // .device |
| // .create_shader_module(&frag_shader_info, None) |
| // .expect("Fragment shader module error"); |
| |
| // let layout_create_info = vk::PipelineLayoutCreateInfo::default(); |
| |
| // let pipeline_layout = base |
| // .device |
| // .create_pipeline_layout(&layout_create_info, None) |
| // .unwrap(); |
| |
| // let shader_entry_name = CStr::from_bytes_with_nul_unchecked(b"main\0"); |
| // let shader_stage_create_infos = [ |
| // vk::PipelineShaderStageCreateInfo { |
| // module: vertex_shader_module, |
| // p_name: shader_entry_name.as_ptr(), |
| // stage: vk::ShaderStageFlags::VERTEX, |
| // ..Default::default() |
| // }, |
| // vk::PipelineShaderStageCreateInfo { |
| // s_type: vk::StructureType::PIPELINE_SHADER_STAGE_CREATE_INFO, |
| // module: fragment_shader_module, |
| // p_name: shader_entry_name.as_ptr(), |
| // stage: vk::ShaderStageFlags::FRAGMENT, |
| // ..Default::default() |
| // }, |
| // ]; |
| // let vertex_input_binding_descriptions = [vk::VertexInputBindingDescription { |
| // binding: 0, |
| // stride: mem::size_of::<Vertex>() as u32, |
| // input_rate: vk::VertexInputRate::VERTEX, |
| // }]; |
| // let vertex_input_attribute_descriptions = [ |
| // vk::VertexInputAttributeDescription { |
| // location: 0, |
| // binding: 0, |
| // format: vk::Format::R32G32B32A32_SFLOAT, |
| // offset: offset_of!(Vertex, pos) as u32, |
| // }, |
| // vk::VertexInputAttributeDescription { |
| // location: 1, |
| // binding: 0, |
| // format: vk::Format::R32G32B32A32_SFLOAT, |
| // offset: offset_of!(Vertex, color) as u32, |
| // }, |
| // ]; |
| |
| // let vertex_input_state_info = vk::PipelineVertexInputStateCreateInfo::default() |
| // .vertex_attribute_descriptions(&vertex_input_attribute_descriptions) |
| // .vertex_binding_descriptions(&vertex_input_binding_descriptions); |
| // let vertex_input_assembly_state_info = vk::PipelineInputAssemblyStateCreateInfo { |
| // topology: vk::PrimitiveTopology::TRIANGLE_LIST, |
| // ..Default::default() |
| // }; |
| // let viewports = [vk::Viewport { |
| // x: 0.0, |
| // y: 0.0, |
| // width: base.surface_resolution.width as f32, |
| // height: base.surface_resolution.height as f32, |
| // min_depth: 0.0, |
| // max_depth: 1.0, |
| // }]; |
| // let scissors = [base.surface_resolution.into()]; |
| // let viewport_state_info = vk::PipelineViewportStateCreateInfo::default() |
| // .scissors(&scissors) |
| // .viewports(&viewports); |
| |
| // let rasterization_info = vk::PipelineRasterizationStateCreateInfo { |
| // front_face: vk::FrontFace::COUNTER_CLOCKWISE, |
| // line_width: 1.0, |
| // polygon_mode: vk::PolygonMode::FILL, |
| // ..Default::default() |
| // }; |
| // let multisample_state_info = vk::PipelineMultisampleStateCreateInfo { |
| // rasterization_samples: vk::SampleCountFlags::TYPE_1, |
| // ..Default::default() |
| // }; |
| // let noop_stencil_state = vk::StencilOpState { |
| // fail_op: vk::StencilOp::KEEP, |
| // pass_op: vk::StencilOp::KEEP, |
| // depth_fail_op: vk::StencilOp::KEEP, |
| // compare_op: vk::CompareOp::ALWAYS, |
| // ..Default::default() |
| // }; |
| // let depth_state_info = vk::PipelineDepthStencilStateCreateInfo { |
| // depth_test_enable: 1, |
| // depth_write_enable: 1, |
| // depth_compare_op: vk::CompareOp::LESS_OR_EQUAL, |
| // front: noop_stencil_state, |
| // back: noop_stencil_state, |
| // max_depth_bounds: 1.0, |
| // ..Default::default() |
| // }; |
| // let color_blend_attachment_states = [vk::PipelineColorBlendAttachmentState { |
| // blend_enable: 0, |
| // src_color_blend_factor: vk::BlendFactor::SRC_COLOR, |
| // dst_color_blend_factor: vk::BlendFactor::ONE_MINUS_DST_COLOR, |
| // color_blend_op: vk::BlendOp::ADD, |
| // src_alpha_blend_factor: vk::BlendFactor::ZERO, |
| // dst_alpha_blend_factor: vk::BlendFactor::ZERO, |
| // alpha_blend_op: vk::BlendOp::ADD, |
| // color_write_mask: vk::ColorComponentFlags::RGBA, |
| // }]; |
| // let color_blend_state = vk::PipelineColorBlendStateCreateInfo::default() |
| // .logic_op(vk::LogicOp::CLEAR) |
| // .attachments(&color_blend_attachment_states); |
| |
| // let dynamic_state = [vk::DynamicState::VIEWPORT, vk::DynamicState::SCISSOR]; |
| // let dynamic_state_info = |
| // vk::PipelineDynamicStateCreateInfo::default().dynamic_states(&dynamic_state); |
| |
| // let graphic_pipeline_info = vk::GraphicsPipelineCreateInfo::default() |
| // .stages(&shader_stage_create_infos) |
| // .vertex_input_state(&vertex_input_state_info) |
| // .input_assembly_state(&vertex_input_assembly_state_info) |
| // .viewport_state(&viewport_state_info) |
| // .rasterization_state(&rasterization_info) |
| // .multisample_state(&multisample_state_info) |
| // .depth_stencil_state(&depth_state_info) |
| // .color_blend_state(&color_blend_state) |
| // .dynamic_state(&dynamic_state_info) |
| // .layout(pipeline_layout) |
| // .render_pass(renderpass); |
| |
| // let graphics_pipelines = base |
| // .device |
| // .create_graphics_pipelines(vk::PipelineCache::null(), &[graphic_pipeline_info], None) |
| // .expect("Unable to create graphics pipeline"); |
| |
| // let graphic_pipeline = graphics_pipelines[0]; |
| |
| // base.render_loop(|| { |
| // let (present_index, _) = base |
| // .swapchain_loader |
| // .acquire_next_image( |
| // base.swapchain, |
| // std::u64::MAX, |
| // base.present_complete_semaphore, |
| // vk::Fence::null(), |
| // ) |
| // .unwrap(); |
| // let clear_values = [ |
| // vk::ClearValue { |
| // color: vk::ClearColorValue { |
| // float32: [0.0, 0.0, 0.0, 0.0], |
| // }, |
| // }, |
| // vk::ClearValue { |
| // depth_stencil: vk::ClearDepthStencilValue { |
| // depth: 1.0, |
| // stencil: 0, |
| // }, |
| // }, |
| // ]; |
| |
| // let render_pass_begin_info = vk::RenderPassBeginInfo::default() |
| // .render_pass(renderpass) |
| // .framebuffer(framebuffers[present_index as usize]) |
| // .render_area(base.surface_resolution.into()) |
| // .clear_values(&clear_values); |
| |
| // record_submit_commandbuffer( |
| // &base.device, |
| // base.draw_command_buffer, |
| // base.draw_commands_reuse_fence, |
| // base.present_queue, |
| // &[vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT], |
| // &[base.present_complete_semaphore], |
| // &[base.rendering_complete_semaphore], |
| // |device, draw_command_buffer| { |
| // device.cmd_begin_render_pass( |
| // draw_command_buffer, |
| // &render_pass_begin_info, |
| // vk::SubpassContents::INLINE, |
| // ); |
| // device.cmd_bind_pipeline( |
| // draw_command_buffer, |
| // vk::PipelineBindPoint::GRAPHICS, |
| // graphic_pipeline, |
| // ); |
| // device.cmd_set_viewport(draw_command_buffer, 0, &viewports); |
| // device.cmd_set_scissor(draw_command_buffer, 0, &scissors); |
| // device.cmd_bind_vertex_buffers( |
| // draw_command_buffer, |
| // 0, |
| // &[vertex_input_buffer], |
| // &[0], |
| // ); |
| // device.cmd_bind_index_buffer( |
| // draw_command_buffer, |
| // index_buffer, |
| // 0, |
| // vk::IndexType::UINT32, |
| // ); |
| // device.cmd_draw_indexed( |
| // draw_command_buffer, |
| // index_buffer_data.len() as u32, |
| // 1, |
| // 0, |
| // 0, |
| // 1, |
| // ); |
| // // Or draw without the index buffer |
| // // device.cmd_draw(draw_command_buffer, 3, 1, 0, 0); |
| // device.cmd_end_render_pass(draw_command_buffer); |
| // }, |
| // ); |
| // //let mut present_info_err = mem::zeroed(); |
| // let wait_semaphors = [base.rendering_complete_semaphore]; |
| // let swapchains = [base.swapchain]; |
| // let image_indices = [present_index]; |
| // let present_info = vk::PresentInfoKHR::default() |
| // .wait_semaphores(&wait_semaphors) // &base.rendering_complete_semaphore) |
| // .swapchains(&swapchains) |
| // .image_indices(&image_indices); |
| |
| // base.swapchain_loader |
| // .queue_present(base.present_queue, &present_info) |
| // .unwrap(); |
| // }); |
| |
| // base.device.device_wait_idle().unwrap(); |
| // for pipeline in graphics_pipelines { |
| // base.device.destroy_pipeline(pipeline, None); |
| // } |
| // base.device.destroy_pipeline_layout(pipeline_layout, None); |
| // base.device |
| // .destroy_shader_module(vertex_shader_module, None); |
| // base.device |
| // .destroy_shader_module(fragment_shader_module, None); |
| // base.device.free_memory(index_buffer_memory, None); |
| // base.device.destroy_buffer(index_buffer, None); |
| // base.device.free_memory(vertex_input_buffer_memory, None); |
| // base.device.destroy_buffer(vertex_input_buffer, None); |
| // for framebuffer in framebuffers { |
| // base.device.destroy_framebuffer(framebuffer, None); |
| // } |
| // base.device.destroy_render_pass(renderpass, None); |
| // } |
| } |
| |
| pub fn init() { |
| render(); |
| // let instance = create_vk_instance(); |
| // let physical_device = get_vk_physical_device(instance); |
| |
| // assert!(physical_device.is_some()); |
| // destroy_vk_device(instance, physical_device.unwrap()); |
| } |