Add support for QNX platform.

This commit is contained in:
Mike Gorchak 2021-03-10 22:17:20 -05:00 committed by Lenny Komow
parent 7ea01c139f
commit 684c2a6873
14 changed files with 268 additions and 8 deletions

View File

@ -172,6 +172,7 @@ on/off options currently supported by this repository:
| BUILD_WSI_XLIB_SUPPORT | Linux | `ON` | Build the loader with the Xlib entry points enabled. Without this, the X11 headers should not be needed, but the extension `VK_KHR_xlib_surface` won't be available. |
| BUILD_WSI_WAYLAND_SUPPORT | Linux | `ON` | Build the loader with the Wayland entry points enabled. Without this, the Wayland headers should not be needed, but the extension `VK_KHR_wayland_surface` won't be available. |
| BUILD_WSI_DIRECTFB_SUPPORT | Linux | `OFF` | Build the loader with the DirectFB entry points enabled. Without this, the DirectFB headers should not be needed, but the extension `VK_EXT_directfb_surface` won't be available. |
| BUILD_WSI_SCREEN_SUPPORT | QNX | `OFF` | Build the loader with the QNX Screen entry points enabled. Without this the extension `VK_QNX_screen_surface` won't be available. |
| ENABLE_WIN10_ONECORE | Windows | `OFF` | Link the loader to the [OneCore](https://msdn.microsoft.com/en-us/library/windows/desktop/mt654039.aspx) umbrella library, instead of the standard Win32 ones. |
| USE_CCACHE | Linux | `OFF` | Enable caching with the CCache program. |
| USE_MASM | Windows | `ON` | Controls whether to build assembly files with MS assembler, else fallback to C code |

View File

@ -122,6 +122,7 @@ if(UNIX AND NOT APPLE) # i.e.: Linux
option(BUILD_WSI_XLIB_SUPPORT "Build Xlib WSI support" ON)
option(BUILD_WSI_WAYLAND_SUPPORT "Build Wayland WSI support" ON)
option(BUILD_WSI_DIRECTFB_SUPPORT "Build DirectFB WSI support" OFF)
option(BUILD_WSI_SCREEN_SUPPORT "Build QNX Screen WSI support" OFF)
if(BUILD_WSI_XCB_SUPPORT)
find_package(XCB REQUIRED)
@ -140,6 +141,10 @@ if(UNIX AND NOT APPLE) # i.e.: Linux
find_package(DirectFB REQUIRED)
include_directories(SYSTEM ${DIRECTFB_INCLUDE_DIR})
endif()
if(BUILD_WSI_SCREEN_SUPPORT)
# Part of OS, no additional include directories are required
endif()
endif()
if(WIN32)

44
build-qnx/common.mk Normal file
View File

@ -0,0 +1,44 @@
ifndef QCONFIG
QCONFIG=qconfig.mk
endif
include $(QCONFIG)
define PINFO
PINFO DESCRIPTION = "Vulkan ICD Loader"
endef
ICD_ROOT=$(CURDIR)/../../../..
EXTRA_INCVPATH+=$(ICD_ROOT)/build_qnx
EXTRA_SRCVPATH+=$(ICD_ROOT)/loader
EXTRA_SRCVPATH+=$(ICD_ROOT)/loader/generated
SO_VERSION=1
NAME=vulkan
# Make the library
SRCS = cJSON.c debug_utils.c dev_ext_trampoline.c loader.c murmurhash.c \
phys_dev_ext.c trampoline.c unknown_ext_chain.c wsi.c \
extension_manual.c
LDFLAGS += -Wl,--unresolved-symbols=report-all -Wl,--no-undefined -Wl,-fPIC
include $(MKFILES_ROOT)/qtargets.mk
CCFLAGS += -DVK_USE_PLATFORM_SCREEN_QNX=1 -Dvulkan_EXPORTS
CCFLAGS += -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers
CCFLAGS += -fno-strict-aliasing -fno-builtin-memcmp -Wno-stringop-truncation
CCFLAGS += -Wno-stringop-overflow -Wimplicit-fallthrough=0 -fvisibility=hidden
CCFLAGS += -Wpointer-arith -fPIC
# Enable this if required
# CCFLAGS += -DVK_ENABLE_BETA_EXTENSIONS
CXXFLAGS += $(CCFLAGS)
# cJSON requires math library for pow() function
LIBS += m
INSTALLDIR=usr/lib

View File

@ -0,0 +1,2 @@
#undef HAVE_SECURE_GETENV
#undef HAVE___SECURE_GETENV

View File

@ -57,6 +57,10 @@ elseif(UNIX AND NOT APPLE) # i.e.: Linux
if(BUILD_WSI_DIRECTFB_SUPPORT)
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS VK_USE_PLATFORM_DIRECTFB_EXT)
endif()
if(BUILD_WSI_SCREEN_SUPPORT)
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS VK_USE_PLATFORM_SCREEN_QNX)
endif()
else()
message(FATAL_ERROR "Unsupported Platform!")
endif()
@ -284,6 +288,7 @@ else()
${VulkanHeaders_INCLUDE_DIRS}/vulkan/vulkan_xcb.h
${VulkanHeaders_INCLUDE_DIRS}/vulkan/vulkan_xlib.h
${VulkanHeaders_INCLUDE_DIRS}/vulkan/vulkan_xlib_xrandr.h
${VulkanHeaders_INCLUDE_DIRS}/vulkan/vulkan_screen.h
${VulkanHeaders_INCLUDE_DIRS}/vulkan/vulkan.h
${VulkanHeaders_INCLUDE_DIRS}/vulkan/vulkan.hpp)
if(BUILD_STATIC_LOADER)

