mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-15 10:40:01 +01:00
Merge branch 'master' into TemporaryHackishBranch
This commit is contained in:
commit
b2b4c8b50a
20 files changed
+527
-385
No files matched your search
+1
-4
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -6,9 +6,11 @@
|
||||
#include <iostream>
|
||||
|
||||
#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.
|
||||
|
||||
+8
-2
@@ -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");
|
||||
}
|
||||
|
||||
+29
-18
@@ -424,18 +424,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());
|
||||
}
|
||||
@@ -752,6 +740,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:
|
||||
{
|
||||
@@ -931,14 +925,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);
|
||||
}
|
||||
@@ -1138,11 +1143,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;
|
||||
|
||||
@@ -278,6 +278,24 @@
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\android\jni\AndroidEGLContext.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\android\jni\AndroidJavaGLContext.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\android\jni\AndroidVulkanContext.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\android\jni\app-android.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
@@ -435,6 +453,30 @@
|
||||
<ClCompile Include="XinputDevice.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\android\jni\AndroidEGLContext.h">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\android\jni\AndroidGraphicsContext.h">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\android\jni\AndroidJavaGLContext.h">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\android\jni\AndroidVulkanContext.h">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\android\jni\app-android.h" />
|
||||
<ClInclude Include="..\android\jni\ArmEmitterTest.h" />
|
||||
<ClInclude Include="..\android\jni\Arm64EmitterTest.h" />
|
||||
|
||||
@@ -200,6 +200,15 @@
|
||||
<ClCompile Include="..\android\jni\native-audio-so.cpp">
|
||||
<Filter>Other Platforms</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\android\jni\AndroidEGLContext.cpp">
|
||||
<Filter>Other Platforms</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\android\jni\AndroidJavaGLContext.cpp">
|
||||
<Filter>Other Platforms</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\android\jni\AndroidVulkanContext.cpp">
|
||||
<Filter>Other Platforms</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Debugger\CtrlDisAsmView.h">
|
||||
@@ -368,6 +377,18 @@
|
||||
<ClInclude Include="..\android\jni\native-audio-so.h">
|
||||
<Filter>Other Platforms</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\android\jni\AndroidEGLContext.h">
|
||||
<Filter>Other Platforms</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\android\jni\AndroidGraphicsContext.h">
|
||||
<Filter>Other Platforms</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\android\jni\AndroidJavaGLContext.h">
|
||||
<Filter>Other Platforms</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\android\jni\AndroidVulkanContext.h">
|
||||
<Filter>Other Platforms</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="icon1.ico">
|
||||
|
||||
+7
-7
@@ -349,6 +349,8 @@ std::vector<std::wstring> GetWideCmdLine() {
|
||||
wargv = CommandLineToArgvW(GetCommandLineW(), &wargc);
|
||||
|
||||
std::vector<std::wstring> wideArgs(wargv, wargv + wargc);
|
||||
LocalFree(wargv);
|
||||
|
||||
return wideArgs;
|
||||
}
|
||||
|
||||
@@ -389,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<std::wstring> wideArgs = GetWideCmdLine();
|
||||
@@ -403,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -426,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;
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
+7
-2
@@ -334,7 +334,12 @@
|
||||
#define IDC_GEDBG_RECORD 40169
|
||||
#define ID_GEDBG_EXPORT_IMAGE 40170
|
||||
#define ID_GEDBG_ENABLE_PREVIEW 40171
|
||||
#define ID_GEDBG_REPLACEMENT_FILENAME 40172
|
||||
#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
|
||||
#define ID_GEDBG_REPLACEMENT_FILENAME 40199
|
||||
#define ID_SIMPLEUI_TOGGLE 40200
|
||||
#define ID_SIMPLEUI_HIDE 40201
|
||||
|
||||
@@ -349,7 +354,7 @@
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 256
|
||||
#define _APS_NEXT_COMMAND_VALUE 40173
|
||||
#define _APS_NEXT_COMMAND_VALUE 40177
|
||||
#define _APS_NEXT_CONTROL_VALUE 1200
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <android/native_window_jni.h>
|
||||
|
||||
#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;
|
||||
};
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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_;
|
||||
};
|
||||
|
||||
@@ -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) {
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
+13
-351
@@ -4,27 +4,25 @@
|
||||
// It calls a set of methods defined in NativeApp.h. These should be implemented
|
||||
// by your game or app.
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <cstdint>
|
||||
|
||||
#include <assert.h>
|
||||
#include <sstream>
|
||||
#include <jni.h>
|
||||
#include <android/log.h>
|
||||
#include <android/native_window_jni.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <GLES2/gl2.h>
|
||||
#include <GLES2/gl2ext.h>
|
||||
#include <queue>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
|
||||
#include <jni.h>
|
||||
#include <android/log.h>
|
||||
#include <android/native_window_jni.h>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/stringutil.h"
|
||||
#include "base/display.h"
|
||||
#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"
|
||||
@@ -37,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"
|
||||
@@ -58,17 +56,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 +64,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<FrameCommand> frameCommands;
|
||||
|
||||
|
||||
@@ -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,
|
||||
Reference in new issue
Block a user