Add support for VK_EXT_directfb_surface extension
authorNicolas Caramelli <caramelli.devel@gmail.com>
Mon, 13 Jul 2020 15:22:09 +0000 (17:22 +0200)
committerjeremyk-lunarg <jeremyk@lunarg.com>
Fri, 7 Aug 2020 17:59:36 +0000 (11:59 -0600)
BUILD.md
cmake/FindDirectFB.cmake [new file with mode: 0644]
cube/CMakeLists.txt
cube/cube.c
cube/cube.cpp
vulkaninfo/CMakeLists.txt
vulkaninfo/vulkaninfo.cpp
vulkaninfo/vulkaninfo.h

index a633c56..6461bc3 100644 (file)
--- a/BUILD.md
+++ b/BUILD.md
@@ -205,6 +205,7 @@ on/off options currently supported by this repository:
 | BUILD_WSI_XCB_SUPPORT | Linux | `ON` | Build the components with XCB support. |
 | BUILD_WSI_XLIB_SUPPORT | Linux | `ON` | Build the components with Xlib support. |
 | BUILD_WSI_WAYLAND_SUPPORT | Linux | `ON` | Build the components with Wayland support. |
+| BUILD_WSI_DIRECTFB_SUPPORT | Linux | `OFF` | Build the components with DirectFB support. |
 | USE_CCACHE | Linux | `OFF` | Enable caching with the CCache program. |
 
 The following is a table of all string options currently supported by this repository:
diff --git a/cmake/FindDirectFB.cmake b/cmake/FindDirectFB.cmake
new file mode 100644 (file)
index 0000000..2c98b2a
--- /dev/null
@@ -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 ()
index 05685ce..ef05db1 100644 (file)
@@ -46,7 +46,8 @@ 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)
-    set(CUBE_WSI_SELECTION "XCB" CACHE STRING "Select WSI target for vkcube (XCB, XLIB, WAYLAND, DISPLAY)")
+    option(BUILD_WSI_DIRECTFB_SUPPORT "Build DirectFB WSI support" OFF)
+    set(CUBE_WSI_SELECTION "XCB" CACHE STRING "Select WSI target for vkcube (XCB, XLIB, WAYLAND, DIRECTFB, DISPLAY)")
 
     if(BUILD_WSI_XCB_SUPPORT)
         find_package(XCB REQUIRED)
@@ -60,6 +61,11 @@ if(UNIX AND NOT APPLE) # i.e. Linux
         find_package(Wayland REQUIRED)
         include_directories(${WAYLAND_CLIENT_INCLUDE_DIR})
     endif()
+
+    if(BUILD_WSI_DIRECTFB_SUPPORT)
+        find_package(DirectFB REQUIRED)
+        include_directories(${DIRECTFB_INCLUDE_DIR})
+    endif()
 endif()
 
 if(WIN32)
@@ -101,6 +107,13 @@ elseif(UNIX AND NOT APPLE) # i.e. Linux
         set(CUBE_INCLUDE_DIRS ${WAYLAND_CLIENT_INCLUDE_DIR} ${CUBE_INCLUDE_DIRS})
         link_libraries(${WAYLAND_CLIENT_LIBRARIES})
         add_definitions(-DVK_USE_PLATFORM_WAYLAND_KHR)
+    elseif(CUBE_WSI_SELECTION STREQUAL "DIRECTFB")
+        if(NOT BUILD_WSI_DIRECTFB_SUPPORT)
+            message(FATAL_ERROR "Selected DIRECTFB for vkcube build but not building DirectFB support")
+        endif()
+        set(CUBE_INCLUDE_DIRS ${DIRECTFB_INCLUDE_DIR} ${CUBE_INCLUDE_DIRS})
+        link_libraries(${DIRECTFB_LIBRARIES})
+        add_definitions(-DVK_USE_PLATFORM_DIRECTFB_EXT)
     elseif(CUBE_WSI_SELECTION STREQUAL "DISPLAY")
         add_definitions(-DVK_USE_PLATFORM_DISPLAY_KHR)
     else()
index 71ad5a4..857056e 100644 (file)
@@ -327,6 +327,10 @@ struct demo {
     struct wl_seat *seat;
     struct wl_pointer *pointer;
     struct wl_keyboard *keyboard;
+#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT)
+    IDirectFB *dfb;
+    IDirectFBSurface *window;
+    IDirectFBEventBuffer *event_buffer;
 #elif defined(VK_USE_PLATFORM_ANDROID_KHR)
     struct ANativeWindow *window;
 #elif defined(VK_USE_PLATFORM_METAL_EXT)
@@ -2367,6 +2371,10 @@ static void demo_cleanup(struct demo *demo) {
     wl_compositor_destroy(demo->compositor);
     wl_registry_destroy(demo->registry);
     wl_display_disconnect(demo->display);
+#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT)
+    demo->event_buffer->Release(demo->event_buffer);
+    demo->window->Release(demo->window);
+    demo->dfb->Release(demo->dfb);
 #endif
 
     vkDestroyInstance(demo->inst, NULL);
@@ -2769,6 +2777,82 @@ static void demo_create_window(struct demo *demo) {
     wl_shell_surface_set_toplevel(demo->shell_surface);
     wl_shell_surface_set_title(demo->shell_surface, APP_SHORT_NAME);
 }
+#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT)
+static void demo_create_directfb_window(struct demo *demo) {
+    DFBResult ret;
+
+    ret = DirectFBInit(NULL, NULL);
+    if (ret) {
+        printf("DirectFBInit failed to initialize DirectFB!\n");
+        fflush(stdout);
+        exit(1);
+    }
+
+    ret = DirectFBCreate(&demo->dfb);
+    if (ret) {
+        printf("DirectFBCreate failed to create main interface of DirectFB!\n");
+        fflush(stdout);
+        exit(1);
+    }
+
+    DFBSurfaceDescription desc;
+    desc.flags = DSDESC_CAPS | DSDESC_WIDTH | DSDESC_HEIGHT;
+    desc.caps = DSCAPS_PRIMARY;
+    desc.width = demo->width;
+    desc.height = demo->height;
+    ret = demo->dfb->CreateSurface(demo->dfb, &desc, &demo->window);
+    if (ret) {
+        printf("CreateSurface failed to create DirectFB surface interface!\n");
+        fflush(stdout);
+        exit(1);
+    }
+
+    ret = demo->dfb->CreateInputEventBuffer(demo->dfb, DICAPS_KEYS, DFB_FALSE, &demo->event_buffer);
+    if (ret) {
+        printf("CreateInputEventBuffer failed to create DirectFB event buffer interface!\n");
+        fflush(stdout);
+        exit(1);
+    }
+}
+
+static void demo_handle_directfb_event(struct demo *demo, const DFBInputEvent *event) {
+    if (event->type != DIET_KEYPRESS) return;
+    switch (event->key_symbol) {
+        case DIKS_ESCAPE:  // Escape
+            demo->quit = true;
+            break;
+        case DIKS_CURSOR_LEFT:  // left arrow key
+            demo->spin_angle -= demo->spin_increment;
+            break;
+        case DIKS_CURSOR_RIGHT:  // right arrow key
+            demo->spin_angle += demo->spin_increment;
+            break;
+        case DIKS_SPACE:  // space bar
+            demo->pause = !demo->pause;
+            break;
+        default:
+            break;
+    }
+}
+
+static void demo_run_directfb(struct demo *demo) {
+    while (!demo->quit) {
+        DFBInputEvent event;
+
+        if (demo->pause) {
+            demo->event_buffer->WaitForEvent(demo->event_buffer);
+            if (!demo->event_buffer->GetEvent(demo->event_buffer, DFB_EVENT(&event)))
+                demo_handle_directfb_event(demo, &event);
+        } else {
+            if (!demo->event_buffer->GetEvent(demo->event_buffer, DFB_EVENT(&event)))
+                demo_handle_directfb_event(demo, &event);
+
+            demo_draw(demo);
+            demo->curFrame++;
+            if (demo->frameCount != INT32_MAX && demo->curFrame == demo->frameCount) demo->quit = true;
+        }
+    }
+}
 #elif defined(VK_USE_PLATFORM_ANDROID_KHR)
 static void demo_run(struct demo *demo) {
     if (!demo->prepared) return;
@@ -3031,6 +3115,11 @@ static void demo_init_vk(struct demo *demo) {
                 platformSurfaceExtFound = 1;
                 demo->extension_names[demo->enabled_extension_count++] = VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME;
             }
+#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT)
+            if (!strcmp(VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME, instance_extensions[i].extensionName)) {
+                platformSurfaceExtFound = 1;
+                demo->extension_names[demo->enabled_extension_count++] = VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME;
+            }
 #elif defined(VK_USE_PLATFORM_DISPLAY_KHR)
             if (!strcmp(VK_KHR_DISPLAY_EXTENSION_NAME, instance_extensions[i].extensionName)) {
                 platformSurfaceExtFound = 1;
@@ -3108,6 +3197,12 @@ static void demo_init_vk(struct demo *demo) {
                  "Do you have a compatible Vulkan installable client driver (ICD) installed?\n"
                  "Please look at the Getting Started guide for additional information.\n",
                  "vkCreateInstance Failure");
+#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT)
+        ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME
+                 " extension.\n\n"
+                 "Do you have a compatible Vulkan installable client driver (ICD) installed?\n"
+                 "Please look at the Getting Started guide for additional information.\n",
+                 "vkCreateInstance Failure");
 #endif
     }
     const VkApplicationInfo app = {
@@ -3405,6 +3500,15 @@ static void demo_create_surface(struct demo *demo) {
     createInfo.window = demo->xcb_window;
 
     err = vkCreateXcbSurfaceKHR(demo->inst, &createInfo, NULL, &demo->surface);
+#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT)
+    VkDirectFBSurfaceCreateInfoEXT createInfo;
+    createInfo.sType = VK_STRUCTURE_TYPE_DIRECTFB_SURFACE_CREATE_INFO_EXT;
+    createInfo.pNext = NULL;
+    createInfo.flags = 0;
+    createInfo.dfb = demo->dfb;
+    createInfo.surface = demo->window;
+
+    err = vkCreateDirectFBSurfaceEXT(demo->inst, &createInfo, NULL, &demo->surface);
 #elif defined(VK_USE_PLATFORM_DISPLAY_KHR)
     err = demo_create_display_surface(demo);
 #elif defined(VK_USE_PLATFORM_METAL_EXT)
@@ -4014,6 +4118,8 @@ int main(int argc, char **argv) {
     demo_create_xlib_window(&demo);
 #elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
     demo_create_window(&demo);
+#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT)
+    demo_create_directfb_window(&demo);
 #endif
 
     demo_init_vk_swapchain(&demo);
@@ -4026,6 +4132,8 @@ int main(int argc, char **argv) {
     demo_run_xlib(&demo);
 #elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
     demo_run(&demo);
+#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT)
+    demo_run_directfb(&demo);
 #elif defined(VK_USE_PLATFORM_DISPLAY_KHR)
     demo_run_display(&demo);
 #endif
index fc32c74..a319b59 100644 (file)
@@ -263,6 +263,10 @@ struct Demo {
 #elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
     void run();
     void create_window();
+#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT)
+    void handle_directfb_event(const DFBInputEvent *);
+    void run_directfb();
+    void create_directfb_window();
 #elif defined(VK_USE_PLATFORM_METAL_EXT)
     void run();
 #elif defined(VK_USE_PLATFORM_DISPLAY_KHR)
@@ -294,6 +298,10 @@ struct Demo {
     wl_seat *seat;
     wl_pointer *pointer;
     wl_keyboard *keyboard;
+#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT)
+    IDirectFB *dfb;
+    IDirectFBSurface *window;
+    IDirectFBEventBuffer *event_buffer;
 #elif defined(VK_USE_PLATFORM_METAL_EXT)
     void *caMetalLayer;
 #endif
@@ -531,6 +539,10 @@ Demo::Demo()
       seat{nullptr},
       pointer{nullptr},
       keyboard{nullptr},
+#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT)
+      dfb{nullptr},
+      window{nullptr},
+      event_buffer{nullptr},
 #endif
       prepared{false},
       use_staging_buffer{false},
@@ -677,6 +689,10 @@ void Demo::cleanup() {
     wl_compositor_destroy(compositor);
     wl_registry_destroy(registry);
     wl_display_disconnect(display);
+#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT)
+    event_buffer->Release(event_buffer);
+    window->Release(window);
+    dfb->Release(dfb);
 #endif
 
     inst.destroy(nullptr);
@@ -1118,6 +1134,11 @@ void Demo::init_vk() {
                 platformSurfaceExtFound = 1;
                 extension_names[enabled_extension_count++] = VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME;
             }
+#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT)
+            if (!strcmp(VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME, instance_extensions[i].extensionName)) {
+                platformSurfaceExtFound = 1;
+                extension_names[enabled_extension_count++] = VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME;
+            }
 #elif defined(VK_USE_PLATFORM_DISPLAY_KHR)
             if (!strcmp(VK_KHR_DISPLAY_EXTENSION_NAME, instance_extensions[i].extensionName)) {
                 platformSurfaceExtFound = 1;
@@ -1167,6 +1188,12 @@ void Demo::init_vk() {
                  "Do you have a compatible Vulkan installable client driver (ICD) installed?\n"
                  "Please look at the Getting Started guide for additional information.\n",
                  "vkCreateInstance Failure");
+#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT)
+        ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME
+                 " extension.\n\n"
+                 "Do you have a compatible Vulkan installable client driver (ICD) installed?\n"
+                 "Please look at the Getting Started guide for additional information.\n",
+                 "vkCreateInstance Failure");
 #elif defined(VK_USE_PLATFORM_DISPLAY_KHR)
         ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_DISPLAY_EXTENSION_NAME
                  " extension.\n\n"
@@ -1315,6 +1342,13 @@ void Demo::create_surface() {
         auto result = inst.createXcbSurfaceKHR(&createInfo, nullptr, &surface);
         VERIFY(result == vk::Result::eSuccess);
     }
+#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT)
+    {
+        auto const createInfo = vk::DirectFBSurfaceCreateInfoEXT().setDfb(dfb).setSurface(window);
+
+        auto result = inst.createDirectFBSurfaceEXT(&createInfo, nullptr, &surface);
+        VERIFY(result == vk::Result::eSuccess);
+    }
 #elif defined(VK_USE_PLATFORM_METAL_EXT)
     {
         auto const createInfo = vk::MetalSurfaceCreateInfoEXT().setPLayer(static_cast<CAMetalLayer *>(caMetalLayer));
@@ -2711,6 +2745,85 @@ void Demo::create_window() {
     wl_shell_surface_set_toplevel(shell_surface);
     wl_shell_surface_set_title(shell_surface, APP_SHORT_NAME);
 }
+#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT)
+
+void Demo::handle_directfb_event(const DFBInputEvent *event) {
+    if (event->type != DIET_KEYPRESS) return;
+    switch (event->key_symbol) {
+        case DIKS_ESCAPE:  // Escape
+            quit = true;
+            break;
+        case DIKS_CURSOR_LEFT:  // left arrow key
+            spin_angle -= spin_increment;
+            break;
+        case DIKS_CURSOR_RIGHT:  // right arrow key
+            spin_angle += spin_increment;
+            break;
+        case DIKS_SPACE:  // space bar
+            pause = !pause;
+            break;
+        default:
+            break;
+    }
+}
+
+void Demo::run_directfb() {
+    while (!quit) {
+        DFBInputEvent event;
+
+        if (pause) {
+            event_buffer->WaitForEvent(event_buffer);
+            if (!event_buffer->GetEvent(event_buffer, DFB_EVENT(&event)))
+                handle_directfb_event(&event);
+        } else {
+            if (!event_buffer->GetEvent(event_buffer, DFB_EVENT(&event)))
+                handle_directfb_event(&event);
+
+            draw();
+            curFrame++;
+            if (frameCount != UINT32_MAX && curFrame == frameCount) {
+                quit = true;
+            }
+        }
+    }
+}
+
+void Demo::create_directfb_window() {
+    DFBResult ret;
+
+    ret = DirectFBInit(NULL, NULL);
+    if (ret) {
+        printf("DirectFBInit failed to initialize DirectFB!\n");
+        fflush(stdout);
+        exit(1);
+    }
+
+    ret = DirectFBCreate(&dfb);
+    if (ret) {
+        printf("DirectFBCreate failed to create main interface of DirectFB!\n");
+        fflush(stdout);
+        exit(1);
+    }
+
+    DFBSurfaceDescription desc;
+    desc.flags = (DFBSurfaceDescriptionFlags)(DSDESC_CAPS | DSDESC_WIDTH | DSDESC_HEIGHT);
+    desc.caps = DSCAPS_PRIMARY;
+    desc.width = -1; //width;
+    desc.height = height;
+    ret = dfb->CreateSurface(dfb, &desc, &window);
+    if (ret) {
+        printf("CreateSurface failed to create DirectFB surface interface!\n");
+        fflush(stdout);
+        exit(1);
+    }
+
+    ret = dfb->CreateInputEventBuffer(dfb, DICAPS_KEYS, DFB_FALSE, &event_buffer);
+    if (ret) {
+        printf("CreateInputEventBuffer failed to create DirectFB event buffer interface!\n");
+        fflush(stdout);
+        exit(1);
+    }
+}
 #elif defined(VK_USE_PLATFORM_METAL_EXT)
 void Demo::run() {
     draw();
@@ -3024,6 +3137,8 @@ int main(int argc, char **argv) {
     demo.create_xlib_window();
 #elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
     demo.create_window();
+#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT)
+    demo.create_directfb_window();
 #endif
 
     demo.init_vk_swapchain();
@@ -3036,6 +3151,8 @@ int main(int argc, char **argv) {
     demo.run_xlib();
 #elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
     demo.run();
+#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT)
+    demo.run_directfb();
 #elif defined(VK_USE_PLATFORM_DISPLAY_KHR)
     demo.run_display();
 #endif
index 05b3f9e..b922e2a 100644 (file)
@@ -40,6 +40,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)
@@ -61,6 +62,13 @@ if(UNIX AND NOT APPLE) # i.e. Linux
         target_link_libraries(vulkaninfo ${WAYLAND_CLIENT_LIBRARIES})
         target_compile_definitions(vulkaninfo PRIVATE -DVK_USE_PLATFORM_WAYLAND_KHR -DVK_NO_PROTOTYPES)
     endif()
+
+    if(BUILD_WSI_DIRECTFB_SUPPORT)
+        find_package(DirectFB REQUIRED)
+        target_include_directories(vulkaninfo PRIVATE ${DIRECTFB_INCLUDE_DIR})
+        target_link_libraries(vulkaninfo ${DIRECTFB_LIBRARIES})
+        target_compile_definitions(vulkaninfo PRIVATE -DVK_USE_PLATFORM_DIRECTFB_EXT -DVK_NO_PROTOTYPES)
+    endif()
 endif()
 
 if(APPLE)
index 88c2454..2bed069 100644 (file)
@@ -873,7 +873,8 @@ int main(int argc, char **argv) {
 
         std::vector<std::unique_ptr<AppSurface>> surfaces;
 #if defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_WIN32_KHR) || \
-    defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_METAL_EXT) || defined(VK_USE_PLATFORM_WAYLAND_KHR)
+    defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_METAL_EXT) || defined(VK_USE_PLATFORM_WAYLAND_KHR) || \
+    defined(VK_USE_PLATFORM_DIRECTFB_EXT)
         for (auto &surface_extension : instance.surface_extensions) {
             surface_extension.create_window(instance);
             surface_extension.surface = surface_extension.create_surface(instance);
@@ -938,7 +939,8 @@ int main(int argc, char **argv) {
                 DumpLayers(*p.get(), instance.global_layers, gpus);
 
 #if defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_WIN32_KHR) || \
-    defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_METAL_EXT) || defined(VK_USE_PLATFORM_WAYLAND_KHR)
+    defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_METAL_EXT) || defined(VK_USE_PLATFORM_WAYLAND_KHR) || \
+    defined(VK_USE_PLATFORM_DIRECTFB_EXT)
                 DumpPresentableSurfaces(*p.get(), instance, gpus, surfaces);
 #endif
                 DumpGroups(*p.get(), instance);
@@ -954,7 +956,8 @@ int main(int argc, char **argv) {
         }
 
 #if defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_WIN32_KHR) || \
-    defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_METAL_EXT) || defined(VK_USE_PLATFORM_WAYLAND_KHR)
+    defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_METAL_EXT) || defined(VK_USE_PLATFORM_WAYLAND_KHR) || \
+    defined(VK_USE_PLATFORM_DIRECTFB_EXT)
 
         for (auto &surface_extension : instance.surface_extensions) {
             AppDestroySurface(instance, surface_extension.surface);
index 1ebad87..43446c1 100644 (file)
@@ -347,6 +347,13 @@ struct VkDll {
     PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR fp_vkGetPhysicalDeviceWaylandPresentationSupportKHR =
         APPLE_FP(vkGetPhysicalDeviceWaylandPresentationSupportKHR);
 #endif  // VK_USE_PLATFORM_WAYLAND_KHR
+#ifdef VK_USE_PLATFORM_DIRECTFB_EXT
+    PFN_vkCreateDirectFBSurfaceEXT fp_vkCreateDirectFBSurfaceEXT = APPLE_FP(vkCreateDirectFBSurfaceEXT);
+#endif  // VK_USE_PLATFORM_DIRECTFB_EXT
+#ifdef VK_USE_PLATFORM_DIRECTFB_EXT
+    PFN_vkGetPhysicalDeviceDirectFBPresentationSupportEXT fp_vkGetPhysicalDeviceDirectFBPresentationSupportEXT =
+        APPLE_FP(vkGetPhysicalDeviceDirectFBPresentationSupportEXT);
+#endif  // VK_USE_PLATFORM_DIRECTFB_EXT
 #ifdef VK_USE_PLATFORM_ANDROID_KHR
     PFN_vkCreateAndroidSurfaceKHR fp_vkCreateAndroidSurfaceKHR = APPLE_FP(vkCreateAndroidSurfaceKHR);
 #endif  // VK_USE_PLATFORM_ANDROID_KHR
@@ -413,6 +420,12 @@ struct VkDll {
 #ifdef VK_USE_PLATFORM_WAYLAND_KHR
         Load(fp_vkGetPhysicalDeviceWaylandPresentationSupportKHR, "vkGetPhysicalDeviceWaylandPresentationSupportKHR");
 #endif  // VK_USE_PLATFORM_WAYLAND_KHR
+#ifdef VK_USE_PLATFORM_DIRECTFB_EXT
+        Load(fp_vkCreateDirectFBSurfaceEXT, "vkCreateDirectFBSurfaceEXT");
+#endif  // VK_USE_PLATFORM_DIRECTFB_EXT
+#ifdef VK_USE_PLATFORM_DIRECTFB_EXT
+        Load(fp_vkGetPhysicalDeviceDirectFBPresentationSupportEXT, "vkGetPhysicalDeviceDirectFBPresentationSupportEXT");
+#endif  // VK_USE_PLATFORM_DIRECTFB_EXT
 #ifdef VK_USE_PLATFORM_ANDROID_KHR
         Load(fp_vkCreateAndroidSurfaceKHR, "vkCreateAndroidSurfaceKHR");
 #endif  // VK_USE_PLATFORM_ANDROID_KHR
@@ -599,6 +612,10 @@ struct AppInstance {
     wl_display *wayland_display;
     wl_surface *wayland_surface;
 #endif
+#ifdef VK_USE_PLATFORM_DIRECTFB_EXT
+    IDirectFB *dfb;
+    IDirectFBSurface *directfb_surface;
+#endif
 #ifdef VK_USE_PLATFORM_ANDROID_KHR  // TODO
     ANativeWindow *window;
 #endif
@@ -778,7 +795,7 @@ static void AppDestroyWin32Window(AppInstance &inst) { CALL_PFN(DestroyWindow)(i
 
 #if defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_WIN32_KHR) ||      \
     defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_METAL_EXT) || defined(VK_USE_PLATFORM_WAYLAND_KHR) || \
-    defined(VK_USE_PLATFORM_ANDROID_KHR)
+    defined(VK_USE_PLATFORM_DIRECTFB_EXT) || defined(VK_USE_PLATFORM_ANDROID_KHR)
 static void AppDestroySurface(AppInstance &inst, VkSurfaceKHR surface) {  // same for all platforms
     inst.dll.fp_vkDestroySurfaceKHR(inst.instance, surface, nullptr);
 }
@@ -984,6 +1001,53 @@ static void AppDestroyWaylandWindow(AppInstance &inst) { wl_display_disconnect(i
 #endif  // VK_USE_PLATFORM_WAYLAND_KHR
 //-----------------------------------------------------------
 
+//-------------------------DIRECTFB--------------------------
+#ifdef VK_USE_PLATFORM_DIRECTFB_EXT
+static void AppCreateDirectFBWindow(AppInstance &inst) {
+    DFBResult ret;
+
+    ret = DirectFBInit(NULL, NULL);
+    if (ret) {
+        THROW_ERR("DirectFBInit failed to initialize DirectFB.\nExiting...");
+    }
+
+    ret = DirectFBCreate(&inst.dfb);
+    if (ret) {
+        THROW_ERR("DirectFBCreate failed to create main interface of DirectFB.\nExiting...");
+    }
+
+    DFBSurfaceDescription desc;
+    desc.flags = (DFBSurfaceDescriptionFlags)(DSDESC_CAPS | DSDESC_WIDTH | DSDESC_HEIGHT);
+    desc.caps = DSCAPS_PRIMARY;
+    desc.width = inst.width;
+    desc.height = inst.height;
+    ret = inst.dfb->CreateSurface(inst.dfb, &desc, &inst.directfb_surface);
+    if (ret) {
+        THROW_ERR("CreateSurface failed to create DirectFB surface interface.\nExiting...");
+    }
+}
+
+static VkSurfaceKHR AppCreateDirectFBSurface(AppInstance &inst) {
+    VkDirectFBSurfaceCreateInfoEXT createInfo;
+    createInfo.sType = VK_STRUCTURE_TYPE_DIRECTFB_SURFACE_CREATE_INFO_EXT;
+    createInfo.pNext = nullptr;
+    createInfo.flags = 0;
+    createInfo.dfb = inst.dfb;
+    createInfo.surface = inst.directfb_surface;
+
+    VkSurfaceKHR surface;
+    VkResult err = inst.dll.fp_vkCreateDirectFBSurfaceEXT(inst.instance, &createInfo, nullptr, &surface);
+    if (err) THROW_VK_ERR("vkCreateDirectFBSurfaceEXT", err);
+    return surface;
+}
+
+static void AppDestroyDirectFBWindow(AppInstance &inst) {
+    inst.directfb_surface->Release(inst.directfb_surface);
+    inst.dfb->Release(inst.dfb);
+}
+#endif  // VK_USE_PLATFORM_DIRECTFB_EXT
+//-----------------------------------------------------------
+
 //-------------------------ANDROID---------------------------
 #ifdef VK_USE_PLATFORM_ANDROID_KHR
 static void AppCreateAndroidWindow(AppInstance &inst) {}
@@ -1097,6 +1161,18 @@ void SetupWindowExtensions(AppInstance &inst) {
         }
     }
 #endif
+//--DIRECTFB--
+#ifdef VK_USE_PLATFORM_DIRECTFB_EXT
+    SurfaceExtension surface_ext_directfb;
+    if (inst.CheckExtensionEnabled(VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME)) {
+        surface_ext_directfb.name = VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME;
+        surface_ext_directfb.create_window = AppCreateDirectFBWindow;
+        surface_ext_directfb.create_surface = AppCreateDirectFBSurface;
+        surface_ext_directfb.destroy_window = AppDestroyDirectFBWindow;
+
+        inst.AddSurfaceExtension(surface_ext_directfb);
+    }
+#endif
 //--ANDROID--
 #ifdef VK_USE_PLATFORM_ANDROID_KHR
     SurfaceExtension surface_ext_android;