gpt4 book ai didi

rust - 为什么启用 VK_KHR_SURFACE 会导致 CreateInstance 失败?

转载 作者:行者123 更新时间:2023-11-29 08:24:50 27 4
gpt4 key购买 nike

取消注释第 96 行:

 // extension_names.push(String::from(VK_KHR_SURFACE)); // uncomment to see error

将导致第 121 行的 CreateInstance 失败。

我正在关注 Vulkan tutorial其中提到通过定义 VK_USE_PLATFORM_WIN32_KHR 激活扩展。好吧,我正在使用 vk-sys(我应该使用其他 Rust Vulkan 绑定(bind)吗?),它是 Vulkano 使用的箱子.我搜索了 Vulkano 的存储库,没有提及 VK_USE_PLATFORM_WIN32_KHR。它也不在 vk-sys docs 中.

有没有办法在 Rust 中定义 VK_USE_PLATFORM_WIN32_KHR 还是不需要?或者我还需要做些什么吗?

extern crate shared_library;
extern crate vk_sys as vk;

use std::mem;
use std::os::raw::c_char;
use std::os::raw::c_void;
use std::ptr;
use std::path::Path;

const VK_KHR_SURFACE: &'static str = "VK_KHR_surface\0"; // base surface that all platforms need
const VK_KHR_WIN32_SURFACE: &'static str = "VK_KHR_win32_surface\0";

// https://github.com/vulkano-rs/vulkano/blob/f4f91f7ee1aace3062571bc1f678b702fbd020cd/vulkano/src/instance/loader.rs#L36
pub unsafe trait Loader {
fn get_instance_proc_addr(
&self,
instance: vk::Instance,
name: *const c_char,
) -> extern "system" fn() -> ();
}

// https://github.com/vulkano-rs/vulkano/blob/f4f91f7ee1aace3062571bc1f678b702fbd020cd/vulkano/src/instance/loader.rs#L56
pub struct DynamicLibraryLoader {
vk_lib: shared_library::dynamic_library::DynamicLibrary,
get_proc_addr: extern "system" fn(instance: vk::Instance, pName: *const c_char)
-> extern "system" fn() -> (),
}

// removed error checking
// https://github.com/vulkano-rs/vulkano/blob/71d90e562a63f2a9aee40abaa3b59949e909015d/vulkano/src/instance/loader.rs#L63
impl DynamicLibraryLoader {
pub unsafe fn new<P>(path: P) -> DynamicLibraryLoader
where
P: AsRef<Path>,
{
let vk_lib =
shared_library::dynamic_library::DynamicLibrary::open(Some(path.as_ref())).unwrap();
let get_proc_addr = {
let ptr: *mut c_void = vk_lib.symbol("vkGetInstanceProcAddr").unwrap();
mem::transmute(ptr)
};

DynamicLibraryLoader {
vk_lib,
get_proc_addr,
}
}
}

// https://github.com/vulkano-rs/vulkano/blob/f4f91f7ee1aace3062571bc1f678b702fbd020cd/vulkano/src/instance/loader.rs#L94
unsafe impl Loader for DynamicLibraryLoader {
#[inline]
fn get_instance_proc_addr(
&self,
instance: vk::Instance,
name: *const c_char,
) -> extern "system" fn() -> () {
(self.get_proc_addr)(instance, name)
}
}

// For Windows. For other OS, see:
// https://github.com/vulkano-rs/vulkano/blob/71d90e562a63f2a9aee40abaa3b59949e909015d/vulkano/src/instance/loader.rs#L171
fn get_path() -> &'static Path {
Path::new("vulkan-1.dll")
}

