diff --git a/Common/Log.h b/Common/Log.h index 452afac7f7..5e45d89c34 100644 --- a/Common/Log.h +++ b/Common/Log.h @@ -17,6 +17,9 @@ #pragma once +#include +#include + #include "MsgHandler.h" #define NOTICE_LEVEL 1 // VERY important information that is NOT errors. Like startup and debugprintfs from the game itself. @@ -26,11 +29,6 @@ #define DEBUG_LEVEL 5 // Detailed debugging - might make things slow. #define VERBOSE_LEVEL 6 // Noisy debugging - sometimes needed but usually unimportant. -#if !defined(_WIN32) -#include -#endif - -#include namespace LogTypes { @@ -113,13 +111,13 @@ bool GenericLogEnabled(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type); if (!(_a_)) {\ ERROR_LOG(_t_, "Error...\n\n Line: %d\n File: %s\n\nIgnore and continue?", \ __LINE__, __FILE__); \ - if (!PanicYesNo("*** Assertion (see log)***\n")) {Crash();} \ + if (!PanicYesNo("*** Assertion ***\n")) { assert(false); } \ } #define _dbg_assert_msg_(_t_, _a_, ...)\ if (!(_a_)) {\ printf(__VA_ARGS__); \ ERROR_LOG(_t_, __VA_ARGS__); \ - if (!PanicYesNo(__VA_ARGS__)) {Crash();} \ + if (!PanicYesNo(__VA_ARGS__)) { assert(false);} \ } #define _dbg_update_() ; //Host_UpdateLogDisplay(); @@ -132,16 +130,10 @@ bool GenericLogEnabled(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type); #endif // dbg_assert #endif // MAX_LOGLEVEL DEBUG -#define _assert_(_a_) _dbg_assert_(SYSTEM, _a_) +#define _assert_(_a_) \ + _dbg_assert_(SYSTEM, _a_) -#ifdef _MSC_VER -#define _assert_msg_(_t_, _a_, _fmt_, ...) \ - if (!(_a_)) {\ - if (!PanicYesNo(_fmt_, __VA_ARGS__)) {Crash();} \ +#define _assert_msg_(_t_, _a_, ...) \ + if (!(_a_) && !PanicYesNo(__VA_ARGS__)) { \ + assert(false); \ } -#else // not win32 -#define _assert_msg_(_t_, _a_, _fmt_, ...) \ - if (!(_a_)) {\ - if (!PanicYesNo(_fmt_, ##__VA_ARGS__)) {Crash();} \ - } -#endif // WIN32 diff --git a/Common/MsgHandler.cpp b/Common/MsgHandler.cpp index 997103dda1..b53d79d41a 100644 --- a/Common/MsgHandler.cpp +++ b/Common/MsgHandler.cpp @@ -15,31 +15,20 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ +#include + #include "ppsspp_config.h" -#include "Common.h" // Local +#include "Common.h" #include "StringUtils.h" #include "base/logging.h" #include "util/text/utf8.h" -#include -bool MsgHandler(const char* caption, const char* text, bool yes_no, int Style); +bool MsgHandler(const char *caption, const char *text, bool yes_no, int Style); -static bool AlertEnabled = true; - -// enable/disable the alert handler -void SetEnableAlert(bool enable) -{ - AlertEnabled = enable; -} - -// This is the first stop for gui alerts where the log is updated and the -// correct window is shown -bool MsgAlert(bool yes_no, int Style, const char* format, ...) -{ +bool MsgAlert(bool yes_no, int Style, const char* format, ...) { // Read message and write it to the log char buffer[2048]; - static const char *captions[] = { "Information", "Question", @@ -48,22 +37,15 @@ bool MsgAlert(bool yes_no, int Style, const char* format, ...) }; const char *caption = captions[Style]; - va_list args; va_start(args, format); CharArrayFromFormatV(buffer, sizeof(buffer)-1, format, args); va_end(args); - // Safe android logging -#if PPSSPP_PLATFORM(ANDROID) - ELOG("%s: %s", caption, buffer); -#endif - // Normal logging + // Normal logging (will also log to Android log) ERROR_LOG(SYSTEM, "%s: %s", caption, buffer); - // Don't ignore questions, especially AskYesNo, PanicYesNo could be ignored - if (AlertEnabled || Style == QUESTION || Style == CRITICAL) + if (Style == QUESTION || Style == CRITICAL) return MsgHandler(caption, buffer, yes_no, Style); - return true; } @@ -72,22 +54,22 @@ bool MsgAlert(bool yes_no, int Style, const char* format, ...) #endif // Default non library dependent panic alert -bool MsgHandler(const char* caption, const char* text, bool yes_no, int Style) -{ +bool MsgHandler(const char* caption, const char* text, bool yes_no, int Style) { #if defined(USING_WIN_UI) - int STYLE = MB_ICONINFORMATION; - if (Style == QUESTION) STYLE = MB_ICONQUESTION; - if (Style == WARNING) STYLE = MB_ICONWARNING; + int msgBoxStyle = MB_ICONINFORMATION; + if (Style == QUESTION) msgBoxStyle = MB_ICONQUESTION; + if (Style == WARNING) msgBoxStyle = MB_ICONWARNING; - std::wstring wtext = ConvertUTF8ToWString(text); + std::wstring wtext = ConvertUTF8ToWString(text) + L"\n\nTry to continue?"; std::wstring wcaption = ConvertUTF8ToWString(caption); - - return IDYES == MessageBox(0, wtext.c_str(), wcaption.c_str(), STYLE | (yes_no ? MB_YESNO : MB_OK)); + OutputDebugString(wtext.c_str()); + return IDYES == MessageBox(0, wtext.c_str(), wcaption.c_str(), msgBoxStyle | (yes_no ? MB_YESNO : MB_OK)); #elif PPSSPP_PLATFORM(UWP) OutputDebugStringUTF8(text); - return true; + return false; #else - printf("%s\n", text); - return true; + // Will use android-log if available, printf if not. + ELOG("%s", text); + return false; #endif } diff --git a/Common/MsgHandler.h b/Common/MsgHandler.h index 75e8137e10..6dd2d6a4ff 100644 --- a/Common/MsgHandler.h +++ b/Common/MsgHandler.h @@ -30,18 +30,8 @@ extern bool MsgAlert(bool yes_no, int Style, const char* format, ...) __attribute__((format(printf, 3, 4))) #endif ; -void SetEnableAlert(bool enable); -#ifndef GEKKO -#if defined(_WIN32) && !defined(__MINGW32__) - #define PanicAlert(format, ...) MsgAlert(false, WARNING, format, __VA_ARGS__) - #define PanicYesNo(format, ...) MsgAlert(true, WARNING, format, __VA_ARGS__) -#else - #define PanicAlert(format, ...) MsgAlert(false, WARNING, format, ##__VA_ARGS__) - #define PanicYesNo(format, ...) MsgAlert(true, WARNING, format, ##__VA_ARGS__) -#endif -#else -// GEKKO - #define PanicAlert(format, ...) ; - #define PanicYesNo(format, ...) ; -#endif +#define PanicAlert(...) MsgAlert(false, WARNING, __VA_ARGS__) + +// Used only for asserts. +#define PanicYesNo(...) MsgAlert(true, CRITICAL, __VA_ARGS__) diff --git a/Common/Vulkan/VulkanContext.cpp b/Common/Vulkan/VulkanContext.cpp index 12e3ab1a09..8ed08ecf39 100644 --- a/Common/Vulkan/VulkanContext.cpp +++ b/Common/Vulkan/VulkanContext.cpp @@ -225,6 +225,7 @@ bool VulkanContext::InitObjects() { } if (!InitSwapchain()) { + // Destroy queue? return false; } return true; @@ -821,8 +822,8 @@ bool VulkanContext::InitSwapchain() { } res = vkCreateSwapchainKHR(device_, &swap_chain_info, NULL, &swapchain_); - assert(res == VK_SUCCESS); if (res != VK_SUCCESS) { + ELOG("vkCreateSwapchainKHR failed!"); return false; } diff --git a/Common/Vulkan/VulkanMemory.cpp b/Common/Vulkan/VulkanMemory.cpp index f2c37c173d..2538865deb 100644 --- a/Common/Vulkan/VulkanMemory.cpp +++ b/Common/Vulkan/VulkanMemory.cpp @@ -44,6 +44,7 @@ bool VulkanPushBuffer::AddBuffer() { VkResult res = vkCreateBuffer(device_, &b, nullptr, &info.buffer); if (VK_SUCCESS != res) { + ELOG("vkCreateBuffer failed! result=%d", (int)res); return false; } @@ -60,10 +61,15 @@ bool VulkanPushBuffer::AddBuffer() { res = vkAllocateMemory(device_, &alloc, nullptr, &info.deviceMemory); if (VK_SUCCESS != res) { + ELOG("vkAllocateMemory failed! result=%d", (int)res); + vkDestroyBuffer(device_, info.buffer, nullptr); return false; } res = vkBindBufferMemory(device_, info.buffer, info.deviceMemory, 0); if (VK_SUCCESS != res) { + ELOG("vkBindBufferMemory failed! result=%d", (int)res); + vkFreeMemory(device_, info.deviceMemory, nullptr); + vkDestroyBuffer(device_, info.buffer, nullptr); return false; } diff --git a/Windows/GPU/D3D9Context.cpp b/Windows/GPU/D3D9Context.cpp index ec7ffdb0ca..4566464a78 100644 --- a/Windows/GPU/D3D9Context.cpp +++ b/Windows/GPU/D3D9Context.cpp @@ -191,7 +191,6 @@ void D3D9Context::Resize() { HRESULT hr = device_->Reset(&presentParams_); if (FAILED(hr)) { // Had to remove DXGetErrorStringA calls here because dxerr.lib is deprecated and will not link with VS 2015. - ERROR_LOG_REPORT(G3D, "Unable to reset D3D device"); PanicAlert("Unable to reset D3D9 device"); } draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, 0, 0, nullptr); diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index c51d4a4a26..41745a5151 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -44,6 +44,7 @@ #include "Core/System.h" #include "Common/CPUDetect.h" #include "Common/GraphicsContext.h" +#include "Common/Log.h" #include "Common/GL/GLInterfaceBase.h" #include "Common/Vulkan/VulkanLoader.h" #include "Common/Vulkan/VulkanContext.h" diff --git a/ext/native/thin3d/VulkanQueueRunner.cpp b/ext/native/thin3d/VulkanQueueRunner.cpp index 29170b8004..eec033bc6e 100644 --- a/ext/native/thin3d/VulkanQueueRunner.cpp +++ b/ext/native/thin3d/VulkanQueueRunner.cpp @@ -938,7 +938,10 @@ void VulkanQueueRunner::CopyReadbackBuffer(int width, int height, Draw::DataForm const size_t srcPixelSize = DataFormatSizeInBytes(srcFormat); VkResult res = vkMapMemory(vulkan_->GetDevice(), readbackMemory_, 0, width * height * srcPixelSize, 0, &mappedData); - assert(res == VK_SUCCESS); + if (res != VK_SUCCESS) { + ELOG("CopyReadbackBuffer: vkMapMemory failed! result=%d", (int)res); + return; + } if (srcFormat == Draw::DataFormat::R8G8B8A8_UNORM) { ConvertFromRGBA8888(pixels, (const uint8_t *)mappedData, pixelStride, width, width, height, destFormat); } else if (srcFormat == Draw::DataFormat::B8G8R8A8_UNORM) { @@ -955,6 +958,7 @@ void VulkanQueueRunner::CopyReadbackBuffer(int width, int height, Draw::DataForm ConvertToD32F(pixels, (const uint8_t *)mappedData, pixelStride, width, width, height, srcFormat); } else { // TODO: Maybe a depth conversion or something? + ELOG("CopyReadbackBuffer: Unknown format"); assert(false); } vkUnmapMemory(vulkan_->GetDevice(), readbackMemory_); diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index fabc3339c8..37f2555c09 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -137,8 +137,8 @@ void VulkanRenderManager::CreateBackbuffers() { VkImage *swapchainImages = new VkImage[swapchainImageCount_]; res = vkGetSwapchainImagesKHR(vulkan_->GetDevice(), vulkan_->GetSwapchain(), &swapchainImageCount_, swapchainImages); - assert(res == VK_SUCCESS); if (res != VK_SUCCESS) { + ELOG("vkGetSwapchainImagesKHR failed"); delete[] swapchainImages; return; } @@ -729,20 +729,17 @@ void VulkanRenderManager::BeginSubmitFrame(int frame) { // Now, I wonder if we should do this early in the frame or late? Right now we do it early, which should be fine. VkResult res = vkAcquireNextImageKHR(vulkan_->GetDevice(), vulkan_->GetSwapchain(), UINT64_MAX, acquireSemaphore_, (VkFence)VK_NULL_HANDLE, &frameData.curSwapchainImage); if (res == VK_SUBOPTIMAL_KHR) { - // Hopefully the resize will happen shortly. Ignore. + // Hopefully the resize will happen shortly. Ignore - one frame might look bad or something. } else if (res == VK_ERROR_OUT_OF_DATE_KHR) { frameData.skipSwap = true; } else { - assert(res == VK_SUCCESS); + _assert_msg_(G3D, res == VK_SUCCESS, "vkAcquireNextImageKHR failed! result=%d", (int)res); } - // TODO: Deal with the VK_SUBOPTIMAL_KHR and VK_ERROR_OUT_OF_DATE_KHR - // return codes VkCommandBufferBeginInfo begin{ VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO }; begin.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; res = vkBeginCommandBuffer(frameData.mainCmd, &begin); - - assert(res == VK_SUCCESS); + _assert_msg_(G3D, res == VK_SUCCESS, "vkBeginCommandBuffer failed! result=%d", (int)res); queueRunner_.SetBackbuffer(framebuffers_[frameData.curSwapchainImage], swapchainImages_[frameData.curSwapchainImage].image); @@ -754,11 +751,11 @@ void VulkanRenderManager::Submit(int frame, bool triggerFence) { FrameData &frameData = frameData_[frame]; if (frameData.hasInitCommands) { VkResult res = vkEndCommandBuffer(frameData.initCmd); - assert(res == VK_SUCCESS); + _assert_msg_(G3D, res == VK_SUCCESS, "vkEndCommandBuffer failed (init)! result=%d", (int)res); } VkResult res = vkEndCommandBuffer(frameData.mainCmd); - assert(res == VK_SUCCESS); + _assert_msg_(G3D, res == VK_SUCCESS, "vkEndCommandBuffer failed (main)! result=%d", (int)res); VkCommandBuffer cmdBufs[2]; int numCmdBufs = 0; @@ -775,7 +772,7 @@ void VulkanRenderManager::Submit(int frame, bool triggerFence) { if (res == VK_ERROR_DEVICE_LOST) { _assert_msg_(G3D, false, "Lost the Vulkan device!"); } else { - assert(res == VK_SUCCESS); + _assert_msg_(G3D, res == VK_SUCCESS, "vkQueueSubmit failed! result=%d", (int)res); } numCmdBufs = 0; } @@ -798,7 +795,7 @@ void VulkanRenderManager::Submit(int frame, bool triggerFence) { if (res == VK_ERROR_DEVICE_LOST) { _assert_msg_(G3D, false, "Lost the Vulkan device!"); } else { - assert(res == VK_SUCCESS); + _assert_msg_(G3D, res == VK_SUCCESS, "vkQueueSubmit failed! result=%d", (int)res); } // When !triggerFence, we notify after syncing with Vulkan. @@ -830,7 +827,7 @@ void VulkanRenderManager::EndSubmitFrame(int frame) { if (res == VK_ERROR_OUT_OF_DATE_KHR) { // ignore, it'll be fine. this happens sometimes during resizes, and we do make sure to recreate the swap chain. } else { - assert(res == VK_SUCCESS); + _assert_msg_(G3D, res == VK_SUCCESS, "vkQueuePresentKHR failed! result=%d", (int)res); } } else { frameData.skipSwap = false;