upgrade SDL to version 2.0.8
[platform/upstream/SDL.git] / src / video / tizen / SDL_tizenvulkan.c
index 8aed194..e776228 100755 (executable)
      misrepresented as being the original software.
   3. This notice may not be removed or altered from any source distribution.
 */
-#include "../../SDL_internal.h"
 
-#include "../SDL_sysvideo.h"
+#include "../../SDL_internal.h"
 
-#include "SDL_syswm.h"
-#include "SDL_video.h"
-#include "SDL_loadso.h"
+#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_TIZEN
 
-#include "SDL_tizenwindow.h"
 #include "SDL_tizenvideo.h"
-#include "SDL_tizenvulkan.h"
-#include "SDL_log.h"
-
-#if SDL_VIDEO_VULKAN
-#define DEFAULT_VULKAN "libvulkan.so"
+#include "SDL_tizenwindow.h"
+#include "SDL_assert.h"
 
-#define LOAD_FUNC(NAME) \
-_this->vk_data->NAME = SDL_LoadFunction(_this->vk_data->vk_dll_handle, #NAME); \
-if (!_this->vk_data->NAME) \
-{ \
-    SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "Could not retrieve Vulkan function " #NAME); \
-    return -1; \
-}
+#include "SDL_loadso.h"
+#include "SDL_tizenvulkan.h"
+#include "SDL_syswm.h"
 
-SDL_bool
-Tizen_vulkan_GetInstanceExtensions(_THIS, const char* driver, unsigned int* count, char** names)
+int Tizen_Vulkan_LoadLibrary(_THIS, const char *path)
 {
-    uint32_t instance_extension_count = 0;
-    uint32_t enabled_extension_count = 0;
-    VkResult err;
-
-    if (strcmp(driver, "tizen")) {
-        SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "Unsupported video driver '%s'", driver);
-        return SDL_FALSE;
+    VkExtensionProperties *extensions = NULL;
+    Uint32 i, extensionCount = 0;
+    SDL_bool hasSurfaceExtension = SDL_FALSE;
+    SDL_bool hasWaylandSurfaceExtension = SDL_FALSE;
+    PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;
+    if(_this->vulkan_config.loader_handle)
+        return SDL_SetError("Vulkan already loaded");
+
+    /* Load the Vulkan loader library */
+    if(!path)
+        path = SDL_getenv("SDL_VULKAN_LIBRARY");
+    if(!path)
+        path = "libvulkan.so.1";
+    _this->vulkan_config.loader_handle = SDL_LoadObject(path);
+    if(!_this->vulkan_config.loader_handle)
+        return -1;
+    SDL_strlcpy(_this->vulkan_config.loader_path, path,
+                SDL_arraysize(_this->vulkan_config.loader_path));
+    vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)SDL_LoadFunction(
+        _this->vulkan_config.loader_handle, "vkGetInstanceProcAddr");
+    if(!vkGetInstanceProcAddr)
+        goto fail;
+    _this->vulkan_config.vkGetInstanceProcAddr = (void *)vkGetInstanceProcAddr;
+    _this->vulkan_config.vkEnumerateInstanceExtensionProperties =
+        (void *)((PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr)(
+            VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties");
+    if(!_this->vulkan_config.vkEnumerateInstanceExtensionProperties)
+        goto fail;
+    extensions = SDL_Vulkan_CreateInstanceExtensionsList(
+        (PFN_vkEnumerateInstanceExtensionProperties)
+            _this->vulkan_config.vkEnumerateInstanceExtensionProperties,
+        &extensionCount);
+    if(!extensions)
+        goto fail;
+    for(i = 0; i < extensionCount; i++)
+    {
+        if(SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
+            hasSurfaceExtension = SDL_TRUE;
+        else if(SDL_strcmp(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
+            hasWaylandSurfaceExtension = SDL_TRUE;
     }
-
-    if (!names) *count = 0;
-
-    err = _this->vk_data->vkEnumerateInstanceExtensionProperties(NULL, &instance_extension_count, NULL);
-    if (err < 0) {
-        SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "Fail to get Instance extension");
-        return SDL_FALSE;
+    SDL_free(extensions);
+    if(!hasSurfaceExtension)
+    {
+        SDL_SetError("Installed Vulkan doesn't implement the "
+                     VK_KHR_SURFACE_EXTENSION_NAME " extension");
+        goto fail;
     }
-
-    if (instance_extension_count > 0) {
-        uint32_t i;
-        VkExtensionProperties *instance_extensions =
-            malloc(sizeof(VkExtensionProperties) * instance_extension_count);
-        err = _this->vk_data->vkEnumerateInstanceExtensionProperties(
-            NULL, &instance_extension_count, instance_extensions);
-        for (i = 0; i < instance_extension_count; i++) {
-            if (!strcmp(VK_KHR_SURFACE_EXTENSION_NAME,instance_extensions[i].extensionName)) {
-                if (names && (*count > 0)) names[enabled_extension_count++] = VK_KHR_SURFACE_EXTENSION_NAME;
-                else enabled_extension_count++;
-            }
-
-            if (!strcmp(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME,instance_extensions[i].extensionName)) {
-                if (names && (*count > 0)) names[enabled_extension_count++] = VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME;
-                else enabled_extension_count++;
-            }
-        }
-        free(instance_extensions);
+    else if(!hasWaylandSurfaceExtension)
+    {
+        SDL_SetError("Installed Vulkan doesn't implement the "
+                     VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME "extension");
+        goto fail;
     }
+    return 0;
 
-    if (*count == 0)
-        *count = enabled_extension_count;
-
-    return SDL_TRUE;
+fail:
+    SDL_UnloadObject(_this->vulkan_config.loader_handle);
+    _this->vulkan_config.loader_handle = NULL;
+    return -1;
 }
 
-SDL_bool
-Tizen_vulkan_CreateSurface(_THIS, SDL_Window* window, SDL_vulkanInstance instance, SDL_vulkanSurface* surface)
+void Tizen_Vulkan_UnloadLibrary(_THIS)
 {
-    SDL_SysWMinfo wminfo;
-    SDL_WindowData *wmdata = (SDL_WindowData *)window->driverdata;
-    SDL_VideoData  *video_data  = (SDL_VideoData *)_this->driverdata;
-
-    if (!SDL_GetWindowWMInfo(window, &wminfo))
-        return SDL_FALSE;
-
-    switch (wminfo.subsystem)
+    if(_this->vulkan_config.loader_handle)
     {
-    case SDL_SYSWM_TIZEN:
-        {
-            VkWaylandSurfaceCreateInfoKHR createInfo;
-            VkResult ret;
-            createInfo.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR;
-            createInfo.pNext = NULL;
-            createInfo.flags = 0;
-            createInfo.display = video_data->display;
-            createInfo.surface = wmdata->surface;
-
-            ret = _this->vk_data->vkCreateWaylandSurfaceKHR((VkInstance)instance, &createInfo, NULL, (VkSurfaceKHR*)surface);
-            if (ret != VK_SUCCESS) {
-                SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "fail to vkCreateWaylandSurfaceKHR : %i", (int)ret);
-                return SDL_FALSE;
-            }
-            return SDL_TRUE;
-        }
-    default:
-        (void)surface;
-        SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "Unsupported subsystem %i", (int)wminfo.subsystem);
-        return SDL_FALSE;
+        SDL_UnloadObject(_this->vulkan_config.loader_handle);
+        _this->vulkan_config.loader_handle = NULL;
     }
 }
 
-
-int
-Tizen_vulkan_LoadLibrary(_THIS, const char *vk_path)
+SDL_bool Tizen_Vulkan_GetInstanceExtensions(_THIS,
+                                          SDL_Window *window,
+                                          unsigned *count,
+                                          const char **names)
 {
-    void *vk_dll_handle = NULL;
-    char *path = NULL;
-
-    if (_this->vk_config.driver_loaded) {
-        return 0;
-    }
-
-    _this->vk_data = (struct SDL_vulkan_Data *) SDL_calloc(1, sizeof(SDL_vulkan_Data));
-    if (!_this->vk_data) {
-        return SDL_OutOfMemory();
+    static const char *const extensionsForTizen[] = {
+        VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME
+    };
+    if(!_this->vulkan_config.loader_handle)
+    {
+        SDL_SetError("Vulkan is not loaded");
+        return SDL_FALSE;
     }
+    return SDL_Vulkan_GetInstanceExtensions_Helper(
+            count, names, SDL_arraysize(extensionsForTizen),
+            extensionsForTizen);
+}
 
-    if (vk_path) {
-        vk_dll_handle = SDL_LoadObject(vk_path);
+SDL_bool Tizen_Vulkan_CreateSurface(_THIS,
+                                  SDL_Window *window,
+                                  VkInstance instance,
+                                  VkSurfaceKHR *surface)
+{
+    SDL_WindowData *windowData = (SDL_WindowData *)window->driverdata;
+    SDL_VideoData* video_data = (SDL_VideoData *)_this->driverdata;
+    PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
+        (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
+    PFN_vkCreateWaylandSurfaceKHR vkCreateWaylandSurfaceKHR =
+        (PFN_vkCreateWaylandSurfaceKHR)vkGetInstanceProcAddr(
+                                            (VkInstance)instance,
+                                            "vkCreateWaylandSurfaceKHR");
+    VkWaylandSurfaceCreateInfoKHR createInfo;
+    VkResult result;
+
+    if(!_this->vulkan_config.loader_handle)
+    {
+        SDL_SetError("Vulkan is not loaded");
+        return SDL_FALSE;
     }
 
-    if (!vk_dll_handle) {
-        path = SDL_getenv("SDL_VIDEO_VULKAN_DRIVER");
-
-        if (!path) {
-            path = DEFAULT_VULKAN;
-        }
-
-        vk_dll_handle = SDL_LoadObject(path);
+    if(!vkCreateWaylandSurfaceKHR)
+    {
+        SDL_SetError(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME
+                     " extension is not enabled in the Vulkan instance.");
+        return SDL_FALSE;
     }
-
-    _this->vk_data->vk_dll_handle = vk_dll_handle;
-
-    if (vk_dll_handle == NULL) {
-        SDL_LogError(SDL_LOG_CATEGORY_ASSERT, "Could not initialize Vulkan library");
-        return -1;
+    SDL_zero(createInfo);
+    createInfo.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR;
+    createInfo.pNext = NULL;
+    createInfo.flags = 0;
+    createInfo.display = video_data->display;
+    createInfo.surface =  windowData->surface;
+    result = vkCreateWaylandSurfaceKHR(instance, &createInfo,
+                                       NULL, surface);
+    if(result != VK_SUCCESS)
+    {
+        SDL_SetError("vkCreateWaylandSurfaceKHR failed: %s",
+                     SDL_Vulkan_GetResultString(result));
+        return SDL_FALSE;
     }
-
-    LOAD_FUNC(vkEnumerateInstanceExtensionProperties);
-    LOAD_FUNC(vkCreateWaylandSurfaceKHR);
-
-    _this->vk_config.driver_loaded = 1;
-
-    return 0;
+    return SDL_TRUE;
 }
 
-#endif
+#endif
\ No newline at end of file