ash/examples/src/lib.rs

608 lines
24 KiB
Rust
Raw Normal View History

2016-12-26 00:38:26 +11:00
extern crate ash;
2019-02-27 06:54:48 +11:00
extern crate winit;
2020-09-03 17:07:09 +10:00
2018-12-05 07:22:03 +11:00
use ash::extensions::{
ext::DebugUtils,
2018-12-05 07:22:03 +11:00
khr::{Surface, Swapchain},
};
use ash::{vk, Entry};
pub use ash::{Device, Instance};
use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle};
use std::borrow::Cow;
2017-12-13 00:25:10 +11:00
use std::cell::RefCell;
2018-07-31 22:51:45 +10:00
use std::default::Default;
use std::ffi::CStr;
2016-12-26 00:38:26 +11:00
use std::ops::Drop;
use std::os::raw::c_char;
2016-12-26 00:38:26 +11:00
#[cfg(any(target_os = "macos", target_os = "ios"))]
use ash::vk::{
KhrGetPhysicalDeviceProperties2Fn, KhrPortabilityEnumerationFn, KhrPortabilitySubsetFn,
};
2021-11-09 09:25:13 +11:00
use winit::{
2021-11-10 05:12:51 +11:00
event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent},
2021-11-09 09:25:13 +11:00
event_loop::{ControlFlow, EventLoop},
platform::run_return::EventLoopExtRunReturn,
window::WindowBuilder,
};
2016-12-26 00:38:26 +11:00
// Simple offset_of macro akin to C++ offsetof
#[macro_export]
2018-07-31 22:51:45 +10:00
macro_rules! offset_of {
($base:path, $field:ident) => {{
#[allow(unused_unsafe)]
unsafe {
let b: $base = mem::zeroed();
std::ptr::addr_of!(b.$field) as isize - std::ptr::addr_of!(b) as isize
2016-12-26 00:38:26 +11:00
}
2018-07-31 22:51:45 +10:00
}};
2016-12-26 00:38:26 +11:00
}
/// 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,
2017-12-13 00:25:10 +11:00
command_buffer: vk::CommandBuffer,
command_buffer_reuse_fence: vk::Fence,
2017-12-13 00:25:10 +11:00
submit_queue: vk::Queue,
wait_mask: &[vk::PipelineStageFlags],
wait_semaphores: &[vk::Semaphore],
signal_semaphores: &[vk::Semaphore],
f: F,
) {
2016-12-26 00:38:26 +11:00
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.");
2017-12-13 00:25:10 +11:00
device
.reset_command_buffer(
command_buffer,
2018-07-31 20:45:29 +10:00
vk::CommandBufferResetFlags::RELEASE_RESOURCES,
2018-12-08 04:47:57 +11:00
)
.expect("Reset command buffer failed.");
2018-12-10 00:47:29 +11:00
let command_buffer_begin_info = vk::CommandBufferBeginInfo::default()
.flags(vk::CommandBufferUsageFlags::ONE_TIME_SUBMIT);
2017-12-13 00:25:10 +11:00
device
.begin_command_buffer(command_buffer, &command_buffer_begin_info)
2016-12-26 00:38:26 +11:00
.expect("Begin commandbuffer");
f(device, command_buffer);
2017-12-13 00:25:10 +11:00
device
.end_command_buffer(command_buffer)
.expect("End commandbuffer");
let command_buffers = vec![command_buffer];
2018-12-10 07:33:21 +11:00
let submit_info = vk::SubmitInfo::default()
2018-12-10 06:41:23 +11:00
.wait_semaphores(wait_semaphores)
.wait_dst_stage_mask(wait_mask)
.command_buffers(&command_buffers)
2018-12-10 07:33:21 +11:00
.signal_semaphores(signal_semaphores);
2017-12-13 00:25:10 +11:00
device
.queue_submit(submit_queue, &[submit_info], command_buffer_reuse_fence)
2016-12-26 11:58:44 +11:00
.expect("queue submit failed.");
2016-12-26 00:38:26 +11:00
}
}
2017-12-13 00:25:10 +11:00
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 = callback_data.message_id_number;
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!(
"{message_severity:?}:\n{message_type:?} [{message_id_name} ({message_id_number})] : {message}\n",
);
2018-11-12 23:12:38 +11:00
vk::FALSE
2016-12-26 00:38:26 +11:00
}
2017-12-13 00:25:10 +11:00
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 _)
2016-12-26 00:38:26 +11:00
}
2016-12-26 00:38:26 +11:00
pub struct ExampleBase {
2018-11-11 20:41:58 +11:00
pub entry: Entry,
pub instance: Instance,
pub device: Device,
2016-12-26 00:38:26 +11:00
pub surface_loader: Surface,
pub swapchain_loader: Swapchain,
pub debug_utils_loader: DebugUtils,
2021-11-09 09:25:13 +11:00
pub window: winit::window::Window,
pub event_loop: RefCell<EventLoop<()>>,
pub debug_call_back: vk::DebugUtilsMessengerEXT,
2016-12-26 00:38:26 +11:00
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,
2016-12-26 00:38:26 +11:00
}
impl ExampleBase {
pub fn render_loop<F: Fn()>(&self, f: F) {
self.event_loop
2021-11-09 09:25:13 +11:00
.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(),
_ => (),
2021-11-09 09:25:13 +11:00
}
});
2016-12-26 00:38:26 +11:00
}
2018-03-03 18:59:28 +11:00
2016-12-26 00:38:26 +11:00
pub fn new(window_width: u32, window_height: u32) -> Self {
unsafe {
let event_loop = EventLoop::new();
2021-11-09 09:25:13 +11:00
let window = WindowBuilder::new()
2017-01-05 18:09:23 +11:00
.with_title("Ash - Example")
2021-11-09 09:25:13 +11:00
.with_inner_size(winit::dpi::LogicalSize::new(
f64::from(window_width),
f64::from(window_height),
2018-12-08 04:47:57 +11:00
))
.build(&event_loop)
2016-12-26 00:38:26 +11:00
.unwrap();
let entry = Entry::linked();
let app_name = CStr::from_bytes_with_nul_unchecked(b"VulkanTriangle\0");
2016-12-26 00:38:26 +11:00
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
2017-12-13 00:25:10 +11:00
.iter()
2016-12-26 00:38:26 +11:00
.map(|raw_name| raw_name.as_ptr())
.collect();
let mut extension_names =
ash_window::enumerate_required_extensions(window.raw_display_handle())
.unwrap()
.to_vec();
extension_names.push(DebugUtils::NAME.as_ptr());
#[cfg(any(target_os = "macos", target_os = "ios"))]
{
extension_names.push(KhrPortabilityEnumerationFn::NAME.as_ptr());
// Enabling this extension is a requirement when using `VK_KHR_portability_subset`
extension_names.push(KhrGetPhysicalDeviceProperties2Fn::NAME.as_ptr());
}
let appinfo = vk::ApplicationInfo::default()
.application_name(app_name)
.application_version(0)
.engine_name(app_name)
.engine_version(0)
.api_version(vk::make_api_version(0, 1, 0, 0));
let create_flags = if cfg!(any(target_os = "macos", target_os = "ios")) {
vk::InstanceCreateFlags::ENUMERATE_PORTABILITY_KHR
} else {
vk::InstanceCreateFlags::default()
};
let create_info = vk::InstanceCreateInfo::default()
.application_info(&appinfo)
.enabled_layer_names(&layers_names_raw)
.enabled_extension_names(&extension_names)
.flags(create_flags);
2018-11-11 20:41:58 +11:00
let instance: Instance = entry
2017-12-13 00:25:10 +11:00
.create_instance(&create_info, None)
2016-12-26 00:38:26 +11:00
.expect("Instance creation error");
let debug_info = vk::DebugUtilsMessengerCreateInfoEXT::default()
.message_severity(
vk::DebugUtilsMessageSeverityFlagsEXT::ERROR
| vk::DebugUtilsMessageSeverityFlagsEXT::WARNING
| vk::DebugUtilsMessageSeverityFlagsEXT::INFO,
2018-12-08 04:47:57 +11:00
)
.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)
2017-12-13 00:25:10 +11:00
.unwrap();
let surface = ash_window::create_surface(
&entry,
&instance,
window.raw_display_handle(),
window.raw_window_handle(),
None,
)
.unwrap();
2017-12-13 00:25:10 +11:00
let pdevices = instance
.enumerate_physical_devices()
.expect("Physical device error");
2018-11-18 05:05:28 +11:00
let surface_loader = Surface::new(&entry, &instance);
2017-12-13 00:25:10 +11:00
let (pdevice, queue_family_index) = pdevices
.iter()
.find_map(|pdevice| {
2017-12-13 00:25:10 +11:00
instance
.get_physical_device_queue_family_properties(*pdevice)
2016-12-26 00:38:26 +11:00
.iter()
.enumerate()
.find_map(|(index, info)| {
2018-07-31 22:51:45 +10:00
let supports_graphic_and_surface =
2018-11-18 05:05:28 +11:00
info.queue_flags.contains(vk::QueueFlags::GRAPHICS)
2019-05-19 07:09:12 +10:00
&& surface_loader
.get_physical_device_surface_support(
*pdevice,
index as u32,
surface,
)
.unwrap();
if supports_graphic_and_surface {
Some((*pdevice, index))
} else {
None
2016-12-26 00:38:26 +11:00
}
2018-12-08 04:47:57 +11:00
})
})
2016-12-26 00:38:26 +11:00
.expect("Couldn't find suitable device.");
let queue_family_index = queue_family_index as u32;
let device_extension_names_raw = [
Swapchain::NAME.as_ptr(),
#[cfg(any(target_os = "macos", target_os = "ios"))]
KhrPortabilitySubsetFn::NAME.as_ptr(),
];
2017-12-13 00:25:10 +11:00
let features = vk::PhysicalDeviceFeatures {
shader_clip_distance: 1,
..Default::default()
};
2016-12-26 00:38:26 +11:00
let priorities = [1.0];
let queue_info = vk::DeviceQueueCreateInfo::default()
2018-12-08 04:47:57 +11:00
.queue_family_index(queue_family_index)
examples: Use `slice::from_ref` to not loose lifetime on nested slices As per the readme `.build()` should only be called as late as possible, and only if absolutely necessary; such cases include slices that are passed directly to functions. More precisely, such build calls and the creation of temporary slices should happen inside the same expression as the function call to be sound and completely lifetime-checked. This pattern of `&[my_builder.build()]` is however not possible when constructing intermediary Vulkan objects that reference the slice. In the first place this slice goes out of scope after the expression that creates the Vulkan object, which is caught and disallowed by rustc (unless this expression itself ends in `.build()`, which is completely unsound as it makes rustc unable to validate this lifetime dependency). In the second place - and as is most relevant for this patch that removes `.build()` calls that were not surrounded by temporary slice constructors - said expression drops the lifetime checks on anything held by `my_builder` which _could_ go out of scope before the newly constructed Vulkan object is used, resulting yet again in Undefined Behaviour. Fortunately, for slices of size 1 which are typical in Vulkan, `std::slice::as_ref` exists which is analogous to taking a pointer to an object and considering it an array of length 1 in C(++). This maintains the lifetime through `Deref` and makes rustc able to fully check all lifetimes and prevent unsound code. Albeit improving overall consistency, the `&[my_builder.build()]` pattern is not substituted in aforementioned Vulkan function-call expressions as that is considered "extraneous" [1] and demonstrates the various ways to safely construct Vulkan objects for the observant reader. [1]: https://github.com/MaikKlein/ash/pull/506#discussion_r762630648
2021-12-19 22:33:39 +11:00
.queue_priorities(&priorities);
let device_create_info = vk::DeviceCreateInfo::default()
examples: Use `slice::from_ref` to not loose lifetime on nested slices As per the readme `.build()` should only be called as late as possible, and only if absolutely necessary; such cases include slices that are passed directly to functions. More precisely, such build calls and the creation of temporary slices should happen inside the same expression as the function call to be sound and completely lifetime-checked. This pattern of `&[my_builder.build()]` is however not possible when constructing intermediary Vulkan objects that reference the slice. In the first place this slice goes out of scope after the expression that creates the Vulkan object, which is caught and disallowed by rustc (unless this expression itself ends in `.build()`, which is completely unsound as it makes rustc unable to validate this lifetime dependency). In the second place - and as is most relevant for this patch that removes `.build()` calls that were not surrounded by temporary slice constructors - said expression drops the lifetime checks on anything held by `my_builder` which _could_ go out of scope before the newly constructed Vulkan object is used, resulting yet again in Undefined Behaviour. Fortunately, for slices of size 1 which are typical in Vulkan, `std::slice::as_ref` exists which is analogous to taking a pointer to an object and considering it an array of length 1 in C(++). This maintains the lifetime through `Deref` and makes rustc able to fully check all lifetimes and prevent unsound code. Albeit improving overall consistency, the `&[my_builder.build()]` pattern is not substituted in aforementioned Vulkan function-call expressions as that is considered "extraneous" [1] and demonstrates the various ways to safely construct Vulkan objects for the observant reader. [1]: https://github.com/MaikKlein/ash/pull/506#discussion_r762630648
2021-12-19 22:33:39 +11:00
.queue_create_infos(std::slice::from_ref(&queue_info))
.enabled_extension_names(&device_extension_names_raw)
2019-03-04 20:16:08 +11:00
.enabled_features(&features);
2019-02-03 22:48:05 +11:00
2018-11-11 20:41:58 +11:00
let device: Device = instance
2017-12-13 00:25:10 +11:00
.create_device(pdevice, &device_create_info, None)
2016-12-26 00:38:26 +11:00
.unwrap();
2019-02-03 22:48:05 +11:00
let present_queue = device.get_device_queue(queue_family_index, 0);
2016-12-26 00:38:26 +11:00
let surface_format = surface_loader
2018-12-05 07:22:03 +11:00
.get_physical_device_surface_formats(pdevice, surface)
.unwrap()[0];
2017-12-13 00:25:10 +11:00
let surface_capabilities = surface_loader
2018-12-05 07:22:03 +11:00
.get_physical_device_surface_capabilities(pdevice, surface)
2017-12-13 00:25:10 +11:00
.unwrap();
2017-01-06 18:47:39 +11:00
let mut desired_image_count = surface_capabilities.min_image_count + 1;
2017-12-13 00:25:10 +11:00
if surface_capabilities.max_image_count > 0
&& desired_image_count > surface_capabilities.max_image_count
{
2017-01-06 18:47:39 +11:00
desired_image_count = surface_capabilities.max_image_count;
}
2016-12-26 00:38:26 +11:00
let surface_resolution = match surface_capabilities.current_extent.width {
2017-12-13 00:25:10 +11:00
std::u32::MAX => vk::Extent2D {
width: window_width,
height: window_height,
},
2016-12-26 00:38:26 +11:00
_ => surface_capabilities.current_extent,
};
2017-12-13 00:25:10 +11:00
let pre_transform = if surface_capabilities
.supported_transforms
.contains(vk::SurfaceTransformFlagsKHR::IDENTITY)
2017-12-13 00:25:10 +11:00
{
vk::SurfaceTransformFlagsKHR::IDENTITY
2016-12-26 00:38:26 +11:00
} else {
surface_capabilities.current_transform
};
2017-12-13 00:25:10 +11:00
let present_modes = surface_loader
2018-12-05 07:22:03 +11:00
.get_physical_device_surface_present_modes(pdevice, surface)
2017-12-13 00:25:10 +11:00
.unwrap();
let present_mode = present_modes
.iter()
2016-12-26 00:38:26 +11:00
.cloned()
.find(|&mode| mode == vk::PresentModeKHR::MAILBOX)
.unwrap_or(vk::PresentModeKHR::FIFO);
2018-11-18 05:05:28 +11:00
let swapchain_loader = Swapchain::new(&instance, &device);
let swapchain_create_info = vk::SwapchainCreateInfoKHR::default()
.surface(surface)
2018-12-08 04:47:57 +11:00
.min_image_count(desired_image_count)
.image_color_space(surface_format.color_space)
.image_format(surface_format.format)
.image_extent(surface_resolution)
2018-12-08 04:47:57 +11:00
.image_usage(vk::ImageUsageFlags::COLOR_ATTACHMENT)
.image_sharing_mode(vk::SharingMode::EXCLUSIVE)
2018-12-08 04:47:57 +11:00
.pre_transform(pre_transform)
.composite_alpha(vk::CompositeAlphaFlagsKHR::OPAQUE)
.present_mode(present_mode)
.clipped(true)
2018-12-08 04:47:57 +11:00
.image_array_layers(1);
2017-12-13 00:25:10 +11:00
let swapchain = swapchain_loader
2018-12-05 07:22:03 +11:00
.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);
2016-12-28 19:24:24 +11:00
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);
2017-12-13 00:25:10 +11:00
let command_buffers = device
.allocate_command_buffers(&command_buffer_allocate_info)
2016-12-26 00:38:26 +11:00
.unwrap();
let setup_command_buffer = command_buffers[0];
let draw_command_buffer = command_buffers[1];
2018-12-05 07:22:03 +11:00
let present_images = swapchain_loader.get_swapchain_images(swapchain).unwrap();
2017-12-13 00:25:10 +11:00
let present_image_views: Vec<vk::ImageView> = present_images
.iter()
2016-12-26 00:38:26 +11:00
.map(|&image| {
let create_view_info = vk::ImageViewCreateInfo::default()
2018-12-08 04:47:57 +11:00
.view_type(vk::ImageViewType::TYPE_2D)
.format(surface_format.format)
2018-12-08 04:47:57 +11:00
.components(vk::ComponentMapping {
r: vk::ComponentSwizzle::R,
g: vk::ComponentSwizzle::G,
b: vk::ComponentSwizzle::B,
a: vk::ComponentSwizzle::A,
})
2018-12-08 04:47:57 +11:00
.subresource_range(vk::ImageSubresourceRange {
aspect_mask: vk::ImageAspectFlags::COLOR,
base_mip_level: 0,
level_count: 1,
base_array_layer: 0,
layer_count: 1,
})
2018-12-08 04:47:57 +11:00
.image(image);
2016-12-28 19:24:24 +11:00
device.create_image_view(&create_view_info, None).unwrap()
2018-12-08 04:47:57 +11:00
})
.collect();
2016-12-26 00:38:26 +11:00
let device_memory_properties = instance.get_physical_device_memory_properties(pdevice);
let depth_image_create_info = vk::ImageCreateInfo::default()
2018-12-08 04:47:57 +11:00
.image_type(vk::ImageType::TYPE_2D)
.format(vk::Format::D16_UNORM)
.extent(surface_resolution.into())
2018-12-08 04:47:57 +11:00
.mip_levels(1)
.array_layers(1)
.samples(vk::SampleCountFlags::TYPE_1)
.tiling(vk::ImageTiling::OPTIMAL)
.usage(vk::ImageUsageFlags::DEPTH_STENCIL_ATTACHMENT)
2018-12-08 04:47:57 +11:00
.sharing_mode(vk::SharingMode::EXCLUSIVE);
2016-12-28 19:24:24 +11:00
let depth_image = device.create_image(&depth_image_create_info, None).unwrap();
2016-12-26 00:38:26 +11:00
let depth_image_memory_req = device.get_image_memory_requirements(depth_image);
2018-08-03 05:22:46 +10:00
let depth_image_memory_index = find_memorytype_index(
&depth_image_memory_req,
&device_memory_properties,
vk::MemoryPropertyFlags::DEVICE_LOCAL,
2018-12-08 04:47:57 +11:00
)
.expect("Unable to find suitable memory index for depth image.");
2016-12-26 00:38:26 +11:00
let depth_image_allocate_info = vk::MemoryAllocateInfo::default()
.allocation_size(depth_image_memory_req.size)
2018-12-10 06:35:48 +11:00
.memory_type_index(depth_image_memory_index);
2017-12-13 00:25:10 +11:00
let depth_image_memory = device
.allocate_memory(&depth_image_allocate_info, None)
2016-12-28 19:24:24 +11:00
.unwrap();
2017-12-13 00:25:10 +11:00
device
.bind_image_memory(depth_image, depth_image_memory, 0)
2016-12-26 00:38:26 +11:00
.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.");
2017-12-13 00:25:10 +11:00
record_submit_commandbuffer(
&device,
setup_command_buffer,
setup_commands_reuse_fence,
2017-12-13 00:25:10 +11:00
present_queue,
&[],
2017-12-13 00:25:10 +11:00
&[],
&[],
|device, setup_command_buffer| {
let layout_transition_barriers = vk::ImageMemoryBarrier::default()
2018-12-10 06:41:23 +11:00
.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()
2018-12-10 06:41:23 +11:00
.aspect_mask(vk::ImageAspectFlags::DEPTH)
.layer_count(1)
.level_count(1),
2018-12-10 07:33:21 +11:00
);
2017-12-13 00:25:10 +11:00
device.cmd_pipeline_barrier(
setup_command_buffer,
2018-07-31 20:45:29 +10:00
vk::PipelineStageFlags::BOTTOM_OF_PIPE,
vk::PipelineStageFlags::LATE_FRAGMENT_TESTS,
2017-12-13 00:25:10 +11:00
vk::DependencyFlags::empty(),
&[],
&[],
&[layout_transition_barriers],
2017-12-13 00:25:10 +11:00
);
},
);
let depth_image_view_info = vk::ImageViewCreateInfo::default()
.subresource_range(
vk::ImageSubresourceRange::default()
.aspect_mask(vk::ImageAspectFlags::DEPTH)
.level_count(1)
.layer_count(1),
2018-12-10 01:01:13 +11:00
)
.image(depth_image)
.format(depth_image_create_info.format)
2018-12-10 06:35:48 +11:00
.view_type(vk::ImageViewType::TYPE_2D);
2017-12-13 00:25:10 +11:00
let depth_image_view = device
.create_image_view(&depth_image_view_info, None)
.unwrap();
let semaphore_create_info = vk::SemaphoreCreateInfo::default();
2017-12-13 00:25:10 +11:00
let present_complete_semaphore = device
.create_semaphore(&semaphore_create_info, None)
2016-12-26 00:38:26 +11:00
.unwrap();
2017-12-13 00:25:10 +11:00
let rendering_complete_semaphore = device
.create_semaphore(&semaphore_create_info, None)
2016-12-26 00:38:26 +11:00
.unwrap();
2016-12-26 00:38:26 +11:00
ExampleBase {
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,
2016-12-26 00:38:26 +11:00
}
}
}
}
2017-01-01 18:09:51 +11:00
2016-12-26 00:38:26 +11:00
impl Drop for ExampleBase {
fn drop(&mut self) {
unsafe {
self.device.device_wait_idle().unwrap();
2017-12-13 00:25:10 +11:00
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);
2016-12-28 19:24:24 +11:00
self.device.destroy_image_view(self.depth_image_view, None);
self.device.destroy_image(self.depth_image, None);
2016-12-26 00:38:26 +11:00
for &image_view in self.present_image_views.iter() {
2016-12-28 19:24:24 +11:00
self.device.destroy_image_view(image_view, None);
2016-12-26 00:38:26 +11:00
}
2016-12-28 19:24:24 +11:00
self.device.destroy_command_pool(self.pool, None);
2017-12-13 00:25:10 +11:00
self.swapchain_loader
2018-12-05 07:22:03 +11:00
.destroy_swapchain(self.swapchain, None);
2016-12-28 19:24:24 +11:00
self.device.destroy_device(None);
2018-12-05 07:22:03 +11:00
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);
2016-12-26 00:38:26 +11:00
}
}
}