ppsspp/android/jni/AndroidVulkanContext.cpp
Henrik Rydgård ff8148dd92 Move native/util, native/data and native/i18 to Common/Data.
Also move colorutil.cpp/h

linking build fix experiment

Delete a bunch of unused CMakeLists.txt files

CMakeLists.txt linking fix

Don't include NativeApp.h from any headers.

Android.mk buildfix

Half of the UWP fix

Buildfix

Minor project file cleanup

Buildfixes

Guess what? More buildfixes!
2020-10-04 07:28:29 +02:00

167 lines
5.3 KiB
C++

#include "AndroidVulkanContext.h"
#include "base/NativeApp.h"
#include "base/display.h"
#include "Common/Log.h"
#include "Common/Vulkan/VulkanContext.h"
#include "Common/Vulkan/VulkanDebug.h"
#include "Common/Vulkan/VulkanLoader.h"
#include "thin3d/VulkanRenderManager.h"
#include "thin3d/thin3d_create.h"
#include "Common/Data/Text/Parsers.h"
#include "Core/Config.h"
#include "Core/ConfigValues.h"
#include "Core/System.h"
AndroidVulkanContext::AndroidVulkanContext() {}
AndroidVulkanContext::~AndroidVulkanContext() {
delete g_Vulkan;
g_Vulkan = nullptr;
}
static uint32_t FlagsFromConfig() {
if (g_Config.bVSync) {
return VULKAN_FLAG_PRESENT_FIFO;
}
return VULKAN_FLAG_PRESENT_MAILBOX | VULKAN_FLAG_PRESENT_FIFO_RELAXED;
}
bool AndroidVulkanContext::InitAPI() {
INFO_LOG(G3D, "AndroidVulkanContext::Init");
init_glslang();
g_LogOptions.breakOnError = true;
g_LogOptions.breakOnWarning = true;
g_LogOptions.msgBoxOnError = false;
INFO_LOG(G3D, "Creating Vulkan context");
Version gitVer(PPSSPP_GIT_VERSION);
if (!VulkanLoad()) {
ERROR_LOG(G3D, "Failed to load Vulkan driver library");
return false;
}
if (!g_Vulkan) {
// TODO: Assert if g_Vulkan already exists here?
g_Vulkan = new VulkanContext();
}
VulkanContext::CreateInfo info{};
info.app_name = "PPSSPP";
info.app_ver = gitVer.ToInteger();
info.flags = FlagsFromConfig();
VkResult res = g_Vulkan->CreateInstance(info);
if (res != VK_SUCCESS) {
ERROR_LOG(G3D, "Failed to create vulkan context: %s", g_Vulkan->InitError().c_str());
VulkanSetAvailable(false);
delete g_Vulkan;
g_Vulkan = nullptr;
return false;
}
int physicalDevice = g_Vulkan->GetBestPhysicalDevice();
if (physicalDevice < 0) {
ERROR_LOG(G3D, "No usable Vulkan device found.");
g_Vulkan->DestroyInstance();
delete g_Vulkan;
g_Vulkan = nullptr;
return false;
}
g_Vulkan->ChooseDevice(physicalDevice);
INFO_LOG(G3D, "Creating Vulkan device");
if (g_Vulkan->CreateDevice() != VK_SUCCESS) {
INFO_LOG(G3D, "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;
}
INFO_LOG(G3D, "Vulkan device created!");
return true;
}
bool AndroidVulkanContext::InitFromRenderThread(ANativeWindow *wnd, int desiredBackbufferSizeX, int desiredBackbufferSizeY, int backbufferFormat, int androidVersion) {
INFO_LOG(G3D, "AndroidVulkanContext::InitFromRenderThread: desiredwidth=%d desiredheight=%d", desiredBackbufferSizeX, desiredBackbufferSizeY);
if (!g_Vulkan) {
ERROR_LOG(G3D, "AndroidVulkanContext::InitFromRenderThread: No Vulkan context");
return false;
}
VkResult res = g_Vulkan->InitSurface(WINDOWSYSTEM_ANDROID, (void *)wnd, nullptr);
if (res != VK_SUCCESS) {
ERROR_LOG(G3D, "g_Vulkan->InitSurface failed: '%s'", VulkanResultToString(res));
return false;
}
bool success = true;
if (g_Vulkan->InitSwapchain()) {
draw_ = Draw::T3DCreateVulkanContext(g_Vulkan, g_Config.bGfxDebugSplitSubmit);
SetGPUBackend(GPUBackend::VULKAN);
success = draw_->CreatePresets(); // Doesn't fail, we ship the compiler.
_assert_msg_(success, "Failed to compile preset shaders");
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
VulkanRenderManager *renderManager = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
renderManager->SetInflightFrames(g_Config.iInflightFrames);
success = renderManager->HasBackbuffers();
} else {
success = false;
}
INFO_LOG(G3D, "AndroidVulkanContext::Init completed, %s", success ? "successfully" : "but failed");
if (!success) {
g_Vulkan->DestroySwapchain();
g_Vulkan->DestroySurface();
g_Vulkan->DestroyDevice();
g_Vulkan->DestroyInstance();
}
return success;
}
void AndroidVulkanContext::ShutdownFromRenderThread() {
INFO_LOG(G3D, "AndroidVulkanContext::Shutdown");
draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
delete draw_;
draw_ = nullptr;
g_Vulkan->WaitUntilQueueIdle();
g_Vulkan->PerformPendingDeletes();
g_Vulkan->DestroySwapchain();
g_Vulkan->DestroySurface();
INFO_LOG(G3D, "Done with ShutdownFromRenderThread");
}
void AndroidVulkanContext::Shutdown() {
INFO_LOG(G3D, "Calling NativeShutdownGraphics");
g_Vulkan->DestroyDevice();
g_Vulkan->DestroyInstance();
// We keep the g_Vulkan context around to avoid invalidating a ton of pointers around the app.
finalize_glslang();
INFO_LOG(G3D, "AndroidVulkanContext::Shutdown completed");
}
void AndroidVulkanContext::SwapBuffers() {
}
void AndroidVulkanContext::Resize() {
INFO_LOG(G3D, "AndroidVulkanContext::Resize begin (oldsize: %dx%d)", g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
g_Vulkan->DestroySwapchain();
g_Vulkan->DestroySurface();
g_Vulkan->UpdateFlags(FlagsFromConfig());
g_Vulkan->ReinitSurface();
g_Vulkan->InitSwapchain();
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
INFO_LOG(G3D, "AndroidVulkanContext::Resize end (final size: %dx%d)", g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
}
void AndroidVulkanContext::SwapInterval(int interval) {
}