From 6f0b382d9eee4e9d88493608564d85c4708c3691 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 13 Dec 2017 19:29:42 +0100 Subject: [PATCH] Move vulkan debug callback out from WindowsVulkanContext into a file that can be shared with other platforms later. --- CMakeLists.txt | 2 + Common/Common.vcxproj | 2 + Common/Common.vcxproj.filters | 2 + Common/Vulkan/VulkanDebug.cpp | 106 +++++++++++++++++++++++++++ Common/Vulkan/VulkanDebug.h | 28 +++++++ Windows/GPU/WindowsVulkanContext.cpp | 88 +--------------------- android/jni/Android.mk | 1 + 7 files changed, 142 insertions(+), 87 deletions(-) create mode 100644 Common/Vulkan/VulkanDebug.cpp create mode 100644 Common/Vulkan/VulkanDebug.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 927aa9bb71..628831ba30 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -328,6 +328,8 @@ if(VULKAN) Common/Vulkan/SPIRVDisasm.h Common/Vulkan/VulkanContext.cpp Common/Vulkan/VulkanContext.h + Common/Vulkan/VulkanDebug.cpp + Common/Vulkan/VulkanDebug.h Common/Vulkan/VulkanImage.cpp Common/Vulkan/VulkanImage.h Common/Vulkan/VulkanLoader.cpp diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj index 86758c4229..cf033d00ea 100644 --- a/Common/Common.vcxproj +++ b/Common/Common.vcxproj @@ -246,6 +246,7 @@ + @@ -317,6 +318,7 @@ + diff --git a/Common/Common.vcxproj.filters b/Common/Common.vcxproj.filters index 0251f2b334..b49c83fd1f 100644 --- a/Common/Common.vcxproj.filters +++ b/Common/Common.vcxproj.filters @@ -75,6 +75,7 @@ + @@ -138,6 +139,7 @@ + diff --git a/Common/Vulkan/VulkanDebug.cpp b/Common/Vulkan/VulkanDebug.cpp new file mode 100644 index 0000000000..4359b42399 --- /dev/null +++ b/Common/Vulkan/VulkanDebug.cpp @@ -0,0 +1,106 @@ +// Copyright (c) 2016- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#include +#include +#include + +#include "Common/Vulkan/VulkanContext.h" +#include "Common/Vulkan/VulkanDebug.h" +#include "base/logging.h" + +const char *ObjTypeToString(VkDebugReportObjectTypeEXT type) { + switch (type) { + case VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT: return "Instance"; + case VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT: return "PhysicalDevice"; + case VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT: return "Device"; + case VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT: return "Queue"; + case VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT: return "CommandBuffer"; + case VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT: return "DeviceMemory"; + case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT: return "Buffer"; + case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT: return "BufferView"; + case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT: return "Image"; + case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT: return "ImageView"; + case VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT: return "ShaderModule"; + case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT: return "Pipeline"; + case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT: return "PipelineLayout"; + case VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT: return "Sampler"; + case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT: return "DescriptorSet"; + case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT: return "DescriptorSetLayout"; + case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT: return "DescriptorPool"; + case VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT: return "Fence"; + case VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT: return "Semaphore"; + case VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT: return "Event"; + case VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT: return "QueryPool"; + case VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT: return "Framebuffer"; + case VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT: return "RenderPass"; + case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT: return "PipelineCache"; + case VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT: return "SurfaceKHR"; + case VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT: return "SwapChainKHR"; + case VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT: return "CommandPool"; + default: return ""; + } +} + +VkBool32 VKAPI_CALL Vulkan_Dbg(VkDebugReportFlagsEXT msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void *pUserData) { + const VulkanLogOptions *options = (const VulkanLogOptions *)pUserData; + std::ostringstream message; + + if (msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT) { + message << "ERROR: "; + } else if (msgFlags & VK_DEBUG_REPORT_WARNING_BIT_EXT) { + message << "WARNING: "; + } else if (msgFlags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) { + message << "PERFORMANCE WARNING: "; + } else if (msgFlags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) { + message << "INFO: "; + } else if (msgFlags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) { + message << "DEBUG: "; + } + message << "[" << pLayerPrefix << "] " << ObjTypeToString(objType) << " Code " << msgCode << " : " << pMsg << "\n"; + + if (msgCode == 2) // Useless perf warning ("Vertex attribute at location X not consumed by vertex shader") + return false; + if (msgCode == 64) // Another useless perf warning that will be seen less and less as we optimize - vkCmdClearAttachments() issued on command buffer object 0x00000195296C6D40 prior to any Draw Cmds. It is recommended you use RenderPass LOAD_OP_CLEAR on Attachments prior to any Draw. + return false; + +#ifdef _WIN32 + std::string msg = message.str(); + OutputDebugStringA(msg.c_str()); + if (msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT) { + if (options->breakOnError && IsDebuggerPresent()) { + DebugBreak(); + } + if (options->msgBoxOnError) { + MessageBoxA(NULL, message.str().c_str(), "Alert", MB_OK); + } + } else if (msgFlags & VK_DEBUG_REPORT_WARNING_BIT_EXT) { + if (options->breakOnWarning && IsDebuggerPresent()) { + DebugBreak(); + } + } +#else + std::cout << message; +#endif + + // false indicates that layer should not bail-out of an + // API call that had validation failures. This may mean that the + // app dies inside the driver due to invalid parameter(s). + // That's what would happen without validation layers, so we'll + // keep that behavior here. + return false; +} diff --git a/Common/Vulkan/VulkanDebug.h b/Common/Vulkan/VulkanDebug.h new file mode 100644 index 0000000000..21a4e671bb --- /dev/null +++ b/Common/Vulkan/VulkanDebug.h @@ -0,0 +1,28 @@ +// Copyright (c) 2016- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#pragma once + +#include "Common/Vulkan/VulkanContext.h" + +struct VulkanLogOptions { + bool breakOnWarning; + bool breakOnError; + bool msgBoxOnError; +}; + +VkBool32 VKAPI_CALL Vulkan_Dbg(VkDebugReportFlagsEXT msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void *pUserData); diff --git a/Windows/GPU/WindowsVulkanContext.cpp b/Windows/GPU/WindowsVulkanContext.cpp index e0958b4f7f..c6c2259fd8 100644 --- a/Windows/GPU/WindowsVulkanContext.cpp +++ b/Windows/GPU/WindowsVulkanContext.cpp @@ -53,6 +53,7 @@ #include "Core/Config.h" #include "Common/Vulkan/VulkanLoader.h" #include "Common/Vulkan/VulkanContext.h" +#include "Common/Vulkan/VulkanDebug.h" #include "base/stringutil.h" #include "thin3d/thin3d.h" @@ -68,95 +69,8 @@ static const bool g_validate_ = false; static VulkanContext *g_Vulkan; -struct VulkanLogOptions { - bool breakOnWarning; - bool breakOnError; - bool msgBoxOnError; -}; static VulkanLogOptions g_LogOptions; -const char *ObjTypeToString(VkDebugReportObjectTypeEXT type) { - switch (type) { - case VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT: return "Instance"; - case VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT: return "PhysicalDevice"; - case VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT: return "Device"; - case VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT: return "Queue"; - case VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT: return "CommandBuffer"; - case VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT: return "DeviceMemory"; - case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT: return "Buffer"; - case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT: return "BufferView"; - case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT: return "Image"; - case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT: return "ImageView"; - case VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT: return "ShaderModule"; - case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT: return "Pipeline"; - case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT: return "PipelineLayout"; - case VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT: return "Sampler"; - case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT: return "DescriptorSet"; - case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT: return "DescriptorSetLayout"; - case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT: return "DescriptorPool"; - case VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT: return "Fence"; - case VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT: return "Semaphore"; - case VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT: return "Event"; - case VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT: return "QueryPool"; - case VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT: return "Framebuffer"; - case VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT: return "RenderPass"; - case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT: return "PipelineCache"; - case VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT: return "SurfaceKHR"; - case VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT: return "SwapChainKHR"; - case VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT: return "CommandPool"; - default: return ""; - } -} - -static VkBool32 VKAPI_CALL Vulkan_Dbg(VkDebugReportFlagsEXT msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void *pUserData) { - const VulkanLogOptions *options = (const VulkanLogOptions *)pUserData; - std::ostringstream message; - - if (msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT) { - message << "ERROR: "; - } else if (msgFlags & VK_DEBUG_REPORT_WARNING_BIT_EXT) { - message << "WARNING: "; - } else if (msgFlags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) { - message << "PERFORMANCE WARNING: "; - } else if (msgFlags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) { - message << "INFO: "; - } else if (msgFlags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) { - message << "DEBUG: "; - } - message << "[" << pLayerPrefix << "] " << ObjTypeToString(objType) << " Code " << msgCode << " : " << pMsg << "\n"; - - if (msgCode == 2) // Useless perf warning ("Vertex attribute at location X not consumed by vertex shader") - return false; - if (msgCode == 64) // Another useless perf warning that will be seen less and less as we optimize - vkCmdClearAttachments() issued on command buffer object 0x00000195296C6D40 prior to any Draw Cmds. It is recommended you use RenderPass LOAD_OP_CLEAR on Attachments prior to any Draw. - return false; - -#ifdef _WIN32 - std::string msg = message.str(); - OutputDebugStringA(msg.c_str()); - if (msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT) { - if (options->breakOnError && IsDebuggerPresent()) { - DebugBreak(); - } - if (options->msgBoxOnError) { - MessageBoxA(NULL, message.str().c_str(), "Alert", MB_OK); - } - } else if (msgFlags & VK_DEBUG_REPORT_WARNING_BIT_EXT) { - if (options->breakOnWarning && IsDebuggerPresent()) { - DebugBreak(); - } - } -#else - std::cout << message; -#endif - - // false indicates that layer should not bail-out of an - // API call that had validation failures. This may mean that the - // app dies inside the driver due to invalid parameter(s). - // That's what would happen without validation layers, so we'll - // keep that behavior here. - return false; -} - bool WindowsVulkanContext::Init(HINSTANCE hInst, HWND hWnd, std::string *error_message) { *error_message = "N/A"; diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 69ecc0b24d..5ea6ccd057 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -127,6 +127,7 @@ EGL_FILES := \ VULKAN_FILES := \ $(SRC)/Common/Vulkan/VulkanLoader.cpp \ $(SRC)/Common/Vulkan/VulkanContext.cpp \ + $(SRC)/Common/Vulkan/VulkanDebug.cpp \ $(SRC)/Common/Vulkan/VulkanImage.cpp \ $(SRC)/Common/Vulkan/VulkanMemory.cpp \ $(SRC)/GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp \