From b10f4cddcf3e4854c56189c099a0c57c9790d47a Mon Sep 17 00:00:00 2001 From: Curi0 Date: Sat, 9 Sep 2017 11:37:07 +0530 Subject: [PATCH] Add Android Vulkan surface creation very untested may not work at all --- src/android_platform.h | 21 +++++++++++++---- src/android_window.c | 51 +++++++++++++++++++++++++++++++++--------- src/internal.h | 3 +++ src/vulkan.c | 3 +++ 4 files changed, 63 insertions(+), 15 deletions(-) diff --git a/src/android_platform.h b/src/android_platform.h index 02dbe8f70..4d4f283a1 100644 --- a/src/android_platform.h +++ b/src/android_platform.h @@ -27,8 +27,6 @@ #include -#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowNull null - #define _GLFW_PLATFORM_CONTEXT_STATE #define _GLFW_PLATFORM_MONITOR_STATE #define _GLFW_PLATFORM_CURSOR_STATE @@ -40,16 +38,31 @@ #include "posix_time.h" #include "posix_thread.h" #include "android_joystick.h" +#include #define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL) #define _glfw_dlclose(handle) dlclose(handle) #define _glfw_dlsym(handle, name) dlsym(handle, name) +#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowAndroid android + // Null-specific per-window data // -typedef struct _GLFWwindowNull +typedef struct _GLFWwindowAndroid { int width; int height; -} _GLFWwindowNull; + ANativeWindow *window; +} _GLFWwindowAndroid; + +typedef VkFlags VkAndroidSurfaceCreateFlagsKHR; + +typedef struct VkAndroidSurfaceCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkAndroidSurfaceCreateFlagsKHR flags; + ANativeWindow* surface; +} VkAndroidSurfaceCreateInfoKHR; + +typedef VkResult (APIENTRY *PFN_vkCreateAndroidSurfaceKHR)(VkInstance,const VkAndroidSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*); diff --git a/src/android_window.c b/src/android_window.c index 2e627672c..424fedbb4 100644 --- a/src/android_window.c +++ b/src/android_window.c @@ -31,8 +31,8 @@ static int createNativeWindow(_GLFWwindow* window, const _GLFWwndconfig* wndconfig) { - window->null.width = wndconfig->width; - window->null.height = wndconfig->height; + window->android.width = wndconfig->width; + window->android.height = wndconfig->height; return GLFW_TRUE; } @@ -104,15 +104,15 @@ void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos) void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height) { if (width) - *width = window->null.width; + *width = window->android.width; if (height) - *height = window->null.height; + *height = window->android.height; } void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) { - window->null.width = width; - window->null.height = height; + window->android.width = width; + window->android.height = height; } void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window, @@ -128,9 +128,9 @@ void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int n, int d) void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height) { if (width) - *width = window->null.width; + *width = window->android.width; if (height) - *height = window->null.height; + *height = window->android.height; } void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, @@ -273,13 +273,18 @@ int _glfwPlatformGetKeyScancode(int key) void _glfwPlatformGetRequiredInstanceExtensions(char** extensions) { + if (!_glfw.vk.KHR_surface || !_glfw.vk.KHR_android_surface) + return; + + extensions[0] = "VK_KHR_surface"; + extensions[1] = "VK_KHR_android_surface"; } int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily) { - return GLFW_FALSE; + return GLFW_TRUE; } VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, @@ -287,7 +292,31 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface) { - // This seems like the most appropriate error to return here - return VK_ERROR_INITIALIZATION_FAILED; + VkResult err; + VkAndroidSurfaceCreateInfoKHR sci; + PFN_vkCreateAndroidSurfaceKHR vkCreateAndroidSurfaceKHR; + + vkCreateAndroidSurfaceKHR = (PFN_vkCreateAndroidSurfaceKHR) + vkGetInstanceProcAddr(instance, "vkCreateAndroidSurfaceKHR"); + if (!vkCreateAndroidSurfaceKHR) + { + _glfwInputError(GLFW_API_UNAVAILABLE, + "Android: Vulkan instance missing VK_KHR_android_surface extension"); + return VK_ERROR_EXTENSION_NOT_PRESENT; + } + + memset(&sci, 0, sizeof(sci)); + sci.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR; + sci.surface = window->android.window; + + err = vkCreateAndroidSurfaceKHR(instance, &sci, allocator, surface); + if (err) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Android: Failed to create Vulkan surface: %s", + _glfwGetVulkanResultString(err)); + } + + return err; } diff --git a/src/internal.h b/src/internal.h index 4c38103e4..3f3575b02 100644 --- a/src/internal.h +++ b/src/internal.h @@ -127,6 +127,7 @@ typedef enum VkStructureType VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR = 1000007000, VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000, VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK = 1000053000, + VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR = 1000008000, VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF } VkStructureType; @@ -590,6 +591,8 @@ struct _GLFWlibrary GLFWbool KHR_wayland_surface; #elif defined(_GLFW_MIR) GLFWbool KHR_mir_surface; +#elif defined(_GLFW_ANDROID) + GLFWbool KHR_android_surface; #endif } vk; diff --git a/src/vulkan.c b/src/vulkan.c index f2473cf6e..70730407d 100644 --- a/src/vulkan.c +++ b/src/vulkan.c @@ -137,6 +137,9 @@ GLFWbool _glfwInitVulkan(int mode) #elif defined(_GLFW_MIR) else if (strcmp(ep[i].extensionName, "VK_KHR_mir_surface") == 0) _glfw.vk.KHR_mir_surface = GLFW_TRUE; +#elif defined(_GLFW_ANDROID) + else if (strcmp(ep[i].extensionName, "VK_KHR_android_surface") == 0) + _glfw.vk.KHR_android_surface = GLFW_TRUE; #endif }