// return codes: https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VkResult
fn check_result(msg: &str, result: vk::Result) {
match result {
vk::SUCCESS => println!("{}: {}", msg, "SUCCESS"),
vk::NOT_READY => println!("{}: {}", msg, "NOT_READY"),
vk::TIMEOUT => println!("{}: {}", msg, "TIMEOUT"),
vk::EVENT_SET => println!("{}: {}", msg, "EVENT_SET"),
vk::EVENT_RESET => println!("{}: {}", msg, "EVENT_RESET"),
vk::INCOMPLETE => println!("{}: {}", msg, "INCOMPLETE"),
vk::ERROR_OUT_OF_HOST_MEMORY => println!("{}: {}", msg, "ERROR_OUT_OF_HOST_MEMORY"),
vk::ERROR_OUT_OF_DEVICE_MEMORY => println!("{}: {}", msg, "ERROR_OUT_OF_DEVICE_MEMORY"),
vk::ERROR_INITIALIZATION_FAILED => println!("{}: {}", msg, "ERROR_INITIALIZATION_FAILED"),
vk::ERROR_DEVICE_LOST => println!("{}: {}", msg, "ERROR_DEVICE_LOST"),
vk::ERROR_MEMORY_MAP_FAILED => println!("{}: {}", msg, "ERROR_MEMORY_MAP_FAILED"),
vk::ERROR_LAYER_NOT_PRESENT => println!("{}: {}", msg, "ERROR_LAYER_NOT_PRESENT"),
vk::ERROR_EXTENSION_NOT_PRESENT => println!("{}: {}", msg, "ERROR_EXTENSION_NOT_PRESENT"),
vk::ERROR_FEATURE_NOT_PRESENT => println!("{}: {}", msg, "ERROR_FEATURE_NOT_PRESENT"),
vk::ERROR_INCOMPATIBLE_DRIVER => println!("{}: {}", msg, "ERROR_INCOMPATIBLE_DRIVER"),
vk::ERROR_TOO_MANY_OBJECTS => println!("{}: {}", msg, "ERROR_TOO_MANY_OBJECTS"),
vk::ERROR_FORMAT_NOT_SUPPORTED => println!("{}: {}", msg, "ERROR_FORMAT_NOT_SUPPORTED"),
// vk::ERROR_FRAGMENTED_POOL => println!("{}: {}", msg, "ERROR_FRAGMENTED_POOL"),
_ => println!("VK_ERR: {:?}", result),
};
}

fn main() {
//********************************************************************************************************** Instance Create Info
let mut extension_names: Vec<String> = Vec::new();
// extension_names.push(String::from(VK_KHR_SURFACE)); // uncomment to see error
extension_names.push(String::from(VK_KHR_WIN32_SURFACE));
println!("extension_names: {:?}", extension_names);

let instance_create_info = vk::InstanceCreateInfo {
sType: vk::STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
pNext: ptr::null(),
flags: 0,
pApplicationInfo: ptr::null(),
enabledLayerCount: 0,
ppEnabledLayerNames: ptr::null(),
enabledExtensionCount: extension_names.len() as u32,
ppEnabledExtensionNames: extension_names.as_ptr() as *const *const i8,
};

//********************************************************************************************************** Instance Creation
let mut instance: vk::Instance = unsafe {mem::uninitialized()};

let loader = unsafe { DynamicLibraryLoader::new(get_path()) };

let entry_points = vk::EntryPoints::load(|name| unsafe {
mem::transmute(loader.get_instance_proc_addr(instance, name.as_ptr()))
});

unsafe {
check_result("create instance", entry_points.CreateInstance(&instance_create_info, ptr::null(), &mut instance));
}
}

cargo .toml:

[dependencies]
vk-sys = "*"
shared_library = "*"

最佳答案

您尝试将 &str 用于 FFI 的方式不起作用。您必须使用 std::ffi::CString。另请查看应如何收集指向 CString 的指针:

extern crate shared_library;
extern crate vk_sys as vk;

use std::mem;
use std::ffi::CString;
use std::os::raw::c_char;
use std::os::raw::c_void;
use std::ptr;
use std::path::Path;

const VK_KHR_SURFACE: &'static str = "VK_KHR_surface"; // base surface that all platforms need
const VK_KHR_WIN32_SURFACE: &'static str = "VK_KHR_win32_surface";

// https://github.com/vulkano-rs/vulkano/blob/f4f91f7ee1aace3062571bc1f678b702fbd020cd/vulkano/src/instance/loader.rs#L36
pub unsafe trait Loader {
fn get_instance_proc_addr(
&self,
instance: vk::Instance,
name: *const c_char,
) -> extern "system" fn() -> ();
}

// https://github.com/vulkano-rs/vulkano/blob/f4f91f7ee1aace3062571bc1f678b702fbd020cd/vulkano/src/instance/loader.rs#L56
pub struct DynamicLibraryLoader {
vk_lib: shared_library::dynamic_library::DynamicLibrary,
get_proc_addr: extern "system" fn(instance: vk::Instance, pName: *const c_char)
-> extern "system" fn() -> (),
}

// removed error checking
// https://github.com/vulkano-rs/vulkano/blob/71d90e562a63f2a9aee40abaa3b59949e909015d/vulkano/src/instance/loader.rs#L63
impl DynamicLibraryLoader {
pub unsafe fn new<P>(path: P) -> DynamicLibraryLoader
where
P: AsRef<Path>,
{
let vk_lib =
shared_library::dynamic_library::DynamicLibrary::open(Some(path.as_ref())).unwrap();
let get_proc_addr = {
let ptr: *mut c_void = vk_lib.symbol("vkGetInstanceProcAddr").unwrap();
mem::transmute(ptr)
};

DynamicLibraryLoader {
vk_lib,
get_proc_addr,
}
}
}

// https://github.com/vulkano-rs/vulkano/blob/f4f91f7ee1aace3062571bc1f678b702fbd020cd/vulkano/src/instance/loader.rs#L94
unsafe impl Loader for DynamicLibraryLoader {
#[inline]
fn get_instance_proc_addr(
&self,
instance: vk::Instance,
name: *const c_char,
) -> extern "system" fn() -> () {
(self.get_proc_addr)(instance, name)
}
}

// For Windows. For other OS, see:
// https://github.com/vulkano-rs/vulkano/blob/71d90e562a63f2a9aee40abaa3b59949e909015d/vulkano/src/instance/loader.rs#L171
fn get_path() -> &'static Path {
Path::new("libvulkan.dylib")
}

// return codes: https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VkResult
fn check_result(msg: &str, result: vk::Result) {
match result {
vk::SUCCESS => println!("{}: {}", msg, "SUCCESS"),
vk::NOT_READY => println!("{}: {}", msg, "NOT_READY"),
vk::TIMEOUT => println!("{}: {}", msg, "TIMEOUT"),
vk::EVENT_SET => println!("{}: {}", msg, "EVENT_SET"),
vk::EVENT_RESET => println!("{}: {}", msg, "EVENT_RESET"),
vk::INCOMPLETE => println!("{}: {}", msg, "INCOMPLETE"),
vk::ERROR_OUT_OF_HOST_MEMORY => println!("{}: {}", msg, "ERROR_OUT_OF_HOST_MEMORY"),
vk::ERROR_OUT_OF_DEVICE_MEMORY => println!("{}: {}", msg, "ERROR_OUT_OF_DEVICE_MEMORY"),
vk::ERROR_INITIALIZATION_FAILED => println!("{}: {}", msg, "ERROR_INITIALIZATION_FAILED"),
vk::ERROR_DEVICE_LOST => println!("{}: {}", msg, "ERROR_DEVICE_LOST"),
vk::ERROR_MEMORY_MAP_FAILED => println!("{}: {}", msg, "ERROR_MEMORY_MAP_FAILED"),
vk::ERROR_LAYER_NOT_PRESENT => println!("{}: {}", msg, "ERROR_LAYER_NOT_PRESENT"),
vk::ERROR_EXTENSION_NOT_PRESENT => println!("{}: {}", msg, "ERROR_EXTENSION_NOT_PRESENT"),
vk::ERROR_FEATURE_NOT_PRESENT => println!("{}: {}", msg, "ERROR_FEATURE_NOT_PRESENT"),
vk::ERROR_INCOMPATIBLE_DRIVER => println!("{}: {}", msg, "ERROR_INCOMPATIBLE_DRIVER"),
vk::ERROR_TOO_MANY_OBJECTS => println!("{}: {}", msg, "ERROR_TOO_MANY_OBJECTS"),
vk::ERROR_FORMAT_NOT_SUPPORTED => println!("{}: {}", msg, "ERROR_FORMAT_NOT_SUPPORTED"),
// vk::ERROR_FRAGMENTED_POOL => println!("{}: {}", msg, "ERROR_FRAGMENTED_POOL"),
_ => println!("VK_ERR: {:?}", result),
};
}

fn main() {
//********************************************************************************************************** Instance Create Info
let mut extension_names: Vec<CString> = Vec::new();
extension_names.push(CString::new(VK_KHR_SURFACE).unwrap()); // uncomment to see error
extension_names.push(CString::new(VK_KHR_WIN32_SURFACE).unwrap());
println!("extension_names: {:?}", extension_names);

let extension_names_ffi = extension_names.iter().map(|ext_name| ext_name.as_ptr() as *const i8).collect::<Vec<_>>();

let instance_create_info = vk::InstanceCreateInfo {
sType: vk::STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
pNext: ptr::null(),
flags: 0,
pApplicationInfo: ptr::null(),
enabledLayerCount: 0,
ppEnabledLayerNames: ptr::null(),
enabledExtensionCount: extension_names.len() as u32,
ppEnabledExtensionNames: extension_names_ffi.as_ptr(),
};

//********************************************************************************************************** Instance Creation
let mut instance: vk::Instance = unsafe {mem::uninitialized()};

let loader = unsafe { DynamicLibraryLoader::new(get_path()) };

let entry_points = vk::EntryPoints::load(|name| unsafe {
mem::transmute(loader.get_instance_proc_addr(instance, name.as_ptr()))
});

unsafe {
check_result("create instance", entry_points.CreateInstance(&instance_create_info, ptr::null(), &mut instance));
}
}

关于rust - 为什么启用 VK_KHR_SURFACE 会导致 CreateInstance 失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52324236/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com