SDL_androidvulkan.c (6323B)
1 /* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org> 4 5 This software is provided 'as-is', without any express or implied 6 warranty. In no event will the authors be held liable for any damages 7 arising from the use of this software. 8 9 Permission is granted to anyone to use this software for any purpose, 10 including commercial applications, and to alter it and redistribute it 11 freely, subject to the following restrictions: 12 13 1. The origin of this software must not be misrepresented; you must not 14 claim that you wrote the original software. If you use this software 15 in a product, an acknowledgment in the product documentation would be 16 appreciated but is not required. 17 2. Altered source versions must be plainly marked as such, and must not be 18 misrepresented as being the original software. 19 3. This notice may not be removed or altered from any source distribution. 20 */ 21 22 /* 23 * @author Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's 24 * SDL_x11vulkan.c. 25 */ 26 27 #include "../../SDL_internal.h" 28 29 #if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_ANDROID 30 31 #include "SDL_androidvideo.h" 32 #include "SDL_androidwindow.h" 33 34 #include "SDL_loadso.h" 35 #include "SDL_androidvulkan.h" 36 #include "SDL_syswm.h" 37 38 int Android_Vulkan_LoadLibrary(_THIS, const char *path) 39 { 40 VkExtensionProperties *extensions = NULL; 41 Uint32 i, extensionCount = 0; 42 SDL_bool hasSurfaceExtension = SDL_FALSE; 43 SDL_bool hasAndroidSurfaceExtension = SDL_FALSE; 44 PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL; 45 if(_this->vulkan_config.loader_handle) 46 return SDL_SetError("Vulkan already loaded"); 47 48 /* Load the Vulkan loader library */ 49 if(!path) 50 path = SDL_getenv("SDL_VULKAN_LIBRARY"); 51 if(!path) 52 path = "libvulkan.so"; 53 _this->vulkan_config.loader_handle = SDL_LoadObject(path); 54 if(!_this->vulkan_config.loader_handle) 55 return -1; 56 SDL_strlcpy(_this->vulkan_config.loader_path, path, 57 SDL_arraysize(_this->vulkan_config.loader_path)); 58 vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)SDL_LoadFunction( 59 _this->vulkan_config.loader_handle, "vkGetInstanceProcAddr"); 60 if(!vkGetInstanceProcAddr) 61 goto fail; 62 _this->vulkan_config.vkGetInstanceProcAddr = (void *)vkGetInstanceProcAddr; 63 _this->vulkan_config.vkEnumerateInstanceExtensionProperties = 64 (void *)((PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr)( 65 VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties"); 66 if(!_this->vulkan_config.vkEnumerateInstanceExtensionProperties) 67 goto fail; 68 extensions = SDL_Vulkan_CreateInstanceExtensionsList( 69 (PFN_vkEnumerateInstanceExtensionProperties) 70 _this->vulkan_config.vkEnumerateInstanceExtensionProperties, 71 &extensionCount); 72 if(!extensions) 73 goto fail; 74 for(i = 0; i < extensionCount; i++) 75 { 76 if(SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) 77 hasSurfaceExtension = SDL_TRUE; 78 else if(SDL_strcmp(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) 79 hasAndroidSurfaceExtension = SDL_TRUE; 80 } 81 SDL_free(extensions); 82 if(!hasSurfaceExtension) 83 { 84 SDL_SetError("Installed Vulkan doesn't implement the " 85 VK_KHR_SURFACE_EXTENSION_NAME " extension"); 86 goto fail; 87 } 88 else if(!hasAndroidSurfaceExtension) 89 { 90 SDL_SetError("Installed Vulkan doesn't implement the " 91 VK_KHR_ANDROID_SURFACE_EXTENSION_NAME "extension"); 92 goto fail; 93 } 94 return 0; 95 96 fail: 97 SDL_UnloadObject(_this->vulkan_config.loader_handle); 98 _this->vulkan_config.loader_handle = NULL; 99 return -1; 100 } 101 102 void Android_Vulkan_UnloadLibrary(_THIS) 103 { 104 if(_this->vulkan_config.loader_handle) 105 { 106 SDL_UnloadObject(_this->vulkan_config.loader_handle); 107 _this->vulkan_config.loader_handle = NULL; 108 } 109 } 110 111 SDL_bool Android_Vulkan_GetInstanceExtensions(_THIS, 112 SDL_Window *window, 113 unsigned *count, 114 const char **names) 115 { 116 static const char *const extensionsForAndroid[] = { 117 VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_ANDROID_SURFACE_EXTENSION_NAME 118 }; 119 if(!_this->vulkan_config.loader_handle) 120 { 121 SDL_SetError("Vulkan is not loaded"); 122 return SDL_FALSE; 123 } 124 return SDL_Vulkan_GetInstanceExtensions_Helper( 125 count, names, SDL_arraysize(extensionsForAndroid), 126 extensionsForAndroid); 127 } 128 129 SDL_bool Android_Vulkan_CreateSurface(_THIS, 130 SDL_Window *window, 131 VkInstance instance, 132 VkSurfaceKHR *surface) 133 { 134 SDL_WindowData *windowData = (SDL_WindowData *)window->driverdata; 135 PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = 136 (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr; 137 PFN_vkCreateAndroidSurfaceKHR vkCreateAndroidSurfaceKHR = 138 (PFN_vkCreateAndroidSurfaceKHR)vkGetInstanceProcAddr( 139 instance, 140 "vkCreateAndroidSurfaceKHR"); 141 VkAndroidSurfaceCreateInfoKHR createInfo; 142 VkResult result; 143 144 if(!_this->vulkan_config.loader_handle) 145 { 146 SDL_SetError("Vulkan is not loaded"); 147 return SDL_FALSE; 148 } 149 150 if(!vkCreateAndroidSurfaceKHR) 151 { 152 SDL_SetError(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME 153 " extension is not enabled in the Vulkan instance."); 154 return SDL_FALSE; 155 } 156 SDL_zero(createInfo); 157 createInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR; 158 createInfo.pNext = NULL; 159 createInfo.flags = 0; 160 createInfo.window = windowData->native_window; 161 result = vkCreateAndroidSurfaceKHR(instance, &createInfo, 162 NULL, surface); 163 if(result != VK_SUCCESS) 164 { 165 SDL_SetError("vkCreateAndroidSurfaceKHR failed: %s", 166 SDL_Vulkan_GetResultString(result)); 167 return SDL_FALSE; 168 } 169 return SDL_TRUE; 170 } 171 172 #endif 173 174 /* vi: set ts=4 sw=4 expandtab: */