include/SDL_vulkan.h
author Mark Callow <libsdl.org@callow.im>
Wed, 21 Feb 2018 09:58:21 -0800
changeset 11886 27d81cb6e6af
parent 11463 b716f3d736a7
child 11906 d97ab6d12404
permissions -rw-r--r--
Fix high-dpi support on macOS and simplify it and iOS variant.

The detault drawableSize for a CAMetalLayer is its bounds x its scale.
So it is sufficient to set the *layer's* scale to the desired value.
icculus@11365
     1
/*
slouken@11376
     2
  Simple DirectMedia Layer
slouken@11376
     3
  Copyright (C) 2017, Mark Callow
slouken@11376
     4
slouken@11376
     5
  This software is provided 'as-is', without any express or implied
slouken@11376
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@11376
     7
  arising from the use of this software.
slouken@11376
     8
slouken@11376
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@11376
    10
  including commercial applications, and to alter it and redistribute it
slouken@11376
    11
  freely, subject to the following restrictions:
slouken@11376
    12
slouken@11376
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@11376
    14
     claim that you wrote the original software. If you use this software
slouken@11376
    15
     in a product, an acknowledgment in the product documentation would be
slouken@11376
    16
     appreciated but is not required.
slouken@11376
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@11376
    18
     misrepresented as being the original software.
slouken@11376
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@11376
    20
*/
icculus@11365
    21
icculus@11365
    22
/**
icculus@11365
    23
 *  \file SDL_vulkan.h
icculus@11365
    24
 *
icculus@11365
    25
 *  Header file for functions to creating Vulkan surfaces on SDL windows.
icculus@11365
    26
 */
icculus@11365
    27
icculus@11365
    28
#ifndef SDL_vulkan_h_
icculus@11365
    29
#define SDL_vulkan_h_
icculus@11365
    30
icculus@11365
    31
#include "SDL_video.h"
icculus@11365
    32
icculus@11365
    33
#include "begin_code.h"
icculus@11365
    34
/* Set up for C function definitions, even when using C++ */
icculus@11365
    35
#ifdef __cplusplus
icculus@11365
    36
extern "C" {
icculus@11365
    37
#endif
icculus@11365
    38
slouken@11376
    39
/* Avoid including vulkan.h, don't define VkInstance if it's already included */
slouken@11376
    40
#ifdef VULKAN_H_
slouken@11376
    41
#define NO_SDL_VULKAN_TYPEDEFS
slouken@11376
    42
#endif
slouken@11376
    43
#ifndef NO_SDL_VULKAN_TYPEDEFS
icculus@11365
    44
#define VK_DEFINE_HANDLE(object) typedef struct object##_T* object;
icculus@11365
    45
icculus@11365
    46
#if defined(__LP64__) || defined(_WIN64) || defined(__x86_64__) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
icculus@11365
    47
#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object;
icculus@11365
    48
#else
icculus@11365
    49
#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object;
icculus@11365
    50
#endif
icculus@11365
    51
icculus@11365
    52
VK_DEFINE_HANDLE(VkInstance)
icculus@11365
    53
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR)
icculus@11365
    54
slouken@11376
    55
#endif /* !NO_SDL_VULKAN_TYPEDEFS */
slouken@11373
    56
icculus@11365
    57
typedef VkInstance SDL_vulkanInstance;
icculus@11365
    58
typedef VkSurfaceKHR SDL_vulkanSurface; /* for compatibility with Tizen */
icculus@11365
    59
icculus@11365
    60
/**
icculus@11365
    61
 *  \name Vulkan support functions
icculus@11365
    62
 *
icculus@11365
    63
 *  \note SDL_Vulkan_GetInstanceExtensions & SDL_Vulkan_CreateSurface API
icculus@11365
    64
 *        is compatable with Tizen's implementation of Vulkan in SDL.
icculus@11365
    65
 */
icculus@11365
    66
/* @{ */
icculus@11365
    67
icculus@11365
    68
/**
icculus@11365
    69
 *  \brief Dynamically load a Vulkan loader library.
icculus@11365
    70
 *
icculus@11365
    71
 *  \param [in] path The platform dependent Vulkan loader library name, or
icculus@11365
    72
 *              \c NULL to open the default Vulkan loader library.
icculus@11365
    73
 *
icculus@11365
    74
 *  \return \c 0 on success, or \c -1 if the library couldn't be loaded.
icculus@11365
    75
 *
icculus@11365
    76
 *  This should be done after initializing the video driver, but before
icculus@11365
    77
 *  creating any Vulkan windows. If no Vulkan loader library is loaded, the
icculus@11365
    78
 *  default library will be loaded upon creation of the first Vulkan window.
icculus@11365
    79
 *
icculus@11365
    80
 *  \note If you specify a non-NULL \a path, you should retrieve all of the
icculus@11365
    81
 *        Vulkan functions used in your program from the dynamic library using
icculus@11365
    82
 *        \c SDL_Vulkan_GetVkGetInstanceProcAddr() unless you can guarantee
icculus@11365
    83
 *        \a path points to the same vulkan loader library that you linked to.
icculus@11365
    84
 *
icculus@11365
    85
 *  \note On Apple devices, if \a path is NULL, SDL will attempt to find
icculus@11365
    86
 *        the vkGetInstanceProcAddr address within all the mach-o images of
icculus@11365
    87
 *        the current process. This is because the currently (v0.17.0)
icculus@11365
    88
 *        recommended MoltenVK (Vulkan on Metal) usage is as a static library.
icculus@11365
    89
 *        If it is not found then SDL will attempt to load \c libMoltenVK.dylib.
icculus@11365
    90
 *        Applications using the dylib alternative therefore do not need to do
icculus@11365
    91
 *        anything special when calling SDL.
icculus@11365
    92
 *
icculus@11365
    93
 *  \note On non-Apple devices, SDL requires you to either not link to the
icculus@11365
    94
 *        Vulkan loader or link to a dynamic library version. This limitation
icculus@11365
    95
 *        may be removed in a future version of SDL.
icculus@11365
    96
 *
icculus@11365
    97
 *  \note This function will fail if there are no working Vulkan drivers
icculus@11365
    98
 *        installed.
icculus@11365
    99
 *
icculus@11365
   100
 *  \sa SDL_Vulkan_GetVkGetInstanceProcAddr()
icculus@11365
   101
 *  \sa SDL_Vulkan_UnloadLibrary()
icculus@11365
   102
 */
icculus@11365
   103
extern DECLSPEC int SDLCALL SDL_Vulkan_LoadLibrary(const char *path);
icculus@11365
   104
icculus@11365
   105
/**
icculus@11365
   106
 *  \brief Get the address of the \c vkGetInstanceProcAddr function.
icculus@11365
   107
 *
icculus@11365
   108
 *  \note This should be called after either calling SDL_Vulkan_LoadLibrary
icculus@11365
   109
 *        or creating an SDL_Window with the SDL_WINDOW_VULKAN flag.
icculus@11365
   110
 */
icculus@11365
   111
extern DECLSPEC void *SDLCALL SDL_Vulkan_GetVkGetInstanceProcAddr(void);
icculus@11365
   112
icculus@11365
   113
/**
icculus@11365
   114
 *  \brief Unload the Vulkan loader library previously loaded by
icculus@11365
   115
 *         \c SDL_Vulkan_LoadLibrary().
icculus@11365
   116
 *
icculus@11365
   117
 *  \sa SDL_Vulkan_LoadLibrary()
icculus@11365
   118
 */
icculus@11365
   119
extern DECLSPEC void SDLCALL SDL_Vulkan_UnloadLibrary(void);
icculus@11365
   120
icculus@11365
   121
