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 \