Skip to content

Instantly share code, notes, and snippets.

@kulicuu
Last active November 4, 2021 15:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kulicuu/cc6abc15864d71312a4bd275b8b9b62d to your computer and use it in GitHub Desktop.
Save kulicuu/cc6abc15864d71312a4bd275b8b9b62d to your computer and use it in GitHub Desktop.
map_memory segmentation fault in Vulkan
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);
}
}
@kulicuu
Copy link
Author

kulicuu commented Nov 3, 2021

Trying to figure out why this causes a segmentation fault.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment