diff --git a/Common/GPU/Vulkan/VulkanDebug.cpp b/Common/GPU/Vulkan/VulkanDebug.cpp index 022093e217c2..c0bf23567771 100644 --- a/Common/GPU/Vulkan/VulkanDebug.cpp +++ b/Common/GPU/Vulkan/VulkanDebug.cpp @@ -90,6 +90,19 @@ VKAPI_ATTR VkBool32 VKAPI_CALL VulkanDebugUtilsCallback( break; } + /* + // Can be used to temporarily turn errors into info for easier debugging. + switch (messageCode) { + case 1544472022: + if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) { + messageSeverity = (VkDebugUtilsMessageSeverityFlagBitsEXT)((messageSeverity & ~VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) | VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT); + } + break; + default: + break; + } + */ + int count; { std::lock_guard lock(g_errorCountMutex); diff --git a/Common/GPU/Vulkan/VulkanFramebuffer.cpp b/Common/GPU/Vulkan/VulkanFramebuffer.cpp index 975dab04bd57..19de9b67c458 100644 --- a/Common/GPU/Vulkan/VulkanFramebuffer.cpp +++ b/Common/GPU/Vulkan/VulkanFramebuffer.cpp @@ -2,6 +2,35 @@ #include "Common/GPU/Vulkan/VulkanFramebuffer.h" #include "Common/GPU/Vulkan/VulkanQueueRunner.h" +static const char *rpTypeDebugNames[] = { + "RENDER", + "RENDER_DEPTH", + "RENDER_INPUT", + "RENDER_DEPTH_INPUT", + "MV_RENDER", + "MV_RENDER_DEPTH", + "MV_RENDER_INPUT", + "MV_RENDER_DEPTH_INPUT", + "MS_RENDER", + "MS_RENDER_DEPTH", + "MS_RENDER_INPUT", + "MS_RENDER_DEPTH_INPUT", + "MS_MV_RENDER", + "MS_MV_RENDER_DEPTH", + "MS_MV_RENDER_INPUT", + "MS_MV_RENDER_DEPTH_INPUT", + "BACKBUF", +}; + +const char *GetRPTypeName(RenderPassType rpType) { + uint32_t index = (uint32_t)rpType; + if (index < ARRAY_SIZE(rpTypeDebugNames)) { + return rpTypeDebugNames[index]; + } else { + return "N/A"; + } +} + VkSampleCountFlagBits MultiSampleLevelToFlagBits(int count) { // TODO: Check hardware support here, or elsewhere? // Some hardware only supports 4x. @@ -387,12 +416,25 @@ VkRenderPass CreateRenderPass(VulkanContext *vulkan, const RPKey &key, RenderPas } if (isBackbuffer) { + // We don't specify any explicit transitions for these, so let's use subpass dependencies. + // This makes sure that writes to the depth image are done before we try to write to it again. + // From Sascha's examples. deps[numDeps].srcSubpass = VK_SUBPASS_EXTERNAL; deps[numDeps].dstSubpass = 0; - deps[numDeps].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + deps[numDeps].srcStageMask = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; + deps[numDeps].dstStageMask = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; + deps[numDeps].srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + deps[numDeps].dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + deps[numDeps].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT; + numDeps++; + // Dependencies for the color image. + deps[numDeps].srcSubpass = VK_SUBPASS_EXTERNAL; + deps[numDeps].dstSubpass = 0; + deps[numDeps].srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; deps[numDeps].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - deps[numDeps].srcAccessMask = 0; + deps[numDeps].srcAccessMask = VK_ACCESS_MEMORY_READ_BIT; deps[numDeps].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + deps[numDeps].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT; numDeps++; } @@ -494,6 +536,10 @@ VkRenderPass CreateRenderPass(VulkanContext *vulkan, const RPKey &key, RenderPas res = vkCreateRenderPass(vulkan->GetDevice(), &rp, nullptr, &pass); } + if (pass) { + vulkan->SetDebugName(pass, VK_OBJECT_TYPE_RENDER_PASS, GetRPTypeName(rpType)); + } + _assert_(res == VK_SUCCESS); _assert_(pass != VK_NULL_HANDLE); return pass; diff --git a/Common/GPU/Vulkan/VulkanFramebuffer.h b/Common/GPU/Vulkan/VulkanFramebuffer.h index 465983efaa7c..97ff9e367a56 100644 --- a/Common/GPU/Vulkan/VulkanFramebuffer.h +++ b/Common/GPU/Vulkan/VulkanFramebuffer.h @@ -157,3 +157,5 @@ class VKRRenderPass { VkSampleCountFlagBits sampleCounts[(size_t)RenderPassType::TYPE_COUNT]; RPKey key_; }; + +const char *GetRPTypeName(RenderPassType rpType); diff --git a/Common/GPU/Vulkan/VulkanQueueRunner.cpp b/Common/GPU/Vulkan/VulkanQueueRunner.cpp index c4a04f90bc98..e6bb324f76c7 100644 --- a/Common/GPU/Vulkan/VulkanQueueRunner.cpp +++ b/Common/GPU/Vulkan/VulkanQueueRunner.cpp @@ -674,26 +674,6 @@ const char *AspectToString(VkImageAspectFlags aspect) { } } -static const char *rpTypeDebugNames[] = { - "RENDER", - "RENDER_DEPTH", - "RENDER_INPUT", - "RENDER_DEPTH_INPUT", - "MV_RENDER", - "MV_RENDER_DEPTH", - "MV_RENDER_INPUT", - "MV_RENDER_DEPTH_INPUT", - "MS_RENDER", - "MS_RENDER_DEPTH", - "MS_RENDER_INPUT", - "MS_RENDER_DEPTH_INPUT", - "MS_MV_RENDER", - "MS_MV_RENDER_DEPTH", - "MS_MV_RENDER_INPUT", - "MS_MV_RENDER_DEPTH_INPUT", - "BACKBUF", -}; - std::string VulkanQueueRunner::StepToString(VulkanContext *vulkan, const VKRStep &step) { char buffer[256]; switch (step.stepType) { @@ -703,7 +683,7 @@ std::string VulkanQueueRunner::StepToString(VulkanContext *vulkan, const VKRStep int h = step.render.framebuffer ? step.render.framebuffer->height : vulkan->GetBackbufferHeight(); int actual_w = step.render.renderArea.extent.width; int actual_h = step.render.renderArea.extent.height; - const char *renderCmd = rpTypeDebugNames[(size_t)step.render.renderPassType]; + const char *renderCmd = GetRPTypeName(step.render.renderPassType); snprintf(buffer, sizeof(buffer), "%s %s %s (draws: %d, %dx%d/%dx%d)", renderCmd, step.tag, step.render.framebuffer ? step.render.framebuffer->Tag() : "", step.render.numDraws, actual_w, actual_h, w, h); break; }