diff --git a/CMakeLists.txt b/CMakeLists.txt index 2844e33c7..7dcff8e15 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -425,6 +425,7 @@ set_option(SDL_TEST "Build the test directory" OFF) if(VITA) set_option(VIDEO_VITA_PIB "Build with PSVita piglet gles2 support" OFF) + set_option(VIDEO_VITA_PVR "Build with PSVita PVR gles/gles2 support" OFF) endif() # General source files @@ -2205,6 +2206,29 @@ elseif(VITA) endif() endif() + if(VIDEO_VITA_PVR) + check_include_file(gpu_es4/psp2_pvr_hint.h HAVE_PVR_H) + + if(HAVE_PVR_H) + add_definitions("-D__psp2__") + set(SDL_VIDEO_OPENGL_EGL 1) + set(HAVE_VIDEO_OPENGLES TRUE) + set(SDL_VIDEO_OPENGL_ES 1) + set(SDL_VIDEO_RENDER_OGL_ES 1) + set(SDL_VIDEO_OPENGL_ES2 1) + set(SDL_VIDEO_RENDER_OGL_ES2 1) + + list(APPEND EXTRA_LIBS + libgpu_es4_ext_stub_weak + libIMGEGL_stub_weak + ) + set(HAVE_VIDEO_VITA_PVR ON) + set(SDL_VIDEO_VITA_PVR 1) + else() + set(HAVE_VIDEO_VITA_PVR OFF) + endif() + endif() + set(SDL_VIDEO_RENDER_VITA_GXM 1) list(APPEND EXTRA_LIBS diff --git a/include/SDL_config.h.cmake b/include/SDL_config.h.cmake index 035292242..7b20a1d68 100644 --- a/include/SDL_config.h.cmake +++ b/include/SDL_config.h.cmake @@ -481,6 +481,7 @@ #cmakedefine SDL_IPHONE_LAUNCHSCREEN @SDL_IPHONE_LAUNCHSCREEN@ #cmakedefine SDL_VIDEO_VITA_PIB @SDL_VIDEO_VITA_PIB@ +#cmakedefine SDL_VIDEO_VITA_PVR @SDL_VIDEO_VITA_PVR@ #if !defined(__WIN32__) && !defined(__WINRT__) # if !defined(_STDINT_H_) && !defined(_STDINT_H) && !defined(HAVE_STDINT_H) && !defined(_HAVE_STDINT_H) diff --git a/include/SDL_egl.h b/include/SDL_egl.h index 223357e5f..62bc0b428 100644 --- a/include/SDL_egl.h +++ b/include/SDL_egl.h @@ -26,6 +26,10 @@ */ #if !defined(_MSC_VER) && !defined(__ANDROID__) +#if defined(__vita__) || defined(__psp2__) +#include +#endif + #include #include diff --git a/src/video/SDL_egl.c b/src/video/SDL_egl.c index de7999cf6..2bd2a08c0 100644 --- a/src/video/SDL_egl.c +++ b/src/video/SDL_egl.c @@ -107,7 +107,7 @@ #define EGL_PLATFORM_DEVICE_EXT 0x0 #endif -#ifdef SDL_VIDEO_STATIC_ANGLE +#if defined(SDL_VIDEO_STATIC_ANGLE) || defined(SDL_VIDEO_DRIVER_VITA) #define LOAD_FUNC(NAME) \ _this->egl_data->NAME = (void *)NAME; #else @@ -123,7 +123,6 @@ if (!_this->egl_data->NAME) \ #define LOAD_FUNC_EGLEXT(NAME) \ _this->egl_data->NAME = _this->egl_data->eglGetProcAddress(#NAME); - static const char * SDL_EGL_GetErrorName(EGLint eglErrorCode) { #define SDL_EGL_ERROR_TRANSLATE(e) case e: return #e; @@ -245,7 +244,7 @@ SDL_EGL_GetProcAddress(_THIS, const char *proc) retval = _this->egl_data->eglGetProcAddress(proc); } - #ifndef __EMSCRIPTEN__ /* LoadFunction isn't needed on Emscripten and will call dlsym(), causing other problems. */ + #if !defined(__EMSCRIPTEN__) && !defined(SDL_VIDEO_DRIVER_VITA) /* LoadFunction isn't needed on Emscripten and will call dlsym(), causing other problems. */ /* Try SDL_LoadFunction() first for EGL <= 1.4, or as a fallback for >= 1.5. */ if (!retval) { static char procname[64]; @@ -344,7 +343,7 @@ SDL_EGL_LoadLibraryOnly(_THIS, const char *egl_path) } #endif -#ifndef SDL_VIDEO_STATIC_ANGLE +#if !defined(SDL_VIDEO_STATIC_ANGLE) && !defined(SDL_VIDEO_DRIVER_VITA) /* A funny thing, loading EGL.so first does not work on the Raspberry, so we load libGL* first */ path = SDL_getenv("SDL_VIDEO_GL_DRIVER"); if (path != NULL) { @@ -430,6 +429,9 @@ SDL_EGL_LoadLibraryOnly(_THIS, const char *egl_path) #endif _this->egl_data->dll_handle = dll_handle; +#if SDL_VIDEO_DRIVER_VITA + _this->egl_data->egl_dll_handle = egl_dll_handle; +#endif /* Load new function pointers */ LOAD_FUNC(eglGetDisplay); @@ -498,6 +500,7 @@ SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_displa _this->egl_data->egl_display = EGL_NO_DISPLAY; #if !defined(__WINRT__) +#if !defined(SDL_VIDEO_DRIVER_VITA) if (platform) { /* EGL 1.5 allows querying for client version with EGL_NO_DISPLAY * -- @@ -522,6 +525,7 @@ SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_displa } } } +#endif /* Try the implementation-specific eglGetDisplay even if eglGetPlatformDisplay fails */ if (_this->egl_data->egl_display == EGL_NO_DISPLAY) { _this->egl_data->egl_display = _this->egl_data->eglGetDisplay(native_display); diff --git a/src/video/vita/SDL_vitagl_pvr.c b/src/video/vita/SDL_vitagl_pvr.c new file mode 100644 index 000000000..809adc2a2 --- /dev/null +++ b/src/video/vita/SDL_vitagl_pvr.c @@ -0,0 +1,95 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2020 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_VITA && SDL_VIDEO_VITA_PVR +#include +#include +#include +#include + +#include "SDL_error.h" +#include "SDL_log.h" +#include "SDL_vitavideo.h" +#include "../SDL_egl_c.h" +#include "SDL_vitagl_pvr_c.h" + +#define MAX_PATH 256 // vita limits are somehow wrong + +int +VITA_GL_LoadLibrary(_THIS, const char *path) +{ + PVRSRV_PSP2_APPHINT hint; + char* override = SDL_getenv("VITA_MODULE_PATH"); + char* default_path = "app0:module/"; + char target_path[MAX_PATH]; + + if (override != NULL) + { + default_path = override; + } + + sceKernelLoadStartModule("vs0:sys/external/libfios2.suprx", 0, NULL, 0, NULL, NULL); + sceKernelLoadStartModule("vs0:sys/external/libc.suprx", 0, NULL, 0, NULL, NULL); + + SDL_snprintf(target_path, MAX_PATH, "%s/%s", default_path, "libgpu_es4_ext.suprx"); + sceKernelLoadStartModule(target_path, 0, NULL, 0, NULL, NULL); + + SDL_snprintf(target_path, MAX_PATH, "%s/%s", default_path, "libIMGEGL.suprx"); + sceKernelLoadStartModule(target_path, 0, NULL, 0, NULL, NULL); + + PVRSRVInitializeAppHint(&hint); + + SDL_snprintf(hint.szGLES1, MAX_PATH, "%s/%s", default_path, "libGLESv1_CM.suprx"); + SDL_snprintf(hint.szGLES2, MAX_PATH, "%s/%s", default_path, "libGLESv2.suprx"); + SDL_snprintf(hint.szWindowSystem, MAX_PATH, "%s/%s", default_path, "libpvrPSP2_WSEGL.suprx"); + + PVRSRVCreateVirtualAppHint(&hint); + + return SDL_EGL_LoadLibrary(_this, path, (NativeDisplayType) 0, 0); +} + +SDL_GLContext +VITA_GL_CreateContext(_THIS, SDL_Window * window) +{ + return SDL_EGL_CreateContext(_this, ((SDL_WindowData *) window->driverdata)->egl_surface); +} + +int +VITA_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) +{ + if (window && context) { + return SDL_EGL_MakeCurrent(_this, ((SDL_WindowData *) window->driverdata)->egl_surface, context); + } else { + return SDL_EGL_MakeCurrent(_this, NULL, NULL); + } +} + +int +VITA_GL_SwapWindow(_THIS, SDL_Window * window) +{ + return SDL_EGL_SwapBuffers(_this, ((SDL_WindowData *) window->driverdata)->egl_surface); +} + + +#endif /* SDL_VIDEO_DRIVER_VITA && SDL_VIDEO_VITA_PVR */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/vita/SDL_vitagl_pvr_c.h b/src/video/vita/SDL_vitagl_pvr_c.h new file mode 100644 index 000000000..c957cdcde --- /dev/null +++ b/src/video/vita/SDL_vitagl_pvr_c.h @@ -0,0 +1,35 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2020 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_vitagl_c_h_ +#define SDL_vitagl_c_h_ + +#include "SDL_vitavideo.h" + +extern int VITA_GL_MakeCurrent(_THIS,SDL_Window * window, SDL_GLContext context); +extern int VITA_GL_SwapWindow(_THIS, SDL_Window * window); +extern SDL_GLContext VITA_GL_CreateContext(_THIS, SDL_Window * window); +extern int VITA_GL_LoadLibrary(_THIS, const char *path); + + +#endif /* SDL_vitagl_c_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/vita/SDL_vitavideo.c b/src/video/vita/SDL_vitavideo.c index 0adf3b8a8..1c09a31e3 100644 --- a/src/video/vita/SDL_vitavideo.c +++ b/src/video/vita/SDL_vitavideo.c @@ -38,9 +38,19 @@ #include "SDL_vitakeyboard.h" #include "SDL_vitamouse_c.h" #include "SDL_vitaframebuffer.h" -#if SDL_VIDEO_VITA_PIB -#include "SDL_vitagl_c.h" + +#if defined(SDL_VIDEO_VITA_PIB) + #include "SDL_vitagl_c.h" +#elif defined(SDL_VIDEO_VITA_PVR) + #include "SDL_vitagl_pvr_c.h" + #include "../SDL_egl_c.h" + #define VITA_GL_GetProcAddress SDL_EGL_GetProcAddress + #define VITA_GL_UnloadLibrary SDL_EGL_UnloadLibrary + #define VITA_GL_SetSwapInterval SDL_EGL_SetSwapInterval + #define VITA_GL_GetSwapInterval SDL_EGL_GetSwapInterval + #define VITA_GL_DeleteContext SDL_EGL_DeleteContext #endif + #include SDL_Window *Vita_Window; @@ -130,7 +140,7 @@ VITA_Create() device->DestroyWindowFramebuffer = VITA_DestroyWindowFramebuffer; */ -#if SDL_VIDEO_VITA_PIB +#if defined(SDL_VIDEO_VITA_PIB) || defined(SDL_VIDEO_VITA_PVR) device->GL_LoadLibrary = VITA_GL_LoadLibrary; device->GL_GetProcAddress = VITA_GL_GetProcAddress; device->GL_UnloadLibrary = VITA_GL_UnloadLibrary; @@ -232,6 +242,16 @@ VITA_CreateWindow(_THIS, SDL_Window * window) Vita_Window = window; +#if defined(SDL_VIDEO_VITA_PVR) + if ((window->flags & SDL_WINDOW_OPENGL) != 0) { + wdata->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) 0); + + if (wdata->egl_surface == EGL_NO_SURFACE) { + return SDL_SetError("Could not create GLES window surface"); + } + } +#endif + // fix input, we need to find a better way SDL_SetKeyboardFocus(window); diff --git a/src/video/vita/SDL_vitavideo.h b/src/video/vita/SDL_vitavideo.h index 13ea895db..2670f2beb 100644 --- a/src/video/vita/SDL_vitavideo.h +++ b/src/video/vita/SDL_vitavideo.h @@ -24,6 +24,7 @@ #include "../../SDL_internal.h" #include "../SDL_sysvideo.h" +#include "../SDL_egl_c.h" #include #include @@ -51,6 +52,8 @@ typedef struct SDL_WindowData SDL_bool uses_gles; SceUID buffer_uid; void* buffer; + EGLSurface egl_surface; + EGLContext egl_context; } SDL_WindowData;