/**
icculus@11365
   122
 *  \brief Get the names of the Vulkan instance extensions needed to create
icculus@11365
   123
 *         a surface with \c SDL_Vulkan_CreateSurface().
icculus@11365
   124
 *
icculus@11365
   125
 *  \param [in]     window Window for which the required Vulkan instance
icculus@11365
   126
 *                  extensions should be retrieved
icculus@11365
   127
 *  \param [in,out] count pointer to an \c unsigned related to the number of
icculus@11365
   128
 *                  required Vulkan instance extensions
icculus@11365
   129
 *  \param [out]    names \c NULL or a pointer to an array to be filled with the
icculus@11365
   130
 *                  required Vulkan instance extensions
icculus@11365
   131
 *
icculus@11365
   132
 *  \return \c SDL_TRUE on success, \c SDL_FALSE on error.
icculus@11365
   133
 *
icculus@11365
   134
 *  If \a pNames is \c NULL, then the number of required Vulkan instance
icculus@11365
   135
 *  extensions is returned in pCount. Otherwise, \a pCount must point to a
icculus@11365
   136
 *  variable set to the number of elements in the \a pNames array, and on
icculus@11365
   137
 *  return the variable is overwritten with the number of names actually
icculus@11365
   138
 *  written to \a pNames. If \a pCount is less than the number of required
icculus@11365
   139
 *  extensions, at most \a pCount structures will be written. If \a pCount
icculus@11365
   140
 *  is smaller than the number of required extensions, \c SDL_FALSE will be
icculus@11365
   141
 *  returned instead of \c SDL_TRUE, to indicate that not all the required
icculus@11365
   142
 *  extensions were returned.
icculus@11365
   143
 *
icculus@11365
   144
 *  \note The returned list of extensions will contain \c VK_KHR_surface
icculus@11365
   145
 *        and zero or more platform specific extensions
icculus@11365
   146
 *
icculus@11365
   147
 *  \note The extension names queried here must be enabled when calling
icculus@11365
   148
 *        VkCreateInstance, otherwise surface creation will fail.
icculus@11365
   149
 *
icculus@11365
   150
 *  \note \c window should have been created with the \c SDL_WINDOW_VULKAN flag.
icculus@11365
   151
 *
icculus@11365
   152
 *  \code
icculus@11463
   153
 *  unsigned int count;
icculus@11365
   154
 *  // get count of required extensions
icculus@11365
   155
 *  if(!SDL_Vulkan_GetInstanceExtensions(window, &count, NULL))
icculus@11365
   156
 *      handle_error();
icculus@11365
   157
 *
icculus@11365
   158
 *  static const char *const additionalExtensions[] =
icculus@11365
   159
 *  {
icculus@11365
   160
 *      VK_EXT_DEBUG_REPORT_EXTENSION_NAME, // example additional extension
icculus@11365
   161
 *  };
icculus@11365
   162
 *  size_t additionalExtensionsCount = sizeof(additionalExtensions) / sizeof(additionalExtensions[0]);
icculus@11365
   163
 *  size_t extensionCount = count + additionalExtensionsCount;
icculus@11365
   164
 *  const char **names = malloc(sizeof(const char *) * extensionCount);
icculus@11365
   165
 *  if(!names)
icculus@11365
   166
 *      handle_error();
icculus@11365
   167
 *
icculus@11365
   168
 *  // get names of required extensions
icculus@11365
   169
 *  if(!SDL_Vulkan_GetInstanceExtensions(window, &count, names))
icculus@11365
   170
 *      handle_error();
icculus@11365
   171
 *
icculus@11365
   172
 *  // copy additional extensions after required extensions
icculus@11365
   173
 *  for(size_t i = 0; i < additionalExtensionsCount; i++)
icculus@11365
   174
 *      names[i + count] = additionalExtensions[i];
icculus@11365
   175
 *
icculus@11365
   176
 *  VkInstanceCreateInfo instanceCreateInfo = {};
icculus@11365
   177
 *  instanceCreateInfo.enabledExtensionCount = extensionCount;
icculus@11365
   178
 *  instanceCreateInfo.ppEnabledExtensionNames = names;
icculus@11365
   179
 *  // fill in rest of instanceCreateInfo
icculus@11365
   180
 *
icculus@11365
   181
 *  VkInstance instance;
icculus@11365
   182
 *  // create the Vulkan instance
icculus@11365
   183
 *  VkResult result = vkCreateInstance(&instanceCreateInfo, NULL, &instance);
icculus@11365
   184
 *  free(names);
icculus@11365
   185
 *  \endcode
icculus@11365
   186
 *
icculus@11365
   187
 *  \sa SDL_Vulkan_CreateSurface()
icculus@11365
   188
 */
icculus@11365
   189
extern DECLSPEC SDL_bool SDLCALL SDL_Vulkan_GetInstanceExtensions(
icculus@11365
   190
														SDL_Window *window,
icculus@11463
   191
														unsigned int *pCount,
icculus@11365
   192
														const char **pNames);
icculus@11365
   193
icculus@11365
   194
