Add Video Extension functions to support Vulkan

This commit is contained in:
Rosalie Wanders 2023-08-02 22:24:06 +02:00
parent ea64cb660b
commit 761b34443a
10 changed files with 322 additions and 23 deletions

View file

@ -44,8 +44,8 @@ jobs:
echo "G_REV=$(git rev-parse --short HEAD)" >> "${GITHUB_ENV}"
if [[ ${{ matrix.bits }} -eq 32 ]]; then sudo dpkg --add-architecture i386; fi
sudo apt-get update
sudo apt-get -y install libfreetype6-dev libgl1-mesa-dev libglu1-mesa-dev libpng-dev libsdl1.2-dev libsdl2-dev nasm zlib1g-dev
if [[ ${{ matrix.bits }} -eq 32 ]]; then sudo apt-get --reinstall -y install gcc-multilib g++-multilib libc6 libc6-dev-i386 libatomic1:i386 libgcc-s1:i386 libstdc++6:i386 libfreetype6-dev:i386 libgl1-mesa-dev:i386 libglu1-mesa-dev:i386 libpng-dev:i386 libsdl1.2-dev:i386 libsdl2-dev:i386 zlib1g-dev:i386; fi
sudo apt-get -y install libfreetype6-dev libgl1-mesa-dev libglu1-mesa-dev libpng-dev libsdl1.2-dev libsdl2-dev libvulkan-dev nasm zlib1g-dev
if [[ ${{ matrix.bits }} -eq 32 ]]; then sudo apt-get --reinstall -y install gcc-multilib g++-multilib libc6 libc6-dev-i386 libatomic1:i386 libgcc-s1:i386 libstdc++6:i386 libfreetype6-dev:i386 libgl1-mesa-dev:i386 libglu1-mesa-dev:i386 libpng-dev:i386 libsdl1.2-dev:i386 libsdl2-dev:i386 libvulkan-dev:i386 zlib1g-dev:i386; fi
sudo ldconfig
- name: Build and related stuff, backup binaries
run: |

View file

@ -136,3 +136,5 @@ This is the most complicated interface, because it involves 3 components: the vi
* '''FRONTEND_API_VERSION''' version 2.1.6:
** added "m64p_core_param" type:
*** M64CORE_SCREENSHOT_CAPTURED
* '''VIDEXT_API_VERSION''' version 3.3.0:
** add the VidExt_InitWithRenderMode, VidExt_VK_GetSurface and VidExt_VK_GetInstanceExtensions functions, which allows a plugin to use Vulkan and a front-end to support Vulkan

View file

@ -23,6 +23,20 @@ All of these functions should only be called from within the video plugin; they
<br />
{| border="1"
|Prototype
|'''<tt>m64p_error VidExt_InitWithRenderMode(m64p_render_mode RenderMode)</tt>'''
|-
|Input Parameters
|'''<tt>RenderMode</tt>''' Render mode, either <tt>M64P_RENDER_OPENGL</tt> or <tt>M64P_RENDER_VULKAN</tt>, defined in [[Mupen64Plus v2.0 headers#m64p_types.h|m64p_types.h]]<br />
|-
|Requirements
|This function should be called before any other Video Extension functions.
|-
|Usage
|This function should be called from within the RomOpen() video plugin function call. The default SDL implementation of this function simply calls SDL_InitSubSystem(SDL_INIT_VIDEO). It does not open a rendering window or switch video modes.
|}
<br />
{| border="1"
|Prototype
|'''<tt>m64p_error VidExt_Quit(void)</tt>'''
|-
|Input Parameters
@ -242,3 +256,35 @@ In the Core Video Extension function ResizeWindow, the SDL function SetVideoMode
|On some platforms (for instance, iOS) the default framebuffer object depends on the surface being rendered to, and might be different from 0. This function should be called to retrieve the name of the default FBO. Calling this function may have performance implications and it should not be called every time the default FBO is bound.
|}
<br />
== Vulkan Functions ==
{| border="1"
|Prototype
|'''<tt>m64p_error VidExt_VK_GetSurface(void** Surface, void* Instance)</tt>'''
|-
|Input Parameters
|'''<tt>Surface</tt>''' Pointer to a VkSurfaceKHR which will be returned when function succeeds<br />
'''<tt>Instance</tt>''' VkInstance which can be used as the front-end's Vulkan instance
|-
|Requirements
|The video extension must be initialized before calling this function.
|-
|Usage
|This function is used to retrieve the Vulkan surface
|}
<br />
{| border="1"
|Prototype
|'''<tt>m64p_error VidExt_VK_GetInstanceExtensions(const char** Extensions[], uint32_t* NumExtensions)</tt>'''
|-
|Input Parameters
|'''<tt>Extensions</tt>''' Pointer to an array of strings<br />
'''<tt>NumExtensions</tt>''' Pointer to an integer which contains the size of the number of objects stored for output.
|-
|Requirements
|The video extension must be initialized before calling this function.
|-
|Usage
|This function is used to retrieve the supported Vulkan extensions.
|}
<br />

View file

@ -360,6 +360,8 @@ ifeq ($(origin SDL_CFLAGS) $(origin SDL_LDLIBS), undefined undefined)
ifeq ($(NETPLAY), 1)
SDL_LDLIBS += -lSDL_net
endif
# SDL1 doesn't support vulkan
VULKAN = 0
$(warning Using SDL 1.2 libraries)
endif
else
@ -433,6 +435,22 @@ ifeq ($(OSD), 1)
LDLIBS += $(GLU_LDLIBS)
endif
ifneq ($(OS), OSX)
ifneq ($(VULKAN), 0)
CFLAGS += -DVIDEXT_VULKAN
ifeq ($(origin VULKAN_CFLAGS) $(origin VULKAN_LDLIBS), undefined undefined)
ifeq ($(shell $(PKG_CONFIG) --modversion vulkan 2>/dev/null),)
$(error No Vulkan development libraries found!)
endif
VULKAN_CFLAGS += $(shell $(PKG_CONFIG) --cflags vulkan)
VULKAN_LDLIBS += $(shell $(PKG_CONFIG) --libs vulkan)
endif
CFLAGS += $(VULKAN_CFLAGS)
LDLIBS += $(VULKAN_LDLIBS)
endif
endif
# set base program pointers and flags
CC = $(CROSS_COMPILE)gcc
CXX = $(CROSS_COMPILE)g++
@ -775,6 +793,7 @@ targets:
@echo " KEYBINDINGS=0 == Disables the default keybindings"
@echo " ACCURATE_FPU=1 == Enables accurate FPU behavior (i.e correct cause bits)"
@echo " OPENCV=1 == Enable OpenCV support"
@echo " VULKAN=0 == Disable vulkan support for the default video extension implementation"
@echo " POSTFIX=name == String added to the name of the the build (default: '')"
@echo " Install Options:"
@echo " PREFIX=path == install/uninstall prefix (default: /usr/local/)"

View file

@ -69,6 +69,7 @@ VidExt_GL_SetAttribute;
VidExt_GL_GetAttribute;
VidExt_GL_SwapBuffers;
VidExt_Init;
VidExt_InitWithRenderMode;
VidExt_ListFullscreenModes;
VidExt_ListFullscreenRates;
VidExt_Quit;
@ -78,4 +79,6 @@ VidExt_SetVideoModeWithRate;
VidExt_ToggleFullScreen;
VidExt_ResizeWindow;
VidExt_GL_GetDefaultFramebuffer;
VidExt_VK_GetSurface;
VidExt_VK_GetInstanceExtensions;
local: *; };

View file

@ -432,6 +432,11 @@ typedef enum {
M64P_GL_CONTEXT_PROFILE_ES
} m64p_GLContextType;
typedef enum {
M64P_RENDER_OPENGL = 0,
M64P_RENDER_VULKAN
} m64p_render_mode;
typedef struct {
unsigned int Functions;
m64p_error (*VidExtFuncInit)(void);
@ -448,6 +453,9 @@ typedef struct {
m64p_error (*VidExtFuncToggleFS)(void);
m64p_error (*VidExtFuncResizeWindow)(int, int);
uint32_t (*VidExtFuncGLGetDefaultFramebuffer)(void);
m64p_error (*VidExtFuncInitWithRenderMode)(m64p_render_mode);
m64p_error (*VidExtFuncVKGetSurface)(void**, void*);
m64p_error (*VidExtFuncVKGetInstanceExtensions)(const char**[], uint32_t*);
} m64p_video_extension_functions;
#endif /* define M64P_TYPES_H */

View file

@ -44,6 +44,19 @@ typedef m64p_error (*ptr_VidExt_Init)(void);
EXPORT m64p_error CALL VidExt_Init(void);
#endif
/* VidExt_InitWithRenderMode()
*
* This function should be called from within the InitiateGFX() video plugin
* function call with the specified rendering mode (OpenGL or Vulkan).
* The default SDL implementation of this function simply calls
* SDL_InitSubSystem(SDL_INIT_VIDEO). It does not open a rendering window or
* switch video modes.
*/
typedef m64p_error (*ptr_VidExt_InitWithRenderMode)(m64p_render_mode);
#if defined(M64P_CORE_PROTOTYPES)
EXPORT m64p_error CALL VidExt_InitWithRenderMode(m64p_render_mode);
#endif
/* VidExt_Quit()
*
* This function closes any open rendering window and shuts down the video
@ -181,6 +194,26 @@ typedef uint32_t (*ptr_VidExt_GL_GetDefaultFramebuffer)(void);
EXPORT uint32_t CALL VidExt_GL_GetDefaultFramebuffer(void);
#endif
/* VidExt_VK_GetSurface()
*
* This functions gives out a vulkan surface
*/
typedef m64p_error (*ptr_VidExt_VK_GetSurface)(void**, void*);
#if defined(M64P_CORE_PROTOTYPES)
EXPORT m64p_error CALL VidExt_VK_GetSurface(void**, void*);
#endif
/* VidExt_VK_GetInstanceExtensions()
*
* This functions gives out a list of supported vulkan
* extensions, and the caller will be given the amount
* of strings stored in the list
*/
typedef m64p_error (*ptr_VidExt_VK_GetInstanceExtensions)(const char**[], uint32_t*);
#if defined(M64P_CORE_PROTOTYPES)
EXPORT m64p_error CALL VidExt_VK_GetInstanceExtensions(const char**[], uint32_t*);
#endif
#ifdef __cplusplus
}
#endif

View file

@ -24,6 +24,14 @@
*/
#include <SDL.h>
/* we need at least SDL 2.0.6 for vulkan */
#if !SDL_VERSION_ATLEAST(2,0,6)
#undef VIDEXT_VULKAN
#endif
#ifdef VIDEXT_VULKAN
#include <SDL_vulkan.h>
#include <vulkan/vulkan.h>
#endif
#include <stdlib.h>
#include <string.h>
@ -43,12 +51,16 @@
#endif
/* local variables */
static m64p_video_extension_functions l_ExternalVideoFuncTable = {14, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
static m64p_video_extension_functions l_ExternalVideoFuncTable = {17, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
static int l_VideoExtensionActive = 0;
static int l_VideoOutputActive = 0;
static int l_Fullscreen = 0;
static int l_SwapControl = 0;
static m64p_render_mode l_RenderMode = M64P_RENDER_OPENGL;
static SDL_Surface *l_pScreen = NULL;
#ifdef VIDEXT_VULKAN
static const char** l_VulkanExtensionNames = NULL;
#endif
/* global function for use by frontend.c */
m64p_error OverrideVideoFunctions(m64p_video_extension_functions *VideoFunctionStruct)
@ -56,11 +68,12 @@ m64p_error OverrideVideoFunctions(m64p_video_extension_functions *VideoFunctionS
/* check input data */
if (VideoFunctionStruct == NULL)
return M64ERR_INPUT_ASSERT;
if (VideoFunctionStruct->Functions < 14)
if (VideoFunctionStruct->Functions < 17)
return M64ERR_INPUT_INVALID;
/* disable video extension if any of the function pointers are NULL */
if (VideoFunctionStruct->VidExtFuncInit == NULL ||
VideoFunctionStruct->VidExtFuncInitWithRenderMode == NULL ||
VideoFunctionStruct->VidExtFuncQuit == NULL ||
VideoFunctionStruct->VidExtFuncListModes == NULL ||
VideoFunctionStruct->VidExtFuncListRates == NULL ||
@ -73,10 +86,12 @@ m64p_error OverrideVideoFunctions(m64p_video_extension_functions *VideoFunctionS
VideoFunctionStruct->VidExtFuncSetCaption == NULL ||
VideoFunctionStruct->VidExtFuncToggleFS == NULL ||
VideoFunctionStruct->VidExtFuncResizeWindow == NULL ||
VideoFunctionStruct->VidExtFuncGLGetDefaultFramebuffer == NULL)
VideoFunctionStruct->VidExtFuncGLGetDefaultFramebuffer == NULL ||
VideoFunctionStruct->VidExtFuncVKGetSurface == NULL ||
VideoFunctionStruct->VidExtFuncVKGetInstanceExtensions == NULL)
{
l_ExternalVideoFuncTable.Functions = 14;
memset(&l_ExternalVideoFuncTable.VidExtFuncInit, 0, 14 * sizeof(void *));
l_ExternalVideoFuncTable.Functions = 17;
memset(&l_ExternalVideoFuncTable.VidExtFuncInit, 0, 17 * sizeof(void *));
l_VideoExtensionActive = 0;
return M64ERR_SUCCESS;
}
@ -104,10 +119,27 @@ EXPORT m64p_error CALL VidExt_Init(void)
if (l_VideoExtensionActive)
return (*l_ExternalVideoFuncTable.VidExtFuncInit)();
/* redirect to VidExt_InitWithRenderMode with OpenGL render mode */
return VidExt_InitWithRenderMode(M64P_RENDER_OPENGL);
}
EXPORT m64p_error CALL VidExt_InitWithRenderMode(m64p_render_mode RenderMode)
{
/* call video extension override if necessary */
if (l_VideoExtensionActive)
return (*l_ExternalVideoFuncTable.VidExtFuncInitWithRenderMode)(RenderMode);
/* set global render mode */
#ifdef VIDEXT_VULKAN
l_RenderMode = RenderMode;
#endif
#if SDL_VERSION_ATLEAST(2,0,0)
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");
/* retrieve default swap interval/VSync */
l_SwapControl = SDL_GL_GetSwapInterval();
/* retrieve default swap interval/VSync */
if (RenderMode == M64P_RENDER_OPENGL) {
l_SwapControl = SDL_GL_GetSwapInterval();
}
#endif
#if SDL_VERSION_ATLEAST(2,24,0)
@ -121,6 +153,20 @@ EXPORT m64p_error CALL VidExt_Init(void)
return M64ERR_SYSTEM_FAIL;
}
/* attempt to load vulkan library */
if (RenderMode == M64P_RENDER_VULKAN)
{
#ifdef VIDEXT_VULKAN
if (SDL_Vulkan_LoadLibrary(NULL) == -1)
{
DebugMessage(M64MSG_ERROR, "SDL_Vulkan_LoadLibrary failed: %s", SDL_GetError());
return M64ERR_SYSTEM_FAIL;
}
#else
return M64ERR_UNSUPPORTED;
#endif
}
return M64ERR_SUCCESS;
}
@ -144,6 +190,15 @@ EXPORT m64p_error CALL VidExt_Quit(void)
SDL_ShowCursor(SDL_ENABLE);
#if SDL_VERSION_ATLEAST(2,0,0)
SDL2_DestroyWindow();
#endif
#ifdef VIDEXT_VULKAN
if (l_RenderMode == M64P_RENDER_VULKAN) {
SDL_Vulkan_UnloadLibrary();
}
if (l_VulkanExtensionNames != NULL) {
free(l_VulkanExtensionNames);
l_VulkanExtensionNames = NULL;
}
#endif
SDL_QuitSubSystem(SDL_INIT_VIDEO);
l_pScreen = NULL;
@ -273,15 +328,24 @@ EXPORT m64p_error CALL VidExt_SetVideoMode(int Width, int Height, int BitsPerPix
return M64ERR_NOT_INIT;
/* Get SDL video flags to use */
if (ScreenMode == M64VIDEO_WINDOWED)
if (l_RenderMode == M64P_RENDER_OPENGL)
{
videoFlags = SDL_OPENGL;
}
#ifdef VIDEXT_VULKAN
else
{
videoFlags = SDL_VULKAN;
}
#endif
if (ScreenMode == M64VIDEO_WINDOWED)
{
if (Flags & M64VIDEOFLAG_SUPPORT_RESIZING)
videoFlags |= SDL_RESIZABLE;
}
else if (ScreenMode == M64VIDEO_FULLSCREEN)
{
videoFlags = SDL_OPENGL | SDL_FULLSCREEN;
videoFlags |= SDL_FULLSCREEN;
}
else
{
@ -315,7 +379,8 @@ EXPORT m64p_error CALL VidExt_SetVideoMode(int Width, int Height, int BitsPerPix
#if SDL_VERSION_ATLEAST(2,0,0)
/* set swap interval/VSync */
if (SDL_GL_SetSwapInterval(l_SwapControl) != 0)
if (l_RenderMode == M64P_RENDER_OPENGL &&
SDL_GL_SetSwapInterval(l_SwapControl) != 0)
{
DebugMessage(M64MSG_ERROR, "SDL swap interval (VSync) set failed: %s", SDL_GetError());
}
@ -347,7 +412,7 @@ EXPORT m64p_error CALL VidExt_SetVideoModeWithRate(int Width, int Height, int Re
#if SDL_VERSION_ATLEAST(2,0,0)
if (!SDL_WasInit(SDL_INIT_VIDEO) || !SDL_VideoWindow)
return M64ERR_NOT_INIT;
int videoFlags = 0;
int display = GetVideoDisplay();
int modeCount = SDL_GetNumDisplayModes(display);
@ -459,7 +524,13 @@ EXPORT m64p_error CALL VidExt_ResizeWindow(int Width, int Height)
}
/* Get SDL video flags to use */
videoFlags = SDL_OPENGL | SDL_RESIZABLE;
if (l_RenderMode == M64P_RENDER_OPENGL)
videoFlags = SDL_OPENGL;
#ifdef VIDEXT_VULKAN
else
videoFlags = SDL_VULKAN;
#endif
videoFlags |= SDL_RESIZABLE;
if ((videoInfo = SDL_GetVideoInfo()) == NULL)
{
DebugMessage(M64MSG_ERROR, "SDL_GetVideoInfo query failed: %s", SDL_GetError());
@ -532,6 +603,10 @@ EXPORT m64p_error CALL VidExt_ToggleFullScreen(void)
StateChanged(M64CORE_VIDEO_MODE, l_Fullscreen ? M64VIDEO_FULLSCREEN : M64VIDEO_WINDOWED);
return M64ERR_SUCCESS;
}
else
{
DebugMessage(M64MSG_ERROR, "SDL_WM_ToggleFullScreen failed: %s", SDL_GetError());
}
return M64ERR_SYSTEM_FAIL;
}
@ -542,6 +617,9 @@ EXPORT m64p_function CALL VidExt_GL_GetProcAddress(const char* Proc)
if (l_VideoExtensionActive)
return (*l_ExternalVideoFuncTable.VidExtFuncGLGetProc)(Proc);
if (l_RenderMode != M64P_RENDER_OPENGL)
return NULL;
if (!SDL_WasInit(SDL_INIT_VIDEO))
return NULL;
@ -586,6 +664,9 @@ EXPORT m64p_error CALL VidExt_GL_SetAttribute(m64p_GLattr Attr, int Value)
if (l_VideoExtensionActive)
return (*l_ExternalVideoFuncTable.VidExtFuncGLSetAttr)(Attr, Value);
if (l_RenderMode != M64P_RENDER_OPENGL)
return M64ERR_INVALID_STATE;
if (!SDL_WasInit(SDL_INIT_VIDEO))
return M64ERR_NOT_INIT;
@ -640,6 +721,9 @@ EXPORT m64p_error CALL VidExt_GL_GetAttribute(m64p_GLattr Attr, int *pValue)
if (l_VideoExtensionActive)
return (*l_ExternalVideoFuncTable.VidExtFuncGLGetAttr)(Attr, pValue);
if (l_RenderMode != M64P_RENDER_OPENGL)
return M64ERR_INVALID_STATE;
if (!SDL_WasInit(SDL_INIT_VIDEO))
return M64ERR_NOT_INIT;
@ -692,6 +776,9 @@ EXPORT m64p_error CALL VidExt_GL_SwapBuffers(void)
if (l_VideoExtensionActive)
return (*l_ExternalVideoFuncTable.VidExtFuncGLSwapBuf)();
if (l_RenderMode != M64P_RENDER_OPENGL)
return M64ERR_INVALID_STATE;
if (!SDL_WasInit(SDL_INIT_VIDEO))
return M64ERR_NOT_INIT;
@ -706,3 +793,72 @@ EXPORT uint32_t CALL VidExt_GL_GetDefaultFramebuffer(void)
return 0;
}
EXPORT m64p_error CALL VidExt_VK_GetSurface(void** Surface, void* Instance)
{
if (l_VideoExtensionActive)
return (*l_ExternalVideoFuncTable.VidExtFuncVKGetSurface)(Surface, Instance);
#ifdef VIDEXT_VULKAN
VkSurfaceKHR vulkanSurface = VK_NULL_HANDLE;
if (l_RenderMode != M64P_RENDER_VULKAN)
return M64ERR_INVALID_STATE;
if (!SDL_WasInit(SDL_INIT_VIDEO) || !SDL_VideoWindow)
return M64ERR_NOT_INIT;
if (SDL_Vulkan_CreateSurface(SDL_VideoWindow, (VkInstance)Instance, &vulkanSurface) == SDL_FALSE) {
DebugMessage(M64MSG_ERROR, "SDL_Vulkan_CreateSurface failed: %s", SDL_GetError());
return M64ERR_SYSTEM_FAIL;
}
*Surface = (void*)vulkanSurface;
return M64ERR_SUCCESS;
#else
return M64ERR_UNSUPPORTED;
#endif
}
EXPORT m64p_error CALL VidExt_VK_GetInstanceExtensions(const char** Extensions[], uint32_t* NumExtensions)
{
if (l_VideoExtensionActive)
return (*l_ExternalVideoFuncTable.VidExtFuncVKGetInstanceExtensions)(Extensions, NumExtensions);
#ifdef VIDEXT_VULKAN
if (l_RenderMode != M64P_RENDER_VULKAN)
return M64ERR_INVALID_STATE;
if (!SDL_WasInit(SDL_INIT_VIDEO))
return M64ERR_NOT_INIT;
unsigned int extensionCount = 0;
if (SDL_Vulkan_GetInstanceExtensions(NULL, &extensionCount, NULL) == SDL_FALSE) {
DebugMessage(M64MSG_ERROR, "SDL_Vulkan_GetInstanceExtensions failed: %s", SDL_GetError());
return M64ERR_SYSTEM_FAIL;
}
/* ensure names have been freed before allocating it again */
if (l_VulkanExtensionNames != NULL) {
free(l_VulkanExtensionNames);
l_VulkanExtensionNames = NULL;
}
l_VulkanExtensionNames = malloc(sizeof(const char*) * extensionCount);
if (l_VulkanExtensionNames == NULL) {
DebugMessage(M64MSG_ERROR, "malloc failed");
return M64ERR_SYSTEM_FAIL;
}
if (SDL_Vulkan_GetInstanceExtensions(NULL, &extensionCount, l_VulkanExtensionNames) == SDL_FALSE) {
DebugMessage(M64MSG_ERROR, "SDL_Vulkan_GetInstanceExtensions failed: %s", SDL_GetError());
return M64ERR_SYSTEM_FAIL;
}
*NumExtensions = extensionCount;
*Extensions = l_VulkanExtensionNames;
return M64ERR_SUCCESS;
#else
return M64ERR_UNSUPPORTED;
#endif
}

View file

@ -62,6 +62,7 @@ typedef struct SDL_VideoInfo
#define SDL_RESIZABLE 0x01000000
#define SDL_NOFRAME 0x02000000
#define SDL_OPENGL 0x04000000
#define SDL_VULKAN 0x10000000
#define SDL_HWSURFACE 0x08000001 /**< \note Not used */
#define SDL_BUTTON_WHEELUP 4
@ -198,7 +199,11 @@ SDL_WM_ToggleFullScreen(SDL_Surface * surface)
int window_w;
int window_h;
if (!SDL_PublicSurface) {
if (
#ifdef VIDEXT_VULKAN
(SDL_VideoFlags & SDL_VULKAN && !SDL_VideoWindow) ||
#endif
(SDL_VideoFlags & SDL_OPENGL && !SDL_PublicSurface)) {
SDL_SetError("SDL_SetVideoMode() hasn't been called");
return 0;
}
@ -208,12 +213,16 @@ SDL_WM_ToggleFullScreen(SDL_Surface * surface)
if (SDL_SetWindowFullscreen(SDL_VideoWindow, 0) < 0) {
return 0;
}
SDL_PublicSurface->flags &= ~SDL_FULLSCREEN;
if (SDL_VideoFlags & SDL_OPENGL) {
SDL_PublicSurface->flags &= ~SDL_FULLSCREEN;
}
} else {
if (SDL_SetWindowFullscreen(SDL_VideoWindow, 1) < 0) {
return 0;
}
SDL_PublicSurface->flags |= SDL_FULLSCREEN;
if (SDL_VideoFlags & SDL_OPENGL) {
SDL_PublicSurface->flags |= SDL_FULLSCREEN;
}
}
/* Center the public surface in the window surface */
@ -233,7 +242,11 @@ SDL_ResizeVideoMode(int width, int height, int bpp, Uint32 flags)
int w, h;
/* We can't resize something we don't have... */
if (!SDL_PublicSurface) {
if (
#ifdef VIDEXT_VULKAN
(SDL_VideoFlags & SDL_VULKAN && !SDL_VideoWindow) ||
#endif
(SDL_VideoFlags & SDL_OPENGL && !SDL_PublicSurface)) {
return -1;
}
@ -415,14 +428,16 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags)
}
#ifndef USE_GLES
if (l_ForceCompatibilityContext)
if (flags & SDL_OPENGL && l_ForceCompatibilityContext)
{
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
}
#else // !USE_GLES
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
if (flags & SDL_OPENGL) {
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
}
#endif // !USE_GLES
/* Create a new window */
@ -433,6 +448,11 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags)
if (flags & SDL_OPENGL) {
window_flags |= SDL_WINDOW_OPENGL;
}
#ifdef VIDEXT_VULKAN
if (flags & SDL_VULKAN) {
window_flags |= SDL_WINDOW_VULKAN;
}
#endif
if (flags & SDL_RESIZABLE) {
window_flags |= SDL_WINDOW_RESIZABLE;
}
@ -456,6 +476,11 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags)
if ((window_flags & SDL_WINDOW_OPENGL) && (flags & SDL_OPENGL)) {
surface_flags |= SDL_OPENGL;
}
#ifdef VIDEXT_VULKAN
if ((window_flags & SDL_WINDOW_VULKAN) && (flags & SDL_VULKAN)) {
surface_flags |= SDL_VULKAN;
}
#endif
if (window_flags & SDL_WINDOW_RESIZABLE) {
surface_flags |= SDL_RESIZABLE;
}
@ -489,6 +514,13 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags)
SDL_PublicSurface = SDL_VideoSurface;
return SDL_PublicSurface;
}
#ifdef VIDEXT_VULKAN
else if (flags & SDL_VULKAN) {
/* Vulkan doesn't have a video surface,
* so just return a stub */
return (SDL_Surface*)0x1;
}
#endif
/* We're finally done! */
return NULL;

View file

@ -30,7 +30,7 @@
#define FRONTEND_API_VERSION 0x020106
#define CONFIG_API_VERSION 0x020302
#define DEBUG_API_VERSION 0x020001
#define VIDEXT_API_VERSION 0x030200
#define VIDEXT_API_VERSION 0x030300
#define NETPLAY_API_VERSION 0x010001
#define VERSION_PRINTF_SPLIT(x) (((x) >> 16) & 0xffff), (((x) >> 8) & 0xff), ((x) & 0xff)