Vendor things
This commit is contained in:
parent
5deceec006
commit
977e3c17e5
19434 changed files with 10682014 additions and 0 deletions
440
third-party/vendor/gpu-allocator/examples/vulkan-visualization/main.rs
vendored
Normal file
440
third-party/vendor/gpu-allocator/examples/vulkan-visualization/main.rs
vendored
Normal file
|
|
@ -0,0 +1,440 @@
|
|||
use std::default::Default;
|
||||
use std::ffi::CString;
|
||||
|
||||
use ash::vk;
|
||||
use gpu_allocator::vulkan::{Allocator, AllocatorCreateDesc};
|
||||
use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle};
|
||||
|
||||
mod imgui_renderer;
|
||||
use imgui_renderer::{handle_imgui_event, ImGuiRenderer};
|
||||
|
||||
mod helper;
|
||||
use helper::record_and_submit_command_buffer;
|
||||
|
||||
fn main() -> ash::prelude::VkResult<()> {
|
||||
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("trace")).init();
|
||||
|
||||
let entry = unsafe { ash::Entry::load() }.unwrap();
|
||||
|
||||
let event_loop = winit::event_loop::EventLoop::new();
|
||||
|
||||
let window_width = 1920;
|
||||
let window_height = 1080;
|
||||
let window = winit::window::WindowBuilder::new()
|
||||
.with_title("gpu-allocator Vulkan visualization")
|
||||
.with_inner_size(winit::dpi::PhysicalSize::new(
|
||||
window_width as f64,
|
||||
window_height as f64,
|
||||
))
|
||||
.with_resizable(false)
|
||||
.build(&event_loop)
|
||||
.unwrap();
|
||||
|
||||
// Create Vulkan instance
|
||||
let instance = {
|
||||
let app_name = CString::new("gpu-allocator examples vulkan-visualization").unwrap();
|
||||
|
||||
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));
|
||||
|
||||
let layer_names: &[CString] = &[CString::new("VK_LAYER_KHRONOS_validation").unwrap()];
|
||||
let layers_names_raw: Vec<*const i8> = layer_names
|
||||
.iter()
|
||||
.map(|raw_name| raw_name.as_ptr())
|
||||
.collect();
|
||||
|
||||
let surface_extensions =
|
||||
ash_window::enumerate_required_extensions(event_loop.raw_display_handle()).unwrap();
|
||||
|
||||
let create_info = vk::InstanceCreateInfo::builder()
|
||||
.application_info(&appinfo)
|
||||
.enabled_layer_names(&layers_names_raw)
|
||||
.enabled_extension_names(surface_extensions);
|
||||
|
||||
unsafe {
|
||||
entry
|
||||
.create_instance(&create_info, None)
|
||||
.expect("Instance creation error")
|
||||
}
|
||||
};
|
||||
|
||||
let surface = unsafe {
|
||||
ash_window::create_surface(
|
||||
&entry,
|
||||
&instance,
|
||||
window.raw_display_handle(),
|
||||
window.raw_window_handle(),
|
||||
None,
|
||||
)
|
||||
}
|
||||
.unwrap();
|
||||
let surface_loader = ash::extensions::khr::Surface::new(&entry, &instance);
|
||||
|
||||
// Look for Vulkan physical device
|
||||
let (pdevice, queue_family_index) = {
|
||||
let pdevices = unsafe {
|
||||
instance
|
||||
.enumerate_physical_devices()
|
||||
.expect("Physical device error")
|
||||
};
|
||||
pdevices
|
||||
.iter()
|
||||
.find_map(|pdevice| {
|
||||
unsafe { instance.get_physical_device_queue_family_properties(*pdevice) }
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find_map(|(index, &info)| {
|
||||
let supports_graphics = info.queue_flags.contains(vk::QueueFlags::GRAPHICS);
|
||||
let supports_surface = unsafe {
|
||||
surface_loader.get_physical_device_surface_support(
|
||||
*pdevice,
|
||||
index as u32,
|
||||
surface,
|
||||
)
|
||||
}
|
||||
.unwrap();
|
||||
if supports_graphics && supports_surface {
|
||||
Some((*pdevice, index))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
})
|
||||
.expect("Couldn't find suitable device.")
|
||||
};
|
||||
|
||||
// Create Vulkan device
|
||||
let device = {
|
||||
let device_extension_names_raw = [ash::extensions::khr::Swapchain::name().as_ptr()];
|
||||
let features = vk::PhysicalDeviceFeatures {
|
||||
shader_clip_distance: 1,
|
||||
..Default::default()
|
||||
};
|
||||
let priorities = [1.0];
|
||||
|
||||
let queue_info = vk::DeviceQueueCreateInfo::builder()
|
||||
.queue_family_index(queue_family_index as u32)
|
||||
.queue_priorities(&priorities);
|
||||
|
||||
let create_info = vk::DeviceCreateInfo::builder()
|
||||
.queue_create_infos(std::slice::from_ref(&queue_info))
|
||||
.enabled_extension_names(&device_extension_names_raw)
|
||||
.enabled_features(&features);
|
||||
|
||||
unsafe { instance.create_device(pdevice, &create_info, None) }.unwrap()
|
||||
};
|
||||
|
||||
let present_queue = unsafe { device.get_device_queue(queue_family_index as u32, 0) };
|
||||
|
||||
let surface_format =
|
||||
unsafe { surface_loader.get_physical_device_surface_formats(pdevice, surface) }.unwrap()[0];
|
||||
let surface_capabilities =
|
||||
unsafe { 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 {
|
||||
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 =
|
||||
unsafe { 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 = ash::extensions::khr::Swapchain::new(&instance, &device);
|
||||
|
||||
let swapchain_create_info = vk::SwapchainCreateInfoKHR::builder()
|
||||
.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 =
|
||||
unsafe { swapchain_loader.create_swapchain(&swapchain_create_info, None) }.unwrap();
|
||||
|
||||
let pool_create_info = vk::CommandPoolCreateInfo::builder()
|
||||
.flags(vk::CommandPoolCreateFlags::RESET_COMMAND_BUFFER)
|
||||
.queue_family_index(queue_family_index as u32);
|
||||
let command_pool = unsafe { device.create_command_pool(&pool_create_info, None) }.unwrap();
|
||||
|
||||
let command_buffer_allocate_info = vk::CommandBufferAllocateInfo::builder()
|
||||
.command_buffer_count(2)
|
||||
.command_pool(command_pool)
|
||||
.level(vk::CommandBufferLevel::PRIMARY);
|
||||
|
||||
let command_buffers =
|
||||
unsafe { 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 = unsafe { swapchain_loader.get_swapchain_images(swapchain) }.unwrap();
|
||||
let mut present_image_views = present_images
|
||||
.iter()
|
||||
.map(|&image| {
|
||||
let create_view_info = vk::ImageViewCreateInfo::builder()
|
||||
.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 { device.create_image_view(&create_view_info, None) }.unwrap()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// Setting up the allocator
|
||||
let mut allocator = Some(
|
||||
Allocator::new(&AllocatorCreateDesc {
|
||||
instance: instance.clone(),
|
||||
device: device.clone(),
|
||||
physical_device: pdevice,
|
||||
debug_settings: Default::default(),
|
||||
buffer_device_address: false,
|
||||
})
|
||||
.unwrap(),
|
||||
);
|
||||
|
||||
let fence_create_info = vk::FenceCreateInfo::builder().flags(vk::FenceCreateFlags::SIGNALED);
|
||||
let draw_commands_reuse_fence =
|
||||
unsafe { device.create_fence(&fence_create_info, None) }.unwrap();
|
||||
let setup_commands_reuse_fence =
|
||||
unsafe { device.create_fence(&fence_create_info, None) }.unwrap();
|
||||
|
||||
let semaphore_create_info = vk::SemaphoreCreateInfo::default();
|
||||
|
||||
let present_complete_semaphore =
|
||||
unsafe { device.create_semaphore(&semaphore_create_info, None) }.unwrap();
|
||||
let rendering_complete_semaphore =
|
||||
unsafe { device.create_semaphore(&semaphore_create_info, None) }.unwrap();
|
||||
|
||||
let mut imgui = imgui::Context::create();
|
||||
imgui.io_mut().display_size = [window_width as f32, window_height as f32];
|
||||
|
||||
let descriptor_pool = {
|
||||
let pool_sizes = [
|
||||
vk::DescriptorPoolSize {
|
||||
ty: vk::DescriptorType::UNIFORM_BUFFER,
|
||||
descriptor_count: 1,
|
||||
},
|
||||
vk::DescriptorPoolSize {
|
||||
ty: vk::DescriptorType::SAMPLED_IMAGE,
|
||||
descriptor_count: 1,
|
||||
},
|
||||
vk::DescriptorPoolSize {
|
||||
ty: vk::DescriptorType::SAMPLER,
|
||||
descriptor_count: 1,
|
||||
},
|
||||
];
|
||||
let create_info = vk::DescriptorPoolCreateInfo::builder()
|
||||
.max_sets(1)
|
||||
.pool_sizes(&pool_sizes);
|
||||
unsafe { device.create_descriptor_pool(&create_info, None) }?
|
||||
};
|
||||
|
||||
let mut imgui_renderer = Some(ImGuiRenderer::new(
|
||||
&mut imgui,
|
||||
&device,
|
||||
descriptor_pool,
|
||||
surface_format.format,
|
||||
allocator.as_mut().unwrap(),
|
||||
setup_command_buffer,
|
||||
setup_commands_reuse_fence,
|
||||
present_queue,
|
||||
)?);
|
||||
|
||||
let mut framebuffers = present_image_views
|
||||
.iter()
|
||||
.map(|&view| {
|
||||
let create_info = vk::FramebufferCreateInfo::builder()
|
||||
.render_pass(imgui_renderer.as_ref().unwrap().render_pass)
|
||||
.attachments(std::slice::from_ref(&view))
|
||||
.width(window_width)
|
||||
.height(window_height)
|
||||
.layers(1);
|
||||
|
||||
unsafe { device.create_framebuffer(&create_info, None) }.unwrap()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let mut visualizer = Some(gpu_allocator::vulkan::AllocatorVisualizer::new());
|
||||
|
||||
event_loop.run(move |event, _, control_flow| {
|
||||
*control_flow = winit::event_loop::ControlFlow::Wait;
|
||||
|
||||
handle_imgui_event(imgui.io_mut(), &window, &event);
|
||||
|
||||
let mut ready_for_rendering = false;
|
||||
match event {
|
||||
winit::event::Event::WindowEvent { event, .. } => match event {
|
||||
winit::event::WindowEvent::CloseRequested
|
||||
| winit::event::WindowEvent::KeyboardInput {
|
||||
input:
|
||||
winit::event::KeyboardInput {
|
||||
virtual_keycode: Some(winit::event::VirtualKeyCode::Escape),
|
||||
..
|
||||
},
|
||||
..
|
||||
} => {
|
||||
*control_flow = winit::event_loop::ControlFlow::Exit;
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
winit::event::Event::MainEventsCleared => ready_for_rendering = true,
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if ready_for_rendering {
|
||||
let (present_index, _) = unsafe {
|
||||
swapchain_loader.acquire_next_image(
|
||||
swapchain,
|
||||
u64::MAX,
|
||||
present_complete_semaphore,
|
||||
vk::Fence::null(),
|
||||
)
|
||||
}
|
||||
.unwrap();
|
||||
|
||||
// Start ImGui frame
|
||||
let ui = imgui.frame();
|
||||
|
||||
// Submit visualizer ImGui commands
|
||||
visualizer
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.render(allocator.as_ref().unwrap(), ui, None);
|
||||
|
||||
// Finish ImGui Frame
|
||||
let imgui_draw_data = imgui.render();
|
||||
|
||||
record_and_submit_command_buffer(
|
||||
&device,
|
||||
draw_command_buffer,
|
||||
draw_commands_reuse_fence,
|
||||
present_queue,
|
||||
&[vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT],
|
||||
&[present_complete_semaphore],
|
||||
&[rendering_complete_semaphore],
|
||||
|device, cmd| {
|
||||
// Render ImGui to swapchain image
|
||||
imgui_renderer.as_mut().unwrap().render(
|
||||
imgui_draw_data,
|
||||
device,
|
||||
window_width,
|
||||
window_height,
|
||||
framebuffers[present_index as usize],
|
||||
cmd,
|
||||
);
|
||||
|
||||
// Transition swapchain image to present state
|
||||
let image_barriers = vk::ImageMemoryBarrier::builder()
|
||||
.src_access_mask(
|
||||
vk::AccessFlags::COLOR_ATTACHMENT_READ
|
||||
| vk::AccessFlags::COLOR_ATTACHMENT_WRITE,
|
||||
)
|
||||
.old_layout(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL)
|
||||
.new_layout(vk::ImageLayout::PRESENT_SRC_KHR)
|
||||
.image(present_images[present_index as usize])
|
||||
.subresource_range(vk::ImageSubresourceRange {
|
||||
aspect_mask: vk::ImageAspectFlags::COLOR,
|
||||
base_mip_level: 0,
|
||||
level_count: vk::REMAINING_MIP_LEVELS,
|
||||
base_array_layer: 0,
|
||||
layer_count: vk::REMAINING_ARRAY_LAYERS,
|
||||
});
|
||||
unsafe {
|
||||
device.cmd_pipeline_barrier(
|
||||
cmd,
|
||||
vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT,
|
||||
vk::PipelineStageFlags::BOTTOM_OF_PIPE,
|
||||
vk::DependencyFlags::empty(),
|
||||
&[],
|
||||
&[],
|
||||
std::slice::from_ref(&image_barriers),
|
||||
)
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
let present_create_info = vk::PresentInfoKHR::builder()
|
||||
.wait_semaphores(std::slice::from_ref(&rendering_complete_semaphore))
|
||||
.swapchains(std::slice::from_ref(&swapchain))
|
||||
.image_indices(std::slice::from_ref(&present_index));
|
||||
|
||||
unsafe { swapchain_loader.queue_present(present_queue, &present_create_info) }.unwrap();
|
||||
} else if *control_flow == winit::event_loop::ControlFlow::Exit {
|
||||
unsafe { device.queue_wait_idle(present_queue) }.unwrap();
|
||||
|
||||
visualizer.take();
|
||||
|
||||
for fb in framebuffers.drain(..) {
|
||||
unsafe { device.destroy_framebuffer(fb, None) };
|
||||
}
|
||||
|
||||
let mut allocator = allocator.take().unwrap();
|
||||
|
||||
imgui_renderer
|
||||
.take()
|
||||
.unwrap()
|
||||
.destroy(&device, &mut allocator);
|
||||
|
||||
unsafe { device.destroy_descriptor_pool(descriptor_pool, None) };
|
||||
unsafe { device.destroy_semaphore(rendering_complete_semaphore, None) };
|
||||
unsafe { device.destroy_semaphore(present_complete_semaphore, None) };
|
||||
unsafe { device.destroy_fence(setup_commands_reuse_fence, None) };
|
||||
unsafe { device.destroy_fence(draw_commands_reuse_fence, None) };
|
||||
drop(allocator);
|
||||
for view in present_image_views.drain(..) {
|
||||
unsafe { device.destroy_image_view(view, None) };
|
||||
}
|
||||
unsafe { device.free_command_buffers(command_pool, &command_buffers) };
|
||||
unsafe { device.destroy_command_pool(command_pool, None) };
|
||||
unsafe { swapchain_loader.destroy_swapchain(swapchain, None) };
|
||||
unsafe { device.destroy_device(None) };
|
||||
unsafe {
|
||||
surface_loader.destroy_surface(surface, None);
|
||||
}
|
||||
unsafe { instance.destroy_instance(None) };
|
||||
}
|
||||
});
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue