440811fd1b0f4ef8d45173fba816037cf0762e8c
[platform/upstream/SDL.git] / src / video / tizen / SDL_tizenvulkan.c
1 /*
2   Simple DirectMedia Layer
3   Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
4   Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
5
6   This software is provided 'as-is', without any express or implied
7   warranty.  In no event will the authors be held liable for any damages
8   arising from the use of this software.
9
10   Permission is granted to anyone to use this software for any purpose,
11   including commercial applications, and to alter it and redistribute it
12   freely, subject to the following restrictions:
13
14   1. The origin of this software must not be misrepresented; you must not
15      claim that you wrote the original software. If you use this software
16      in a product, an acknowledgment in the product documentation would be
17      appreciated but is not required.
18   2. Altered source versions must be plainly marked as such, and must not be
19      misrepresented as being the original software.
20   3. This notice may not be removed or altered from any source distribution.
21 */
22 #include "../../SDL_internal.h"
23
24 #if SDL_VIDEO_VULKAN
25
26 #include "../SDL_sysvideo.h"
27
28 #include "SDL_syswm.h"
29 #include "SDL_video.h"
30 #include "SDL_loadso.h"
31
32 #include "SDL_tizenwindow.h"
33 #include "SDL_tizenvideo.h"
34 #include "SDL_tizenvulkan.h"
35
36 #define DEFAULT_VULKAN "libvulkan.so"
37
38 #define LOAD_FUNC(NAME) \
39 _this->vk_data->NAME = SDL_LoadFunction(_this->vk_data->vk_dll_handle, #NAME); \
40 if (!_this->vk_data->NAME) \
41 { \
42     return SDL_SetError("Could not retrieve Vulkan function " #NAME); \
43 }
44
45 SDL_bool
46 Tizen_vulkan_GetInstanceExtensions(_THIS, const char* driver, unsigned int* count, char** names)
47 {
48     uint32_t instance_extension_count = 0;
49     uint32_t enabled_extension_count = 0;
50     VkResult err;
51
52     if (strcmp(driver, "tizen")) {
53         SDL_SetError("Unsupported video driver '%s'", driver);
54         return SDL_FALSE;
55     }
56
57     if (!names) *count = 0;
58
59     err = _this->vk_data->vkEnumerateInstanceExtensionProperties(NULL, &instance_extension_count, NULL);
60     if (err < 0) {
61         SDL_SetError("Fail to get Instance extension");
62         return SDL_FALSE;
63     }
64
65     if (instance_extension_count > 0) {
66         uint32_t i;
67         VkExtensionProperties *instance_extensions =
68             malloc(sizeof(VkExtensionProperties) * instance_extension_count);
69         err = _this->vk_data->vkEnumerateInstanceExtensionProperties(
70             NULL, &instance_extension_count, instance_extensions);
71         for (i = 0; i < instance_extension_count; i++) {
72             if (!strcmp(VK_KHR_SURFACE_EXTENSION_NAME,instance_extensions[i].extensionName)) {
73                 if (names && (*count > 0)) names[enabled_extension_count++] = VK_KHR_SURFACE_EXTENSION_NAME;
74                 else enabled_extension_count++;
75             }
76
77             if (!strcmp(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME,instance_extensions[i].extensionName)) {
78                 if (names && (*count > 0)) names[enabled_extension_count++] = VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME;
79                 else enabled_extension_count++;
80             }
81         }
82         free(instance_extensions);
83     }
84
85     if (*count == 0)
86         *count = enabled_extension_count;
87
88     return SDL_TRUE;
89 }
90
91 SDL_bool
92 Tizen_vulkan_CreateSurface(_THIS, SDL_Window* window, SDL_vulkanInstance instance, SDL_vulkanSurface* surface)
93 {
94     SDL_SysWMinfo wminfo;
95     SDL_WindowData *wmdata = (SDL_WindowData *)window->driverdata;
96     SDL_VideoData  *video_data  = (SDL_VideoData *)_this->driverdata;
97
98     if (!SDL_GetWindowWMInfo(window, &wminfo))
99         return SDL_FALSE;
100
101     switch (wminfo.subsystem)
102     {
103     case SDL_SYSWM_TIZEN:
104         {
105             VkWaylandSurfaceCreateInfoKHR createInfo;
106             VkResult ret;
107             createInfo.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR;
108             createInfo.pNext = NULL;
109             createInfo.flags = 0;
110             createInfo.display = video_data->display;
111             createInfo.surface = wmdata->surface;
112
113             ret = _this->vk_data->vkCreateWaylandSurfaceKHR((VkInstance)instance, &createInfo, NULL, (VkSurfaceKHR*)surface);
114             if (ret != VK_SUCCESS) {
115                 SDL_SetError("fail to vkCreateWaylandSurfaceKHR : %i", (int)ret);
116                 return SDL_FALSE;
117             }
118             return SDL_TRUE;
119         }
120     default:
121         (void)surface;
122         SDL_SetError("Unsupported subsystem %i", (int)wminfo.subsystem);
123         return SDL_FALSE;
124     }
125 }
126
127
128 int
129 Tizen_vulkan_LoadLibrary(_THIS, const char *vk_path)
130 {
131     void *vk_dll_handle = NULL;
132     char *path = NULL;
133
134     if (_this->vk_config.driver_loaded) {
135         return 0;
136     }
137
138     _this->vk_data = (struct SDL_vulkan_Data *) SDL_calloc(1, sizeof(SDL_vulkan_Data));
139     if (!_this->vk_data) {
140         return SDL_OutOfMemory();
141     }
142
143     if (vk_path) {
144         vk_dll_handle = SDL_LoadObject(vk_path);
145     }
146
147     if (!vk_dll_handle) {
148         path = SDL_getenv("SDL_VIDEO_VULKAN_DRIVER");
149
150         if (!path) {
151             path = DEFAULT_VULKAN;
152         }
153
154         vk_dll_handle = SDL_LoadObject(path);
155     }
156
157     _this->vk_data->vk_dll_handle = vk_dll_handle;
158
159     if (vk_dll_handle == NULL) {
160         return SDL_SetError("Could not initialize Vulkan library");
161     }
162
163     LOAD_FUNC(vkEnumerateInstanceExtensionProperties);
164     LOAD_FUNC(vkCreateWaylandSurfaceKHR);
165
166     _this->vk_config.driver_loaded = 1;
167
168     return 0;
169 }
170
171 #endif