View File

@ -697,6 +697,7 @@ target-specific extensions:
| Linux (Wayland) | VK_KHR_wayland_surface |
| Linux (X11) | VK_KHR_xcb_surface and VK_KHR_xlib_surface |
| macOS (MoltenVK) | VK_MVK_macos_surface |
| QNX (Screen) | VK_QNX_screen_surface |
It is important to understand that while the loader may support the various
entry points for these extensions, there is a handshake required to actually
@ -2553,9 +2554,9 @@ vkObj alloc_icd_obj()
### Handling KHR Surface Objects in WSI Extensions
Normally, ICDs handle object creation and destruction for various Vulkan
objects. The WSI surface extensions for Linux, Windows, and macOS
objects. The WSI surface extensions for Linux, Windows, macOS, and QNX
("VK\_KHR\_win32\_surface", "VK\_KHR\_xcb\_surface", "VK\_KHR\_xlib\_surface",
"VK\_KHR\_wayland\_surface", "VK\_MVK\_macos\_surface"
"VK\_KHR\_wayland\_surface", "VK\_MVK\_macos\_surface", "VK\_QNX\_screen\_surface"
and "VK\_KHR\_surface")
are handled differently. For these extensions, the `VkSurfaceKHR` object
creation and destruction may be handled by either the loader or an ICD.
@ -2571,6 +2572,7 @@ If the loader handles the management of the `VkSurfaceKHR` objects:
* Windows
* Android
* MacOS (`vkCreateMacOSSurfaceMVK`)
* QNX (`vkCreateScreenSurfaceQNX`)
2. The loader creates a `VkIcdSurfaceXXX` object for the corresponding
`vkCreateXXXSurfaceKHR` call.
* The `VkIcdSurfaceXXX` structures are defined in `include/vulkan/vk_icd.h`.
@ -2578,7 +2580,7 @@ If the loader handles the management of the `VkSurfaceKHR` objects:
`VkIcdSurfaceXXX` structure.
4. The first field of all the `VkIcdSurfaceXXX` structures is a
`VkIcdSurfaceBase` enumerant that indicates whether the
surface object is Win32, XCB, Xlib, or Wayland.
surface object is Win32, XCB, Xlib, Wayland, or Screen.
The ICD may choose to handle `VkSurfaceKHR` object creation instead. If an ICD
desires to handle creating and destroying it must do the following:

View File

