diff --git a/BUILD.md b/BUILD.md index 5fc7075f..89289363 100644 --- a/BUILD.md +++ b/BUILD.md @@ -179,6 +179,7 @@ on/off options currently supported by this repository: | BUILD_WSI_XCB_SUPPORT | Linux | `ON` | Build the loader with the XCB entry points enabled. Without this, the XCB headers should not be needed, but the extension `VK_KHR_xcb_surface` won't be available. | | 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. | | ENABLE_STATIC_LOADER | Windows | `OFF` | By default, the loader is built as a dynamic library. This allows it to be built as a static library, instead. | | 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. | diff --git a/CMakeLists.txt b/CMakeLists.txt index 5f76007e..a833a03e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -121,6 +121,7 @@ if(UNIX AND NOT APPLE) # i.e.: Linux option(BUILD_WSI_XCB_SUPPORT "Build XCB WSI support" ON) 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) if(BUILD_WSI_XCB_SUPPORT) find_package(XCB REQUIRED) @@ -134,6 +135,11 @@ if(UNIX AND NOT APPLE) # i.e.: Linux find_package(Wayland REQUIRED) include_directories(SYSTEM ${WAYLAND_CLIENT_INCLUDE_DIR}) endif() + + if(BUILD_WSI_DIRECTFB_SUPPORT) + find_package(DirectFB REQUIRED) + include_directories(SYSTEM ${DIRECTFB_INCLUDE_DIR}) + endif() endif() if(WIN32) diff --git a/cmake/FindDirectFB.cmake b/cmake/FindDirectFB.cmake new file mode 100644 index 00000000..2c98b2ac --- /dev/null +++ b/cmake/FindDirectFB.cmake @@ -0,0 +1,28 @@ +# Try to find DirectFB +# +# This will define: +# +# DIRECTFB_FOUND - True if DirectFB is found +# DIRECTFB_LIBRARIES - Link these to use DirectFB +# DIRECTFB_INCLUDE_DIR - Include directory for DirectFB +# DIRECTFB_DEFINITIONS - Compiler flags for using DirectFB +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +IF (NOT WIN32) + FIND_PACKAGE(PkgConfig) + PKG_CHECK_MODULES(PKG_DIRECTFB QUIET directfb) + + SET(DIRECTFB_DEFINITIONS ${PKG_DIRECTFB_CFLAGS}) + + FIND_PATH(DIRECTFB_INCLUDE_DIR NAMES directfb.h HINTS ${PKG_DIRECTFB_INCLUDE_DIRS}) + + FIND_LIBRARY(DIRECTFB_LIBRARIES NAMES directfb HINTS ${PKG_DIRECTFB_LIBRARY_DIRS}) + + include(FindPackageHandleStandardArgs) + + FIND_PACKAGE_HANDLE_STANDARD_ARGS(DIRECTFB DEFAULT_MSG DIRECTFB_LIBRARIES DIRECTFB_INCLUDE_DIR) + + MARK_AS_ADVANCED(DIRECTFB_INCLUDE_DIR DIRECTFB_LIBRARIES) +ENDIF () diff --git a/loader/CMakeLists.txt b/loader/CMakeLists.txt index 67277aa3..c71bd645 100644 --- a/loader/CMakeLists.txt +++ b/loader/CMakeLists.txt @@ -53,6 +53,10 @@ elseif(UNIX AND NOT APPLE) # i.e.: Linux if(BUILD_WSI_WAYLAND_SUPPORT) set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS VK_USE_PLATFORM_WAYLAND_KHR) endif() + + if(BUILD_WSI_DIRECTFB_SUPPORT) + set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS VK_USE_PLATFORM_DIRECTFB_EXT) + endif() else() message(FATAL_ERROR "Unsupported Platform!") endif() diff --git a/loader/loader.h b/loader/loader.h index 7f29ab60..f621d0ce 100644 --- a/loader/loader.h +++ b/loader/loader.h @@ -326,6 +326,9 @@ struct loader_instance { #ifdef VK_USE_PLATFORM_XLIB_KHR bool wsi_xlib_surface_enabled; #endif +#ifdef VK_USE_PLATFORM_DIRECTFB_EXT + bool wsi_directfb_surface_enabled; +#endif #ifdef VK_USE_PLATFORM_ANDROID_KHR bool wsi_android_surface_enabled; #endif diff --git a/loader/wsi.c b/loader/wsi.c index cb59f5f1..804046cf 100644 --- a/loader/wsi.c +++ b/loader/wsi.c @@ -52,6 +52,9 @@ void wsi_create_instance(struct loader_instance *ptr_instance, const VkInstanceC #ifdef VK_USE_PLATFORM_XLIB_KHR ptr_instance->wsi_xlib_surface_enabled = false; #endif // VK_USE_PLATFORM_XLIB_KHR +#ifdef VK_USE_PLATFORM_DIRECTFB_EXT + ptr_instance->wsi_directfb_surface_enabled = false; +#endif // VK_USE_PLATFORM_DIRECTFB_EXT #ifdef VK_USE_PLATFORM_ANDROID_KHR ptr_instance->wsi_android_surface_enabled = false; #endif // VK_USE_PLATFORM_ANDROID_KHR @@ -96,6 +99,12 @@ void wsi_create_instance(struct loader_instance *ptr_instance, const VkInstanceC continue; } #endif // VK_USE_PLATFORM_XLIB_KHR +#ifdef VK_USE_PLATFORM_DIRECTFB_EXT + if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME) == 0) { + ptr_instance->wsi_directfb_surface_enabled = true; + continue; + } +#endif // VK_USE_PLATFORM_DIRECTFB_EXT #ifdef VK_USE_PLATFORM_ANDROID_KHR if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_ANDROID_SURFACE_EXTENSION_NAME) == 0) { ptr_instance->wsi_android_surface_enabled = true; @@ -154,6 +163,9 @@ bool wsi_unsupported_instance_extension(const VkExtensionProperties *ext_prop) { #ifndef VK_USE_PLATFORM_XLIB_KHR if (!strcmp(ext_prop->extensionName, "VK_KHR_xlib_surface")) return true; #endif // VK_USE_PLATFORM_XLIB_KHR +#ifndef VK_USE_PLATFORM_DIRECTFB_EXT + if (!strcmp(ext_prop->extensionName, "VK_EXT_directfb_surface")) return true; +#endif // VK_USE_PLATFORM_DIRECTFB_EXT return false; } @@ -942,6 +954,124 @@ VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceXlibPresentationSuppo } #endif // VK_USE_PLATFORM_XLIB_KHR +#ifdef VK_USE_PLATFORM_DIRECTFB_EXT + +// Functions for the VK_EXT_directfb_surface extension: + +// This is the trampoline entrypoint for CreateDirectFBSurfaceEXT +LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDirectFBSurfaceEXT(VkInstance instance, + const VkDirectFBSurfaceCreateInfoEXT *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkSurfaceKHR *pSurface) { + const VkLayerInstanceDispatchTable *disp; + disp = loader_get_instance_layer_dispatch(instance); + VkResult res; + + res = disp->CreateDirectFBSurfaceEXT(instance, pCreateInfo, pAllocator, pSurface); + return res; +} + +// This is the instance chain terminator function for CreateDirectFBSurfaceEXT +VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDirectFBSurfaceEXT(VkInstance instance, + const VkDirectFBSurfaceCreateInfoEXT *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_directfb_surface_enabled) { + loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, + "VK_EXT_directfb_surface extension not enabled. vkCreateDirectFBSurfaceEXT 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->directfb_surf.base), sizeof(pIcdSurface->directfb_surf)); + if (pIcdSurface == NULL) { + vkRes = VK_ERROR_OUT_OF_HOST_MEMORY; + goto out; + } + + pIcdSurface->directfb_surf.base.platform = VK_ICD_WSI_PLATFORM_DIRECTFB; + pIcdSurface->directfb_surf.dfb = pCreateInfo->dfb; + pIcdSurface->directfb_surf.surface = pCreateInfo->surface; + + // 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.CreateDirectFBSurfaceEXT) { + vkRes = icd_term->dispatch.CreateDirectFBSurfaceEXT(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 +// GetPhysicalDeviceDirectFBPresentationSupportEXT +LOADER_EXPORT VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceDirectFBPresentationSupportEXT(VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, + IDirectFB *dfb) { + VkPhysicalDevice unwrapped_phys_dev = loader_unwrap_physical_device(physicalDevice); + const VkLayerInstanceDispatchTable *disp; + disp = loader_get_instance_layer_dispatch(physicalDevice); + VkBool32 res = disp->GetPhysicalDeviceDirectFBPresentationSupportEXT(unwrapped_phys_dev, queueFamilyIndex, dfb); + return res; +} + +// This is the instance chain terminator function for +// GetPhysicalDeviceDirectFBPresentationSupportEXT +VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceDirectFBPresentationSupportEXT(VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, + IDirectFB *dfb) { + // 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_directfb_surface_enabled) { + loader_log( + ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, + "VK_EXT_directfb_surface extension not enabled. vkGetPhysicalDeviceWaylandPresentationSupportKHR not executed!\n"); + return VK_SUCCESS; + } + + if (NULL == icd_term->dispatch.GetPhysicalDeviceDirectFBPresentationSupportEXT) { + loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, + "ICD for selected physical device is not exporting vkGetPhysicalDeviceDirectFBPresentationSupportEXT!\n"); + assert(false && "loader: null GetPhysicalDeviceDirectFBPresentationSupportEXT ICD pointer"); + } + + return icd_term->dispatch.GetPhysicalDeviceDirectFBPresentationSupportEXT(phys_dev_term->phys_dev, queueFamilyIndex, dfb); +} +#endif // VK_USE_PLATFORM_DIRECTFB_EXT + #ifdef VK_USE_PLATFORM_ANDROID_KHR // Functions for the VK_KHR_android_surface extension: @@ -2094,6 +2224,18 @@ bool wsi_swapchain_instance_gpa(struct loader_instance *ptr_instance, const char return true; } #endif // VK_USE_PLATFORM_XLIB_KHR +#ifdef VK_USE_PLATFORM_DIRECTFB_EXT + + // Functions for the VK_EXT_directfb_surface extension: + if (!strcmp("vkCreateDirectFBSurfaceEXT", name)) { + *addr = ptr_instance->wsi_directfb_surface_enabled ? (void *)vkCreateDirectFBSurfaceEXT : NULL; + return true; + } + if (!strcmp("vkGetPhysicalDeviceDirectFBPresentationSupportEXT", name)) { + *addr = ptr_instance->wsi_directfb_surface_enabled ? (void *)vkGetPhysicalDeviceDirectFBPresentationSupportEXT : NULL; + return true; + } +#endif // VK_USE_PLATFORM_DIRECTFB_EXT #ifdef VK_USE_PLATFORM_ANDROID_KHR // Functions for the VK_KHR_android_surface extension: diff --git a/loader/wsi.h b/loader/wsi.h index 314c983c..e6c699f5 100644 --- a/loader/wsi.h +++ b/loader/wsi.h @@ -39,6 +39,9 @@ typedef struct { #ifdef VK_USE_PLATFORM_XLIB_KHR VkIcdSurfaceXlib xlib_surf; #endif // VK_USE_PLATFORM_XLIB_KHR +#ifdef VK_USE_PLATFORM_DIRECTFB_EXT + VkIcdSurfaceDirectFB directfb_surf; +#endif // VK_USE_PLATFORM_DIRECTFB_EXT #ifdef VK_USE_PLATFORM_MACOS_MVK VkIcdSurfaceMacOS macos_surf; #endif // VK_USE_PLATFORM_MACOS_MVK @@ -121,6 +124,14 @@ VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceXlibPresentationSuppo uint32_t queueFamilyIndex, Display *dpy, VisualID visualID); #endif +#ifdef VK_USE_PLATFORM_DIRECTFB_EXT +VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDirectFBSurfaceEXT(VkInstance instance, + const VkDirectFBSurfaceCreateInfoEXT *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface); +VKAPI_ATTR VkBool32 VKAPI_CALL terminator_GetPhysicalDeviceDirectFBPresentationSupportEXT(VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, + IDirectFB *dfb); +#endif #ifdef VK_USE_PLATFORM_MACOS_MVK VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMacOSSurfaceMVK(VkInstance instance, const VkMacOSSurfaceCreateInfoMVK *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface); diff --git a/scripts/common_codegen.py b/scripts/common_codegen.py index 11b4fe59..b301b3a7 100644 --- a/scripts/common_codegen.py +++ b/scripts/common_codegen.py @@ -56,6 +56,7 @@ platform_dict = { 'win32' : 'VK_USE_PLATFORM_WIN32_KHR', 'xcb' : 'VK_USE_PLATFORM_XCB_KHR', 'xlib' : 'VK_USE_PLATFORM_XLIB_KHR', + 'directfb' : 'VK_USE_PLATFORM_DIRECTFB_EXT', 'xlib_xrandr' : 'VK_USE_PLATFORM_XLIB_XRANDR_EXT', 'provisional' : 'VK_ENABLE_BETA_EXTENSIONS', } diff --git a/scripts/loader_extension_generator.py b/scripts/loader_extension_generator.py index b4748b90..53e13bd1 100644 --- a/scripts/loader_extension_generator.py +++ b/scripts/loader_extension_generator.py @@ -32,6 +32,7 @@ WSI_EXT_NAMES = ['VK_KHR_surface', 'VK_KHR_xlib_surface', 'VK_KHR_xcb_surface', 'VK_KHR_wayland_surface', + 'VK_EXT_directfb_surface', 'VK_KHR_win32_surface', 'VK_KHR_android_surface', 'VK_MVK_macos_surface',