ppsspp/android/jni/AndroidVulkanContext.cpp
Henrik Rydgård 0e3a84b4a8 Move most GPU things to Common.
It works after the move, on Windows and Android at least.

Deletes the D3DX9 shader compiler loader, which was not used.
2020-10-04 23:39:02 +02:00

168 lines
5.4 KiB
C++

#include "AndroidVulkanContext.h"
#include "Common/System/Display.h"
#include "Common/System/NativeApp.h"
#include "Common/System/System.h"
#include "Common/Log.h"
#include "Common/GPU/Vulkan/VulkanContext.h"
#include "Common/GPU/Vulkan/VulkanDebug.h"
#include "Common/GPU/Vulkan/VulkanLoader.h"
#include "Common/GPU/Vulkan/VulkanRenderManager.h"
#include "Common/GPU/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) {
}