diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 8a22d764c..539e63f47 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -2869,27 +2869,20 @@ namespace dxvk { label << ")"; - beginInternalDebugRegion(vk::makeLabel(0xf0e6dc, label.str().c_str())); + pushDebugRegion(vk::makeLabel(0xf0e6dc, label.str().c_str()), + util::DxvkDebugLabelType::InternalRenderPass); } void DxvkContext::beginDebugLabel(const VkDebugUtilsLabelEXT& label) { - if (m_features.test(DxvkContextFeature::DebugUtils)) { - endInternalDebugRegion(); - - m_cmd->cmdBeginDebugUtilsLabel(DxvkCmdBuffer::ExecBuffer, label); - m_debugLabelStack.emplace_back(label); - } + if (m_features.test(DxvkContextFeature::DebugUtils)) + pushDebugRegion(label, util::DxvkDebugLabelType::External); } void DxvkContext::endDebugLabel() { - if (m_features.test(DxvkContextFeature::DebugUtils)) { - if (!m_debugLabelStack.empty()) { - m_cmd->cmdEndDebugUtilsLabel(DxvkCmdBuffer::ExecBuffer); - m_debugLabelStack.pop_back(); - } - } + if (m_features.test(DxvkContextFeature::DebugUtils)) + popDebugRegion(util::DxvkDebugLabelType::External); } @@ -5208,7 +5201,9 @@ namespace dxvk { flushBarriers(); flushResolves(); - endInternalDebugRegion(); + + if (unlikely(m_features.test(DxvkContextFeature::DebugUtils))) + popDebugRegion(util::DxvkDebugLabelType::InternalRenderPass); } else if (!suspend) { // We may end a previously suspended render pass if (m_flags.test(DxvkContextFlag::GpRenderPassSuspended)) { @@ -8170,23 +8165,34 @@ namespace dxvk { } - void DxvkContext::beginInternalDebugRegion(const VkDebugUtilsLabelEXT& label) { - if (m_features.test(DxvkContextFeature::DebugUtils)) { - // If the app provides us with debug regions, don't add any - // internal ones to avoid potential issues with scoping. - if (m_debugLabelStack.empty()) { - m_cmd->cmdBeginDebugUtilsLabel(DxvkCmdBuffer::ExecBuffer, label); - m_debugLabelInternalActive = true; - } - } + void DxvkContext::pushDebugRegion(const VkDebugUtilsLabelEXT& label, util::DxvkDebugLabelType type) { + m_cmd->cmdBeginDebugUtilsLabel(DxvkCmdBuffer::ExecBuffer, label); + m_debugLabelStack.emplace_back(label, type); } - void DxvkContext::endInternalDebugRegion() { - if (m_debugLabelInternalActive) { - m_debugLabelInternalActive = false; + void DxvkContext::popDebugRegion(util::DxvkDebugLabelType type) { + // Find last active region of the given type + size_t index = m_debugLabelStack.size(); + + while (index && m_debugLabelStack[index - 1u].type() != type) + index -= 1u; + + if (!index) + return; + + // End all debug regions inside the scope we want to end, as + // well as the debug region of the requested type itself + for (size_t i = index; i <= m_debugLabelStack.size(); i++) m_cmd->cmdEndDebugUtilsLabel(DxvkCmdBuffer::ExecBuffer); + + // Re-emit nested debug regions and erase the region we ended + for (size_t i = index; i < m_debugLabelStack.size(); i++) { + m_cmd->cmdBeginDebugUtilsLabel(DxvkCmdBuffer::ExecBuffer, m_debugLabelStack[i].get()); + m_debugLabelStack[i - 1u] = m_debugLabelStack[i]; } + + m_debugLabelStack.pop_back(); } diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index bca3eac77..85ad7574c 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -1453,7 +1453,6 @@ namespace dxvk { std::vector m_imageLayoutTransitions; std::vector m_debugLabelStack; - bool m_debugLabelInternalActive = false; Rc m_latencyTracker; uint64_t m_latencyFrameId = 0u; @@ -2072,10 +2071,12 @@ namespace dxvk { void beginRenderPassDebugRegion(); - void beginInternalDebugRegion( - const VkDebugUtilsLabelEXT& label); + void pushDebugRegion( + const VkDebugUtilsLabelEXT& label, + util::DxvkDebugLabelType type); - void endInternalDebugRegion(); + void popDebugRegion( + util::DxvkDebugLabelType type); void beginActiveDebugRegions(); diff --git a/src/dxvk/dxvk_util.h b/src/dxvk/dxvk_util.h index 863647f24..ab166e3f0 100644 --- a/src/dxvk/dxvk_util.h +++ b/src/dxvk/dxvk_util.h @@ -4,6 +4,14 @@ namespace dxvk::util { + /** + * \brief Debug utils label type + */ + enum class DxvkDebugLabelType : uint32_t { + External, ///< App-provided scope + InternalRenderPass, ///< Internal render pass markers + }; + /** * \brief Debug label wrapper * @@ -16,12 +24,16 @@ namespace dxvk::util { DxvkDebugLabel() = default; - DxvkDebugLabel(const VkDebugUtilsLabelEXT& label) - : m_text(label.pLabelName ? label.pLabelName : "") { + DxvkDebugLabel(const VkDebugUtilsLabelEXT& label, DxvkDebugLabelType type) + : m_text(label.pLabelName ? label.pLabelName : ""), m_type(type) { for (uint32_t i = 0; i < m_color.size(); i++) m_color[i] = label.color[i]; } + DxvkDebugLabelType type() const { + return m_type; + } + VkDebugUtilsLabelEXT get() const { VkDebugUtilsLabelEXT label = { VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT }; label.pLabelName = m_text.c_str(); @@ -34,6 +46,7 @@ namespace dxvk::util { std::string m_text; std::array m_color = { }; + DxvkDebugLabelType m_type; };