twitchapon-anim

Basic Twitchapon Receiver/Visuals
git clone git://bsandro.tech/twitchapon-anim
Log | Files | Refs | README | LICENSE

vulkan.c (11752B)


      1 //========================================================================
      2 // GLFW 3.3 - www.glfw.org
      3 //------------------------------------------------------------------------
      4 // Copyright (c) 2002-2006 Marcus Geelnard
      5 // Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
      6 //
      7 // This software is provided 'as-is', without any express or implied
      8 // warranty. In no event will the authors be held liable for any damages
      9 // arising from the use of this software.
     10 //
     11 // Permission is granted to anyone to use this software for any purpose,
     12 // including commercial applications, and to alter it and redistribute it
     13 // freely, subject to the following restrictions:
     14 //
     15 // 1. The origin of this software must not be misrepresented; you must not
     16 //    claim that you wrote the original software. If you use this software
     17 //    in a product, an acknowledgment in the product documentation would
     18 //    be appreciated but is not required.
     19 //
     20 // 2. Altered source versions must be plainly marked as such, and must not
     21 //    be misrepresented as being the original software.
     22 //
     23 // 3. This notice may not be removed or altered from any source
     24 //    distribution.
     25 //
     26 //========================================================================
     27 // Please use C89 style variable declarations in this file because VS 2010
     28 //========================================================================
     29 
     30 #include "internal.h"
     31 
     32 #include <assert.h>
     33 #include <string.h>
     34 #include <stdlib.h>
     35 
     36 #define _GLFW_FIND_LOADER    1
     37 #define _GLFW_REQUIRE_LOADER 2
     38 
     39 
     40 //////////////////////////////////////////////////////////////////////////
     41 //////                       GLFW internal API                      //////
     42 //////////////////////////////////////////////////////////////////////////
     43 
     44 GLFWbool _glfwInitVulkan(int mode)
     45 {
     46     VkResult err;
     47     VkExtensionProperties* ep;
     48     uint32_t i, count;
     49 
     50     if (_glfw.vk.available)
     51         return GLFW_TRUE;
     52 
     53 #if !defined(_GLFW_VULKAN_STATIC)
     54 #if defined(_GLFW_VULKAN_LIBRARY)
     55     _glfw.vk.handle = _glfw_dlopen(_GLFW_VULKAN_LIBRARY);
     56 #elif defined(_GLFW_WIN32)
     57     _glfw.vk.handle = _glfw_dlopen("vulkan-1.dll");
     58 #elif defined(_GLFW_COCOA)
     59     _glfw.vk.handle = _glfw_dlopen("libvulkan.1.dylib");
     60     if (!_glfw.vk.handle)
     61         _glfw.vk.handle = _glfwLoadLocalVulkanLoaderNS();
     62 #else
     63     _glfw.vk.handle = _glfw_dlopen("libvulkan.so.1");
     64 #endif
     65     if (!_glfw.vk.handle)
     66     {
     67         if (mode == _GLFW_REQUIRE_LOADER)
     68             _glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: Loader not found");
     69 
     70         return GLFW_FALSE;
     71     }
     72 
     73     _glfw.vk.GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)
     74         _glfw_dlsym(_glfw.vk.handle, "vkGetInstanceProcAddr");
     75     if (!_glfw.vk.GetInstanceProcAddr)
     76     {
     77         _glfwInputError(GLFW_API_UNAVAILABLE,
     78                         "Vulkan: Loader does not export vkGetInstanceProcAddr");
     79 
     80         _glfwTerminateVulkan();
     81         return GLFW_FALSE;
     82     }
     83 
     84     _glfw.vk.EnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties)
     85         vkGetInstanceProcAddr(NULL, "vkEnumerateInstanceExtensionProperties");
     86     if (!_glfw.vk.EnumerateInstanceExtensionProperties)
     87     {
     88         _glfwInputError(GLFW_API_UNAVAILABLE,
     89                         "Vulkan: Failed to retrieve vkEnumerateInstanceExtensionProperties");
     90 
     91         _glfwTerminateVulkan();
     92         return GLFW_FALSE;
     93     }
     94 #endif // _GLFW_VULKAN_STATIC
     95 
     96     err = vkEnumerateInstanceExtensionProperties(NULL, &count, NULL);
     97     if (err)
     98     {
     99         // NOTE: This happens on systems with a loader but without any Vulkan ICD
    100         if (mode == _GLFW_REQUIRE_LOADER)
    101         {
    102             _glfwInputError(GLFW_API_UNAVAILABLE,
    103                             "Vulkan: Failed to query instance extension count: %s",
    104                             _glfwGetVulkanResultString(err));
    105         }
    106 
    107         _glfwTerminateVulkan();
    108         return GLFW_FALSE;
    109     }
    110 
    111     ep = calloc(count, sizeof(VkExtensionProperties));
    112 
    113     err = vkEnumerateInstanceExtensionProperties(NULL, &count, ep);
    114     if (err)
    115     {
    116         _glfwInputError(GLFW_API_UNAVAILABLE,
    117                         "Vulkan: Failed to query instance extensions: %s",
    118                         _glfwGetVulkanResultString(err));
    119 
    120         free(ep);
    121         _glfwTerminateVulkan();
    122         return GLFW_FALSE;
    123     }
    124 
    125     for (i = 0;  i < count;  i++)
    126     {
    127         if (strcmp(ep[i].extensionName, "VK_KHR_surface") == 0)
    128             _glfw.vk.KHR_surface = GLFW_TRUE;
    129 #if defined(_GLFW_WIN32)
    130         else if (strcmp(ep[i].extensionName, "VK_KHR_win32_surface") == 0)
    131             _glfw.vk.KHR_win32_surface = GLFW_TRUE;
    132 #elif defined(_GLFW_COCOA)
    133         else if (strcmp(ep[i].extensionName, "VK_MVK_macos_surface") == 0)
    134             _glfw.vk.MVK_macos_surface = GLFW_TRUE;
    135         else if (strcmp(ep[i].extensionName, "VK_EXT_metal_surface") == 0)
    136             _glfw.vk.EXT_metal_surface = GLFW_TRUE;
    137 #elif defined(_GLFW_X11)
    138         else if (strcmp(ep[i].extensionName, "VK_KHR_xlib_surface") == 0)
    139             _glfw.vk.KHR_xlib_surface = GLFW_TRUE;
    140         else if (strcmp(ep[i].extensionName, "VK_KHR_xcb_surface") == 0)
    141             _glfw.vk.KHR_xcb_surface = GLFW_TRUE;
    142 #elif defined(_GLFW_WAYLAND)
    143         else if (strcmp(ep[i].extensionName, "VK_KHR_wayland_surface") == 0)
    144             _glfw.vk.KHR_wayland_surface = GLFW_TRUE;
    145 #endif
    146     }
    147 
    148     free(ep);
    149 
    150     _glfw.vk.available = GLFW_TRUE;
    151 
    152     _glfwPlatformGetRequiredInstanceExtensions(_glfw.vk.extensions);
    153 
    154     return GLFW_TRUE;
    155 }
    156 
    157 void _glfwTerminateVulkan(void)
    158 {
    159 #if !defined(_GLFW_VULKAN_STATIC)
    160     if (_glfw.vk.handle)
    161         _glfw_dlclose(_glfw.vk.handle);
    162 #endif
    163 }
    164 
    165 const char* _glfwGetVulkanResultString(VkResult result)
    166 {
    167     switch (result)
    168     {
    169         case VK_SUCCESS:
    170             return "Success";
    171         case VK_NOT_READY:
    172             return "A fence or query has not yet completed";
    173         case VK_TIMEOUT:
    174             return "A wait operation has not completed in the specified time";
    175         case VK_EVENT_SET:
    176             return "An event is signaled";
    177         case VK_EVENT_RESET:
    178             return "An event is unsignaled";
    179         case VK_INCOMPLETE:
    180             return "A return array was too small for the result";
    181         case VK_ERROR_OUT_OF_HOST_MEMORY:
    182             return "A host memory allocation has failed";
    183         case VK_ERROR_OUT_OF_DEVICE_MEMORY:
    184             return "A device memory allocation has failed";
    185         case VK_ERROR_INITIALIZATION_FAILED:
    186             return "Initialization of an object could not be completed for implementation-specific reasons";
    187         case VK_ERROR_DEVICE_LOST:
    188             return "The logical or physical device has been lost";
    189         case VK_ERROR_MEMORY_MAP_FAILED:
    190             return "Mapping of a memory object has failed";
    191         case VK_ERROR_LAYER_NOT_PRESENT:
    192             return "A requested layer is not present or could not be loaded";
    193         case VK_ERROR_EXTENSION_NOT_PRESENT:
    194             return "A requested extension is not supported";
    195         case VK_ERROR_FEATURE_NOT_PRESENT:
    196             return "A requested feature is not supported";
    197         case VK_ERROR_INCOMPATIBLE_DRIVER:
    198             return "The requested version of Vulkan is not supported by the driver or is otherwise incompatible";
    199         case VK_ERROR_TOO_MANY_OBJECTS:
    200             return "Too many objects of the type have already been created";
    201         case VK_ERROR_FORMAT_NOT_SUPPORTED:
    202             return "A requested format is not supported on this device";
    203         case VK_ERROR_SURFACE_LOST_KHR:
    204             return "A surface is no longer available";
    205         case VK_SUBOPTIMAL_KHR:
    206             return "A swapchain no longer matches the surface properties exactly, but can still be used";
    207         case VK_ERROR_OUT_OF_DATE_KHR:
    208             return "A surface has changed in such a way that it is no longer compatible with the swapchain";
    209         case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR:
    210             return "The display used by a swapchain does not use the same presentable image layout";
    211         case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR:
    212             return "The requested window is already connected to a VkSurfaceKHR, or to some other non-Vulkan API";
    213         case VK_ERROR_VALIDATION_FAILED_EXT:
    214             return "A validation layer found an error";
    215         default:
    216             return "ERROR: UNKNOWN VULKAN ERROR";
    217     }
    218 }
    219 
    220 
    221 //////////////////////////////////////////////////////////////////////////
    222 //////                        GLFW public API                       //////
    223 //////////////////////////////////////////////////////////////////////////
    224 
    225 GLFWAPI int glfwVulkanSupported(void)
    226 {
    227     _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
    228     return _glfwInitVulkan(_GLFW_FIND_LOADER);
    229 }
    230 
    231 GLFWAPI const char** glfwGetRequiredInstanceExtensions(uint32_t* count)
    232 {
    233     assert(count != NULL);
    234 
    235     *count = 0;
    236 
    237     _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
    238 
    239     if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER))
    240         return NULL;
    241 
    242     if (!_glfw.vk.extensions[0])
    243         return NULL;
    244 
    245     *count = 2;
    246     return (const char**) _glfw.vk.extensions;
    247 }
    248 
    249 GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance,
    250                                               const char* procname)
    251 {
    252     GLFWvkproc proc;
    253     assert(procname != NULL);
    254 
    255     _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
    256 
    257     if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER))
    258         return NULL;
    259 
    260     proc = (GLFWvkproc) vkGetInstanceProcAddr(instance, procname);
    261 #if defined(_GLFW_VULKAN_STATIC)
    262     if (!proc)
    263     {
    264         if (strcmp(procname, "vkGetInstanceProcAddr") == 0)
    265             return (GLFWvkproc) vkGetInstanceProcAddr;
    266     }
    267 #else
    268     if (!proc)
    269         proc = (GLFWvkproc) _glfw_dlsym(_glfw.vk.handle, procname);
    270 #endif
    271 
    272     return proc;
    273 }
    274 
    275 GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance,
    276                                                      VkPhysicalDevice device,
    277                                                      uint32_t queuefamily)
    278 {
    279     assert(instance != VK_NULL_HANDLE);
    280     assert(device != VK_NULL_HANDLE);
    281 
    282     _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
    283 
    284     if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER))
    285         return GLFW_FALSE;
    286 
    287     if (!_glfw.vk.extensions[0])
    288     {
    289         _glfwInputError(GLFW_API_UNAVAILABLE,
    290                         "Vulkan: Window surface creation extensions not found");
    291         return GLFW_FALSE;
    292     }
    293 
    294     return _glfwPlatformGetPhysicalDevicePresentationSupport(instance,
    295                                                              device,
    296                                                              queuefamily);
    297 }
    298 
    299 GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance,
    300                                          GLFWwindow* handle,
    301                                          const VkAllocationCallbacks* allocator,
    302                                          VkSurfaceKHR* surface)
    303 {
    304     _GLFWwindow* window = (_GLFWwindow*) handle;
    305     assert(instance != VK_NULL_HANDLE);
    306     assert(window != NULL);
    307     assert(surface != NULL);
    308 
    309     *surface = VK_NULL_HANDLE;
    310 
    311     _GLFW_REQUIRE_INIT_OR_RETURN(VK_ERROR_INITIALIZATION_FAILED);
    312 
    313     if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER))
    314         return VK_ERROR_INITIALIZATION_FAILED;
    315 
    316     if (!_glfw.vk.extensions[0])
    317     {
    318         _glfwInputError(GLFW_API_UNAVAILABLE,
    319                         "Vulkan: Window surface creation extensions not found");
    320         return VK_ERROR_EXTENSION_NOT_PRESENT;
    321     }
    322 
    323     if (window->context.client != GLFW_NO_API)
    324     {
    325         _glfwInputError(GLFW_INVALID_VALUE,
    326                         "Vulkan: Window surface creation requires the window to have the client API set to GLFW_NO_API");
    327         return VK_ERROR_NATIVE_WINDOW_IN_USE_KHR;
    328     }
    329 
    330     return _glfwPlatformCreateWindowSurface(instance, window, allocator, surface);
    331 }
    332