| 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 |
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)
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)
--- /dev/null
+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
--- /dev/null
+#undef HAVE_SECURE_GETENV
+#undef HAVE___SECURE_GETENV
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()
${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)
| 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
### 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.
* 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`.
`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:
}
// 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();
if (xdgdatadirs == NULL) {
xdgdata_alloc = false;
}
-#if !defined(__Fuchsia__)
+#if !defined(__Fuchsia__) && !defined(__QNXNTO__)
if (xdgconfdirs == NULL || xdgconfdirs[0] == '\0') {
xdgconfdirs = FALLBACK_CONFIG_DIRS;
}
#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;
};
#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:
}
#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
#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) {
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;
#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;
}
#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,
}
#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;
#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;
};
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);
'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',
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()
}
#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) {