From 2a71e164f5cfd24aebc4eccac180f9ec0e4e69ac Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Thu, 31 Dec 2015 00:30:52 +0100 Subject: [PATCH] Enable vulkan validation --- Common/Vulkan/SPIRVDisasm.h | 3 +- Windows/GPU/WindowsVulkanContext.cpp | 78 ++++++++++++++++++++++++++-- Windows/PPSSPP.vcxproj | 2 +- 3 files changed, 77 insertions(+), 6 deletions(-) diff --git a/Common/Vulkan/SPIRVDisasm.h b/Common/Vulkan/SPIRVDisasm.h index 199f5048fb..d5d036fbb4 100644 --- a/Common/Vulkan/SPIRVDisasm.h +++ b/Common/Vulkan/SPIRVDisasm.h @@ -4,6 +4,7 @@ #include #include -// Mostly just a toy to understand SPIR-V better. +// Mostly just a toy to understand SPIR-V better. Not an accurate SPIR-V disassembler, +// and the result will not reassemble. bool DisassembleSPIRV(std::vector spirv, std::string *output); \ No newline at end of file diff --git a/Windows/GPU/WindowsVulkanContext.cpp b/Windows/GPU/WindowsVulkanContext.cpp index b19be7a81e..0f37bb0d96 100644 --- a/Windows/GPU/WindowsVulkanContext.cpp +++ b/Windows/GPU/WindowsVulkanContext.cpp @@ -48,8 +48,7 @@ #include #include - -#define VK_PROTOTYPES +#include #include "ext/vulkan/vulkan.h" #include "ext/native/thin3d/VulkanContext.h" @@ -60,6 +59,74 @@ const bool g_validate_ = true; VulkanContext *g_Vulkan; +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 "Unknown"; + } +} + +static VkBool32 Vulkan_Dbg(VkDebugReportFlagsEXT msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void *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; + +#ifdef _WIN32 + OutputDebugStringA(message.str().c_str()); + OutputDebugStringA("\n"); + if (msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT) { + // MessageBox(NULL, message.str().c_str(), "Alert", MB_OK); + } else { + } +#else + std::cout << message << std::endl; +#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"; @@ -68,8 +135,9 @@ bool WindowsVulkanContext::Init(HINSTANCE hInst, HWND hWnd, std::string *error_m return false; } - g_Vulkan = new VulkanContext("PPSSPP", 0); - + g_Vulkan = new VulkanContext("PPSSPP", VULKAN_FLAG_VALIDATE); + g_Vulkan->CreateDevice(0); + g_Vulkan->InitDebugMsgCallback(Vulkan_Dbg); g_Vulkan->InitObjects(hInst, hWnd, true); _CrtCheckMemory(); @@ -85,6 +153,8 @@ void WindowsVulkanContext::Shutdown() { g_Vulkan->EndSurfaceRenderPass(); g_Vulkan->DestroyObjects(); + g_Vulkan->DestroyDebugMsgCallback(); + g_Vulkan->DestroyDevice(); delete g_Vulkan; g_Vulkan = nullptr; } diff --git a/Windows/PPSSPP.vcxproj b/Windows/PPSSPP.vcxproj index 8fdfd0717d..845e7baf7f 100644 --- a/Windows/PPSSPP.vcxproj +++ b/Windows/PPSSPP.vcxproj @@ -171,7 +171,7 @@ Disabled - x64\Debug\glslang.lib;..\ext\vulkan\vulkan-1.lib;Winmm.lib;Ws2_32.lib;opengl32.lib;dsound.lib;glu32.lib;..\ffmpeg\Windows\x86_64\lib\avcodec.lib;..\ffmpeg\Windows\x86_64\lib\avformat.lib;..\ffmpeg\Windows\x86_64\lib\avutil.lib;..\ffmpeg\Windows\x86_64\lib\swresample.lib;..\ffmpeg\Windows\x86_64\lib\swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;%(AdditionalDependencies) + ..\ext\vulkan\vulkan-1.lib;Winmm.lib;Ws2_32.lib;opengl32.lib;dsound.lib;glu32.lib;..\ffmpeg\Windows\x86_64\lib\avcodec.lib;..\ffmpeg\Windows\x86_64\lib\avformat.lib;..\ffmpeg\Windows\x86_64\lib\avutil.lib;..\ffmpeg\Windows\x86_64\lib\swresample.lib;..\ffmpeg\Windows\x86_64\lib\swscale.lib;comctl32.lib;d3d9.lib;dxguid.lib;%(AdditionalDependencies) true $(OutDir)$(ProjectName).pdb true