Last active
November 4, 2021 15:10
-
-
Save kulicuu/cc6abc15864d71312a4bd275b8b9b62d to your computer and use it in GitHub Desktop.
map_memory segmentation fault in Vulkan
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use memoffset::offset_of; | |
use simple_logger::SimpleLogger; | |
use winit::{ | |
event::{ | |
Event, KeyboardInput, WindowEvent, | |
ElementState, StartCause, VirtualKeyCode | |
}, | |
event_loop::{ControlFlow, EventLoop}, | |
window::WindowBuilder, | |
window::Window | |
}; | |
// use winit::event::{ElementState, StartCause, VirtualKeyCode}; | |
use structopt::StructOpt; | |
use erupt::{ | |
cstr, | |
utils::{self, surface}, | |
vk, DeviceLoader, EntryLoader, InstanceLoader, | |
}; | |
use std::{ | |
ffi::{c_void, CStr, CString}, | |
mem::*, | |
os::raw::c_char, | |
ptr, | |
result::Result, | |
result::Result::*, | |
string::String, | |
thread, | |
time, | |
}; | |
use raw_window_handle::{HasRawWindowHandle, RawWindowHandle}; | |
const TITLE: &str = "Peregrine Ray-Trace"; | |
const FRAMES_IN_FLIGHT: usize = 2; | |
const LAYER_KHRONOS_VALIDATION: *const c_char = cstr!("VK_LAYER_KHRONOS_validation"); | |
#[derive(Debug, StructOpt)] | |
struct Opt { | |
/// Use validation layers | |
#[structopt(short, long)] | |
validation_layers: bool, | |
} | |
unsafe extern "system" fn debug_callback( | |
_message_severity: vk::DebugUtilsMessageSeverityFlagBitsEXT, | |
_message_types: vk::DebugUtilsMessageTypeFlagsEXT, | |
p_callback_data: *const vk::DebugUtilsMessengerCallbackDataEXT, | |
_p_user_data: *mut c_void, | |
) -> vk::Bool32 { | |
eprintln!( | |
"Vulkan: {}", | |
CStr::from_ptr((*p_callback_data).p_message).to_string_lossy() | |
); | |
vk::FALSE | |
} | |
#[repr(C)] | |
#[derive(Debug, Clone, Copy)] | |
struct VertexV3 { | |
pos: [f32; 4], | |
color: [f32; 4], | |
} | |
impl VertexV3 { | |
fn get_binding_descriptions() -> [vk::VertexInputBindingDescription; 1] { | |
[vk::VertexInputBindingDescription { | |
binding: 0, | |
stride: std::mem::size_of::<Self>() as u32, | |
input_rate: vk::VertexInputRate::VERTEX, | |
}] | |
} | |
pub fn get_attribute_descriptions() -> [vk::VertexInputAttributeDescription; 2] { | |
[ | |
vk::VertexInputAttributeDescription { | |
binding: 0, | |
location: 0, | |
format: vk::Format::R32G32B32A32_SFLOAT, | |
offset: offset_of!(Self, pos) as u32, | |
}, | |
vk::VertexInputAttributeDescription { | |
binding: 0, | |
location: 1, | |
format: vk::Format::R32G32B32A32_SFLOAT, | |
offset: offset_of!(Self, color) as u32, | |
}, | |
] | |
} | |
} | |
fn main() { | |
println!("Ray-Peregrine Lab 24::::!!!!"); | |
let mut vulkan_output = String::from(""); | |
println!("Ray-EE-Oct-12"); | |
let event_loop = EventLoop::new(); | |
let window = WindowBuilder::new() | |
.with_title("Peregrine Ray-Trace") | |
.build(&event_loop) | |
.unwrap(); | |
let entry = EntryLoader::new().unwrap(); | |
// https://vulkan-tutorial.com/Drawing_a_triangle/Setup/Instance | |
let application_name = CString::new("Peregrine Ray-Trace").unwrap(); | |
let engine_name = CString::new("Vulkan Engine").unwrap(); | |
let app_info = vk::ApplicationInfoBuilder::new() | |
.application_name(&application_name) | |
.application_version(vk::make_api_version(0, 1, 0, 0)) | |
.engine_name(&engine_name) | |
.engine_version(vk::make_api_version(0, 1, 0, 0)) | |
.api_version(vk::make_api_version(0, 1, 0, 0)); | |
let mut instance_extensions = surface::enumerate_required_extensions(&window).unwrap(); | |
instance_extensions.push(vk::EXT_DEBUG_UTILS_EXTENSION_NAME); | |
let mut instance_layers = Vec::new(); | |
instance_layers.push(LAYER_KHRONOS_VALIDATION); | |
let device_extensions = vec![ | |
vk::KHR_SWAPCHAIN_EXTENSION_NAME, | |
vk::KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, | |
vk::KHR_RAY_QUERY_EXTENSION_NAME, | |
vk::KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME, | |
vk::KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, | |
vk::KHR_SPIRV_1_4_EXTENSION_NAME, | |
]; | |
let mut device_layers = Vec::new(); | |
device_layers.push(LAYER_KHRONOS_VALIDATION); | |
let instance_info = vk::InstanceCreateInfoBuilder::new() | |
.application_info(&app_info) | |
.enabled_extension_names(&instance_extensions) | |
.enabled_layer_names(&instance_layers); | |
let instance = unsafe { InstanceLoader::new(&entry, &instance_info, None) }.unwrap(); | |
// https://vulkan-tutorial.com/Drawing_a_triangle/Setup/Validation_layers | |
// if opt.validation_layers ... | |
let messenger = { | |
let messenger_info = vk::DebugUtilsMessengerCreateInfoEXTBuilder::new() | |
.message_severity( | |
vk::DebugUtilsMessageSeverityFlagsEXT::VERBOSE_EXT | |
| vk::DebugUtilsMessageSeverityFlagsEXT::WARNING_EXT | |
| vk::DebugUtilsMessageSeverityFlagsEXT::ERROR_EXT, | |
) | |
.message_type( | |
vk::DebugUtilsMessageTypeFlagsEXT::GENERAL_EXT | |
| vk::DebugUtilsMessageTypeFlagsEXT::VALIDATION_EXT | |
| vk::DebugUtilsMessageTypeFlagsEXT::PERFORMANCE_EXT, | |
) | |
.pfn_user_callback(Some(debug_callback)); | |
unsafe { instance.create_debug_utils_messenger_ext(&messenger_info, None) }.unwrap() | |
}; | |
let surface = unsafe { surface::create_surface(&instance, &window, None) }.unwrap(); | |
let (physical_device, queue_family, format, present_mode, device_properties) = | |
unsafe { instance.enumerate_physical_devices(None) } | |
.unwrap() | |
.into_iter() | |
.filter_map(|physical_device| unsafe { | |
// println!("Physical Device: {:?}", physical_device); | |
// println!("Phyisical Device Queue Family Properties: {:?}", instance.get_physical_device_properties(physical_device)); | |
let queue_family = match instance | |
.get_physical_device_queue_family_properties(physical_device, None) | |
.into_iter() | |
.enumerate() | |
.position(|(i, queue_family_properties)| { | |
queue_family_properties | |
.queue_flags | |
.contains(vk::QueueFlags::GRAPHICS) | |
&& instance | |
.get_physical_device_surface_support_khr( | |
physical_device, | |
i as u32, | |
surface, | |
) | |
.unwrap() | |
}) { | |
Some(queue_family) => queue_family as u32, | |
None => return None, | |
}; | |
let formats = instance | |
.get_physical_device_surface_formats_khr(physical_device, surface, None) | |
.unwrap(); | |
let format = match formats | |
.iter() | |
.find(|surface_format| { | |
surface_format.format == vk::Format::B8G8R8A8_SRGB | |
&& surface_format.color_space == vk::ColorSpaceKHR::SRGB_NONLINEAR_KHR | |
}) | |
.or_else(|| formats.get(0)) | |
{ | |
Some(surface_format) => *surface_format, | |
None => return None, | |
}; | |
let present_mode = instance | |
.get_physical_device_surface_present_modes_khr(physical_device, surface, None) | |
.unwrap() | |
.into_iter() | |
.find(|present_mode| present_mode == &vk::PresentModeKHR::MAILBOX_KHR) | |
.unwrap_or(vk::PresentModeKHR::FIFO_KHR); | |
let supported_device_extensions = instance | |
.enumerate_device_extension_properties(physical_device, None, None) | |
.unwrap(); | |
let device_extensions_supported = | |
device_extensions.iter().all(|device_extension| { | |
let device_extension = CStr::from_ptr(*device_extension); | |
supported_device_extensions.iter().any(|properties| { | |
CStr::from_ptr(properties.extension_name.as_ptr()) == device_extension | |
}) | |
}); | |
if !device_extensions_supported { | |
return None; | |
} | |
let device_properties = instance.get_physical_device_properties(physical_device); | |
Some(( | |
physical_device, | |
queue_family, | |
format, | |
present_mode, | |
device_properties, | |
)) | |
}) | |
.max_by_key(|(_, _, _, _, properties)| match properties.device_type { | |
vk::PhysicalDeviceType::DISCRETE_GPU => 2, | |
vk::PhysicalDeviceType::INTEGRATED_GPU => 1, | |
_ => 0, | |
}) | |
.expect("No suitable physical device found"); | |
//end of declaration of enum (physical_device, queue_family, format, present_mode, device_properties) | |
// https://vulkan-tutorial.com/Drawing_a_triangle/Setup/Logical_device_and_queues | |
let queue_info = vec![vk::DeviceQueueCreateInfoBuilder::new() | |
.queue_family_index(queue_family) | |
.queue_priorities(&[1.0])]; | |
let features = vk::PhysicalDeviceFeaturesBuilder::new(); | |
let device_info = vk::DeviceCreateInfoBuilder::new() | |
.queue_create_infos(&queue_info) | |
.enabled_features(&features) | |
.enabled_extension_names(&device_extensions) | |
.enabled_layer_names(&device_layers); | |
let device = | |
unsafe { DeviceLoader::new(&instance, physical_device, &device_info, None) }.unwrap(); | |
// let queue2 = unsafe { device2.get_device_queue(queue_family, 0) }; | |
let queue = unsafe { device.get_device_queue(queue_family, 0) }; | |
println!("\n \n"); | |
let model_path: &'static str = "assets/terrain__002__.obj"; | |
let (models, materials) = tobj::load_obj(&model_path, &tobj::LoadOptions::default()).expect("Failed to load model object!"); | |
let model = models[0].clone(); | |
let materials = materials.unwrap(); | |
let material = materials.clone().into_iter().nth(0).unwrap(); | |
let mut vertices = vec![]; | |
let mut indices = vec![]; | |
let mesh = model.mesh; | |
let total_vertices_count = mesh.positions.len() / 3; | |
for i in 0..total_vertices_count { | |
let vertex = VertexV3 { | |
pos: [ | |
mesh.positions[i * 3], | |
mesh.positions[i * 3 + 1], | |
mesh.positions[i * 3 + 2], | |
1.0, | |
], | |
color: [1.0, 1.0, 1.0, 1.0], | |
}; | |
vertices.push(vertex); | |
}; | |
indices = mesh.indices.clone(); | |
println!("Starting buffer and memory allocation/mapping processes... \n"); | |
let vertex_buffer_size = ::std::mem::size_of_val(&vertices) as vk::DeviceSize; | |
println!("vertex_buffer_size: {:?}", vertex_buffer_size); | |
let physical_device_memory_properties = unsafe { instance.get_physical_device_memory_properties(physical_device) }; | |
println!("\n physical_device_memory_properties: {:?}", physical_device_memory_properties); | |
pretty_print(physical_device_memory_properties); | |
let vertex_buffer_create_info = vk::BufferCreateInfoBuilder::new() | |
.size(vertex_buffer_size * 200) | |
.usage(vk::BufferUsageFlags::VERTEX_BUFFER) | |
.sharing_mode(vk::SharingMode::EXCLUSIVE); | |
println!("\n vertex_buffer_create_info: {:?}", vertex_buffer_create_info); | |
let vertex_buffer = unsafe { | |
device | |
.create_buffer(&vertex_buffer_create_info, None) | |
.expect("Failed to create vertex buffer.") | |
}; | |
let vertex_buffer_memory_reqs = unsafe { | |
device | |
.get_buffer_memory_requirements(vertex_buffer) | |
}; | |
println!("\n vertex_buffer_memory_reqs: {:?}", vertex_buffer_memory_reqs); | |
let vertex_buffer_memory_allocate_info = | |
vk::MemoryAllocateInfoBuilder::new() | |
.allocation_size(vertex_buffer_memory_reqs.size) | |
.memory_type_index(2) | |
.build(); | |
println!("\n vertex_buffer_memory_allocate_info, {:?} \n", vertex_buffer_memory_allocate_info); | |
let vertex_buffer_memory = unsafe { | |
device | |
.allocate_memory(&vertex_buffer_memory_allocate_info, None) | |
.expect("Failed to allocate vertex buffer memory.") | |
}; | |
println!("\n vertex_buffer_memory: {:?} \n", &vertex_buffer_memory); | |
unsafe { device.bind_buffer_memory(vertex_buffer, vertex_buffer_memory, 0) } | |
.expect("Error on bind buffer memory"); | |
unsafe { | |
let mut pointer: *mut std::ffi::c_void = std::ptr::null_mut(); | |
let mut ref1 = &mut pointer; | |
device | |
.map_memory( | |
vertex_buffer_memory, | |
256, | |
vk::WHOLE_SIZE, | |
None, | |
ref1, | |
) | |
.expect("failed to map 333memory."); | |
} | |
} | |
fn pretty_print(stuff: vk::PhysicalDeviceMemoryProperties) { | |
println!("\n pretty_print physical_device_memory_properties: \n"); | |
for memory_type in stuff.memory_types { | |
println!("memory type: {:?}", memory_type); | |
} | |
for heap in stuff.memory_heaps { | |
println!("memory heap: {:?}", heap); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Trying to figure out why this causes a segmentation fault.