diff options
Diffstat (limited to 'third_party/rust/gpu-allocator/examples/vulkan-buffer.rs')
-rw-r--r-- | third_party/rust/gpu-allocator/examples/vulkan-buffer.rs | 202 |
1 files changed, 202 insertions, 0 deletions
diff --git a/third_party/rust/gpu-allocator/examples/vulkan-buffer.rs b/third_party/rust/gpu-allocator/examples/vulkan-buffer.rs new file mode 100644 index 0000000000..6900717403 --- /dev/null +++ b/third_party/rust/gpu-allocator/examples/vulkan-buffer.rs @@ -0,0 +1,202 @@ +use std::default::Default; +use std::ffi::CStr; + +use ash::vk; +use log::info; + +use gpu_allocator::vulkan::{ + AllocationCreateDesc, AllocationScheme, Allocator, AllocatorCreateDesc, +}; +use gpu_allocator::MemoryLocation; + +fn main() { + env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("trace")).init(); + + let entry = unsafe { ash::Entry::load() }.unwrap(); + + // Create Vulkan instance + let instance = { + let app_name = CStr::from_bytes_with_nul(b"Vulkan gpu-allocator test\0").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_raw = [CStr::from_bytes_with_nul(b"VK_LAYER_KHRONOS_validation\0") + .unwrap() + .as_ptr()]; + + let create_info = vk::InstanceCreateInfo::builder() + .application_info(&appinfo) + .enabled_layer_names(&layer_names_raw); + + unsafe { + entry + .create_instance(&create_info, None) + .expect("Instance creation error") + } + }; + + // 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); + if supports_graphics { + Some((*pdevice, index)) + } else { + None + } + }) + }) + .expect("Couldn't find suitable device.") + }; + + // Create vulkan device + let device = { + let device_extension_names_raw = vec![]; + 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() } + }; + + // Setting up the allocator + let mut allocator = Allocator::new(&AllocatorCreateDesc { + instance: instance.clone(), + device: device.clone(), + physical_device: pdevice, + debug_settings: Default::default(), + buffer_device_address: false, + allocation_sizes: Default::default(), + }) + .unwrap(); + + // Test allocating Gpu Only memory + { + let test_buffer_info = vk::BufferCreateInfo::builder() + .size(512) + .usage(vk::BufferUsageFlags::STORAGE_BUFFER) + .sharing_mode(vk::SharingMode::EXCLUSIVE); + let test_buffer = unsafe { device.create_buffer(&test_buffer_info, None) }.unwrap(); + let requirements = unsafe { device.get_buffer_memory_requirements(test_buffer) }; + let location = MemoryLocation::GpuOnly; + + let allocation = allocator + .allocate(&AllocationCreateDesc { + requirements, + location, + linear: true, + allocation_scheme: AllocationScheme::GpuAllocatorManaged, + name: "Test allocation (Gpu Only)", + }) + .unwrap(); + + unsafe { + device + .bind_buffer_memory(test_buffer, allocation.memory(), allocation.offset()) + .unwrap() + }; + + allocator.free(allocation).unwrap(); + + unsafe { device.destroy_buffer(test_buffer, None) }; + + info!("Allocation and deallocation of GpuOnly memory was successful."); + } + + // Test allocating Cpu to Gpu memory + { + let test_buffer_info = vk::BufferCreateInfo::builder() + .size(512) + .usage(vk::BufferUsageFlags::STORAGE_BUFFER) + .sharing_mode(vk::SharingMode::EXCLUSIVE); + let test_buffer = unsafe { device.create_buffer(&test_buffer_info, None) }.unwrap(); + let requirements = unsafe { device.get_buffer_memory_requirements(test_buffer) }; + let location = MemoryLocation::CpuToGpu; + + let allocation = allocator + .allocate(&AllocationCreateDesc { + requirements, + location, + linear: true, + allocation_scheme: AllocationScheme::GpuAllocatorManaged, + name: "Test allocation (Cpu to Gpu)", + }) + .unwrap(); + + unsafe { + device + .bind_buffer_memory(test_buffer, allocation.memory(), allocation.offset()) + .unwrap() + }; + + allocator.free(allocation).unwrap(); + + unsafe { device.destroy_buffer(test_buffer, None) }; + + info!("Allocation and deallocation of CpuToGpu memory was successful."); + } + + // Test allocating Gpu to Cpu memory + { + let test_buffer_info = vk::BufferCreateInfo::builder() + .size(512) + .usage(vk::BufferUsageFlags::STORAGE_BUFFER) + .sharing_mode(vk::SharingMode::EXCLUSIVE); + let test_buffer = unsafe { device.create_buffer(&test_buffer_info, None) }.unwrap(); + let requirements = unsafe { device.get_buffer_memory_requirements(test_buffer) }; + let location = MemoryLocation::GpuToCpu; + + let allocation = allocator + .allocate(&AllocationCreateDesc { + requirements, + location, + linear: true, + allocation_scheme: AllocationScheme::GpuAllocatorManaged, + name: "Test allocation (Gpu to Cpu)", + }) + .unwrap(); + + unsafe { + device + .bind_buffer_memory(test_buffer, allocation.memory(), allocation.offset()) + .unwrap() + }; + + allocator.free(allocation).unwrap(); + + unsafe { device.destroy_buffer(test_buffer, None) }; + + info!("Allocation and deallocation of GpuToCpu memory was successful."); + } + + drop(allocator); // Explicitly drop before destruction of device and instance. + unsafe { device.destroy_device(None) }; + unsafe { instance.destroy_instance(None) }; +} |