mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
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!
157 lines
No EOL
4.6 KiB
C++
157 lines
No EOL
4.6 KiB
C++
#include "Core/Config.h"
|
|
#include "Core/ConfigValues.h"
|
|
#include "base/NativeApp.h"
|
|
#include "base/display.h"
|
|
#include "thin3d/thin3d.h"
|
|
#include "thin3d/thin3d_create.h"
|
|
#include "thin3d/VulkanRenderManager.h"
|
|
#include "Common/Data/Text/Parsers.h"
|
|
|
|
#include "Core/System.h"
|
|
#include "SDLVulkanGraphicsContext.h"
|
|
|
|
#if defined(VK_USE_PLATFORM_METAL_EXT)
|
|
#include "SDLCocoaMetalLayer.h"
|
|
#endif
|
|
|
|
#ifdef _DEBUG
|
|
static const bool g_Validate = true;
|
|
#else
|
|
static const bool g_Validate = false;
|
|
#endif
|
|
|
|
static uint32_t FlagsFromConfig() {
|
|
uint32_t flags = 0;
|
|
flags = g_Config.bVSync ? VULKAN_FLAG_PRESENT_FIFO : VULKAN_FLAG_PRESENT_MAILBOX;
|
|
if (g_Validate) {
|
|
flags |= VULKAN_FLAG_VALIDATE;
|
|
}
|
|
return flags;
|
|
}
|
|
|
|
bool SDLVulkanGraphicsContext::Init(SDL_Window *&window, int x, int y, int mode, std::string *error_message) {
|
|
window = SDL_CreateWindow("Initializing Vulkan...", x, y, pixel_xres, pixel_yres, mode);
|
|
if (!window) {
|
|
fprintf(stderr, "Error creating SDL window: %s\n", SDL_GetError());
|
|
exit(1);
|
|
}
|
|
|
|
init_glslang();
|
|
|
|
g_LogOptions.breakOnError = true;
|
|
g_LogOptions.breakOnWarning = true;
|
|
g_LogOptions.msgBoxOnError = false;
|
|
|
|
Version gitVer(PPSSPP_GIT_VERSION);
|
|
|
|
if (!VulkanLoad()) {
|
|
*error_message = "Failed to load Vulkan driver library";
|
|
return false;
|
|
}
|
|
|
|
vulkan_ = new VulkanContext();
|
|
int vulkanFlags = FlagsFromConfig();
|
|
|
|
VulkanContext::CreateInfo info{};
|
|
info.app_name = "PPSSPP";
|
|
info.app_ver = gitVer.ToInteger();
|
|
info.flags = vulkanFlags;
|
|
if (VK_SUCCESS != vulkan_->CreateInstance(info)) {
|
|
*error_message = vulkan_->InitError();
|
|
delete vulkan_;
|
|
vulkan_ = nullptr;
|
|
return false;
|
|
}
|
|
vulkan_->ChooseDevice(vulkan_->GetBestPhysicalDevice());
|
|
if (vulkan_->CreateDevice() != VK_SUCCESS) {
|
|
*error_message = vulkan_->InitError();
|
|
delete vulkan_;
|
|
vulkan_ = nullptr;
|
|
return false;
|
|
}
|
|
|
|
SDL_SysWMinfo sys_info{};
|
|
SDL_VERSION(&sys_info.version); //Set SDL version
|
|
if (!SDL_GetWindowWMInfo(window, &sys_info)) {
|
|
fprintf(stderr, "Error getting SDL window wm info: %s\n", SDL_GetError());
|
|
exit(1);
|
|
}
|
|
switch (sys_info.subsystem) {
|
|
case SDL_SYSWM_X11:
|
|
#if defined(VK_USE_PLATFORM_XLIB_KHR)
|
|
vulkan_->InitSurface(WINDOWSYSTEM_XLIB, (void*)sys_info.info.x11.display,
|
|
(void *)(intptr_t)sys_info.info.x11.window);
|
|
#elif defined(VK_USE_PLATFORM_XCB_KHR)
|
|
vulkan_->InitSurface(WINDOWSYSTEM_XCB, (void*)XGetXCBConnection(sys_info.info.x11.display),
|
|
(void *)(intptr_t)sys_info.info.x11.window);
|
|
#endif
|
|
break;
|
|
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
|
|
case SDL_SYSWM_WAYLAND:
|
|
vulkan_->InitSurface(WINDOWSYSTEM_WAYLAND, (void*)sys_info.info.wl.display, (void *)sys_info.info.wl.surface);
|
|
break;
|
|
#endif
|
|
#if defined(VK_USE_PLATFORM_METAL_EXT)
|
|
#if defined(PPSSPP_PLATFORM_MAC)
|
|
case SDL_SYSWM_COCOA:
|
|
vulkan_->InitSurface(WINDOWSYSTEM_METAL_EXT, makeWindowMetalCompatible(sys_info.info.cocoa.window), nullptr);
|
|
break;
|
|
#else
|
|
case SDL_SYSWM_UIKIT:
|
|
vulkan_->InitSurface(WINDOWSYSTEM_METAL_EXT, makeWindowMetalCompatible(sys_info.info.uikit.window), nullptr);
|
|
break;
|
|
#endif
|
|
#endif
|
|
default:
|
|
fprintf(stderr, "Vulkan subsystem %d not supported\n", sys_info.subsystem);
|
|
exit(1);
|
|
break;
|
|
}
|
|
|
|
if (!vulkan_->InitSwapchain()) {
|
|
*error_message = vulkan_->InitError();
|
|
Shutdown();
|
|
return false;
|
|
}
|
|
|
|
draw_ = Draw::T3DCreateVulkanContext(vulkan_, false);
|
|
SetGPUBackend(GPUBackend::VULKAN);
|
|
bool success = draw_->CreatePresets();
|
|
_assert_(success);
|
|
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight());
|
|
|
|
renderManager_ = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
|
|
renderManager_->SetInflightFrames(g_Config.iInflightFrames);
|
|
|
|
return true;
|
|
}
|
|
|
|
void SDLVulkanGraphicsContext::Shutdown() {
|
|
if (draw_)
|
|
draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight());
|
|
delete draw_;
|
|
draw_ = nullptr;
|
|
vulkan_->WaitUntilQueueIdle();
|
|
vulkan_->DestroySwapchain();
|
|
vulkan_->DestroySurface();
|
|
vulkan_->DestroyDevice();
|
|
vulkan_->DestroyInstance();
|
|
delete vulkan_;
|
|
vulkan_ = nullptr;
|
|
finalize_glslang();
|
|
}
|
|
|
|
void SDLVulkanGraphicsContext::Resize() {
|
|
draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight());
|
|
vulkan_->DestroySwapchain();
|
|
vulkan_->UpdateFlags(FlagsFromConfig());
|
|
vulkan_->InitSwapchain();
|
|
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight());
|
|
}
|
|
|
|
void SDLVulkanGraphicsContext::Poll() {
|
|
// Check for existing swapchain to avoid issues during shutdown.
|
|
if (vulkan_->GetSwapchain() && renderManager_->NeedsSwapchainRecreate()) {
|
|
Resize();
|
|
}
|
|
} |