mirror of
https://github.com/italicsjenga/portability.git
synced 2024-11-22 23:11:30 +11:00
Merge #108
108: fix overly conservative function pointer retrieval r=kvark a=msiglreith Addresses some parts of https://github.com/gfx-rs/portability/pull/98 Current implementation rejects too agressively which is not required, in most cases the spec defines the returned pointers as undefined. InstanceProcAddr also doesn't correctly retrieve some device proc addresses. CTS looks fine (9 green, 3 unsupported, `dEQP-VK.api.device_init.create_instance_device_intentional_alloc_fail` crashes but seems unrelated) cc @grovesNL Co-authored-by: msiglreith <m.siglreith@gmail.com>
This commit is contained in:
commit
468147d823
|
@ -4,15 +4,15 @@ use hal::{
|
|||
Surface, Swapchain as HalSwapchain, FrameSync,
|
||||
};
|
||||
use hal::buffer::IndexBufferView;
|
||||
use hal::command::RawCommandBuffer;
|
||||
use hal::device::WaitFor;
|
||||
use hal::pool::RawCommandPool;
|
||||
use hal::command::RawCommandBuffer;
|
||||
use hal::queue::RawCommandQueue;
|
||||
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::{mem, ptr};
|
||||
#[cfg(feature = "renderdoc")]
|
||||
use std::os::raw::c_void;
|
||||
use std::{mem, ptr};
|
||||
|
||||
use super::*;
|
||||
|
||||
|
@ -61,7 +61,9 @@ pub extern "C" fn gfxCreateInstance(
|
|||
// Compare major and minor parts of version only - patch is ignored
|
||||
let (supported_major, supported_minor, _) = VERSION;
|
||||
let requested_major_minor = ai.apiVersion >> 12;
|
||||
let version_supported = requested_major_minor & (supported_major << 10 | supported_minor) == requested_major_minor;
|
||||
let version_supported = requested_major_minor
|
||||
& (supported_major << 10 | supported_minor)
|
||||
== requested_major_minor;
|
||||
if !version_supported {
|
||||
return VkResult::VK_ERROR_INCOMPATIBLE_DRIVER;
|
||||
}
|
||||
|
@ -70,13 +72,16 @@ pub extern "C" fn gfxCreateInstance(
|
|||
let enabled_extensions = if create_info.enabledExtensionCount == 0 {
|
||||
Vec::new()
|
||||
} else {
|
||||
let extensions = slice::from_raw_parts(create_info.ppEnabledExtensionNames, create_info.enabledExtensionCount as _)
|
||||
.iter()
|
||||
.map(|raw| CStr::from_ptr(*raw)
|
||||
let extensions = slice::from_raw_parts(
|
||||
create_info.ppEnabledExtensionNames,
|
||||
create_info.enabledExtensionCount as _,
|
||||
).iter()
|
||||
.map(|raw| {
|
||||
CStr::from_ptr(*raw)
|
||||
.to_str()
|
||||
.expect("Invalid extension name")
|
||||
.to_owned()
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
for extension in &extensions {
|
||||
if !INSTANCE_EXTENSION_NAMES.contains(&extension.as_str()) {
|
||||
|
@ -366,43 +371,6 @@ pub extern "C" fn gfxGetInstanceProcAddr(
|
|||
return device_addr;
|
||||
}
|
||||
|
||||
// Required instance
|
||||
match name {
|
||||
"vkEnumerateInstanceVersion" |
|
||||
"vkEnumerateInstanceExtensionProperties" |
|
||||
"vkEnumerateInstanceLayerProperties" |
|
||||
"vkCreateInstance" => {
|
||||
// Instance is not required for these special cases
|
||||
// See https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkGetInstanceProcAddr.html
|
||||
}
|
||||
_ => {
|
||||
if instance.as_ref().is_none() {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Required extensions
|
||||
match name {
|
||||
"vkGetPhysicalDeviceSurfaceSupportKHR" |
|
||||
"vkGetPhysicalDeviceSurfaceCapabilitiesKHR" |
|
||||
"vkGetPhysicalDeviceSurfaceFormatsKHR" |
|
||||
"vkGetPhysicalDeviceSurfacePresentModesKHR" |
|
||||
"vkDestroySurfaceKHR"
|
||||
=> {
|
||||
let surface_extension_enabled = instance
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.enabled_extensions
|
||||
.iter()
|
||||
.any(|e| e == INSTANCE_EXTENSION_NAME_VK_KHR_SURFACE);
|
||||
if !surface_extension_enabled {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
proc_addr!{ name,
|
||||
vkCreateInstance, PFN_vkCreateInstance => gfxCreateInstance,
|
||||
vkDestroyInstance, PFN_vkDestroyInstance => gfxDestroyInstance,
|
||||
|
@ -446,22 +414,16 @@ pub extern "C" fn gfxGetDeviceProcAddr(
|
|||
Err(_) => return None,
|
||||
};
|
||||
|
||||
// Required device
|
||||
if device.as_ref().is_none() {
|
||||
return None;
|
||||
}
|
||||
|
||||
// Required extensions
|
||||
// Requesting the function pointer to an extensions which is available but not
|
||||
// enabled with an valid device requires returning NULL.
|
||||
if let Some(device) = device.as_ref() {
|
||||
match name {
|
||||
"vkCreateSwapchainKHR" |
|
||||
"vkDestroySwapchainKHR" |
|
||||
"vkGetSwapchainImagesKHR" |
|
||||
"vkAcquireNextImageKHR" |
|
||||
"vkQueuePresentKHR"
|
||||
=> {
|
||||
"vkCreateSwapchainKHR"
|
||||
| "vkDestroySwapchainKHR"
|
||||
| "vkGetSwapchainImagesKHR"
|
||||
| "vkAcquireNextImageKHR"
|
||||
| "vkQueuePresentKHR" => {
|
||||
let swapchain_extension_enabled = device
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.enabled_extensions
|
||||
.iter()
|
||||
.any(|e| e == DEVICE_EXTENSION_NAME_VK_KHR_SWAPCHAIN);
|
||||
|
@ -471,6 +433,7 @@ pub extern "C" fn gfxGetDeviceProcAddr(
|
|||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
proc_addr!{ name,
|
||||
vkGetDeviceProcAddr, PFN_vkGetDeviceProcAddr => gfxGetDeviceProcAddr,
|
||||
|
|
Loading…
Reference in a new issue