SDL_DirectFB_vulkan.c (6216B)
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 #include "../../SDL_internal.h" 23 24 #if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_DIRECTFB 25 26 #include "SDL_DirectFB_window.h" 27 28 #include "SDL_loadso.h" 29 #include "SDL_DirectFB_vulkan.h" 30 31 int DirectFB_Vulkan_LoadLibrary(_THIS, const char *path) 32 { 33 VkExtensionProperties *extensions = NULL; 34 Uint32 i, extensionCount = 0; 35 SDL_bool hasSurfaceExtension = SDL_FALSE; 36 SDL_bool hasDirectFBSurfaceExtension = SDL_FALSE; 37 PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL; 38 if(_this->vulkan_config.loader_handle) 39 return SDL_SetError("Vulkan already loaded"); 40 41 /* Load the Vulkan loader library */ 42 if(!path) 43 path = SDL_getenv("SDL_VULKAN_LIBRARY"); 44 if(!path) 45 path = "libvulkan.so.1"; 46 _this->vulkan_config.loader_handle = SDL_LoadObject(path); 47 if(!_this->vulkan_config.loader_handle) 48 return -1; 49 SDL_strlcpy(_this->vulkan_config.loader_path, path, 50 SDL_arraysize(_this->vulkan_config.loader_path)); 51 vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)SDL_LoadFunction( 52 _this->vulkan_config.loader_handle, "vkGetInstanceProcAddr"); 53 if(!vkGetInstanceProcAddr) 54 goto fail; 55 _this->vulkan_config.vkGetInstanceProcAddr = (void *)vkGetInstanceProcAddr; 56 _this->vulkan_config.vkEnumerateInstanceExtensionProperties = 57 (void *)((PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr)( 58 VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties"); 59 if(!_this->vulkan_config.vkEnumerateInstanceExtensionProperties) 60 goto fail; 61 extensions = SDL_Vulkan_CreateInstanceExtensionsList( 62 (PFN_vkEnumerateInstanceExtensionProperties) 63 _this->vulkan_config.vkEnumerateInstanceExtensionProperties, 64 &extensionCount); 65 if(!extensions) 66 goto fail; 67 for(i = 0; i < extensionCount; i++) 68 { 69 if(SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) 70 hasSurfaceExtension = SDL_TRUE; 71 else if(SDL_strcmp(VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) 72 hasDirectFBSurfaceExtension = SDL_TRUE; 73 } 74 SDL_free(extensions); 75 if(!hasSurfaceExtension) 76 { 77 SDL_SetError("Installed Vulkan doesn't implement the " 78 VK_KHR_SURFACE_EXTENSION_NAME " extension"); 79 goto fail; 80 } 81 else if(!hasDirectFBSurfaceExtension) 82 { 83 SDL_SetError("Installed Vulkan doesn't implement the " 84 VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME "extension"); 85 goto fail; 86 } 87 return 0; 88 89 fail: 90 SDL_UnloadObject(_this->vulkan_config.loader_handle); 91 _this->vulkan_config.loader_handle = NULL; 92 return -1; 93 } 94 95 void DirectFB_Vulkan_UnloadLibrary(_THIS) 96 { 97 if(_this->vulkan_config.loader_handle) 98 { 99 SDL_UnloadObject(_this->vulkan_config.loader_handle); 100 _this->vulkan_config.loader_handle = NULL; 101 } 102 } 103 104 SDL_bool DirectFB_Vulkan_GetInstanceExtensions(_THIS, 105 SDL_Window *window, 106 unsigned *count, 107 const char **names) 108 { 109 static const char *const extensionsForDirectFB[] = { 110 VK_KHR_SURFACE_EXTENSION_NAME, VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME 111 }; 112 if(!_this->vulkan_config.loader_handle) 113 { 114 SDL_SetError("Vulkan is not loaded"); 115 return SDL_FALSE; 116 } 117 return SDL_Vulkan_GetInstanceExtensions_Helper( 118 count, names, SDL_arraysize(extensionsForDirectFB), 119 extensionsForDirectFB); 120 } 121 122 SDL_bool DirectFB_Vulkan_CreateSurface(_THIS, 123 SDL_Window *window, 124 VkInstance instance, 125 VkSurfaceKHR *surface) 126 { 127 SDL_DFB_DEVICEDATA(_this); 128 SDL_DFB_WINDOWDATA(window); 129 PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = 130 (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr; 131 PFN_vkCreateDirectFBSurfaceEXT vkCreateDirectFBSurfaceEXT = 132 (PFN_vkCreateDirectFBSurfaceEXT)vkGetInstanceProcAddr( 133 instance, 134 "vkCreateDirectFBSurfaceEXT"); 135 VkDirectFBSurfaceCreateInfoEXT createInfo; 136 VkResult result; 137 138 if(!_this->vulkan_config.loader_handle) 139 { 140 SDL_SetError("Vulkan is not loaded"); 141 return SDL_FALSE; 142 } 143 144 if(!vkCreateDirectFBSurfaceEXT) 145 { 146 SDL_SetError(VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME 147 " extension is not enabled in the Vulkan instance."); 148 return SDL_FALSE; 149 } 150 SDL_zero(createInfo); 151 createInfo.sType = VK_STRUCTURE_TYPE_DIRECTFB_SURFACE_CREATE_INFO_EXT; 152 createInfo.pNext = NULL; 153 createInfo.flags = 0; 154 createInfo.dfb = devdata->dfb; 155 createInfo.surface = windata->surface; 156 result = vkCreateDirectFBSurfaceEXT(instance, &createInfo, 157 NULL, surface); 158 if(result != VK_SUCCESS) 159 { 160 SDL_SetError("vkCreateDirectFBSurfaceEXT failed: %s", 161 SDL_Vulkan_GetResultString(result)); 162 return SDL_FALSE; 163 } 164 return SDL_TRUE; 165 } 166 167 #endif 168 169 /* vim: set ts=4 sw=4 expandtab: */