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