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,
|
Surface, Swapchain as HalSwapchain, FrameSync,
|
||||||
};
|
};
|
||||||
use hal::buffer::IndexBufferView;
|
use hal::buffer::IndexBufferView;
|
||||||
|
use hal::command::RawCommandBuffer;
|
||||||
use hal::device::WaitFor;
|
use hal::device::WaitFor;
|
||||||
use hal::pool::RawCommandPool;
|
use hal::pool::RawCommandPool;
|
||||||
use hal::command::RawCommandBuffer;
|
|
||||||
use hal::queue::RawCommandQueue;
|
use hal::queue::RawCommandQueue;
|
||||||
|
|
||||||
use std::ffi::{CStr, CString};
|
use std::ffi::{CStr, CString};
|
||||||
use std::{mem, ptr};
|
|
||||||
#[cfg(feature = "renderdoc")]
|
#[cfg(feature = "renderdoc")]
|
||||||
use std::os::raw::c_void;
|
use std::os::raw::c_void;
|
||||||
|
use std::{mem, ptr};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
@ -61,7 +61,9 @@ pub extern "C" fn gfxCreateInstance(
|
||||||
// Compare major and minor parts of version only - patch is ignored
|
// Compare major and minor parts of version only - patch is ignored
|
||||||
let (supported_major, supported_minor, _) = VERSION;
|
let (supported_major, supported_minor, _) = VERSION;
|
||||||
let requested_major_minor = ai.apiVersion >> 12;
|
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 {
|
if !version_supported {
|
||||||
return VkResult::VK_ERROR_INCOMPATIBLE_DRIVER;
|
return VkResult::VK_ERROR_INCOMPATIBLE_DRIVER;
|
||||||
}
|
}
|
||||||
|
@ -70,13 +72,16 @@ pub extern "C" fn gfxCreateInstance(
|
||||||
let enabled_extensions = if create_info.enabledExtensionCount == 0 {
|
let enabled_extensions = if create_info.enabledExtensionCount == 0 {
|
||||||
Vec::new()
|
Vec::new()
|
||||||
} else {
|
} else {
|
||||||
let extensions = slice::from_raw_parts(create_info.ppEnabledExtensionNames, create_info.enabledExtensionCount as _)
|
let extensions = slice::from_raw_parts(
|
||||||
.iter()
|
create_info.ppEnabledExtensionNames,
|
||||||
.map(|raw| CStr::from_ptr(*raw)
|
create_info.enabledExtensionCount as _,
|
||||||
|
).iter()
|
||||||
|
.map(|raw| {
|
||||||
|
CStr::from_ptr(*raw)
|
||||||
.to_str()
|
.to_str()
|
||||||
.expect("Invalid extension name")
|
.expect("Invalid extension name")
|
||||||
.to_owned()
|
.to_owned()
|
||||||
)
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
for extension in &extensions {
|
for extension in &extensions {
|
||||||
if !INSTANCE_EXTENSION_NAMES.contains(&extension.as_str()) {
|
if !INSTANCE_EXTENSION_NAMES.contains(&extension.as_str()) {
|
||||||
|
@ -366,43 +371,6 @@ pub extern "C" fn gfxGetInstanceProcAddr(
|
||||||
return device_addr;
|
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,
|
proc_addr!{ name,
|
||||||
vkCreateInstance, PFN_vkCreateInstance => gfxCreateInstance,
|
vkCreateInstance, PFN_vkCreateInstance => gfxCreateInstance,
|
||||||
vkDestroyInstance, PFN_vkDestroyInstance => gfxDestroyInstance,
|
vkDestroyInstance, PFN_vkDestroyInstance => gfxDestroyInstance,
|
||||||
|
@ -446,22 +414,16 @@ pub extern "C" fn gfxGetDeviceProcAddr(
|
||||||
Err(_) => return None,
|
Err(_) => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Required device
|
// Requesting the function pointer to an extensions which is available but not
|
||||||
if device.as_ref().is_none() {
|
// enabled with an valid device requires returning NULL.
|
||||||
return None;
|
if let Some(device) = device.as_ref() {
|
||||||
}
|
|
||||||
|
|
||||||
// Required extensions
|
|
||||||
match name {
|
match name {
|
||||||
"vkCreateSwapchainKHR" |
|
"vkCreateSwapchainKHR"
|
||||||
"vkDestroySwapchainKHR" |
|
| "vkDestroySwapchainKHR"
|
||||||
"vkGetSwapchainImagesKHR" |
|
| "vkGetSwapchainImagesKHR"
|
||||||
"vkAcquireNextImageKHR" |
|
| "vkAcquireNextImageKHR"
|
||||||
"vkQueuePresentKHR"
|
| "vkQueuePresentKHR" => {
|
||||||
=> {
|
|
||||||
let swapchain_extension_enabled = device
|
let swapchain_extension_enabled = device
|
||||||
.as_ref()
|
|
||||||
.unwrap()
|
|
||||||
.enabled_extensions
|
.enabled_extensions
|
||||||
.iter()
|
.iter()
|
||||||
.any(|e| e == DEVICE_EXTENSION_NAME_VK_KHR_SWAPCHAIN);
|
.any(|e| e == DEVICE_EXTENSION_NAME_VK_KHR_SWAPCHAIN);
|
||||||
|
@ -471,6 +433,7 @@ pub extern "C" fn gfxGetDeviceProcAddr(
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
proc_addr!{ name,
|
proc_addr!{ name,
|
||||||
vkGetDeviceProcAddr, PFN_vkGetDeviceProcAddr => gfxGetDeviceProcAddr,
|
vkGetDeviceProcAddr, PFN_vkGetDeviceProcAddr => gfxGetDeviceProcAddr,
|
||||||
|
|
Loading…
Reference in a new issue