From 10c67b99c8ac118aab0edad922ba0549cd1dde46 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 14 Jan 2018 15:52:20 -0800 Subject: [PATCH 1/9] Windows: Fix extracting UMD block data. Sometimes it's useful to extract a filename the game uses, etc., that's actually an LBN. --- Windows/MainWindowMenu.cpp | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index f689fc9f05..aafb37a905 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -911,14 +911,25 @@ namespace MainWindow { } else if (info.type == FILETYPE_DIRECTORY) { MessageBox(hWnd, L"Cannot extract directories.", L"Sorry", 0); } else if (W32Util::BrowseForFileName(false, hWnd, L"Save file as...", 0, L"All files\0*.*\0\0", L"", fn)) { - FILE *fp = File::OpenCFile(fn, "wb"); u32 handle = pspFileSystem.OpenFile(filename, FILEACCESS_READ, ""); + // Note: len may be in blocks. + size_t len = pspFileSystem.SeekFile(handle, 0, FILEMOVE_END); + bool isBlockMode = pspFileSystem.DevType(handle) == PSP_DEV_TYPE_BLOCK; + + FILE *fp = File::OpenCFile(fn, "wb"); + pspFileSystem.SeekFile(handle, 0, FILEMOVE_BEGIN); u8 buffer[4096]; - size_t bytes; - do { - bytes = pspFileSystem.ReadFile(handle, buffer, sizeof(buffer)); + size_t bufferSize = isBlockMode ? sizeof(buffer) / 2048 : sizeof(buffer); + while (len > 0) { + // This is all in blocks, not bytes, if isBlockMode. + size_t remain = std::min(len, bufferSize); + size_t readSize = pspFileSystem.ReadFile(handle, buffer, remain); + if (readSize == 0) + break; + size_t bytes = isBlockMode ? readSize * 2048 : readSize; fwrite(buffer, 1, bytes, fp); - } while (bytes == sizeof(buffer)); + len -= readSize; + } pspFileSystem.CloseFile(handle); fclose(fp); } From 5716fce283f1b19b3eb477d4d7b175548ce82a17 Mon Sep 17 00:00:00 2001 From: Akira Miyakoda Date: Mon, 15 Jan 2018 21:18:08 +0900 Subject: [PATCH 2/9] Allow up to 10x window size on Windows. 4x can be too small for today's high resolution monitors. --- Windows/MainWindowMenu.cpp | 14 +++++++++++++- Windows/ppsspp.rc | 6 ++++++ Windows/resource.h | 7 ++++++- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index f689fc9f05..22ca8df541 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -732,6 +732,12 @@ namespace MainWindow { case ID_OPTIONS_WINDOW2X: SetWindowSize(2); break; case ID_OPTIONS_WINDOW3X: SetWindowSize(3); break; case ID_OPTIONS_WINDOW4X: SetWindowSize(4); break; + case ID_OPTIONS_WINDOW5X: SetWindowSize(5); break; + case ID_OPTIONS_WINDOW6X: SetWindowSize(6); break; + case ID_OPTIONS_WINDOW7X: SetWindowSize(7); break; + case ID_OPTIONS_WINDOW8X: SetWindowSize(8); break; + case ID_OPTIONS_WINDOW9X: SetWindowSize(9); break; + case ID_OPTIONS_WINDOW10X: SetWindowSize(10); break; case ID_OPTIONS_RESOLUTIONDUMMY: { @@ -1107,11 +1113,17 @@ namespace MainWindow { CheckMenuItem(menu, zoomitems[i], MF_BYCOMMAND | ((i == g_Config.iInternalResolution) ? MF_CHECKED : MF_UNCHECKED)); } - static const int windowSizeItems[4] = { + static const int windowSizeItems[10] = { ID_OPTIONS_WINDOW1X, ID_OPTIONS_WINDOW2X, ID_OPTIONS_WINDOW3X, ID_OPTIONS_WINDOW4X, + ID_OPTIONS_WINDOW5X, + ID_OPTIONS_WINDOW6X, + ID_OPTIONS_WINDOW7X, + ID_OPTIONS_WINDOW8X, + ID_OPTIONS_WINDOW9X, + ID_OPTIONS_WINDOW10X, }; RECT rc; diff --git a/Windows/ppsspp.rc b/Windows/ppsspp.rc index cd334bcc7f..075640f669 100644 --- a/Windows/ppsspp.rc +++ b/Windows/ppsspp.rc @@ -492,6 +492,12 @@ BEGIN MENUITEM "&2x", ID_OPTIONS_WINDOW2X MENUITEM "&3x", ID_OPTIONS_WINDOW3X MENUITEM "&4x", ID_OPTIONS_WINDOW4X + MENUITEM "&5x", ID_OPTIONS_WINDOW5X + MENUITEM "&6x", ID_OPTIONS_WINDOW6X + MENUITEM "&7x", ID_OPTIONS_WINDOW7X + MENUITEM "&8x", ID_OPTIONS_WINDOW8X + MENUITEM "&9x", ID_OPTIONS_WINDOW9X + MENUITEM "&10x", ID_OPTIONS_WINDOW10X END POPUP "Backend" diff --git a/Windows/resource.h b/Windows/resource.h index 887038bd47..ca52341e45 100644 --- a/Windows/resource.h +++ b/Windows/resource.h @@ -334,6 +334,11 @@ #define IDC_GEDBG_RECORD 40169 #define ID_GEDBG_EXPORT_IMAGE 40170 #define ID_GEDBG_ENABLE_PREVIEW 40171 +#define ID_OPTIONS_WINDOW6X 40172 +#define ID_OPTIONS_WINDOW7X 40173 +#define ID_OPTIONS_WINDOW8X 40174 +#define ID_OPTIONS_WINDOW9X 40175 +#define ID_OPTIONS_WINDOW10X 40176 // Dummy option to let the buffered rendering hotkey cycle through all the options. #define ID_OPTIONS_BUFFEREDRENDERINGDUMMY 40500 @@ -346,7 +351,7 @@ #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 256 -#define _APS_NEXT_COMMAND_VALUE 40172 +#define _APS_NEXT_COMMAND_VALUE 40177 #define _APS_NEXT_CONTROL_VALUE 1200 #define _APS_NEXT_SYMED_VALUE 101 #endif From 6e1821a8c764571a9eb00a2b96c44bcf06886c6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 17 Jan 2018 11:18:20 +0100 Subject: [PATCH 3/9] Experimenally try a new gamecontrollerdb.txt line for 360 wireless receiver on linux. See #10181 --- assets/gamecontrollerdb.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/gamecontrollerdb.txt b/assets/gamecontrollerdb.txt index d05c7b4348..8b1e8ac772 100644 --- a/assets/gamecontrollerdb.txt +++ b/assets/gamecontrollerdb.txt @@ -184,4 +184,4 @@ bd1200000000000015d0000000000000,Tomee SNES USB Controller,x:b3,a:b2,b:b1,y:b0,b 050000004c0500006802000000810000,PLAYSTATION(R)3 Controller,platform:Linux,x:b3,a:b0,b:b1,y:b2,back:b8,guide:b10,start:b9,dpleft:b15,dpdown:b14,dpright:b16,dpup:b13,leftshoulder:b4,lefttrigger:a2,rightshoulder:b6,rightshoulder:b5,righttrigger:a5,leftstick:b7,leftstick:b11,rightstick:b12,leftx:a0,lefty:a1,rightx:a3,righty:a4, 03000000c82d00000190000011010000,8Bitdo NES30 Pro 8Bitdo NES30 Pro,platform:Linux,a:b1,b:b0,x:b4,y:b3,back:b10,start:b11,leftstick:b13,rightstick:b14,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5, 05000000c82d00002038000000010000,8Bitdo NES30 Pro,platform:Linux,a:b1,b:b0,x:b4,y:b3,back:b10,guide:b2,start:b11,leftstick:b13,rightstick:b14,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a5,righttrigger:a4, -030000005e040000a102000000010000,Xbox 360 Wireless Receiver,b:b1,righty:a3,rightx:a2,a:b0,x:b2,righttrigger:b7,rightstick:b12,leftshoulder:b4,dpup:b15,start:b9,dpdown:b16,rightshoulder:b5,dpright:b14,lefttrigger:b6,leftstick:b11,guide:b8,y:b3,lefty:a1,leftx:a0,back:b8,dpleft:b13,platform:Linux, +030000005e040000a102000000010000,Xbox 360 Wireless Receiver,platform:Linux,a:b0,b:b1,x:b2,y:b3,back:b6,guide:b8,start:b7,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:b13,dpdown:b14,dpleft:b11,dpright:b12,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5, From 3f73cfb835270b452cdecc2a1ec7051b14287e9f Mon Sep 17 00:00:00 2001 From: Akira Miyakoda Date: Wed, 17 Jan 2018 19:25:01 +0900 Subject: [PATCH 4/9] Windows: Fix a small memory leak. CommandLineToArgvW() allocates a memory block which must be freed by LocalFree(). --- Windows/main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Windows/main.cpp b/Windows/main.cpp index 8832038653..8c10f1e99d 100644 --- a/Windows/main.cpp +++ b/Windows/main.cpp @@ -349,6 +349,8 @@ std::vector GetWideCmdLine() { wargv = CommandLineToArgvW(GetCommandLineW(), &wargc); std::vector wideArgs(wargv, wargv + wargc); + LocalFree(wargv); + return wideArgs; } From f8cd9c7e55e46a7f957eb9d673f90b6d8013d2fd Mon Sep 17 00:00:00 2001 From: Akira Miyakoda Date: Thu, 18 Jan 2018 00:36:27 +0900 Subject: [PATCH 5/9] Windows: Use sufficient buffer for config file paths. MAX_PATH bytes are insufficient when a very long path is converted into UTF-8. --- Windows/main.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/Windows/main.cpp b/Windows/main.cpp index 8c10f1e99d..4d6a28c849 100644 --- a/Windows/main.cpp +++ b/Windows/main.cpp @@ -391,10 +391,10 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin langRegion = GetDefaultLangRegion(); osName = GetWindowsVersion() + " " + GetWindowsSystemArchitecture(); - char configFilename[MAX_PATH] = { 0 }; + std::string configFilename = ""; const std::wstring configOption = L"--config="; - char controlsConfigFilename[MAX_PATH] = { 0 }; + std::string controlsConfigFilename = ""; const std::wstring controlsOption = L"--controlconfig="; std::vector wideArgs = GetWideCmdLine(); @@ -405,14 +405,12 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin if (wideArgs[i][0] == L'-') { if (wideArgs[i].find(configOption) != std::wstring::npos && wideArgs[i].size() > configOption.size()) { const std::wstring tempWide = wideArgs[i].substr(configOption.size()); - const std::string tempStr = ConvertWStringToUTF8(tempWide); - std::strncpy(configFilename, tempStr.c_str(), MAX_PATH); + configFilename = ConvertWStringToUTF8(tempWide); } if (wideArgs[i].find(controlsOption) != std::wstring::npos && wideArgs[i].size() > controlsOption.size()) { const std::wstring tempWide = wideArgs[i].substr(controlsOption.size()); - const std::string tempStr = ConvertWStringToUTF8(tempWide); - std::strncpy(controlsConfigFilename, tempStr.c_str(), MAX_PATH); + controlsConfigFilename = ConvertWStringToUTF8(tempWide); } } } @@ -428,7 +426,7 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin g_Config.AddSearchPath(""); g_Config.AddSearchPath(GetSysDirectory(DIRECTORY_SYSTEM)); g_Config.SetDefaultPath(GetSysDirectory(DIRECTORY_SYSTEM)); - g_Config.Load(configFilename, controlsConfigFilename); + g_Config.Load(configFilename.c_str(), controlsConfigFilename.c_str()); bool debugLogLevel = false; From a10888cb671974664f9885246cb56833699f4ae0 Mon Sep 17 00:00:00 2001 From: Akira Miyakoda Date: Thu, 18 Jan 2018 17:47:40 +0900 Subject: [PATCH 6/9] Revert "EditorConfig: Workaround MSVC2017 bug." This reverts commit 1912a948abbed46f04ccc2e7e930c1cf2eb3c22a. The bug has been fixed in MSVC2017 15.3. --- .editorconfig | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.editorconfig b/.editorconfig index 21b678c82b..c379dffa45 100644 --- a/.editorconfig +++ b/.editorconfig @@ -2,10 +2,7 @@ root = true [*] -# Temporarily disabled because MSVC2017 misinterprets as utf-8-bom. -# TODO: Reinstate once fixed build is released: -# https://developercommunity.visualstudio.com/content/problem/22922/editorconfig-support-interprets-charset-utf-8-as-u.html -#charset = utf-8 +charset = utf-8 indent_style = tab insert_final_newline = true # Would be nice, but don't want to change files unnecessarily. From 8eeee7e1ab6c9e2e2c6d5597325f62f79289a91e Mon Sep 17 00:00:00 2001 From: Akira Miyakoda Date: Fri, 19 Jan 2018 18:22:06 +0900 Subject: [PATCH 7/9] Windows: Fix loading files with a long path. Better handling of a path which exceeds MAX_PATH when converted into UTF-8. --- Windows/MainWindowMenu.cpp | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index deda9a5c29..ff5c5989dd 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -404,18 +404,6 @@ namespace MainWindow { Core_EnableStepping(false); } - // TODO: What is this for / what does it fix? - if (browseDialog->GetType() != W32Util::AsyncBrowseDialog::DIR) { - // Decode the filename with fullpath. - char drive[MAX_PATH]; - char dir[MAX_PATH]; - char fname[MAX_PATH]; - char ext[MAX_PATH]; - _splitpath(filename.c_str(), drive, dir, fname, ext); - - filename = std::string(drive) + std::string(dir) + std::string(fname) + std::string(ext); - } - filename = ReplaceAll(filename, "\\", "/"); NativeMessageReceived("boot", filename.c_str()); } From 133bef575a1b6538dd01be8b280f9b73d8bde2e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 20 Jan 2018 21:47:16 +0100 Subject: [PATCH 8/9] Split Android graphics context implementations into their own files. --- CMakeLists.txt | 7 + Common/Vulkan/VulkanContext.cpp | 2 + UI/NativeApp.cpp | 10 +- Windows/PPSSPP.vcxproj | 42 ++++ Windows/PPSSPP.vcxproj.filters | 21 ++ android/jni/Android.mk | 3 + android/jni/AndroidEGLContext.cpp | 62 +++++ android/jni/AndroidEGLContext.h | 22 ++ android/jni/AndroidGraphicsContext.h | 23 ++ android/jni/AndroidJavaGLContext.cpp | 19 ++ android/jni/AndroidJavaGLContext.h | 22 ++ android/jni/AndroidVulkanContext.cpp | 198 ++++++++++++++++ android/jni/AndroidVulkanContext.h | 34 +++ android/jni/app-android.cpp | 342 +-------------------------- 14 files changed, 468 insertions(+), 339 deletions(-) create mode 100644 android/jni/AndroidEGLContext.cpp create mode 100644 android/jni/AndroidEGLContext.h create mode 100644 android/jni/AndroidGraphicsContext.h create mode 100644 android/jni/AndroidJavaGLContext.cpp create mode 100644 android/jni/AndroidJavaGLContext.h create mode 100644 android/jni/AndroidVulkanContext.cpp create mode 100644 android/jni/AndroidVulkanContext.h diff --git a/CMakeLists.txt b/CMakeLists.txt index d8cdbee3a4..1a1ae75c2d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -660,6 +660,13 @@ if(ANDROID) set(nativeExtra ${nativeExtra} ext/native/base/NativeApp.h android/jni/app-android.cpp + android/jni/AndroidEGLContext.cpp + android/jni/AndroidEGLContext.h + android/jni/AndroidJavaGLContext.cpp + android/jni/AndroidJavaGLContext.h + android/jni/AndroidVulkanContext.cpp + android/jni/AndroidVulkanContext.h + android/jni/AndroidGraphicsContext.h android/jni/native_audio.cpp android/jni/native_audio.h android/jni/native-audio-so.cpp diff --git a/Common/Vulkan/VulkanContext.cpp b/Common/Vulkan/VulkanContext.cpp index 70448a0905..6f3cfb5d55 100644 --- a/Common/Vulkan/VulkanContext.cpp +++ b/Common/Vulkan/VulkanContext.cpp @@ -6,9 +6,11 @@ #include #include "base/basictypes.h" +#include "base/display.h" #include "VulkanContext.h" #include "GPU/Common/ShaderCommon.h" #include "Common/StringUtils.h" +#include "Core/Config.h" // Change this to 1, 2, and 3 to fake failures in a few places, so that // we can test our fallback-to-GL code. diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 1c51566224..d570aa8ce5 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -722,8 +722,14 @@ void NativeShutdownGraphics() { ui_draw2d.Shutdown(); ui_draw2d_front.Shutdown(); - colorPipeline->Release(); - texColorPipeline->Release(); + if (colorPipeline) { + colorPipeline->Release(); + colorPipeline = nullptr; + } + if (texColorPipeline) { + texColorPipeline->Release(); + texColorPipeline = nullptr; + } ILOG("NativeShutdownGraphics done"); } diff --git a/Windows/PPSSPP.vcxproj b/Windows/PPSSPP.vcxproj index ea471b88fb..9e95c6a1b8 100644 --- a/Windows/PPSSPP.vcxproj +++ b/Windows/PPSSPP.vcxproj @@ -278,6 +278,24 @@ + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + true true @@ -435,6 +453,30 @@ + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + diff --git a/Windows/PPSSPP.vcxproj.filters b/Windows/PPSSPP.vcxproj.filters index 7aa93096ef..8cce6b63ec 100644 --- a/Windows/PPSSPP.vcxproj.filters +++ b/Windows/PPSSPP.vcxproj.filters @@ -200,6 +200,15 @@ Other Platforms + + Other Platforms + + + Other Platforms + + + Other Platforms + @@ -368,6 +377,18 @@ Other Platforms + + Other Platforms + + + Other Platforms + + + Other Platforms + + + Other Platforms + diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 5ea6ccd057..ecd4352c45 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -406,6 +406,9 @@ LOCAL_STATIC_LIBRARIES += ppsspp_core LOCAL_MODULE := ppsspp_jni LOCAL_SRC_FILES := \ $(SRC)/android/jni/app-android.cpp \ + $(SRC)/android/jni/AndroidEGLContext.cpp \ + $(SRC)/android/jni/AndroidJavaGLContext.cpp \ + $(SRC)/android/jni/AndroidVulkanContext.cpp \ $(SRC)/android/jni/native_audio.cpp \ $(SRC)/android/jni/native-audio-so.cpp \ $(SRC)/UI/BackgroundAudio.cpp \ diff --git a/android/jni/AndroidEGLContext.cpp b/android/jni/AndroidEGLContext.cpp new file mode 100644 index 0000000000..8742085535 --- /dev/null +++ b/android/jni/AndroidEGLContext.cpp @@ -0,0 +1,62 @@ +#include "base/logging.h" +#include "base/NativeApp.h" +#include "gfx_es2/gpu_features.h" + +#include "AndroidEGLContext.h" +#include "GL/GLInterface/EGLAndroid.h" +#include "Core/System.h" + +bool AndroidEGLGraphicsContext::Init(ANativeWindow *wnd, int backbufferWidth, int backbufferHeight, int backbufferFormat, int androidVersion) { + wnd_ = wnd; + gl = HostGL_CreateGLInterface(); + if (!gl) { + ELOG("ERROR: Failed to create GL interface"); + return false; + } + ILOG("EGL interface created. Desired backbuffer size: %dx%d", backbufferWidth, backbufferHeight); + + // Apparently we still have to set this through Java through setFixedSize on the bufferHolder for it to take effect... + gl->SetBackBufferDimensions(backbufferWidth, backbufferHeight); + gl->SetMode(MODE_DETECT_ES); + + bool use565 = false; + + // This workaround seems only be needed on some really old devices. + if (androidVersion < ANDROID_VERSION_ICS) { + switch (backbufferFormat) { + case 4: // PixelFormat.RGB_565 + use565 = true; + break; + default: + break; + } + } + + if (!gl->Create(wnd, false, use565)) { + ELOG("EGL creation failed! (use565=%d)", (int)use565); + // TODO: What do we do now? + delete gl; + return false; + } + gl->MakeCurrent(); + CheckGLExtensions(); + draw_ = Draw::T3DCreateGLContext(); + SetGPUBackend(GPUBackend::OPENGL); + bool success = draw_->CreatePresets(); // There will always be a GLSL compiler capable of compiling these. + assert(success); + return true; +} + +void AndroidEGLGraphicsContext::Shutdown() { + delete draw_; + draw_ = nullptr; + NativeShutdownGraphics(); + gl->ClearCurrent(); + gl->Shutdown(); + delete gl; + ANativeWindow_release(wnd_); +} + +void AndroidEGLGraphicsContext::SwapBuffers() { + gl->Swap(); +} diff --git a/android/jni/AndroidEGLContext.h b/android/jni/AndroidEGLContext.h new file mode 100644 index 0000000000..efeafecf80 --- /dev/null +++ b/android/jni/AndroidEGLContext.h @@ -0,0 +1,22 @@ +#pragma once + +#include "AndroidGraphicsContext.h" +#include "Common/GL/GLInterfaceBase.h" + +class AndroidEGLGraphicsContext : public AndroidGraphicsContext { +public: + AndroidEGLGraphicsContext() : draw_(nullptr), wnd_(nullptr), gl(nullptr) {} + bool Init(ANativeWindow *wnd, int desiredBackbufferSizeX, int desiredBackbufferSizeY, int backbufferFormat, int androidVersion) override; + void Shutdown() override; + void SwapBuffers() override; + void SwapInterval(int interval) override {} + void Resize() override {} + Draw::DrawContext *GetDrawContext() override { + return draw_; + } + +private: + Draw::DrawContext *draw_; + ANativeWindow *wnd_; + cInterfaceBase *gl; +}; diff --git a/android/jni/AndroidGraphicsContext.h b/android/jni/AndroidGraphicsContext.h new file mode 100644 index 0000000000..027be92505 --- /dev/null +++ b/android/jni/AndroidGraphicsContext.h @@ -0,0 +1,23 @@ +#pragma once + +#include + +#include "thin3d/thin3d.h" + +#include "Common/GraphicsContext.h" + +enum { + ANDROID_VERSION_GINGERBREAD = 9, + ANDROID_VERSION_ICS = 14, + ANDROID_VERSION_JELLYBEAN = 16, + ANDROID_VERSION_KITKAT = 19, + ANDROID_VERSION_LOLLIPOP = 21, + ANDROID_VERSION_MARSHMALLOW = 23, + ANDROID_VERSION_NOUGAT = 24, + ANDROID_VERSION_NOUGAT_1 = 25, +}; + +class AndroidGraphicsContext : public GraphicsContext { +public: + virtual bool Init(ANativeWindow *wnd, int desiredBackbufferSizeX, int desiredBackbufferSizeY, int backbufferFormat, int androidVersion) = 0; +}; diff --git a/android/jni/AndroidJavaGLContext.cpp b/android/jni/AndroidJavaGLContext.cpp new file mode 100644 index 0000000000..8a97a62187 --- /dev/null +++ b/android/jni/AndroidJavaGLContext.cpp @@ -0,0 +1,19 @@ +#include "AndroidJavaGLContext.h" +#include "base/NativeApp.h" +#include "gfx_es2/gpu_features.h" +#include "Core/System.h" + +AndroidJavaEGLGraphicsContext::AndroidJavaEGLGraphicsContext() { + CheckGLExtensions(); + draw_ = Draw::T3DCreateGLContext(); + SetGPUBackend(GPUBackend::OPENGL); + bool success = draw_->CreatePresets(); + assert(success); +} + +void AndroidJavaEGLGraphicsContext::Shutdown() { + ILOG("AndroidJavaEGLGraphicsContext::Shutdown"); + delete draw_; + draw_ = nullptr; + NativeShutdownGraphics(); +} diff --git a/android/jni/AndroidJavaGLContext.h b/android/jni/AndroidJavaGLContext.h new file mode 100644 index 0000000000..36e443e51d --- /dev/null +++ b/android/jni/AndroidJavaGLContext.h @@ -0,0 +1,22 @@ +#pragma once + +#include "AndroidGraphicsContext.h" + +// Doesn't do much. Just to fit in. +class AndroidJavaEGLGraphicsContext : public GraphicsContext { +public: + AndroidJavaEGLGraphicsContext(); + ~AndroidJavaEGLGraphicsContext() { + delete draw_; + } + void Shutdown() override; + void SwapBuffers() override {} + void SwapInterval(int interval) override {} + void Resize() override {} + Draw::DrawContext *GetDrawContext() override { + return draw_; + } +private: + Draw::DrawContext *draw_; +}; + diff --git a/android/jni/AndroidVulkanContext.cpp b/android/jni/AndroidVulkanContext.cpp new file mode 100644 index 0000000000..99b21469be --- /dev/null +++ b/android/jni/AndroidVulkanContext.cpp @@ -0,0 +1,198 @@ +#include "AndroidVulkanContext.h" +#include "base/NativeApp.h" +#include "base/display.h" +#include "Common/Vulkan/VulkanLoader.h" +#include "Common/Vulkan/VulkanContext.h" +#include "thin3d/VulkanRenderManager.h" +#include "util/text/parsers.h" +#include "Core/Config.h" +#include "Core/System.h" + +static VulkanLogOptions g_LogOptions; + +const char *ObjTypeToString(VkDebugReportObjectTypeEXT type) { + switch (type) { + case VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT: return "Instance"; + case VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT: return "PhysicalDevice"; + case VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT: return "Device"; + case VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT: return "Queue"; + case VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT: return "CommandBuffer"; + case VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT: return "DeviceMemory"; + case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT: return "Buffer"; + case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT: return "BufferView"; + case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT: return "Image"; + case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT: return "ImageView"; + case VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT: return "ShaderModule"; + case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT: return "Pipeline"; + case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT: return "PipelineLayout"; + case VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT: return "Sampler"; + case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT: return "DescriptorSet"; + case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT: return "DescriptorSetLayout"; + case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT: return "DescriptorPool"; + case VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT: return "Fence"; + case VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT: return "Semaphore"; + case VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT: return "Event"; + case VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT: return "QueryPool"; + case VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT: return "Framebuffer"; + case VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT: return "RenderPass"; + case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT: return "PipelineCache"; + case VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT: return "SurfaceKHR"; + case VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT: return "SwapChainKHR"; + case VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT: return "CommandPool"; + default: return "Unknown"; + } +} + +static VKAPI_ATTR VkBool32 VKAPI_CALL Vulkan_Dbg(VkDebugReportFlagsEXT msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void *pUserData) { + const VulkanLogOptions *options = (const VulkanLogOptions *)pUserData; + int loglevel = ANDROID_LOG_INFO; + if (msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT) { + loglevel = ANDROID_LOG_ERROR; + } else if (msgFlags & VK_DEBUG_REPORT_WARNING_BIT_EXT) { + loglevel = ANDROID_LOG_WARN; + } else if (msgFlags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) { + loglevel = ANDROID_LOG_WARN; + } else if (msgFlags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) { + loglevel = ANDROID_LOG_WARN; + } else if (msgFlags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) { + loglevel = ANDROID_LOG_WARN; + } + + __android_log_print(loglevel, APP_NAME, "[%s] %s Code %d : %s", pLayerPrefix, ObjTypeToString(objType), msgCode, pMsg); + + // false indicates that layer should not bail-out of an + // API call that had validation failures. This may mean that the + // app dies inside the driver due to invalid parameter(s). + // That's what would happen without validation layers, so we'll + // keep that behavior here. + return false; +} + +AndroidVulkanContext::~AndroidVulkanContext() { + delete g_Vulkan; + g_Vulkan = nullptr; +} + +bool AndroidVulkanContext::Init(ANativeWindow *wnd, int desiredBackbufferSizeX, int desiredBackbufferSizeY, int backbufferFormat, int androidVersion) { + ILOG("AndroidVulkanContext::Init"); + init_glslang(); + + g_LogOptions.breakOnError = true; + g_LogOptions.breakOnWarning = true; + g_LogOptions.msgBoxOnError = false; + + ILOG("Creating Vulkan context"); + Version gitVer(PPSSPP_GIT_VERSION); + + if (!g_Vulkan) { + g_Vulkan = new VulkanContext(); + } + VulkanContext::CreateInfo info{}; + info.app_name = "PPSSPP"; + info.app_ver = gitVer.ToInteger(); + info.flags = VULKAN_FLAG_PRESENT_MAILBOX | VULKAN_FLAG_PRESENT_FIFO_RELAXED; + if (VK_SUCCESS != g_Vulkan->CreateInstance(info)) { + ELOG("Failed to create vulkan context: %s", g_Vulkan->InitError().c_str()); + System_SendMessage("toast", "No Vulkan compatible device found. Using OpenGL instead."); + delete g_Vulkan; + g_Vulkan = nullptr; + return false; + } + + int physicalDevice = g_Vulkan->GetBestPhysicalDevice(); + if (physicalDevice < 0) { + ELOG("No usable Vulkan device found."); + g_Vulkan->DestroyInstance(); + delete g_Vulkan; + g_Vulkan = nullptr; + return false; + } + + g_Vulkan->ChooseDevice(physicalDevice); + // Here we can enable device extensions if we like. + + ILOG("Creating Vulkan device"); + if (g_Vulkan->CreateDevice() != VK_SUCCESS) { + ILOG("Failed to create vulkan device: %s", g_Vulkan->InitError().c_str()); + System_SendMessage("toast", "No Vulkan driver found. Using OpenGL instead."); + g_Vulkan->DestroyInstance(); + delete g_Vulkan; + g_Vulkan = nullptr; + return false; + } + int width = desiredBackbufferSizeX; + int height = desiredBackbufferSizeY; + if (!width || !height) { + width = pixel_xres; + height = pixel_yres; + } + ILOG("InitSurfaceAndroid: width=%d height=%d", width, height); + g_Vulkan->InitSurface(WINDOWSYSTEM_ANDROID, (void *)wnd, nullptr, width, height); + if (g_validate_) { + int bits = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT; + g_Vulkan->InitDebugMsgCallback(&Vulkan_Dbg, bits, &g_LogOptions); + } + + bool success = true; + if (g_Vulkan->InitObjects()) { + draw_ = Draw::T3DCreateVulkanContext(g_Vulkan, g_Config.bGfxDebugSplitSubmit); + SetGPUBackend(GPUBackend::VULKAN); + success = draw_->CreatePresets(); // Doesn't fail, we ship the compiler. + assert(success); + draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); + + VulkanRenderManager *renderManager = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); + success = renderManager->HasBackbuffers(); + } else { + success = false; + } + + ILOG("AndroidVulkanContext::Init completed, %s", success ? "successfully" : "but failed"); + if (!success) { + g_Vulkan->DestroyObjects(); + g_Vulkan->DestroyDevice(); + g_Vulkan->DestroyDebugMsgCallback(); + + g_Vulkan->DestroyInstance(); + } + return success; +} + +void AndroidVulkanContext::Shutdown() { + ILOG("AndroidVulkanContext::Shutdown"); + draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); + ILOG("Calling NativeShutdownGraphics"); + NativeShutdownGraphics(); + delete draw_; + draw_ = nullptr; + g_Vulkan->WaitUntilQueueIdle(); + g_Vulkan->DestroyObjects(); + g_Vulkan->DestroyDevice(); + g_Vulkan->DestroyDebugMsgCallback(); + + g_Vulkan->DestroyInstance(); + + // We keep the g_Vulkan context around to avoid invalidating a ton of pointers around the app. + + finalize_glslang(); + ILOG("AndroidVulkanContext::Shutdown completed"); +} + +void AndroidVulkanContext::SwapBuffers() { +} + +void AndroidVulkanContext::Resize() { + ILOG("AndroidVulkanContext::Resize begin (%d, %d)", g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); + + draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); + g_Vulkan->DestroyObjects(); + + // backbufferResize updated these values. TODO: Notify another way? + g_Vulkan->ReinitSurface(pixel_xres, pixel_yres); + g_Vulkan->InitObjects(); + draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); + ILOG("AndroidVulkanContext::Resize end (%d, %d)", g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); +} + +void AndroidVulkanContext::SwapInterval(int interval) { +} diff --git a/android/jni/AndroidVulkanContext.h b/android/jni/AndroidVulkanContext.h new file mode 100644 index 0000000000..8c48e09c92 --- /dev/null +++ b/android/jni/AndroidVulkanContext.h @@ -0,0 +1,34 @@ +#pragma once + +#include "AndroidGraphicsContext.h" + +static const bool g_validate_ = true; + +class VulkanContext; + +class AndroidVulkanContext : public AndroidGraphicsContext { +public: + AndroidVulkanContext() : draw_(nullptr) {} + ~AndroidVulkanContext(); + + bool Init(ANativeWindow *wnd, int desiredBackbufferSizeX, int desiredBackbufferSizeY, int backbufferFormat, int androidVersion) override; + void Shutdown() override; + void SwapInterval(int interval) override; + void SwapBuffers() override; + void Resize() override; + + void *GetAPIContext() override { return g_Vulkan; } + + Draw::DrawContext *GetDrawContext() override { + return draw_; + } +private: + VulkanContext *g_Vulkan = nullptr; + Draw::DrawContext *draw_ = nullptr; +}; + +struct VulkanLogOptions { + bool breakOnWarning; + bool breakOnError; + bool msgBoxOnError; +}; diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index a06e2125f5..b5ef7779a2 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -4,7 +4,6 @@ // It calls a set of methods defined in NativeApp.h. These should be implemented // by your game or app. - #include #include #include @@ -18,6 +17,11 @@ #include #include +#include "AndroidGraphicsContext.h" +#include "AndroidVulkanContext.h" +#include "AndroidEGLContext.h" +#include "AndroidJavaGLContext.h" + #include "base/basictypes.h" #include "base/stringutil.h" #include "base/display.h" @@ -58,17 +62,6 @@ JavaVM *javaVM; static AndroidAudioState *g_audioState; -enum { - ANDROID_VERSION_GINGERBREAD = 9, - ANDROID_VERSION_ICS = 14, - ANDROID_VERSION_JELLYBEAN = 16, - ANDROID_VERSION_KITKAT = 19, - ANDROID_VERSION_LOLLIPOP = 21, - ANDROID_VERSION_MARSHMALLOW = 23, - ANDROID_VERSION_NOUGAT = 24, - ANDROID_VERSION_NOUGAT_1 = 25, -}; - struct FrameCommand { FrameCommand() {} FrameCommand(std::string cmd, std::string prm) : command(cmd), params(prm) {} @@ -77,331 +70,6 @@ struct FrameCommand { std::string params; }; -class AndroidGraphicsContext : public GraphicsContext { -public: - virtual bool Init(ANativeWindow *wnd, int desiredBackbufferSizeX, int desiredBackbufferSizeY, int backbufferFormat, int androidVersion) = 0; -}; - -class AndroidEGLGraphicsContext : public AndroidGraphicsContext { -public: - AndroidEGLGraphicsContext() : draw_(nullptr), wnd_(nullptr), gl(nullptr) {} - bool Init(ANativeWindow *wnd, int desiredBackbufferSizeX, int desiredBackbufferSizeY, int backbufferFormat, int androidVersion) override; - void Shutdown() override; - void SwapBuffers() override; - void SwapInterval(int interval) override {} - void Resize() override {} - Draw::DrawContext *GetDrawContext() override { - return draw_; - } - -private: - Draw::DrawContext *draw_; - ANativeWindow *wnd_; - cInterfaceBase *gl; -}; - -bool AndroidEGLGraphicsContext::Init(ANativeWindow *wnd, int backbufferWidth, int backbufferHeight, int backbufferFormat, int androidVersion) { - wnd_ = wnd; - gl = HostGL_CreateGLInterface(); - if (!gl) { - ELOG("ERROR: Failed to create GL interface"); - return false; - } - ILOG("EGL interface created. Desired backbuffer size: %dx%d", backbufferWidth, backbufferHeight); - - // Apparently we still have to set this through Java through setFixedSize on the bufferHolder for it to take effect... - gl->SetBackBufferDimensions(backbufferWidth, backbufferHeight); - gl->SetMode(MODE_DETECT_ES); - - bool use565 = false; - - // This workaround seems only be needed on some really old devices. - if (androidVersion < ANDROID_VERSION_ICS) { - switch (backbufferFormat) { - case 4: // PixelFormat.RGB_565 - use565 = true; - break; - default: - break; - } - } - - if (!gl->Create(wnd, false, use565)) { - ELOG("EGL creation failed! (use565=%d)", (int)use565); - // TODO: What do we do now? - delete gl; - return false; - } - gl->MakeCurrent(); - CheckGLExtensions(); - draw_ = Draw::T3DCreateGLContext(); - SetGPUBackend(GPUBackend::OPENGL); - bool success = draw_->CreatePresets(); // There will always be a GLSL compiler capable of compiling these. - assert(success); - return true; -} - -void AndroidEGLGraphicsContext::Shutdown() { - delete draw_; - draw_ = nullptr; - NativeShutdownGraphics(); - gl->ClearCurrent(); - gl->Shutdown(); - delete gl; - ANativeWindow_release(wnd_); - finalize_glslang(); -} - -void AndroidEGLGraphicsContext::SwapBuffers() { - gl->Swap(); -} - -// Doesn't do much. Just to fit in. -class AndroidJavaEGLGraphicsContext : public GraphicsContext { -public: - AndroidJavaEGLGraphicsContext() { - CheckGLExtensions(); - draw_ = Draw::T3DCreateGLContext(); - SetGPUBackend(GPUBackend::OPENGL); - bool success = draw_->CreatePresets(); - assert(success); - } - ~AndroidJavaEGLGraphicsContext() { - delete draw_; - } - void Shutdown() override { - ILOG("AndroidJavaEGLGraphicsContext::Shutdown"); - delete draw_; - draw_ = nullptr; - NativeShutdownGraphics(); - finalize_glslang(); - } - void SwapBuffers() override {} - void SwapInterval(int interval) override {} - void Resize() override {} - Draw::DrawContext *GetDrawContext() override { - return draw_; - } -private: - Draw::DrawContext *draw_; -}; - - -static const bool g_validate_ = true; -static VulkanContext *g_Vulkan; - -class AndroidVulkanContext : public AndroidGraphicsContext { -public: - AndroidVulkanContext() : draw_(nullptr) {} - ~AndroidVulkanContext() { - delete g_Vulkan; - g_Vulkan = nullptr; - } - - bool Init(ANativeWindow *wnd, int desiredBackbufferSizeX, int desiredBackbufferSizeY, int backbufferFormat, int androidVersion) override; - void Shutdown() override; - void SwapInterval(int interval) override; - void SwapBuffers() override; - void Resize() override; - - void *GetAPIContext() override { return g_Vulkan; } - - Draw::DrawContext *GetDrawContext() override { - return draw_; - } -private: - Draw::DrawContext *draw_; -}; - -struct VulkanLogOptions { - bool breakOnWarning; - bool breakOnError; - bool msgBoxOnError; -}; -static VulkanLogOptions g_LogOptions; - -const char *ObjTypeToString(VkDebugReportObjectTypeEXT type) { - switch (type) { - case VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT: return "Instance"; - case VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT: return "PhysicalDevice"; - case VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT: return "Device"; - case VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT: return "Queue"; - case VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT: return "CommandBuffer"; - case VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT: return "DeviceMemory"; - case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT: return "Buffer"; - case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT: return "BufferView"; - case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT: return "Image"; - case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT: return "ImageView"; - case VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT: return "ShaderModule"; - case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT: return "Pipeline"; - case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT: return "PipelineLayout"; - case VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT: return "Sampler"; - case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT: return "DescriptorSet"; - case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT: return "DescriptorSetLayout"; - case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT: return "DescriptorPool"; - case VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT: return "Fence"; - case VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT: return "Semaphore"; - case VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT: return "Event"; - case VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT: return "QueryPool"; - case VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT: return "Framebuffer"; - case VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT: return "RenderPass"; - case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT: return "PipelineCache"; - case VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT: return "SurfaceKHR"; - case VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT: return "SwapChainKHR"; - case VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT: return "CommandPool"; - default: return "Unknown"; - } -} - -static VKAPI_ATTR VkBool32 VKAPI_CALL Vulkan_Dbg(VkDebugReportFlagsEXT msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void *pUserData) { - const VulkanLogOptions *options = (const VulkanLogOptions *)pUserData; - int loglevel = ANDROID_LOG_INFO; - if (msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT) { - loglevel = ANDROID_LOG_ERROR; - } else if (msgFlags & VK_DEBUG_REPORT_WARNING_BIT_EXT) { - loglevel = ANDROID_LOG_WARN; - } else if (msgFlags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) { - loglevel = ANDROID_LOG_WARN; - } else if (msgFlags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) { - loglevel = ANDROID_LOG_WARN; - } else if (msgFlags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) { - loglevel = ANDROID_LOG_WARN; - } - - __android_log_print(loglevel, APP_NAME, "[%s] %s Code %d : %s", pLayerPrefix, ObjTypeToString(objType), msgCode, pMsg); - - // false indicates that layer should not bail-out of an - // API call that had validation failures. This may mean that the - // app dies inside the driver due to invalid parameter(s). - // That's what would happen without validation layers, so we'll - // keep that behavior here. - return false; -} - -bool AndroidVulkanContext::Init(ANativeWindow *wnd, int desiredBackbufferSizeX, int desiredBackbufferSizeY, int backbufferFormat, int androidVersion) { - ILOG("AndroidVulkanContext::Init"); - init_glslang(); - - g_LogOptions.breakOnError = true; - g_LogOptions.breakOnWarning = true; - g_LogOptions.msgBoxOnError = false; - - ILOG("Creating Vulkan context"); - Version gitVer(PPSSPP_GIT_VERSION); - - if (!g_Vulkan) { - g_Vulkan = new VulkanContext(); - } - VulkanContext::CreateInfo info{}; - info.app_name = "PPSSPP"; - info.app_ver = gitVer.ToInteger(); - info.flags = VULKAN_FLAG_PRESENT_MAILBOX | VULKAN_FLAG_PRESENT_FIFO_RELAXED; - if (VK_SUCCESS != g_Vulkan->CreateInstance(info)) { - ELOG("Failed to create vulkan context: %s", g_Vulkan->InitError().c_str()); - System_SendMessage("toast", "No Vulkan compatible device found. Using OpenGL instead."); - delete g_Vulkan; - g_Vulkan = nullptr; - return false; - } - - int physicalDevice = g_Vulkan->GetBestPhysicalDevice(); - if (physicalDevice < 0) { - ELOG("No usable Vulkan device found."); - g_Vulkan->DestroyInstance(); - delete g_Vulkan; - g_Vulkan = nullptr; - return false; - } - - g_Vulkan->ChooseDevice(physicalDevice); - // Here we can enable device extensions if we like. - - ILOG("Creating Vulkan device"); - if (g_Vulkan->CreateDevice() != VK_SUCCESS) { - ILOG("Failed to create vulkan device: %s", g_Vulkan->InitError().c_str()); - System_SendMessage("toast", "No Vulkan driver found. Using OpenGL instead."); - g_Vulkan->DestroyInstance(); - delete g_Vulkan; - g_Vulkan = nullptr; - return false; - } - int width = desiredBackbufferSizeX; - int height = desiredBackbufferSizeY; - if (!width || !height) { - width = pixel_xres; - height = pixel_yres; - } - ILOG("InitSurfaceAndroid: width=%d height=%d", width, height); - g_Vulkan->InitSurface(WINDOWSYSTEM_ANDROID, (void *)wnd, nullptr, width, height); - if (g_validate_) { - int bits = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT; - g_Vulkan->InitDebugMsgCallback(&Vulkan_Dbg, bits, &g_LogOptions); - } - - bool success = true; - if (g_Vulkan->InitObjects()) { - draw_ = Draw::T3DCreateVulkanContext(g_Vulkan, g_Config.bGfxDebugSplitSubmit); - SetGPUBackend(GPUBackend::VULKAN); - success = draw_->CreatePresets(); // Doesn't fail, we ship the compiler. - assert(success); - draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); - - VulkanRenderManager *renderManager = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); - success = renderManager->HasBackbuffers(); - } else { - success = false; - } - - ILOG("AndroidVulkanContext::Init completed, %s", success ? "successfully" : "but failed"); - if (!success) { - g_Vulkan->DestroyObjects(); - g_Vulkan->DestroyDevice(); - g_Vulkan->DestroyDebugMsgCallback(); - - g_Vulkan->DestroyInstance(); - } - return success; -} - -void AndroidVulkanContext::Shutdown() { - ILOG("AndroidVulkanContext::Shutdown"); - draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); - ILOG("Calling NativeShutdownGraphics"); - NativeShutdownGraphics(); - delete draw_; - draw_ = nullptr; - g_Vulkan->WaitUntilQueueIdle(); - g_Vulkan->DestroyObjects(); - g_Vulkan->DestroyDevice(); - g_Vulkan->DestroyDebugMsgCallback(); - - g_Vulkan->DestroyInstance(); - - // We keep the g_Vulkan context around to avoid invalidating a ton of pointers around the app. - - finalize_glslang(); - ILOG("AndroidVulkanContext::Shutdown completed"); -} - -void AndroidVulkanContext::SwapBuffers() { -} - -void AndroidVulkanContext::Resize() { - ILOG("AndroidVulkanContext::Resize begin (%d, %d)", g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); - - draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); - g_Vulkan->DestroyObjects(); - - // backbufferResize updated these values. TODO: Notify another way? - g_Vulkan->ReinitSurface(pixel_xres, pixel_yres); - g_Vulkan->InitObjects(); - draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); - ILOG("AndroidVulkanContext::Resize end (%d, %d)", g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); -} - -void AndroidVulkanContext::SwapInterval(int interval) { -} - static std::mutex frameCommandLock; static std::queue frameCommands; From 5d3c1e787189b1539d9d0a3ead81fbb5c8bd5bda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 20 Jan 2018 21:55:25 +0100 Subject: [PATCH 9/9] Additional header cleanup --- android/jni/app-android.cpp | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index b5ef7779a2..05306c22be 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -4,23 +4,18 @@ // It calls a set of methods defined in NativeApp.h. These should be implemented // by your game or app. -#include +#include +#include +#include + #include -#include -#include -#include -#include -#include -#include -#include #include #include #include -#include "AndroidGraphicsContext.h" -#include "AndroidVulkanContext.h" -#include "AndroidEGLContext.h" -#include "AndroidJavaGLContext.h" +#include +#include +#include #include "base/basictypes.h" #include "base/stringutil.h" @@ -28,7 +23,6 @@ #include "base/NativeApp.h" #include "base/logging.h" #include "base/timeutil.h" -#include "thread/prioritizedworkqueue.h" #include "thread/threadutil.h" #include "file/zip_read.h" #include "input/input_state.h" @@ -41,17 +35,17 @@ #include "gfx/gl_common.h" #include "gfx_es2/gpu_features.h" -#include "thin3d/thin3d.h" -#include "thin3d/VulkanRenderManager.h" +#include "Common/GraphicsContext.h" +#include "AndroidGraphicsContext.h" +#include "AndroidVulkanContext.h" +#include "AndroidEGLContext.h" +#include "AndroidJavaGLContext.h" + #include "Core/Config.h" #include "Core/Loaders.h" #include "Core/System.h" #include "Common/CPUDetect.h" -#include "Common/GraphicsContext.h" #include "Common/Log.h" -#include "Common/GL/GLInterfaceBase.h" -#include "Common/Vulkan/VulkanLoader.h" -#include "Common/Vulkan/VulkanContext.h" #include "UI/GameInfoCache.h" #include "app-android.h"