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/SDL/SDLVulkanGraphicsContext.cpp
Views: 1401
#include "ppsspp_config.h"1#include "Core/Config.h"2#include "Core/ConfigValues.h"3#include "Common/System/System.h"4#include "Common/System/NativeApp.h"5#include "Common/System/Display.h"6#include "Common/GPU/thin3d.h"7#include "Common/GPU/thin3d_create.h"8#include "Common/GPU/Vulkan/VulkanRenderManager.h"9#include "Common/Data/Text/Parsers.h"1011#include "Core/System.h"12#if PPSSPP_PLATFORM(MAC)13#include "SDL2/SDL_vulkan.h"14#else15#include "SDL_vulkan.h"16#endif17#include "SDLVulkanGraphicsContext.h"1819#if defined(VK_USE_PLATFORM_METAL_EXT)20#include "SDLCocoaMetalLayer.h"21#endif2223#ifdef _DEBUG24static const bool g_Validate = true;25#else26static const bool g_Validate = false;27#endif2829// TODO: Share this between backends.30static uint32_t FlagsFromConfig() {31uint32_t flags;32if (g_Config.bVSync) {33flags = VULKAN_FLAG_PRESENT_FIFO;34} else {35flags = VULKAN_FLAG_PRESENT_MAILBOX | VULKAN_FLAG_PRESENT_IMMEDIATE;36}37if (g_Validate) {38flags |= VULKAN_FLAG_VALIDATE;39}40return flags;41}4243bool SDLVulkanGraphicsContext::Init(SDL_Window *&window, int x, int y, int w, int h, int mode, std::string *error_message) {44window = SDL_CreateWindow("Initializing Vulkan...", x, y, w, h, mode);45if (!window) {46fprintf(stderr, "Error creating SDL window: %s\n", SDL_GetError());47exit(1);48}4950init_glslang();5152g_LogOptions.breakOnError = true;53g_LogOptions.breakOnWarning = true;54g_LogOptions.msgBoxOnError = false;5556Version gitVer(PPSSPP_GIT_VERSION);5758std::string errorStr;59if (!VulkanLoad(&errorStr)) {60*error_message = "Failed to load Vulkan driver library: ";61(*error_message) += errorStr;62return false;63}6465vulkan_ = new VulkanContext();66int vulkanFlags = FlagsFromConfig();6768VulkanContext::CreateInfo info{};69info.app_name = "PPSSPP";70info.app_ver = gitVer.ToInteger();71info.flags = vulkanFlags;72if (VK_SUCCESS != vulkan_->CreateInstance(info)) {73*error_message = vulkan_->InitError();74delete vulkan_;75vulkan_ = nullptr;76return false;77}7879int deviceNum = vulkan_->GetPhysicalDeviceByName(g_Config.sVulkanDevice);80if (deviceNum < 0) {81deviceNum = vulkan_->GetBestPhysicalDevice();82if (!g_Config.sVulkanDevice.empty())83g_Config.sVulkanDevice = vulkan_->GetPhysicalDeviceProperties(deviceNum).properties.deviceName;84}8586if (vulkan_->CreateDevice(deviceNum) != VK_SUCCESS) {87*error_message = vulkan_->InitError();88delete vulkan_;89vulkan_ = nullptr;90return false;91}9293vulkan_->SetCbGetDrawSize([window]() {94int w=1,h=1;95SDL_Vulkan_GetDrawableSize(window, &w, &h);96return VkExtent2D {(uint32_t)w, (uint32_t)h};97});9899SDL_SysWMinfo sys_info{};100SDL_VERSION(&sys_info.version); //Set SDL version101if (!SDL_GetWindowWMInfo(window, &sys_info)) {102fprintf(stderr, "Error getting SDL window wm info: %s\n", SDL_GetError());103exit(1);104}105switch (sys_info.subsystem) {106case SDL_SYSWM_X11:107#if defined(VK_USE_PLATFORM_XLIB_KHR)108vulkan_->InitSurface(WINDOWSYSTEM_XLIB, (void*)sys_info.info.x11.display,109(void *)(intptr_t)sys_info.info.x11.window);110#elif defined(VK_USE_PLATFORM_XCB_KHR)111vulkan_->InitSurface(WINDOWSYSTEM_XCB, (void*)XGetXCBConnection(sys_info.info.x11.display),112(void *)(intptr_t)sys_info.info.x11.window);113#endif114break;115#if defined(VK_USE_PLATFORM_WAYLAND_KHR)116case SDL_SYSWM_WAYLAND:117vulkan_->InitSurface(WINDOWSYSTEM_WAYLAND, (void*)sys_info.info.wl.display, (void *)sys_info.info.wl.surface);118break;119#endif120#if defined(VK_USE_PLATFORM_METAL_EXT)121#if PPSSPP_PLATFORM(MAC)122case SDL_SYSWM_COCOA:123vulkan_->InitSurface(WINDOWSYSTEM_METAL_EXT, makeWindowMetalCompatible(sys_info.info.cocoa.window), nullptr);124break;125#else126case SDL_SYSWM_UIKIT:127vulkan_->InitSurface(WINDOWSYSTEM_METAL_EXT, makeWindowMetalCompatible(sys_info.info.uikit.window), nullptr);128break;129#endif130#endif131#if defined(VK_USE_PLATFORM_DISPLAY_KHR)132case SDL_SYSWM_KMSDRM:133/*134There is no problem passing null for the next two arguments, and reinit will be called later135huangzihan china136*/137vulkan_->InitSurface(WINDOWSYSTEM_DISPLAY, nullptr, nullptr);138break;139#endif140default:141fprintf(stderr, "Vulkan subsystem %d not supported\n", sys_info.subsystem);142exit(1);143break;144}145146if (!vulkan_->InitSwapchain()) {147*error_message = vulkan_->InitError();148Shutdown();149return false;150}151152bool useMultiThreading = g_Config.bRenderMultiThreading;153if (g_Config.iInflightFrames == 1) {154useMultiThreading = false;155}156draw_ = Draw::T3DCreateVulkanContext(vulkan_, useMultiThreading);157SetGPUBackend(GPUBackend::VULKAN);158bool success = draw_->CreatePresets();159_assert_(success);160draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight());161162renderManager_ = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);163renderManager_->SetInflightFrames(g_Config.iInflightFrames);164return true;165}166167void SDLVulkanGraphicsContext::Shutdown() {168if (draw_)169draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight());170delete draw_;171draw_ = nullptr;172vulkan_->WaitUntilQueueIdle();173vulkan_->DestroySwapchain();174vulkan_->DestroySurface();175vulkan_->DestroyDevice();176vulkan_->DestroyInstance();177delete vulkan_;178vulkan_ = nullptr;179finalize_glslang();180}181182void SDLVulkanGraphicsContext::Resize() {183draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight());184vulkan_->DestroySwapchain();185vulkan_->UpdateFlags(FlagsFromConfig());186vulkan_->InitSwapchain();187draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight());188}189190void SDLVulkanGraphicsContext::Poll() {191// Check for existing swapchain to avoid issues during shutdown.192if (vulkan_->GetSwapchain() && renderManager_->NeedsSwapchainRecreate()) {193Resize();194}195}196197198