@ -253,7 +253,7 @@ void *loader_device_heap_realloc(const struct loader_device *device, void *pMemo
}
// Environment variables
#if defined(__linux__) || defined(__APPLE__) || defined(__Fuchsia__)
#if defined(__linux__) || defined(__APPLE__) || defined(__Fuchsia__) || defined(__QNXNTO__)
static inline bool IsHighIntegrity() {
return geteuid() != getuid() || getegid() != getgid();
@ -3940,7 +3940,7 @@ static VkResult ReadDataFilesInSearchPaths(const struct loader_instance *inst, e
if (xdgdatadirs == NULL) {
xdgdata_alloc = false;
}
#if !defined(__Fuchsia__)
#if !defined(__Fuchsia__) && !defined(__QNXNTO__)
if (xdgconfdirs == NULL || xdgconfdirs[0] == '\0') {
xdgconfdirs = FALLBACK_CONFIG_DIRS;
}

View File

@ -347,6 +347,9 @@ struct loader_instance {
#endif
#ifdef VK_USE_PLATFORM_FUCHSIA
bool wsi_imagepipe_surface_enabled;
#endif
#ifdef VK_USE_PLATFORM_SCREEN_QNX
bool wsi_screen_surface_enabled;
#endif
bool wsi_display_enabled;
bool wsi_display_props2_enabled;

View File

@ -35,7 +35,7 @@
#include "vulkan/vk_platform.h"
#include "vulkan/vk_sdk_platform.h"
#if defined(__linux__) || defined(__APPLE__) || defined(__Fuchsia__)
#if defined(__linux__) || defined(__APPLE__) || defined(__Fuchsia__) || defined(__QNXNTO__)
/* Linux-specific common code: */
// Headers:
@ -124,7 +124,31 @@ static inline char *loader_platform_executable_path(char *buffer, size_t size) {
}
#elif defined(__Fuchsia__)
static inline char *loader_platform_executable_path(char *buffer, size_t size) { return NULL; }
#endif // defined (__APPLE__)
#elif defined(__QNXNTO__)
#define SYSCONFDIR "/etc"
#include <fcntl.h>
#include <sys/stat.h>
static inline char *loader_platform_executable_path(char *buffer, size_t size) {
int fd = open("/proc/self/exefile", O_RDONLY);
size_t rdsize;
if (fd == -1 ) {
return NULL;
}
rdsize = read(fd, buffer, size);
if (rdsize == size) {
return NULL;
}
buffer[rdsize] = 0x00;
close(fd);
return buffer;
}
#endif // defined (__QNXNTO__)
// Compatability with compilers that don't support __has_feature
#ifndef __has_feature

View File

@ -75,6 +75,9 @@ void wsi_create_instance(struct loader_instance *ptr_instance, const VkInstanceC
#ifdef VK_USE_PLATFORM_METAL_EXT
ptr_instance->wsi_metal_surface_enabled = false;
#endif // VK_USE_PLATFORM_METAL_EXT
#ifdef VK_USE_PLATFORM_SCREEN_QNX
ptr_instance->wsi_screen_surface_enabled = false;
#endif // VK_USE_PLATFORM_SCREEN_QNX
for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SURFACE_EXTENSION_NAME) == 0) {
@ -151,6 +154,12 @@ void wsi_create_instance(struct loader_instance *ptr_instance, const VkInstanceC
continue;
}
#endif
#if defined(VK_USE_PLATFORM_SCREEN_QNX)
if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_QNX_SCREEN_SURFACE_EXTENSION_NAME) == 0) {
ptr_instance->wsi_screen_surface_enabled = true;
continue;
}
#endif // VK_USE_PLATFORM_SCREEN_QNX
if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_DISPLAY_EXTENSION_NAME) == 0) {
ptr_instance->wsi_display_enabled = true;
continue;
@ -184,6 +193,9 @@ bool wsi_unsupported_instance_extension(const VkExtensionProperties *ext_prop) {
#ifndef VK_USE_PLATFORM_DIRECTFB_EXT
if (!strcmp(ext_prop->extensionName, "VK_EXT_directfb_surface")) return true;
#endif // VK_USE_PLATFORM_DIRECTFB_EXT
#ifndef VK_USE_PLATFORM_SCREEN_QNX
if (!strcmp(ext_prop->extensionName, "VK_QNX_screen_surface")) return true;
#endif // VK_USE_PLATFORM_WAYLAND_KHR
return false;
}
@ -1469,6 +1481,120 @@ out:
#endif
#ifdef VK_USE_PLATFORM_SCREEN_QNX
// This is the trampoline entrypoint for CreateScrenSurfaceQNX
LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateScreenSurfaceQNX(VkInstance instance,
const VkScreenSurfaceCreateInfoQNX *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkSurfaceKHR *pSurface) {
const VkLayerInstanceDispatchTable *disp;
disp = loader_get_instance_layer_dispatch(instance);
VkResult res;
res = disp->CreateScreenSurfaceQNX(instance, pCreateInfo, pAllocator, pSurface);
return res;
}
// This is the instance chain terminator function for CreateScreenSurfaceQNX
VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateScreenSurfaceQNX(VkInstance instance,
const VkScreenSurfaceCreateInfoQNX *pCreateInfo,
const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
VkResult vkRes = VK_SUCCESS;
VkIcdSurface *pIcdSurface = NULL;
uint32_t i = 0;
// First, check to ensure the appropriate extension was enabled:
struct loader_instance *ptr_instance = loader_get_instance(instance);
if (!ptr_instance->wsi_screen_surface_enabled) {
loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
"VK_QNX_screen_surface extension not enabled. vkCreateScreenSurfaceQNX not executed!\n");
vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
goto out;
}
// Next, if so, proceed with the implementation of this function:
pIcdSurface = AllocateIcdSurfaceStruct(ptr_instance, sizeof(pIcdSurface->screen_surf.base), sizeof(pIcdSurface->screen_surf));
if (pIcdSurface == NULL) {
vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
goto out;
}
pIcdSurface->screen_surf.base.platform = VK_ICD_WSI_PLATFORM_SCREEN;
pIcdSurface->screen_surf.context = pCreateInfo->context;
pIcdSurface->screen_surf.window = pCreateInfo->window;
// Loop through each ICD and determine if they need to create a surface
for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
if (icd_term->scanned_icd->interface_version >= ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
if (NULL != icd_term->dispatch.CreateScreenSurfaceQNX) {
vkRes = icd_term->dispatch.CreateScreenSurfaceQNX(icd_term->instance, pCreateInfo, pAllocator,
&pIcdSurface->real_icd_surfaces[i]);
if (VK_SUCCESS != vkRes) {
goto out;
}
}
}
}
*pSurface = (VkSurfaceKHR)pIcdSurface;
out:
if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
if (NULL != pIcdSurface->real_icd_surfaces) {
i = 0;
for (struct loader_icd_term *icd_term = ptr_instance->icd_terms; icd_term != NULL; icd_term = icd_term->next, i++) {
if ((VkSurfaceKHR)NULL != pIcdSurface->real_icd_surfaces[i] && NULL != icd_term->dispatch.DestroySurfaceKHR) {
icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
}
}
loader_instance_heap_free(ptr_instance, pIcdSurface->real_icd_surfaces);
}
loader_instance_heap_free(ptr_instance, pIcdSurface);
}
return vkRes;
}
// This is the trampoline entrypoint for
// GetPhysicalDeviceScreenPresentationSupportQNX
LOADER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceScreenPresentationSupportQNX(VkPhysicalDevice physicalDevice,
uint32_t queueFamilyIndex,
struct _screen_window *window) {
VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice);
const VkLayerInstanceDispatchTable *disp;
disp = loader_get_instance_layer_dispatch(physicalDevice);
VkBool32 res = disp->GetPhysicalDeviceScreenPresentationSupportQNX(unwrapped_phys_dev, queueFamilyIndex, window);
return res;
}
// This is the instance chain terminator function for
// GetPhysicalDeviceScreenPresentationSupportQNX
VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceScreenPresentationSupportQNX(VkPhysicalDevice physicalDevice,
uint32_t queueFamilyIndex,
struct _screen_window *window) {
// First, check to ensure the appropriate extension was enabled:
struct loader_physical_device_term *phys_dev_term = (struct loader_physical_device_term *)physicalDevice;
struct loader_icd_term *icd_term = phys_dev_term->this_icd_term;
struct loader_instance *ptr_instance = (struct loader_instance *)icd_term->this_instance;
if (!ptr_instance->wsi_screen_surface_enabled) {
loader_log(
ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
"VK_QNX_screen_surface extension not enabled. vkGetPhysicalDeviceScreenPresentationSupportQNX not executed!\n");
return VK_SUCCESS;
}
if (NULL == icd_term->dispatch.GetPhysicalDeviceScreenPresentationSupportQNX) {
loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
"ICD for selected physical device is not exporting vkGetPhysicalDeviceScreenPresentationSupportQNX!\n");
assert(false && "loader: null GetPhysicalDeviceScreenPresentationSupportQNX ICD pointer");
}
return icd_term->dispatch.GetPhysicalDeviceScreenPresentationSupportQNX(phys_dev_term->phys_dev, queueFamilyIndex, window);
}
#endif // VK_USE_PLATFORM_SCREEN_QNX
// Functions for the VK_KHR_display instance extension:
LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice,
uint32_t *pPropertyCount,
@ -2468,6 +2594,19 @@ bool wsi_swapchain_instance_gpa(struct loader_instance *ptr_instance, const char
}
#endif // VK_USE_PLATFORM_METAL_EXT
#ifdef VK_USE_PLATFORM_SCREEN_QNX
// Functions for the VK_QNX_screen_surface extension:
if (!strcmp("vkCreateScreenSurfaceQNX", name)) {
*addr = ptr_instance->wsi_screen_surface_enabled ? (void *)vkCreateScreenSurfaceQNX : NULL;
return true;
}
if (!strcmp("vkGetPhysicalDeviceScreenPresentationSupportQNX", name)) {
*addr = ptr_instance->wsi_screen_surface_enabled ? (void *)vkGetPhysicalDeviceScreenPresentationSupportQNX : NULL;
return true;
}
#endif // VK_USE_PLATFORM_SCREEN_QNX
// Functions for VK_KHR_display extension:
if (!strcmp("vkGetPhysicalDeviceDisplayPropertiesKHR", name)) {
*addr = ptr_instance->wsi_display_enabled ? (void *)vkGetPhysicalDeviceDisplayPropertiesKHR : NULL;

View File

@ -54,6 +54,9 @@ typedef struct {
#ifdef VK_USE_PLATFORM_METAL_EXT
VkIcdSurfaceMetal metal_surf;
#endif // VK_USE_PLATFORM_METAL_EXT
#ifdef VK_USE_PLATFORM_SCREEN_QNX
VkIcdSurfaceScreen screen_surf;
#endif // VK_USE_PLATFORM_SCREEN_QNX
VkIcdSurfaceDisplay display_surf;
VkIcdSurfaceHeadless headless_surf;
};
@ -155,6 +158,14 @@ terminator_CreateStreamDescriptorSurfaceGGP(VkInstance instance, const VkStreamD
VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMetalSurfaceEXT(VkInstance instance, const VkMetalSurfaceCreateInfoEXT *pCreateInfo,
const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface);
#endif
#ifdef VK_USE_PLATFORM_SCREEN_QNX
VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateScreenSurfaceQNX(VkInstance instance,
const VkScreenSurfaceCreateInfoQNX *pCreateInfo,
const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface);
VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceScreenPresentationSupportQNX(VkPhysicalDevice physicalDevice,
uint32_t queueFamilyIndex,
struct _screen_window *window);
#endif // VK_USE_PLATFORM_SCREEN_QNX
VKAPI_ATTR VkResult VKAPI_CALL terminator_GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice,
uint32_t *pPropertyCount,
VkDisplayPropertiesKHR *pProperties);

View File

@ -44,7 +44,8 @@ WSI_EXT_NAMES = ['VK_KHR_surface',
'VK_KHR_swapchain',
'VK_KHR_display_swapchain',
'VK_KHR_get_display_properties2',
'VK_KHR_get_surface_capabilities2']
'VK_KHR_get_surface_capabilities2',
'VK_QNX_screen_surface']
ADD_INST_CMDS = ['vkCreateInstance',
'vkEnumerateInstanceExtensionProperties',

View File

@ -45,6 +45,10 @@ elseif(UNIX AND NOT APPLE) # i.e.: Linux
if(BUILD_WSI_WAYLAND_SUPPORT)
add_definitions(-DVK_USE_PLATFORM_WAYLAND_KHR)
endif()
if(BUILD_WSI_SCREEN_SUPPORT)
add_definitions(-DVK_USE_PLATFORM_SCREEN_QNX)
endif()
else()
message(FATAL_ERROR "Unsupported Platform!")
endif()

View File

@ -1104,6 +1104,25 @@ VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWaylandPresentationSupportKHR(
}
#endif // VK_USE_PLATFORM_WAYLAND_KHR
#ifdef VK_USE_PLATFORM_SCREEN_QNX
VKAPI_ATTR VkResult VKAPI_CALL vkCreateScreenSurfaceQNX(VkInstance instance, const VkScreenSurfaceCreateInfoQNX* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface)
{
wrapped_inst_obj *inst;
auto vk_inst = unwrap_instance(instance, &inst);
VkResult result = inst->layer_disp.CreateScreenSurfaceQNX(vk_inst, pCreateInfo, pAllocator, pSurface);
return result;
}
VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceScreenPresentationSupportQNX(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, struct _screen_window* window)
{
wrapped_phys_dev_obj *phys_dev;
auto vk_phys_dev = unwrap_phys_dev(physicalDevice, &phys_dev);
VkBool32 result = phys_dev->inst->layer_disp.GetPhysicalDeviceScreenPresentationSupportQNX(vk_phys_dev, queueFamilyIndex, window);
return result;
}
#endif // VK_USE_PLATFORM_SCREEN_QNX
VKAPI_ATTR VkResult VKAPI_CALL
vkCreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pMsgCallback) {