src/video/android/SDL_androidvulkan.c
author Sylvain Becker <sylvain.becker@gmail.com>
Thu, 03 Jan 2019 16:22:33 +0100
changeset 12497 9e13f3286831
parent 11872 e917e911dab6
child 12503 806492103856
permissions -rw-r--r--
Android: prevent the error message from SDL_EGL_CreateSurface() to be masked.
icculus@11365
     1
/*
icculus@11365
     2
  Simple DirectMedia Layer
slouken@11811
     3
  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
icculus@11365
     4
icculus@11365
     5
  This software is provided 'as-is', without any express or implied
icculus@11365
     6
  warranty.  In no event will the authors be held liable for any damages
icculus@11365
     7
  arising from the use of this software.
icculus@11365
     8
icculus@11365
     9
  Permission is granted to anyone to use this software for any purpose,
icculus@11365
    10
  including commercial applications, and to alter it and redistribute it
icculus@11365
    11
  freely, subject to the following restrictions:
icculus@11365
    12
icculus@11365
    13
  1. The origin of this software must not be misrepresented; you must not
icculus@11365
    14
     claim that you wrote the original software. If you use this software
icculus@11365
    15
     in a product, an acknowledgment in the product documentation would be
icculus@11365
    16
     appreciated but is not required.
icculus@11365
    17
  2. Altered source versions must be plainly marked as such, and must not be
icculus@11365
    18
     misrepresented as being the original software.
icculus@11365
    19
  3. This notice may not be removed or altered from any source distribution.
icculus@11365
    20
*/
icculus@11365
    21
icculus@11365
    22
/*
icculus@11365
    23
 * @author Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
icculus@11365
    24
 * SDL_x11vulkan.c.
icculus@11365
    25
 */
icculus@11365
    26
icculus@11365
    27
#include "../../SDL_internal.h"
icculus@11365
    28
slouken@11381
    29
#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_ANDROID
icculus@11365
    30
icculus@11365
    31
#include "SDL_androidvideo.h"
icculus@11365
    32
#include "SDL_androidwindow.h"
icculus@11365
    33
#include "SDL_assert.h"
icculus@11365
    34
icculus@11365
    35
#include "SDL_loadso.h"
icculus@11365
    36
#include "SDL_androidvulkan.h"
icculus@11365
    37
#include "SDL_syswm.h"
icculus@11365
    38
icculus@11365
    39
int Android_Vulkan_LoadLibrary(_THIS, const char *path)
icculus@11365
    40
{
icculus@11365
    41
    VkExtensionProperties *extensions = NULL;
slouken@11380
    42
    Uint32 i, extensionCount = 0;
icculus@11365
    43
    SDL_bool hasSurfaceExtension = SDL_FALSE;
icculus@11365
    44
    SDL_bool hasAndroidSurfaceExtension = SDL_FALSE;
icculus@11365
    45
    PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;
icculus@11365
    46
    if(_this->vulkan_config.loader_handle)
icculus@11365
    47
        return SDL_SetError("Vulkan already loaded");
icculus@11365
    48
icculus@11365
    49
    /* Load the Vulkan loader library */
icculus@11365
    50
    if(!path)
icculus@11365
    51
        path = SDL_getenv("SDL_VULKAN_LIBRARY");
icculus@11365
    52
    if(!path)
slouken@11456
    53
        path = "libvulkan.so";
icculus@11365
    54
    _this->vulkan_config.loader_handle = SDL_LoadObject(path);
icculus@11365
    55
    if(!_this->vulkan_config.loader_handle)
icculus@11365
    56
        return -1;
icculus@11365
    57
    SDL_strlcpy(_this->vulkan_config.loader_path, path,
icculus@11365
    58
                SDL_arraysize(_this->vulkan_config.loader_path));
sezero@11872
    59
    vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)SDL_LoadFunction(
icculus@11365
    60
        _this->vulkan_config.loader_handle, "vkGetInstanceProcAddr");
icculus@11365
    61
    if(!vkGetInstanceProcAddr)
icculus@11365
    62
        goto fail;
sezero@11872
    63
    _this->vulkan_config.vkGetInstanceProcAddr = (void *)vkGetInstanceProcAddr;
icculus@11365
    64
    _this->vulkan_config.vkEnumerateInstanceExtensionProperties =
