Cleanup log output on swapchain/surface recreation.

This commit is contained in:
Henrik Rydgård committed 2020-07-18 20:35:39 +02:00
1 parent 6e6cac6b9b
commit 697c3b8b36
7 files changed
+91 -60

No files matched your search

+55 -36
View File
@@ -318,26 +318,18 @@ bool VulkanContext::MemoryTypeFromProperties(uint32_t typeBits, VkFlags requirem
return false;
}
bool VulkanContext::InitObjects() {
if (!InitQueue()) {
return false;
void VulkanContext::DestroySwapchain() {
if (swapchain_ != VK_NULL_HANDLE) {
vkDestroySwapchainKHR(device_, swapchain_, nullptr);
swapchain_ = VK_NULL_HANDLE;
}
if (!InitSwapchain()) {
// Destroy queue?
return false;
}
return true;
}
void VulkanContext::DestroyObjects() {
ILOG("VulkanContext::DestroyObjects (including swapchain)");
if (swapchain_ != VK_NULL_HANDLE)
vkDestroySwapchainKHR(device_, swapchain_, nullptr);
swapchain_ = VK_NULL_HANDLE;
vkDestroySurfaceKHR(instance_, surface_, nullptr);
surface_ = VK_NULL_HANDLE;
void VulkanContext::DestroySurface() {
if (surface_ != VK_NULL_HANDLE) {
vkDestroySurfaceKHR(instance_, surface_, nullptr);
surface_ = VK_NULL_HANDLE;
}
}
VkResult VulkanContext::GetInstanceLayerExtensionList(const char *layerName, std::vector<VkExtensionProperties> &extensions) {
@@ -716,7 +708,10 @@ VkResult VulkanContext::ReinitSurface() {
surface_ = VK_NULL_HANDLE;
}
ILOG("Creating Vulkan surface for window");
ILOG("Creating Vulkan surface for window (%p %p)", winsysData1_, winsysData2_);
VkResult retval = VK_SUCCESS;
switch (winsys_) {
#ifdef _WIN32
case WINDOWSYSTEM_WIN32:
@@ -725,7 +720,8 @@ VkResult VulkanContext::ReinitSurface() {
win32.flags = 0;
win32.hwnd = (HWND)winsysData2_;
win32.hinstance = (HINSTANCE)winsysData1_;
return vkCreateWin32SurfaceKHR(instance_, &win32, nullptr, &surface_);
retval = vkCreateWin32SurfaceKHR(instance_, &win32, nullptr, &surface_);
break;
}
#endif
#if defined(__ANDROID__)
@@ -735,7 +731,8 @@ VkResult VulkanContext::ReinitSurface() {
VkAndroidSurfaceCreateInfoKHR android{ VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR };
android.flags = 0;
android.window = wnd;
return vkCreateAndroidSurfaceKHR(instance_, &android, nullptr, &surface_);
retval = vkCreateAndroidSurfaceKHR(instance_, &android, nullptr, &surface_);
break;
}
#endif
#if defined(VK_USE_PLATFORM_METAL_EXT)
@@ -745,7 +742,8 @@ VkResult VulkanContext::ReinitSurface() {
metal.flags = 0;
metal.pLayer = winsysData1_;
metal.pNext = winsysData2_;
return vkCreateMetalSurfaceEXT(instance_, &metal, nullptr, &surface_);
retval = vkCreateMetalSurfaceEXT(instance_, &metal, nullptr, &surface_);
break;
}
#endif
#if defined(VK_USE_PLATFORM_XLIB_KHR)
@@ -755,7 +753,8 @@ VkResult VulkanContext::ReinitSurface() {
xlib.flags = 0;
xlib.dpy = (Display *)winsysData1_;
xlib.window = (Window)winsysData2_;
return vkCreateXlibSurfaceKHR(instance_, &xlib, nullptr, &surface_);
retval = vkCreateXlibSurfaceKHR(instance_, &xlib, nullptr, &surface_);
break;
}
#endif
#if defined(VK_USE_PLATFORM_XCB_KHR)
@@ -765,7 +764,8 @@ VkResult VulkanContext::ReinitSurface() {
xcb.flags = 0;
xcb.connection = (Connection *)winsysData1_;
xcb.window = (Window)(uintptr_t)winsysData2_;
return vkCreateXcbSurfaceKHR(instance_, &xcb, nullptr, &surface_);
retval = vkCreateXcbSurfaceKHR(instance_, &xcb, nullptr, &surface_);
break;
}
#endif
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
@@ -775,7 +775,8 @@ VkResult VulkanContext::ReinitSurface() {
wayland.flags = 0;
wayland.display = (wl_display *)winsysData1_;
wayland.surface = (wl_surface *)winsysData2_;
return vkCreateWaylandSurfaceKHR(instance_, &wayland, nullptr, &surface_);
retval = vkCreateWaylandSurfaceKHR(instance_, &wayland, nullptr, &surface_);
break;
}
#endif
@@ -783,9 +784,19 @@ VkResult VulkanContext::ReinitSurface() {
_assert_msg_(G3D, false, "Vulkan support for chosen window system not implemented");
return VK_ERROR_INITIALIZATION_FAILED;
}
if (retval != VK_SUCCESS) {
return retval;
}
if (!ChooseQueue()) {
return VK_ERROR_INITIALIZATION_FAILED;
}
return VK_SUCCESS;
}
bool VulkanContext::InitQueue() {
bool VulkanContext::ChooseQueue() {
// Iterate over each queue to learn whether it supports presenting:
VkBool32 *supportsPresent = new VkBool32[queue_count];
for (uint32_t i = 0; i < queue_count; i++) {
@@ -869,7 +880,6 @@ bool VulkanContext::InitQueue() {
}
vkGetDeviceQueue(device_, graphics_queue_family_index_, 0, &gfx_queue_);
ILOG("gfx_queue_: %p", gfx_queue_);
return true;
}
@@ -906,21 +916,27 @@ bool VulkanContext::InitSwapchain() {
res = vkGetPhysicalDeviceSurfacePresentModesKHR(physical_devices_[physical_device_], surface_, &presentModeCount, presentModes);
assert(res == VK_SUCCESS);
ILOG("surfCapabilities_.currentExtent: %dx%d", surfCapabilities_.currentExtent.width, surfCapabilities_.currentExtent.height);
ILOG("surfCapabilities_.minImageExtent: %dx%d", surfCapabilities_.minImageExtent.width, surfCapabilities_.minImageExtent.height);
ILOG("surfCapabilities_.maxImageExtent: %dx%d", surfCapabilities_.maxImageExtent.width, surfCapabilities_.maxImageExtent.height);
swapChainExtent_.width = clamp(surfCapabilities_.currentExtent.width, surfCapabilities_.minImageExtent.width, surfCapabilities_.maxImageExtent.width);
swapChainExtent_.height = clamp(surfCapabilities_.currentExtent.height, surfCapabilities_.minImageExtent.height, surfCapabilities_.maxImageExtent.height);
ILOG("swapChainExtent: %dx%d", swapChainExtent_.width, swapChainExtent_.height);
ILOG("surfCapabilities_.current: %dx%d min: %dx%d max: %dx%d computed: %dx%d",
surfCapabilities_.currentExtent.width, surfCapabilities_.currentExtent.height,
surfCapabilities_.minImageExtent.width, surfCapabilities_.minImageExtent.height,
surfCapabilities_.maxImageExtent.width, surfCapabilities_.maxImageExtent.height,
swapChainExtent_.width, swapChainExtent_.height);
// TODO: Find a better way to specify the prioritized present mode while being able
// to fall back in a sensible way.
VkPresentModeKHR swapchainPresentMode = VK_PRESENT_MODE_MAX_ENUM_KHR;
std::string modes = "";
for (size_t i = 0; i < presentModeCount; i++) {
ILOG("Supported present mode: %d (%s)", presentModes[i], PresentModeString(presentModes[i]));
modes += PresentModeString(presentModes[i]);
if (i != presentModeCount - 1) {
modes += ", ";
}
}
ILOG("Supported present modes: %s", modes.c_str());
for (size_t i = 0; i < presentModeCount; i++) {
bool match = false;
match = match || ((flags_ & VULKAN_FLAG_PRESENT_MAILBOX) && presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR);
@@ -940,13 +956,11 @@ bool VulkanContext::InitSwapchain() {
// HACK
swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR;
#endif
ILOG("Chosen present mode: %d (%s)", swapchainPresentMode, PresentModeString(swapchainPresentMode));
delete[] presentModes;
// Determine the number of VkImage's to use in the swap chain (we desire to
// own only 1 image at a time, besides the images being displayed and
// queued for display):
uint32_t desiredNumberOfSwapChainImages = surfCapabilities_.minImageCount + 1;
ILOG("numSwapChainImages: %d", desiredNumberOfSwapChainImages);
if ((surfCapabilities_.maxImageCount > 0) &&
(desiredNumberOfSwapChainImages > surfCapabilities_.maxImageCount))
{
@@ -954,14 +968,16 @@ bool VulkanContext::InitSwapchain() {
desiredNumberOfSwapChainImages = surfCapabilities_.maxImageCount;
}
ILOG("Chosen present mode: %d (%s). numSwapChainImages: %d/%d",
swapchainPresentMode, PresentModeString(swapchainPresentMode),
desiredNumberOfSwapChainImages, surfCapabilities_.maxImageCount);
// We mostly follow the practices from
// https://arm-software.github.io/vulkan_best_practice_for_mobile_developers/samples/surface_rotation/surface_rotation_tutorial.html
//
VkSurfaceTransformFlagBitsKHR preTransform;
std::string supportedTransforms = surface_transforms_to_string(surfCapabilities_.supportedTransforms);
std::string currentTransform = surface_transforms_to_string(surfCapabilities_.currentTransform);
ILOG("Supported transforms: %s", supportedTransforms.c_str());
ILOG("Current transform: %s", currentTransform.c_str());
g_display_rotation = DisplayRotation::ROTATE_0;
g_display_rot_matrix.setIdentity();
bool swapChainExtentSwap = false;
@@ -993,8 +1009,10 @@ bool VulkanContext::InitSwapchain() {
// Let the OS rotate the image (potentially slow on many Android devices)
preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
}
std::string preTransformStr = surface_transforms_to_string(preTransform);
ILOG("Chosen pretransform transform: %s", preTransformStr.c_str());
ILOG("Transform supported: %s current: %s chosen: %s", supportedTransforms.c_str(), currentTransform.c_str(), preTransformStr.c_str());
if (physicalDeviceProperties_[physical_device_].properties.vendorID == VULKAN_VENDOR_IMGTEC) {
ILOG("Applying PowerVR hack (rounding off the width!)");
@@ -1017,6 +1035,7 @@ bool VulkanContext::InitSwapchain() {
swap_chain_info.oldSwapchain = VK_NULL_HANDLE;
swap_chain_info.clipped = true;
swap_chain_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
// Don't ask for TRANSFER_DST for the swapchain image, we don't use that.
// if (surfCapabilities_.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT)
// swap_chain_info.imageUsage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
+5 -4
View File
@@ -147,12 +147,11 @@ public:
VkResult InitSurface(WindowSystem winsys, void *data1, void *data2);
VkResult ReinitSurface();
bool InitQueue();
bool InitObjects();
bool InitSwapchain();
// Also destroys the surface.
void DestroyObjects();
void DestroySwapchain();
void DestroySurface();
void DestroyDevice();
void PerformPendingDeletes();
@@ -273,6 +272,8 @@ public:
void GetImageMemoryRequirements(VkImage image, VkMemoryRequirements *mem_reqs, bool *dedicatedAllocation);
private:
bool ChooseQueue();
VkResult InitDebugUtilsCallback();
// A layer can expose extensions, keep track of those extensions here.
+2 -2
View File
@@ -114,11 +114,11 @@ static void InitSDLAudioDevice(const std::string &name = "") {
}
}
if (audioDev <= 0) {
ILOG("SDL: Trying a different device");
ILOG("SDL: Trying a different audio device");
audioDev = SDL_OpenAudioDevice(nullptr, 0, &fmt, &g_retFmt, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE);
}
if (audioDev <= 0) {
ELOG("Failed to open audio: %s", SDL_GetError());
ELOG("Failed to open audio device: %s", SDL_GetError());
} else {
if (g_retFmt.samples != fmt.samples) // Notify, but still use it
ELOG("Output audio samples: %d (requested: %d)", g_retFmt.samples, fmt.samples);
+17 -8
View File
@@ -20,6 +20,15 @@ static const bool g_Validate = true;
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) {
@@ -41,10 +50,7 @@ bool SDLVulkanGraphicsContext::Init(SDL_Window *&window, int x, int y, int mode,
}
vulkan_ = new VulkanContext();
int vulkanFlags = VULKAN_FLAG_PRESENT_MAILBOX;
if (g_Validate) {
vulkanFlags |= VULKAN_FLAG_VALIDATE;
}
int vulkanFlags = FlagsFromConfig();
VulkanContext::CreateInfo info{};
info.app_name = "PPSSPP";
@@ -102,7 +108,7 @@ bool SDLVulkanGraphicsContext::Init(SDL_Window *&window, int x, int y, int mode,
break;
}
if (!vulkan_->InitObjects()) {
if (!vulkan_->InitSwapchain()) {
*error_message = vulkan_->InitError();
Shutdown();
return false;
@@ -126,7 +132,8 @@ void SDLVulkanGraphicsContext::Shutdown() {
delete draw_;
draw_ = nullptr;
vulkan_->WaitUntilQueueIdle();
vulkan_->DestroyObjects();
vulkan_->DestroySwapchain();
vulkan_->DestroySurface();
vulkan_->DestroyDevice();
vulkan_->DestroyInstance();
delete vulkan_;
@@ -136,9 +143,11 @@ void SDLVulkanGraphicsContext::Shutdown() {
void SDLVulkanGraphicsContext::Resize() {
draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight());
vulkan_->DestroyObjects();
vulkan_->DestroySwapchain();
vulkan_->DestroySurface();
vulkan_->UpdateFlags(FlagsFromConfig());
vulkan_->ReinitSurface();
vulkan_->InitObjects();
vulkan_->InitSwapchain();
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight());
}
+2 -1
View File
@@ -350,13 +350,14 @@ void GameSettingsScreen::CreateViews() {
}
#endif
#ifdef _WIN32
#if !PPSSPP_PLATFORM(ANDROID)
CheckBox *vSync = graphicsSettings->Add(new CheckBox(&g_Config.bVSync, gr->T("VSync")));
vSync->OnClick.Add([=](EventParams &e) {
NativeResized();
return UI::EVENT_CONTINUE;
});
#endif
CheckBox *frameDuplication = graphicsSettings->Add(new CheckBox(&g_Config.bRenderDuplicateFrames, gr->T("Render duplicate frames to 60hz")));
frameDuplication->SetEnabledFunc([] {
return g_Config.iRenderingMode != FB_NON_BUFFERED_MODE || (g_Config.bSoftwareRendering && g_Config.iFrameSkip != 0);
+3 -5
View File
@@ -173,12 +173,10 @@ void WindowsVulkanContext::Shutdown() {
void WindowsVulkanContext::Resize() {
draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
g_Vulkan->DestroyObjects();
g_Vulkan->DestroySwapchain();
g_Vulkan->UpdateFlags(FlagsFromConfig());
g_Vulkan->ReinitSurface();
g_Vulkan->InitObjects();
g_Vulkan_->ReinitSurface();
g_Vulkan_->InitSwapchain();
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
}
+7 -4
View File
@@ -116,7 +116,8 @@ bool AndroidVulkanContext::InitFromRenderThread(ANativeWindow *wnd, int desiredB
ILOG("AndroidVulkanContext::Init completed, %s", success ? "successfully" : "but failed");
if (!success) {
g_Vulkan->DestroyObjects();
g_Vulkan->DestroySwapchain();
g_Vulkan->DestroySurface();
g_Vulkan->DestroyDevice();
g_Vulkan->DestroyInstance();
}
@@ -130,7 +131,8 @@ void AndroidVulkanContext::ShutdownFromRenderThread() {
draw_ = nullptr;
g_Vulkan->WaitUntilQueueIdle();
g_Vulkan->PerformPendingDeletes();
g_Vulkan->DestroyObjects(); // Also destroys the surface, a bit asymmetric
g_Vulkan->DestroySwapchain();
g_Vulkan->DestroySurface();
ILOG("Done with ShutdownFromRenderThread");
}
@@ -150,11 +152,12 @@ void AndroidVulkanContext::Resize() {
ILOG("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->DestroyObjects();
g_Vulkan->DestroySwapchain();
g_Vulkan->DestroySurface();
g_Vulkan->UpdateFlags(FlagsFromConfig());
g_Vulkan->ReinitSurface();
g_Vulkan->InitObjects();
g_Vulkan->InitSwapchain();
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
ILOG("AndroidVulkanContext::Resize end (final size: %dx%d)", g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
}