/**
icculus@11365
   195
 *  \brief Create a Vulkan rendering surface for a window.
icculus@11365
   196
 *
icculus@11365
   197
 *  \param [in]  window   SDL_Window to which to attach the rendering surface.
icculus@11365
   198
 *  \param [in]  instance handle to the Vulkan instance to use.
icculus@11365
   199
 *  \param [out] surface  pointer to a VkSurfaceKHR handle to receive the
icculus@11365
   200
 *                        handle of the newly created surface.
icculus@11365
   201
 *
icculus@11365
   202
 *  \return \c SDL_TRUE on success, \c SDL_FALSE on error.
icculus@11365
   203
 *
icculus@11365
   204
 *  \code
icculus@11365
   205
 *  VkInstance instance;
icculus@11365
   206
 *  SDL_Window *window;
icculus@11365
   207
 *
icculus@11365
   208
 *  // create instance and window
icculus@11365
   209
 *
icculus@11365
   210
 *  // create the Vulkan surface
icculus@11365
   211
 *  VkSurfaceKHR surface;
icculus@11365
   212
 *  if(!SDL_Vulkan_CreateSurface(window, instance, &surface))
icculus@11365
   213
 *      handle_error();
icculus@11365
   214
 *  \endcode
icculus@11365
   215
 *
icculus@11365
   216
 *  \note \a window should have been created with the \c SDL_WINDOW_VULKAN flag.
icculus@11365
   217
 *
icculus@11365
   218
 *  \note \a instance should have been created with the extensions returned
icculus@11365
   219
 *        by \c SDL_Vulkan_CreateSurface() enabled.
icculus@11365
   220
 *
icculus@11365
   221
 *  \sa SDL_Vulkan_GetInstanceExtensions()
icculus@11365
   222
 */
icculus@11365
   223
extern DECLSPEC SDL_bool SDLCALL SDL_Vulkan_CreateSurface(
icculus@11365
   224
												SDL_Window *window,
icculus@11365
   225
												VkInstance instance,
icculus@11365
   226
												VkSurfaceKHR* surface);
icculus@11365
   227
icculus@11365
   228
/**
icculus@11365
   229
 *  \brief Get the size of a window's underlying drawable in pixels (for use
icculus@11365
   230
 *         with setting viewport, scissor & etc).
icculus@11365
   231
 *
icculus@11365
   232
 *  \param window   SDL_Window from which the drawable size should be queried
icculus@11365
   233
 *  \param w        Pointer to variable for storing the width in pixels,
icculus@11365
   234
 *                  may be NULL
icculus@11365
   235
 *  \param h        Pointer to variable for storing the height in pixels,
icculus@11365
   236
 *                  may be NULL
icculus@11365
   237
 *
icculus@11365
   238
 * This may differ from SDL_GetWindowSize() if we're rendering to a high-DPI
icculus@11365
   239
 * drawable, i.e. the window was created with SDL_WINDOW_ALLOW_HIGHDPI on a
icculus@11365
   240
 * platform with high-DPI support (Apple calls this "Retina"), and not disabled
icculus@11365
   241
 * by the \c SDL_HINT_VIDEO_HIGHDPI_DISABLED hint.
icculus@11365
   242
 *
libsdl@11886
   243
 *  \note On macOS high-DPI support must be enabled for an application by
libsdl@11886
   244
 *        setting NSHighResolutionCapable to true in its Info.plist.
libsdl@11886
   245
 *
icculus@11365
   246
 *  \sa SDL_GetWindowSize()
icculus@11365
   247
 *  \sa SDL_CreateWindow()
icculus@11365
   248
 */
icculus@11365
   249
extern DECLSPEC void SDLCALL SDL_Vulkan_GetDrawableSize(SDL_Window * window,
icculus@11365
   250
                                                        int *w, int *h);
icculus@11365
   251
icculus@11365
   252
/* @} *//* Vulkan support functions */
icculus@11365
   253
icculus@11365
   254
/* Ends C function definitions when using C++ */
icculus@11365
   255
#ifdef __cplusplus
icculus@11365
   256
}
icculus@11365
   257
#endif
icculus@11365
   258
#include "close_code.h"
icculus@11365
   259
icculus@11365
   260
#endif /* SDL_vulkan_h_ */