mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
Merge pull request #20898 from hrydgard/vulkan-init-refactor
Small Vulkan init refactor
This commit is contained in:
10 files changed
+73
-67
No files matched your search
@@ -197,11 +197,6 @@ VkResult VulkanContext::CreateInstance(const CreateInfo &info) {
|
||||
if (EnableInstanceExtension(VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME, 0)) {
|
||||
extensionsLookup_.EXT_swapchain_colorspace = true;
|
||||
}
|
||||
#if PPSSPP_PLATFORM(IOS_APP_STORE)
|
||||
if (EnableInstanceExtension(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME, 0)) {
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
// Validate that all the instance extensions we ask for are actually available.
|
||||
for (auto ext : instance_extensions_enabled_) {
|
||||
@@ -397,6 +392,8 @@ void VulkanContext::DestroySurface() {
|
||||
if (surface_ != VK_NULL_HANDLE) {
|
||||
vkDestroySurfaceKHR(instance_, surface_, nullptr);
|
||||
surface_ = VK_NULL_HANDLE;
|
||||
|
||||
// NOTE: We do not reset winSysData1 and 2, it's useful for debugging to compare them.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -935,6 +932,12 @@ void VulkanContext::SetDebugNameImpl(uint64_t handle, VkObjectType type, const c
|
||||
|
||||
VkResult VulkanContext::InitSurface(WindowSystem winsys, void *data1, void *data2) {
|
||||
winsys_ = winsys;
|
||||
if (winsysData1_ != data1) {
|
||||
WARN_LOG(Log::G3D, "winsysData1 changed from %p to %p", winsysData1_, data1);
|
||||
}
|
||||
if (winsysData2_ != data2) {
|
||||
WARN_LOG(Log::G3D, "winsysData2 changed from %p to %p", winsysData2_, data2);
|
||||
}
|
||||
winsysData1_ = data1;
|
||||
winsysData2_ = data2;
|
||||
return ReinitSurface();
|
||||
@@ -1337,13 +1340,17 @@ static std::string surface_transforms_to_string(VkSurfaceTransformFlagsKHR trans
|
||||
return str;
|
||||
}
|
||||
|
||||
bool VulkanContext::InitSwapchain() {
|
||||
bool VulkanContext::InitSwapchain(VkPresentModeKHR desiredPresentMode) {
|
||||
_assert_(physical_device_ >= 0 && physical_device_ < (int)physical_devices_.size());
|
||||
if (!surface_) {
|
||||
ERROR_LOG(Log::G3D, "VK: No surface, can't create swapchain");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (swapchain_) {
|
||||
INFO_LOG(Log::G3D, "Swapchain already exists, recreating...");
|
||||
}
|
||||
|
||||
VkResult res = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_devices_[physical_device_], surface_, &surfCapabilities_);
|
||||
if (res == VK_ERROR_SURFACE_LOST_KHR) {
|
||||
// Not much to do.
|
||||
@@ -1406,7 +1413,7 @@ bool VulkanContext::InitSwapchain() {
|
||||
|
||||
// Kind of silly logic now, but at least it performs a final sanity check of the chosen value.
|
||||
for (size_t i = 0; i < presentModeCount; i++) {
|
||||
bool match = presentModes[i] == createInfo_.presentMode;
|
||||
bool match = presentModes[i] == desiredPresentMode;
|
||||
// Default to the first present mode from the list.
|
||||
if (match || swapchainPresentMode == VK_PRESENT_MODE_MAX_ENUM_KHR) {
|
||||
swapchainPresentMode = presentModes[i];
|
||||
@@ -1496,6 +1503,8 @@ bool VulkanContext::InitSwapchain() {
|
||||
}
|
||||
}
|
||||
|
||||
VkSwapchainKHR oldSwapchain = swapchain_;
|
||||
|
||||
VkSwapchainCreateInfoKHR swap_chain_info{ VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR };
|
||||
swap_chain_info.surface = surface_;
|
||||
swap_chain_info.minImageCount = desiredNumberOfSwapChainImages;
|
||||
@@ -1506,7 +1515,7 @@ bool VulkanContext::InitSwapchain() {
|
||||
swap_chain_info.preTransform = preTransform;
|
||||
swap_chain_info.imageArrayLayers = 1;
|
||||
swap_chain_info.presentMode = swapchainPresentMode;
|
||||
swap_chain_info.oldSwapchain = VK_NULL_HANDLE;
|
||||
swap_chain_info.oldSwapchain = swapchain_;
|
||||
swap_chain_info.clipped = true;
|
||||
swap_chain_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
|
||||
@@ -1535,6 +1544,11 @@ bool VulkanContext::InitSwapchain() {
|
||||
}
|
||||
INFO_LOG(Log::G3D, "Created swapchain: %dx%d %s", swap_chain_info.imageExtent.width, swap_chain_info.imageExtent.height, (surfCapabilities_.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) ? "(TRANSFER_SRC_BIT supported)" : "");
|
||||
swapchainInited_ = true;
|
||||
|
||||
if (oldSwapchain != VK_NULL_HANDLE) {
|
||||
vkDestroySwapchainKHR(device_, oldSwapchain, nullptr);
|
||||
INFO_LOG(Log::G3D, "Destroyed old swapchain.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -52,6 +52,7 @@ template<class R, class T> inline void ChainStruct(R &root, T *newStruct) {
|
||||
|
||||
// Not all will be usable on all platforms, of course...
|
||||
enum WindowSystem {
|
||||
WINDOWSYSTEM_UNINITIALIZED,
|
||||
#ifdef _WIN32
|
||||
WINDOWSYSTEM_WIN32,
|
||||
#endif
|
||||
@@ -181,7 +182,6 @@ public:
|
||||
int app_ver;
|
||||
VulkanInitFlags flags;
|
||||
std::string customDriver;
|
||||
VkPresentModeKHR presentMode;
|
||||
};
|
||||
|
||||
VkResult CreateInstance(const CreateInfo &info);
|
||||
@@ -217,7 +217,8 @@ public:
|
||||
VkResult InitSurface(WindowSystem winsys, void *data1, void *data2);
|
||||
VkResult ReinitSurface();
|
||||
|
||||
bool InitSwapchain();
|
||||
// If the present mode is not available, will fall back to the first available (which is almost always FIFO).
|
||||
bool InitSwapchain(VkPresentModeKHR desiredPresentMode);
|
||||
void SetCbGetDrawSize(std::function<VkExtent2D()>);
|
||||
|
||||
void DestroySwapchain();
|
||||
@@ -450,7 +451,7 @@ private:
|
||||
|
||||
bool CheckLayers(const std::vector<LayerProperties> &layer_props, const std::vector<const char *> &layer_names) const;
|
||||
|
||||
WindowSystem winsys_{};
|
||||
WindowSystem winsys_ = WINDOWSYSTEM_UNINITIALIZED;
|
||||
|
||||
// Don't use the real types here to avoid having to include platform-specific stuff
|
||||
// that we really don't want in everything that uses VulkanContext.
|
||||
|
||||
@@ -174,7 +174,6 @@ bool VulkanQueueRunner::InitDepthStencilBuffer(VkCommandBuffer cmd, VulkanBarrie
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void VulkanQueueRunner::DestroyBackBuffers() {
|
||||
if (depth_.view) {
|
||||
vulkan_->Delete().QueueDeleteImageView(depth_.view);
|
||||
@@ -551,10 +550,10 @@ void VulkanQueueRunner::ApplyMGSHack(std::vector<VKRStep *> &steps) {
|
||||
if (rc.offset.y < minScissorY) {
|
||||
minScissorY = rc.offset.y;
|
||||
}
|
||||
if (rc.offset.x + rc.extent.width > maxScissorX) {
|
||||
if (rc.offset.x + (int)rc.extent.width > maxScissorX) {
|
||||
maxScissorX = rc.offset.x + rc.extent.width;
|
||||
}
|
||||
if (rc.offset.y + rc.extent.height > maxScissorY) {
|
||||
if (rc.offset.y + (int)rc.extent.height > maxScissorY) {
|
||||
maxScissorY = rc.offset.y + rc.extent.height;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -36,7 +36,8 @@ const VkComponentMapping VULKAN_1555_SWIZZLE = { VK_COMPONENT_SWIZZLE_B, VK_COMP
|
||||
const VkComponentMapping VULKAN_565_SWIZZLE = { VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_IDENTITY };
|
||||
const VkComponentMapping VULKAN_8888_SWIZZLE = { VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY };
|
||||
|
||||
VkPresentModeKHR ConfigPresentModeToVulkan(PresentMode presentMode) {
|
||||
VkPresentModeKHR ConfigPresentModeToVulkan() {
|
||||
PresentMode presentMode = (PresentMode)g_Config.iVulkanPresentationMode;
|
||||
switch (presentMode) {
|
||||
case PresentMode::Immediate:
|
||||
return VK_PRESENT_MODE_IMMEDIATE_KHR;
|
||||
@@ -70,7 +71,6 @@ void InitVulkanCreateInfoFromConfig(VulkanContext::CreateInfo *info) {
|
||||
info->app_ver = gitVer.ToInteger();
|
||||
info->flags = VulkanInitFlagsFromConfig();
|
||||
info->customDriver = g_Config.sCustomDriver;
|
||||
info->presentMode = ConfigPresentModeToVulkan((PresentMode)g_Config.iVulkanPresentationMode);
|
||||
}
|
||||
|
||||
VkShaderModule CompileShaderModule(VulkanContext *vulkan, VkShaderStageFlagBits stage, const char *code, std::string *error) {
|
||||
|
||||
@@ -89,5 +89,5 @@ private:
|
||||
|
||||
VkShaderModule CompileShaderModule(VulkanContext *vulkan, VkShaderStageFlagBits stage, const char *code, std::string *error);
|
||||
|
||||
VkPresentModeKHR ConfigPresentModeToVulkan(PresentMode presentMode);
|
||||
VkPresentModeKHR ConfigPresentModeToVulkan();
|
||||
void InitVulkanCreateInfoFromConfig(VulkanContext::CreateInfo *info);
|
||||
@@ -128,7 +128,8 @@ bool SDLVulkanGraphicsContext::Init(SDL_Window *&window, int x, int y, int w, in
|
||||
break;
|
||||
}
|
||||
|
||||
if (!vulkan_->InitSwapchain()) {
|
||||
VkPresentModeKHR presentMode = ConfigPresentModeToVulkan();
|
||||
if (!vulkan_->InitSwapchain(presentMode)) {
|
||||
*error_message = vulkan_->InitError();
|
||||
Shutdown();
|
||||
return false;
|
||||
@@ -166,11 +167,11 @@ void SDLVulkanGraphicsContext::Shutdown() {
|
||||
|
||||
void SDLVulkanGraphicsContext::Resize() {
|
||||
draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight());
|
||||
// NOTE: Removing DestroySwapchain here causes a double re-create on MacOS with MoltenVK, for some reason.
|
||||
// It's like passing on oldSwapchain doesn't really work as expected.
|
||||
vulkan_->DestroySwapchain();
|
||||
VulkanContext::CreateInfo info{};
|
||||
InitVulkanCreateInfoFromConfig(&info);
|
||||
vulkan_->UpdateCreateInfo(info);
|
||||
vulkan_->InitSwapchain();
|
||||
VkPresentModeKHR presentMode = ConfigPresentModeToVulkan();
|
||||
vulkan_->InitSwapchain(presentMode);
|
||||
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight());
|
||||
}
|
||||
|
||||
|
||||
@@ -116,7 +116,9 @@ bool WindowsVulkanContext::Init(HINSTANCE hInst, HWND hWnd, std::string *error_m
|
||||
}
|
||||
|
||||
vulkan_->InitSurface(WINDOWSYSTEM_WIN32, (void *)hInst, (void *)hWnd);
|
||||
if (!vulkan_->InitSwapchain()) {
|
||||
|
||||
VkPresentModeKHR presentMode = ConfigPresentModeToVulkan();
|
||||
if (!vulkan_->InitSwapchain(presentMode)) {
|
||||
*error_message = vulkan_->InitError();
|
||||
Shutdown();
|
||||
return false;
|
||||
@@ -164,10 +166,8 @@ void WindowsVulkanContext::Shutdown() {
|
||||
|
||||
void WindowsVulkanContext::Resize() {
|
||||
draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight());
|
||||
vulkan_->DestroySwapchain();
|
||||
VulkanContext::CreateInfo info{};
|
||||
InitVulkanCreateInfoFromConfig(&info);
|
||||
vulkan_->InitSwapchain();
|
||||
VkPresentModeKHR presentMode = ConfigPresentModeToVulkan();
|
||||
vulkan_->InitSwapchain(presentMode);
|
||||
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight());
|
||||
}
|
||||
|
||||
|
||||
@@ -70,8 +70,9 @@ bool AndroidVulkanContext::InitFromRenderThread(ANativeWindow *wnd, int desiredB
|
||||
return false;
|
||||
}
|
||||
|
||||
VkPresentModeKHR presentMode = ConfigPresentModeToVulkan();
|
||||
bool success = false;
|
||||
if (g_Vulkan->InitSwapchain()) {
|
||||
if (g_Vulkan->InitSwapchain(presentMode)) {
|
||||
bool useMultiThreading = g_Config.bRenderMultiThreading;
|
||||
if (g_Config.iInflightFrames == 1) {
|
||||
useMultiThreading = false;
|
||||
@@ -120,17 +121,15 @@ void AndroidVulkanContext::Shutdown() {
|
||||
|
||||
void AndroidVulkanContext::Resize() {
|
||||
INFO_LOG(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();
|
||||
|
||||
// TODO: We should only destroy the surface here if the window changed. We can track this inside g_Vulkan.
|
||||
g_Vulkan->DestroySurface();
|
||||
|
||||
VulkanContext::CreateInfo info{};
|
||||
InitVulkanCreateInfoFromConfig(&info);
|
||||
g_Vulkan->UpdateCreateInfo(info);
|
||||
|
||||
g_Vulkan->ReinitSurface();
|
||||
g_Vulkan->InitSwapchain();
|
||||
|
||||
VkPresentModeKHR presentMode = ConfigPresentModeToVulkan();
|
||||
g_Vulkan->InitSwapchain(presentMode);
|
||||
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
|
||||
INFO_LOG(Log::G3D, "AndroidVulkanContext::Resize end (final size: %dx%d)", g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
|
||||
}
|
||||
+22
-31
@@ -41,7 +41,7 @@ enum class GraphicsContextState {
|
||||
|
||||
class IOSVulkanContext : public GraphicsContext {
|
||||
public:
|
||||
IOSVulkanContext();
|
||||
IOSVulkanContext() {}
|
||||
~IOSVulkanContext() {
|
||||
delete g_Vulkan;
|
||||
g_Vulkan = nullptr;
|
||||
@@ -64,8 +64,6 @@ private:
|
||||
GraphicsContextState state_ = GraphicsContextState::PENDING;
|
||||
};
|
||||
|
||||
IOSVulkanContext::IOSVulkanContext() {}
|
||||
|
||||
bool IOSVulkanContext::InitFromRenderThread(CAMetalLayer *layer, int desiredBackbufferSizeX, int desiredBackbufferSizeY) {
|
||||
INFO_LOG(Log::G3D, "IOSVulkanContext::InitFromRenderThread: desiredwidth=%d desiredheight=%d", desiredBackbufferSizeX, desiredBackbufferSizeY);
|
||||
if (!g_Vulkan) {
|
||||
@@ -79,33 +77,30 @@ bool IOSVulkanContext::InitFromRenderThread(CAMetalLayer *layer, int desiredBack
|
||||
return false;
|
||||
}
|
||||
|
||||
bool success = true;
|
||||
if (g_Vulkan->InitSwapchain()) {
|
||||
bool useMultiThreading = g_Config.bRenderMultiThreading;
|
||||
if (g_Config.iInflightFrames == 1) {
|
||||
useMultiThreading = false;
|
||||
}
|
||||
draw_ = Draw::T3DCreateVulkanContext(g_Vulkan, useMultiThreading);
|
||||
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(Log::G3D, "IOSVulkanContext::Init completed, %s", success ? "successfully" : "but failed");
|
||||
if (!success) {
|
||||
VkPresentModeKHR presentMode = ConfigPresentModeToVulkan();
|
||||
if (!g_Vulkan->InitSwapchain(presentMode)) {
|
||||
ERROR_LOG(Log::G3D, "InitSwapchain failed");
|
||||
g_Vulkan->DestroySwapchain();
|
||||
g_Vulkan->DestroySurface();
|
||||
g_Vulkan->DestroyDevice();
|
||||
g_Vulkan->DestroyInstance();
|
||||
return false;
|
||||
}
|
||||
return success;
|
||||
|
||||
bool useMultiThreading = g_Config.bRenderMultiThreading;
|
||||
if (g_Config.iInflightFrames == 1) {
|
||||
useMultiThreading = false;
|
||||
}
|
||||
|
||||
draw_ = Draw::T3DCreateVulkanContext(g_Vulkan, useMultiThreading);
|
||||
SetGPUBackend(GPUBackend::VULKAN);
|
||||
bool shaderSuccess = draw_->CreatePresets(); // Doesn't fail, we ship the compiler.
|
||||
_assert_msg_(shaderSuccess, "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);
|
||||
return true;
|
||||
}
|
||||
|
||||
void IOSVulkanContext::ShutdownFromRenderThread() {
|
||||
@@ -135,13 +130,9 @@ void IOSVulkanContext::Resize() {
|
||||
draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
|
||||
g_Vulkan->DestroySwapchain();
|
||||
g_Vulkan->DestroySurface();
|
||||
|
||||
VulkanContext::CreateInfo info{};
|
||||
InitVulkanCreateInfoFromConfig(&info);
|
||||
g_Vulkan->UpdateCreateInfo(info);
|
||||
|
||||
g_Vulkan->ReinitSurface();
|
||||
g_Vulkan->InitSwapchain();
|
||||
VkPresentModeKHR presentMode = ConfigPresentModeToVulkan();
|
||||
g_Vulkan->InitSwapchain(presentMode);
|
||||
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
|
||||
INFO_LOG(Log::G3D, "IOSVulkanContext::Resize end (final size: %dx%d)", g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
|
||||
}
|
||||
|
||||
@@ -129,7 +129,8 @@ void LibretroVulkanContext::ContextDestroy() {
|
||||
void LibretroVulkanContext::CreateDrawContext() {
|
||||
vk->ReinitSurface();
|
||||
|
||||
if (!vk->InitSwapchain()) {
|
||||
// TODO: Integrate properly with libretro vulkan context. We currently use a wacky wrapper (libretro_vulkan.cpp)
|
||||
if (!vk->InitSwapchain(VK_PRESENT_MODE_FIFO_KHR)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user