sezero@11872
    65
        (void *)((PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr)(
icculus@11365
    66
            VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties");
icculus@11365
    67
    if(!_this->vulkan_config.vkEnumerateInstanceExtensionProperties)
icculus@11365
    68
        goto fail;
icculus@11365
    69
    extensions = SDL_Vulkan_CreateInstanceExtensionsList(
icculus@11365
    70
        (PFN_vkEnumerateInstanceExtensionProperties)
icculus@11365
    71
            _this->vulkan_config.vkEnumerateInstanceExtensionProperties,
icculus@11365
    72
        &extensionCount);
icculus@11365
    73
    if(!extensions)
icculus@11365
    74
        goto fail;
slouken@11380
    75
    for(i = 0; i < extensionCount; i++)
icculus@11365
    76
    {
icculus@11365
    77
        if(SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
icculus@11365
    78
            hasSurfaceExtension = SDL_TRUE;
icculus@11365
    79
        else if(SDL_strcmp(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
icculus@11365
    80
            hasAndroidSurfaceExtension = SDL_TRUE;
icculus@11365
    81
    }
icculus@11365
    82
    SDL_free(extensions);
icculus@11365
    83
    if(!hasSurfaceExtension)
icculus@11365
    84
    {
icculus@11365
    85
        SDL_SetError("Installed Vulkan doesn't implement the "
icculus@11365
    86
                     VK_KHR_SURFACE_EXTENSION_NAME " extension");
icculus@11365
    87
        goto fail;
icculus@11365
    88
    }
icculus@11365
    89
    else if(!hasAndroidSurfaceExtension)
icculus@11365
    90
    {
icculus@11365
    91
        SDL_SetError("Installed Vulkan doesn't implement the "
icculus@11365
    92
                     VK_KHR_ANDROID_SURFACE_EXTENSION_NAME "extension");
icculus@11365
    93
        goto fail;
icculus@11365
    94
    }
icculus@11365
    95
    return 0;
icculus@11365
    96
icculus@11365
    97
fail:
icculus@11365
    98
    SDL_UnloadObject(_this->vulkan_config.loader_handle);
icculus@11365
    99
    _this->vulkan_config.loader_handle = NULL;
icculus@11365
   100
    return -1;
icculus@11365
   101
}
icculus@11365
   102
icculus@11365
   103
void Android_Vulkan_UnloadLibrary(_THIS)
icculus@11365
   104
{
icculus@11365
   105
    if(_this->vulkan_config.loader_handle)
icculus@11365
   106
    {
icculus@11365
   107
        SDL_UnloadObject(_this->vulkan_config.loader_handle);
icculus@11365
   108
        _this->vulkan_config.loader_handle = NULL;
icculus@11365
   109
    }
icculus@11365
   110
}
icculus@11365
   111
icculus@11365
   112
SDL_bool Android_Vulkan_GetInstanceExtensions(_THIS,
icculus@11365
   113
                                          SDL_Window *window,
icculus@11365
   114
                                          unsigned *count,
icculus@11365
   115
                                          const char **names)
icculus@11365
   116
{
icculus@11365
   117
    static const char *const extensionsForAndroid[] = {
icculus@11365
   118
        VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_ANDROID_SURFACE_EXTENSION_NAME
icculus@11365
   119
    };
icculus@11365
   120
    if(!_this->vulkan_config.loader_handle)
icculus@11365
   121
    {
icculus@11365
   122
        SDL_SetError("Vulkan is not loaded");
icculus@11365
   123
        return SDL_FALSE;
icculus@11365
   124
    }
icculus@11365
   125
    return SDL_Vulkan_GetInstanceExtensions_Helper(
slouken@11374
   126
            count, names, SDL_arraysize(extensionsForAndroid),
icculus@11365
   127
            extensionsForAndroid);
icculus@11365
   128
}
icculus@11365
   129
icculus@11365
   130
SDL_bool Android_Vulkan_CreateSurface(_THIS,
icculus@11365
   131
                                  SDL_Window *window,
icculus@11365
   132
                                  VkInstance instance,
icculus@11365
   133
                                  VkSurfaceKHR *surface)
icculus@11365
   134
{
icculus@11365
   135
    SDL_WindowData *windowData = (SDL_WindowData *)window->driverdata;
icculus@11365
   136
    PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
icculus@11365
   137
        (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
icculus@11365
   138
    PFN_vkCreateAndroidSurfaceKHR vkCreateAndroidSurfaceKHR =
icculus@11365
   139
        (PFN_vkCreateAndroidSurfaceKHR)vkGetInstanceProcAddr(
icculus@11365
   140
                                            (VkInstance)instance,
icculus@11365
   141
                                            "vkCreateAndroidSurfaceKHR");
slouken@11839
   142
    VkAndroidSurfaceCreateInfoKHR createInfo;
icculus@11365
   143
    VkResult result;
icculus@11365
   144
icculus@11365
   145
    if(!_this->vulkan_config.loader_handle)
icculus@11365
   146
    {
icculus@11365
   147
        SDL_SetError("Vulkan is not loaded");
icculus@11365
   148
        return SDL_FALSE;
icculus@11365
   149
    }
icculus@11365
   150
icculus@11365
   151
    if(!vkCreateAndroidSurfaceKHR)
icculus@11365
   152
    {
slouken@11374
   153
        SDL_SetError(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME
icculus@11365
   154
                     " extension is not enabled in the Vulkan instance.");
icculus@11365
   155
        return SDL_FALSE;
icculus@11365
   156
    }
slouken@11839
   157
    SDL_zero(createInfo);
slouken@11374
   158
    createInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
icculus@11365
   159
    createInfo.pNext = NULL;
icculus@11365
   160
    createInfo.flags = 0;
icculus@11365
   161
    createInfo.window = windowData->native_window;
icculus@11365
   162
    result = vkCreateAndroidSurfaceKHR(instance, &createInfo,
icculus@11365
   163
                                       NULL, surface);
icculus@11365
   164
    if(result != VK_SUCCESS)
icculus@11365
   165
    {
icculus@11365
   166
        SDL_SetError("vkCreateAndroidSurfaceKHR failed: %s",
icculus@11365
   167
                     SDL_Vulkan_GetResultString(result));
icculus@11365
   168
        return SDL_FALSE;
icculus@11365
   169
    }
icculus@11365
   170
    return SDL_TRUE;
icculus@11365
   171
}
icculus@11365
   172
icculus@11365
   173
#endif
icculus@11365
   174
icculus@11365
   175
/* vi: set ts=4 sw=4 expandtab: */