diff --git a/src/d3d11/d3d11_annotation.cpp b/src/d3d11/d3d11_annotation.cpp index 4e02c5990..5b5494501 100644 --- a/src/d3d11/d3d11_annotation.cpp +++ b/src/d3d11/d3d11_annotation.cpp @@ -87,7 +87,7 @@ namespace dxvk { label.pLabelName = labelName.c_str(); DecodeD3DCOLOR(color, label.color); - ctx->beginDebugLabel(&label); + ctx->beginDebugLabel(label); }); return m_eventDepth++; @@ -125,7 +125,7 @@ namespace dxvk { label.pLabelName = labelName.c_str(); DecodeD3DCOLOR(color, label.color); - ctx->insertDebugLabel(&label); + ctx->insertDebugLabel(label); }); } diff --git a/src/d3d9/d3d9_annotation.cpp b/src/d3d9/d3d9_annotation.cpp index 09b3ef18a..71ed9769c 100644 --- a/src/d3d9/d3d9_annotation.cpp +++ b/src/d3d9/d3d9_annotation.cpp @@ -135,7 +135,7 @@ namespace dxvk { label.pLabelName = labelName.c_str(); DecodeD3DCOLOR(color, label.color); - ctx->beginDebugLabel(&label); + ctx->beginDebugLabel(label); }); // Handled by the global list. @@ -165,7 +165,7 @@ namespace dxvk { label.pLabelName = labelName.c_str(); DecodeD3DCOLOR(color, label.color); - ctx->insertDebugLabel(&label); + ctx->insertDebugLabel(label); }); } diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 657707011..e6bfd504a 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -2487,21 +2487,29 @@ namespace dxvk { } - void DxvkContext::beginDebugLabel(VkDebugUtilsLabelEXT *label) { - if (m_features.test(DxvkContextFeature::DebugUtils)) - m_cmd->cmdBeginDebugUtilsLabel(DxvkCmdBuffer::ExecBuffer, *label); + void DxvkContext::beginDebugLabel(const VkDebugUtilsLabelEXT& label) { + if (m_features.test(DxvkContextFeature::DebugUtils)) { + endInternalDebugRegion(); + + m_cmd->cmdBeginDebugUtilsLabel(DxvkCmdBuffer::ExecBuffer, label); + m_debugLabelStack.emplace_back(label); + } } void DxvkContext::endDebugLabel() { - if (m_features.test(DxvkContextFeature::DebugUtils)) - m_cmd->cmdEndDebugUtilsLabel(DxvkCmdBuffer::ExecBuffer); + if (m_features.test(DxvkContextFeature::DebugUtils)) { + if (!m_debugLabelStack.empty()) { + m_cmd->cmdEndDebugUtilsLabel(DxvkCmdBuffer::ExecBuffer); + m_debugLabelStack.pop_back(); + } + } } - void DxvkContext::insertDebugLabel(VkDebugUtilsLabelEXT *label) { + void DxvkContext::insertDebugLabel(const VkDebugUtilsLabelEXT& label) { if (m_features.test(DxvkContextFeature::DebugUtils)) - m_cmd->cmdInsertDebugUtilsLabel(DxvkCmdBuffer::ExecBuffer, *label); + m_cmd->cmdInsertDebugUtilsLabel(DxvkCmdBuffer::ExecBuffer, label); } @@ -6665,6 +6673,8 @@ namespace dxvk { void DxvkContext::beginCurrentCommands() { + beginActiveDebugRegions(); + // The current state of the internal command buffer is // undefined, so we have to bind and set up everything // before any draw or dispatch command is recorded. @@ -6713,6 +6723,8 @@ namespace dxvk { m_execBarriers.finalize(m_cmd); m_barrierTracker.clear(); + + endActiveDebugRegions(); } @@ -7256,4 +7268,36 @@ 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::endInternalDebugRegion() { + if (m_debugLabelInternalActive) { + m_debugLabelInternalActive = false; + m_cmd->cmdEndDebugUtilsLabel(DxvkCmdBuffer::ExecBuffer); + } + } + + + void DxvkContext::beginActiveDebugRegions() { + for (const auto& region : m_debugLabelStack) + m_cmd->cmdBeginDebugUtilsLabel(DxvkCmdBuffer::ExecBuffer, region.get()); + } + + + void DxvkContext::endActiveDebugRegions() { + for (size_t i = 0; i < m_debugLabelStack.size(); i++) + m_cmd->cmdEndDebugUtilsLabel(DxvkCmdBuffer::ExecBuffer); + } + } diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 1ead0df0b..debce6861 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -1328,12 +1328,12 @@ namespace dxvk { /** * \brief Begins a debug label region - * \param [in] label The debug label * * Marks the start of a debug label region. Used by debugging/profiling * tools to mark different workloads within a frame. + * \param [in] label The debug label */ - void beginDebugLabel(VkDebugUtilsLabelEXT *label); + void beginDebugLabel(const VkDebugUtilsLabelEXT& label); /** * \brief Ends a debug label region @@ -1345,12 +1345,12 @@ namespace dxvk { /** * \brief Inserts a debug label - * \param [in] label The debug label * * Inserts an instantaneous debug label. Used by debugging/profiling * tools to mark different workloads within a frame. + * \param [in] label The debug label */ - void insertDebugLabel(VkDebugUtilsLabelEXT *label); + void insertDebugLabel(const VkDebugUtilsLabelEXT& label); /** * \brief Increments a given stat counter @@ -1418,6 +1418,9 @@ namespace dxvk { std::vector m_imageLayoutTransitions; + std::vector m_debugLabelStack; + bool m_debugLabelInternalActive = false; + void blitImageFb( Rc dstView, const VkOffset3D* dstOffsets, @@ -1935,6 +1938,15 @@ namespace dxvk { return pred(DxvkAccess::Read); } + void beginInternalDebugRegion( + const VkDebugUtilsLabelEXT& label); + + void endInternalDebugRegion(); + + void beginActiveDebugRegions(); + + void endActiveDebugRegions(); + static bool formatsAreCopyCompatible( VkFormat imageFormat, VkFormat bufferFormat); diff --git a/src/dxvk/dxvk_util.h b/src/dxvk/dxvk_util.h index edeb22398..863647f24 100644 --- a/src/dxvk/dxvk_util.h +++ b/src/dxvk/dxvk_util.h @@ -3,7 +3,41 @@ #include "dxvk_include.h" namespace dxvk::util { - + + /** + * \brief Debug label wrapper + * + * Wrapper around a Vulkan debug label that + * persistently stores the string in question. + */ + class DxvkDebugLabel { + + public: + + DxvkDebugLabel() = default; + + DxvkDebugLabel(const VkDebugUtilsLabelEXT& label) + : m_text(label.pLabelName ? label.pLabelName : "") { + for (uint32_t i = 0; i < m_color.size(); i++) + m_color[i] = label.color[i]; + } + + VkDebugUtilsLabelEXT get() const { + VkDebugUtilsLabelEXT label = { VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT }; + label.pLabelName = m_text.c_str(); + for (uint32_t i = 0; i < m_color.size(); i++) + label.color[i] = m_color[i]; + return label; + } + + private: + + std::string m_text; + std::array m_color = { }; + + }; + + /** * \brief Gets pipeline stage flags for shader stages *