CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/android/jni/AndroidVulkanContext.cpp
Views: 1401
#include "AndroidVulkanContext.h"1#include "Common/System/Display.h"2#include "Common/System/NativeApp.h"3#include "Common/System/System.h"4#include "Common/Log.h"5#include "Common/GPU/Vulkan/VulkanContext.h"6#include "Common/GPU/Vulkan/VulkanDebug.h"7#include "Common/GPU/Vulkan/VulkanLoader.h"8#include "Common/GPU/Vulkan/VulkanRenderManager.h"9#include "Common/GPU/thin3d_create.h"10#include "Common/Data/Text/Parsers.h"11#include "Core/Config.h"12#include "Core/ConfigValues.h"13#include "Core/System.h"141516#ifdef _DEBUG17static const bool g_Validate = true;18#else19static const bool g_Validate = false;20#endif2122// TODO: Share this between backends.23static uint32_t FlagsFromConfig() {24uint32_t flags;25if (g_Config.bVSync) {26flags = VULKAN_FLAG_PRESENT_FIFO;27} else {28flags = VULKAN_FLAG_PRESENT_MAILBOX | VULKAN_FLAG_PRESENT_IMMEDIATE;29}30if (g_Validate) {31flags |= VULKAN_FLAG_VALIDATE;32}33return flags;34}3536AndroidVulkanContext::AndroidVulkanContext() {}3738AndroidVulkanContext::~AndroidVulkanContext() {39delete g_Vulkan;40g_Vulkan = nullptr;41}4243bool AndroidVulkanContext::InitAPI() {44INFO_LOG(Log::G3D, "AndroidVulkanContext::Init");45init_glslang();4647g_LogOptions.breakOnError = true;48g_LogOptions.breakOnWarning = true;49g_LogOptions.msgBoxOnError = false;5051INFO_LOG(Log::G3D, "Creating Vulkan context");52Version gitVer(PPSSPP_GIT_VERSION);5354std::string errorStr;55if (!VulkanLoad(&errorStr)) {56ERROR_LOG(Log::G3D, "Failed to load Vulkan driver library: %s", errorStr.c_str());57state_ = GraphicsContextState::FAILED_INIT;58return false;59}6061if (!g_Vulkan) {62// TODO: Assert if g_Vulkan already exists here?63g_Vulkan = new VulkanContext();64}6566VulkanContext::CreateInfo info{};67info.app_name = "PPSSPP";68info.app_ver = gitVer.ToInteger();69info.flags = FlagsFromConfig();70if (!g_Vulkan->CreateInstanceAndDevice(info)) {71delete g_Vulkan;72g_Vulkan = nullptr;73state_ = GraphicsContextState::FAILED_INIT;74return false;75}7677INFO_LOG(Log::G3D, "Vulkan device created!");78state_ = GraphicsContextState::INITIALIZED;79return true;80}8182bool AndroidVulkanContext::InitFromRenderThread(ANativeWindow *wnd, int desiredBackbufferSizeX, int desiredBackbufferSizeY, int backbufferFormat, int androidVersion) {83INFO_LOG(Log::G3D, "AndroidVulkanContext::InitFromRenderThread: desiredwidth=%d desiredheight=%d", desiredBackbufferSizeX, desiredBackbufferSizeY);84if (!g_Vulkan) {85ERROR_LOG(Log::G3D, "AndroidVulkanContext::InitFromRenderThread: No Vulkan context");86return false;87}8889VkResult res = g_Vulkan->InitSurface(WINDOWSYSTEM_ANDROID, (void *)wnd, nullptr);90if (res != VK_SUCCESS) {91ERROR_LOG(Log::G3D, "g_Vulkan->InitSurface failed: '%s'", VulkanResultToString(res));92return false;93}9495bool success = true;96if (g_Vulkan->InitSwapchain()) {97bool useMultiThreading = g_Config.bRenderMultiThreading;98if (g_Config.iInflightFrames == 1) {99useMultiThreading = false;100}101draw_ = Draw::T3DCreateVulkanContext(g_Vulkan, useMultiThreading);102SetGPUBackend(GPUBackend::VULKAN);103success = draw_->CreatePresets(); // Doesn't fail, we ship the compiler.104_assert_msg_(success, "Failed to compile preset shaders");105draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());106107VulkanRenderManager *renderManager = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);108renderManager->SetInflightFrames(g_Config.iInflightFrames);109success = renderManager->HasBackbuffers();110} else {111success = false;112}113114INFO_LOG(Log::G3D, "AndroidVulkanContext::Init completed, %s", success ? "successfully" : "but failed");115if (!success) {116g_Vulkan->DestroySwapchain();117g_Vulkan->DestroySurface();118g_Vulkan->DestroyDevice();119g_Vulkan->DestroyInstance();120}121return success;122}123124void AndroidVulkanContext::ShutdownFromRenderThread() {125INFO_LOG(Log::G3D, "AndroidVulkanContext::Shutdown");126draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());127delete draw_;128draw_ = nullptr;129g_Vulkan->WaitUntilQueueIdle();130g_Vulkan->PerformPendingDeletes();131g_Vulkan->DestroySwapchain();132g_Vulkan->DestroySurface();133INFO_LOG(Log::G3D, "Done with ShutdownFromRenderThread");134}135136void AndroidVulkanContext::Shutdown() {137INFO_LOG(Log::G3D, "Calling NativeShutdownGraphics");138g_Vulkan->DestroyDevice();139g_Vulkan->DestroyInstance();140// We keep the g_Vulkan context around to avoid invalidating a ton of pointers around the app.141finalize_glslang();142INFO_LOG(Log::G3D, "AndroidVulkanContext::Shutdown completed");143}144145void AndroidVulkanContext::Resize() {146INFO_LOG(Log::G3D, "AndroidVulkanContext::Resize begin (oldsize: %dx%d)", g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());147148draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());149g_Vulkan->DestroySwapchain();150g_Vulkan->DestroySurface();151152g_Vulkan->UpdateFlags(FlagsFromConfig());153154g_Vulkan->ReinitSurface();155g_Vulkan->InitSwapchain();156draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());157INFO_LOG(Log::G3D, "AndroidVulkanContext::Resize end (final size: %dx%d)", g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());158}159160161