Reland "Vulkan: Implement debug markers"

This reverts commit 0c01e36783b20a0177c653490cb4f8ea4a896075.

Reason for revert: Its dependency that was reverted has now relanded:

    https://chromium-review.googlesource.com/c/angle/angle/+/1489153

Original change's description:
> Revert "Vulkan: Implement debug markers"
>
> This reverts commit 983e446921946734fe47217c345a8fe2f079319d.
>
> Reason for revert: Depends on a CL that's reverted: https://chromium-review.googlesource.com/c/angle/angle/+/1470605
>
> Original change's description:
> > Vulkan: Implement debug markers
> >
> > Covers both GL_KHR_debug and GL_EXT_debug_marker.
> >
> > Debug markers are used to specify events or hierarchically categorize a
> > set of commands within the command buffer.  When debugging, this allows
> > for quicker navigation to the draw calls of interest, and otherwise
> > provides context to debug output.
> >
> > Bug: angleproject:2853
> > Change-Id: Id65e11fc877d9e70b6fd0fae7f0bbbcb1164bf10
> > Reviewed-on: https://chromium-review.googlesource.com/c/1403956
> > Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
> > Reviewed-by: Jamie Madill <jmadill@chromium.org>
> > Reviewed-by: Geoff Lang <geofflang@chromium.org>
>
> TBR=geofflang@chromium.org,jmadill@chromium.org,syoussefi@chromium.org
>
> Change-Id: I7fcfc8683195d396aec61848719f52c0fa049ece
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: angleproject:2853
> Reviewed-on: https://chromium-review.googlesource.com/c/1470606
> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
> Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>

TBR=geofflang@chromium.org,jmadill@google.com,syoussefi@chromium.org

Bug: angleproject:2853
Change-Id: Ie19ae103244d54dcf7108d5f61c24e318fc44057
Reviewed-on: https://chromium-review.googlesource.com/c/1489154
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
Reviewed-by: Jamie Madill <jmadill@google.com>
diff --git a/src/common/Color.h b/src/common/Color.h
index 7adcfa9c..e1de358 100644
--- a/src/common/Color.h
+++ b/src/common/Color.h
@@ -18,7 +18,7 @@
 struct Color
 {
     Color();
-    Color(T r, T g, T b, T a);
+    constexpr Color(T r, T g, T b, T a);
 
     const T *data() const { return &red; }
     T *ptr() { return &red; }
diff --git a/src/common/Color.inl b/src/common/Color.inl
index d7705b4..8ce6fcf 100644
--- a/src/common/Color.inl
+++ b/src/common/Color.inl
@@ -15,7 +15,7 @@
 }
 
 template <typename T>
-Color<T>::Color(T r, T g, T b, T a) : red(r), green(g), blue(b), alpha(a)
+constexpr Color<T>::Color(T r, T g, T b, T a) : red(r), green(g), blue(b), alpha(a)
 {
 }
 
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index a491c70..c573d58 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -5008,8 +5008,8 @@
 void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
 {
     std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
+    mImplementation->pushDebugGroup(source, id, msg);
     mState.getDebug().pushGroup(source, id, std::move(msg));
-    mImplementation->pushDebugGroup(source, id, length, message);
 }
 
 void Context::popDebugGroup()
diff --git a/src/libANGLE/renderer/ContextImpl.h b/src/libANGLE/renderer/ContextImpl.h
index 4ee2756..0203276 100644
--- a/src/libANGLE/renderer/ContextImpl.h
+++ b/src/libANGLE/renderer/ContextImpl.h
@@ -137,8 +137,8 @@
     virtual void popGroupMarker()                                      = 0;
 
     // KHR_debug
-    virtual void pushDebugGroup(GLenum source, GLuint id, GLsizei length, const char *message) = 0;
-    virtual void popDebugGroup()                                                               = 0;
+    virtual void pushDebugGroup(GLenum source, GLuint id, const std::string &message) = 0;
+    virtual void popDebugGroup()                                                      = 0;
 
     // State sync with dirty bits.
     virtual angle::Result syncState(const gl::Context *context,
diff --git a/src/libANGLE/renderer/d3d/d3d11/Context11.cpp b/src/libANGLE/renderer/d3d/d3d11/Context11.cpp
index 7060368..3e673cf 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Context11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/Context11.cpp
@@ -421,10 +421,10 @@
     }
 }
 
-void Context11::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const char *message)
+void Context11::pushDebugGroup(GLenum source, GLuint id, const std::string &message)
 {
     // Fall through to the EXT_debug_marker functions
-    pushGroupMarker(length, message);
+    pushGroupMarker(message.size(), message.c_str());
 }
 
 void Context11::popDebugGroup()
diff --git a/src/libANGLE/renderer/d3d/d3d11/Context11.h b/src/libANGLE/renderer/d3d/d3d11/Context11.h
index aef1b20..df1e261 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Context11.h
+++ b/src/libANGLE/renderer/d3d/d3d11/Context11.h
@@ -119,7 +119,7 @@
     void popGroupMarker() override;
 
     // KHR_debug
-    void pushDebugGroup(GLenum source, GLuint id, GLsizei length, const char *message) override;
+    void pushDebugGroup(GLenum source, GLuint id, const std::string &message) override;
     void popDebugGroup() override;
 
     // State sync with dirty bits.
diff --git a/src/libANGLE/renderer/d3d/d3d9/Context9.cpp b/src/libANGLE/renderer/d3d/d3d9/Context9.cpp
index a39dcf0..da4fabc 100644
--- a/src/libANGLE/renderer/d3d/d3d9/Context9.cpp
+++ b/src/libANGLE/renderer/d3d/d3d9/Context9.cpp
@@ -244,10 +244,10 @@
     }
 }
 
-void Context9::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const char *message)
+void Context9::pushDebugGroup(GLenum source, GLuint id, const std::string &message)
 {
     // Fall through to the EXT_debug_marker functions
-    pushGroupMarker(length, message);
+    pushGroupMarker(message.size(), message.c_str());
 }
 
 void Context9::popDebugGroup()
diff --git a/src/libANGLE/renderer/d3d/d3d9/Context9.h b/src/libANGLE/renderer/d3d/d3d9/Context9.h
index 7f81a53..944231a 100644
--- a/src/libANGLE/renderer/d3d/d3d9/Context9.h
+++ b/src/libANGLE/renderer/d3d/d3d9/Context9.h
@@ -118,7 +118,7 @@
     void popGroupMarker() override;
 
     // KHR_debug
-    void pushDebugGroup(GLenum source, GLuint id, GLsizei length, const char *message) override;
+    void pushDebugGroup(GLenum source, GLuint id, const std::string &message) override;
     void popDebugGroup() override;
 
     // State sync with dirty bits.
diff --git a/src/libANGLE/renderer/gl/ContextGL.cpp b/src/libANGLE/renderer/gl/ContextGL.cpp
index 2cb10e2..14464cc 100644
--- a/src/libANGLE/renderer/gl/ContextGL.cpp
+++ b/src/libANGLE/renderer/gl/ContextGL.cpp
@@ -508,9 +508,9 @@
     mRenderer->popGroupMarker();
 }
 
-void ContextGL::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const char *message)
+void ContextGL::pushDebugGroup(GLenum source, GLuint id, const std::string &message)
 {
-    mRenderer->pushDebugGroup(source, id, length, message);
+    mRenderer->pushDebugGroup(source, id, message);
 }
 
 void ContextGL::popDebugGroup()
diff --git a/src/libANGLE/renderer/gl/ContextGL.h b/src/libANGLE/renderer/gl/ContextGL.h
index 9e513cf..263e40f 100644
--- a/src/libANGLE/renderer/gl/ContextGL.h
+++ b/src/libANGLE/renderer/gl/ContextGL.h
@@ -173,7 +173,7 @@
     void popGroupMarker() override;
 
     // KHR_debug
-    void pushDebugGroup(GLenum source, GLuint id, GLsizei length, const char *message) override;
+    void pushDebugGroup(GLenum source, GLuint id, const std::string &message) override;
     void popDebugGroup() override;
 
     // State sync with dirty bits.
diff --git a/src/libANGLE/renderer/gl/RendererGL.cpp b/src/libANGLE/renderer/gl/RendererGL.cpp
index 2655aaa..042ead5 100644
--- a/src/libANGLE/renderer/gl/RendererGL.cpp
+++ b/src/libANGLE/renderer/gl/RendererGL.cpp
@@ -422,7 +422,7 @@
 
 void RendererGL::popGroupMarker() {}
 
-void RendererGL::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const char *message) {}
+void RendererGL::pushDebugGroup(GLenum source, GLuint id, const std::string &message) {}
 
 void RendererGL::popDebugGroup() {}
 
diff --git a/src/libANGLE/renderer/gl/RendererGL.h b/src/libANGLE/renderer/gl/RendererGL.h
index 0ef85ec..f8f6c6b 100644
--- a/src/libANGLE/renderer/gl/RendererGL.h
+++ b/src/libANGLE/renderer/gl/RendererGL.h
@@ -146,7 +146,7 @@
     void popGroupMarker();
 
     // KHR_debug
-    void pushDebugGroup(GLenum source, GLuint id, GLsizei length, const char *message);
+    void pushDebugGroup(GLenum source, GLuint id, const std::string &message);
     void popDebugGroup();
 
     std::string getVendorString() const;
diff --git a/src/libANGLE/renderer/null/ContextNULL.cpp b/src/libANGLE/renderer/null/ContextNULL.cpp
index dfbd69a..86fd9c5 100644
--- a/src/libANGLE/renderer/null/ContextNULL.cpp
+++ b/src/libANGLE/renderer/null/ContextNULL.cpp
@@ -266,7 +266,7 @@
 
 void ContextNULL::popGroupMarker() {}
 
-void ContextNULL::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const char *message) {}
+void ContextNULL::pushDebugGroup(GLenum source, GLuint id, const std::string &message) {}
 
 void ContextNULL::popDebugGroup() {}
 
diff --git a/src/libANGLE/renderer/null/ContextNULL.h b/src/libANGLE/renderer/null/ContextNULL.h
index a369e4c..0d963ea 100644
--- a/src/libANGLE/renderer/null/ContextNULL.h
+++ b/src/libANGLE/renderer/null/ContextNULL.h
@@ -140,7 +140,7 @@
     void popGroupMarker() override;
 
     // KHR_debug
-    void pushDebugGroup(GLenum source, GLuint id, GLsizei length, const char *message) override;
+    void pushDebugGroup(GLenum source, GLuint id, const std::string &message) override;
     void popDebugGroup() override;
 
     // State sync with dirty bits.
diff --git a/src/libANGLE/renderer/vulkan/CommandGraph.cpp b/src/libANGLE/renderer/vulkan/CommandGraph.cpp
index 2aef407..5f6892b 100644
--- a/src/libANGLE/renderer/vulkan/CommandGraph.cpp
+++ b/src/libANGLE/renderer/vulkan/CommandGraph.cpp
@@ -85,11 +85,45 @@
                     UNREACHABLE();
                     return "FenceSync";
             }
+        case CommandGraphResourceType::DebugMarker:
+            switch (function)
+            {
+                case CommandGraphNodeFunction::InsertDebugMarker:
+                    return "InsertDebugMarker";
+                case CommandGraphNodeFunction::PushDebugMarker:
+                    return "PushDebugMarker";
+                case CommandGraphNodeFunction::PopDebugMarker:
+                    return "PopDebugMarker";
+                default:
+                    UNREACHABLE();
+                    return "DebugMarker";
+            }
         default:
             UNREACHABLE();
             return "";
     }
 }
+
+void MakeDebugUtilsLabel(GLenum source, const char *marker, VkDebugUtilsLabelEXT *label)
+{
+    static constexpr angle::ColorF kLabelColors[6] = {
+        angle::ColorF(1.0f, 0.5f, 0.5f, 1.0f),  // DEBUG_SOURCE_API
+        angle::ColorF(0.5f, 1.0f, 0.5f, 1.0f),  // DEBUG_SOURCE_WINDOW_SYSTEM
+        angle::ColorF(0.5f, 0.5f, 1.0f, 1.0f),  // DEBUG_SOURCE_SHADER_COMPILER
+        angle::ColorF(0.7f, 0.7f, 0.7f, 1.0f),  // DEBUG_SOURCE_THIRD_PARTY
+        angle::ColorF(0.5f, 0.8f, 0.9f, 1.0f),  // DEBUG_SOURCE_APPLICATION
+        angle::ColorF(0.9f, 0.8f, 0.5f, 1.0f),  // DEBUG_SOURCE_OTHER
+    };
+
+    int colorIndex = source - GL_DEBUG_SOURCE_API;
+    ASSERT(colorIndex >= 0 && static_cast<size_t>(colorIndex) < ArraySize(kLabelColors));
+
+    label->sType      = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT;
+    label->pNext      = nullptr;
+    label->pLabelName = marker;
+    kLabelColors[colorIndex].writeData(label->color);
+}
+
 }  // anonymous namespace
 
 // CommandGraphResource implementation.
@@ -356,6 +390,14 @@
     mFenceSyncEvent = event.getHandle();
 }
 
+void CommandGraphNode::setDebugMarker(GLenum source, std::string &&marker)
+{
+    ASSERT(mFunction == CommandGraphNodeFunction::InsertDebugMarker ||
+           mFunction == CommandGraphNodeFunction::PushDebugMarker);
+    mDebugMarkerSource = source;
+    mDebugMarker       = std::move(marker);
+}
+
 // Do not call this in anything but testing code, since it's slow.
 bool CommandGraphNode::isChildOf(CommandGraphNode *parent)
 {
@@ -499,6 +541,39 @@
 
             break;
 
+        case CommandGraphNodeFunction::InsertDebugMarker:
+            ASSERT(!mOutsideRenderPassCommands.valid() && !mInsideRenderPassCommands.valid());
+
+            if (vkCmdInsertDebugUtilsLabelEXT)
+            {
+                VkDebugUtilsLabelEXT label;
+                MakeDebugUtilsLabel(mDebugMarkerSource, mDebugMarker.c_str(), &label);
+
+                vkCmdInsertDebugUtilsLabelEXT(primaryCommandBuffer->getHandle(), &label);
+            }
+            break;
+
+        case CommandGraphNodeFunction::PushDebugMarker:
+            ASSERT(!mOutsideRenderPassCommands.valid() && !mInsideRenderPassCommands.valid());
+
+            if (vkCmdBeginDebugUtilsLabelEXT)
+            {
+                VkDebugUtilsLabelEXT label;
+                MakeDebugUtilsLabel(mDebugMarkerSource, mDebugMarker.c_str(), &label);
+
+                vkCmdBeginDebugUtilsLabelEXT(primaryCommandBuffer->getHandle(), &label);
+            }
+            break;
+
+        case CommandGraphNodeFunction::PopDebugMarker:
+            ASSERT(!mOutsideRenderPassCommands.valid() && !mInsideRenderPassCommands.valid());
+
+            if (vkCmdEndDebugUtilsLabelEXT)
+            {
+                vkCmdEndDebugUtilsLabelEXT(primaryCommandBuffer->getHandle());
+            }
+            break;
+
         default:
             UNREACHABLE();
     }
@@ -712,6 +787,26 @@
     newNode->setFenceSync(event);
 }
 
+void CommandGraph::insertDebugMarker(GLenum source, std::string &&marker)
+{
+    CommandGraphNode *newNode = allocateBarrierNode(CommandGraphResourceType::DebugMarker,
+                                                    CommandGraphNodeFunction::InsertDebugMarker);
+    newNode->setDebugMarker(source, std::move(marker));
+}
+
+void CommandGraph::pushDebugMarker(GLenum source, std::string &&marker)
+{
+    CommandGraphNode *newNode = allocateBarrierNode(CommandGraphResourceType::DebugMarker,
+                                                    CommandGraphNodeFunction::PushDebugMarker);
+    newNode->setDebugMarker(source, std::move(marker));
+}
+
+void CommandGraph::popDebugMarker()
+{
+    allocateBarrierNode(CommandGraphResourceType::DebugMarker,
+                        CommandGraphNodeFunction::PopDebugMarker);
+}
+
 // Dumps the command graph into a dot file that works with graphviz.
 void CommandGraph::dumpGraphDotFile(std::ostream &out) const
 {
@@ -739,38 +834,53 @@
 
         std::stringstream strstr;
         strstr << GetResourceTypeName(node->getResourceTypeForDiagnostics(), node->getFunction());
-        strstr << " ";
 
-        auto it = objectIDMap.find(node->getResourceIDForDiagnostics());
-        if (it != objectIDMap.end())
+        if (node->getResourceTypeForDiagnostics() == CommandGraphResourceType::DebugMarker)
         {
-            strstr << it->second;
+            // For debug markers, use the string from the debug marker itself.
+            if (node->getFunction() != CommandGraphNodeFunction::PopDebugMarker)
+            {
+                strstr << " " << node->getDebugMarker();
+            }
         }
         else
         {
-            int id = 0;
+            strstr << " ";
 
-            switch (node->getResourceTypeForDiagnostics())
+            // Otherwise assign each object an ID, so all the nodes of the same object have the same
+            // label.
+            ASSERT(node->getResourceIDForDiagnostics() != 0);
+            auto it = objectIDMap.find(node->getResourceIDForDiagnostics());
+            if (it != objectIDMap.end())
             {
-                case CommandGraphResourceType::Buffer:
-                    id = bufferIDCounter++;
-                    break;
-                case CommandGraphResourceType::Framebuffer:
-                    id = framebufferIDCounter++;
-                    break;
-                case CommandGraphResourceType::Image:
-                    id = imageIDCounter++;
-                    break;
-                case CommandGraphResourceType::Query:
-                    id = queryIDCounter++;
-                    break;
-                default:
-                    UNREACHABLE();
-                    break;
+                strstr << it->second;
             }
+            else
+            {
+                int id = 0;
 
-            objectIDMap[node->getResourceIDForDiagnostics()] = id;
-            strstr << id;
+                switch (node->getResourceTypeForDiagnostics())
+                {
+                    case CommandGraphResourceType::Buffer:
+                        id = bufferIDCounter++;
+                        break;
+                    case CommandGraphResourceType::Framebuffer:
+                        id = framebufferIDCounter++;
+                        break;
+                    case CommandGraphResourceType::Image:
+                        id = imageIDCounter++;
+                        break;
+                    case CommandGraphResourceType::Query:
+                        id = queryIDCounter++;
+                        break;
+                    default:
+                        UNREACHABLE();
+                        break;
+                }
+
+                objectIDMap[node->getResourceIDForDiagnostics()] = id;
+                strstr << id;
+            }
         }
 
         const std::string &label = strstr.str();
diff --git a/src/libANGLE/renderer/vulkan/CommandGraph.h b/src/libANGLE/renderer/vulkan/CommandGraph.h
index 14cf9c9..adf1993 100644
--- a/src/libANGLE/renderer/vulkan/CommandGraph.h
+++ b/src/libANGLE/renderer/vulkan/CommandGraph.h
@@ -31,6 +31,7 @@
     Image,
     Query,
     FenceSync,
+    DebugMarker,
 };
 
 // Certain functionality cannot be put in secondary command buffers, so they are special-cased in
@@ -43,6 +44,9 @@
     WriteTimestamp,
     SetFenceSync,
     WaitFenceSync,
+    InsertDebugMarker,
+    PushDebugMarker,
+    PopDebugMarker,
 };
 
 // Receives notifications when a command buffer is no longer able to record. Can be used with
@@ -131,6 +135,8 @@
 
     void setQueryPool(const QueryPool *queryPool, uint32_t queryIndex);
     void setFenceSync(const vk::Event &event);
+    void setDebugMarker(GLenum source, std::string &&marker);
+    const std::string &getDebugMarker() const { return mDebugMarker; }
 
     ANGLE_INLINE void addGlobalMemoryBarrier(VkFlags srcAccess, VkFlags dstAccess)
     {
@@ -177,6 +183,9 @@
     uint32_t mQueryIndex;
     // GLsync and EGLSync:
     VkEvent mFenceSyncEvent;
+    // Debug markers:
+    GLenum mDebugMarkerSource;
+    std::string mDebugMarker;
 
     // Parents are commands that must be submitted before 'this' CommandNode can be submitted.
     std::vector<CommandGraphNode *> mParents;
@@ -369,6 +378,10 @@
     // GLsync and EGLSync:
     void setFenceSync(const vk::Event &event);
     void waitFenceSync(const vk::Event &event);
+    // Debug markers:
+    void insertDebugMarker(GLenum source, std::string &&marker);
+    void pushDebugMarker(GLenum source, std::string &&marker);
+    void popDebugMarker();
 
   private:
     CommandGraphNode *allocateBarrierNode(CommandGraphResourceType resourceType,
diff --git a/src/libANGLE/renderer/vulkan/ContextVk.cpp b/src/libANGLE/renderer/vulkan/ContextVk.cpp
index a10c7b3..c2ab5fb 100644
--- a/src/libANGLE/renderer/vulkan/ContextVk.cpp
+++ b/src/libANGLE/renderer/vulkan/ContextVk.cpp
@@ -586,27 +586,31 @@
 
 void ContextVk::insertEventMarker(GLsizei length, const char *marker)
 {
-    // TODO: Forward this to a Vulkan debug marker.  http://anglebug.com/2853
+    std::string markerStr(marker, length <= 0 ? strlen(marker) : length);
+    mRenderer->insertDebugMarker(GL_DEBUG_SOURCE_APPLICATION, static_cast<GLuint>(-1),
+                                 std::move(markerStr));
 }
 
 void ContextVk::pushGroupMarker(GLsizei length, const char *marker)
 {
-    // TODO: Forward this to a Vulkan debug marker.  http://anglebug.com/2853
+    std::string markerStr(marker, length <= 0 ? strlen(marker) : length);
+    mRenderer->pushDebugMarker(GL_DEBUG_SOURCE_APPLICATION, static_cast<GLuint>(-1),
+                               std::move(markerStr));
 }
 
 void ContextVk::popGroupMarker()
 {
-    // TODO: Forward this to a Vulkan debug marker.  http://anglebug.com/2853
+    mRenderer->popDebugMarker();
 }
 
-void ContextVk::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const char *message)
+void ContextVk::pushDebugGroup(GLenum source, GLuint id, const std::string &message)
 {
-    // TODO: Forward this to a Vulkan debug marker.  http://anglebug.com/2853
+    mRenderer->pushDebugMarker(source, id, std::string(message));
 }
 
 void ContextVk::popDebugGroup()
 {
-    // TODO: Forward this to a Vulkan debug marker.  http://anglebug.com/2853
+    mRenderer->popDebugMarker();
 }
 
 bool ContextVk::isViewportFlipEnabledForDrawFBO() const
diff --git a/src/libANGLE/renderer/vulkan/ContextVk.h b/src/libANGLE/renderer/vulkan/ContextVk.h
index ade7494..05a8df6 100644
--- a/src/libANGLE/renderer/vulkan/ContextVk.h
+++ b/src/libANGLE/renderer/vulkan/ContextVk.h
@@ -90,7 +90,7 @@
     void popGroupMarker() override;
 
     // KHR_debug
-    void pushDebugGroup(GLenum source, GLuint id, GLsizei length, const char *message) override;
+    void pushDebugGroup(GLenum source, GLuint id, const std::string &message) override;
     void popDebugGroup() override;
 
     bool isViewportFlipEnabledForDrawFBO() const;
diff --git a/src/libANGLE/renderer/vulkan/RendererVk.cpp b/src/libANGLE/renderer/vulkan/RendererVk.cpp
index 75e5bf1..177c2f3 100644
--- a/src/libANGLE/renderer/vulkan/RendererVk.cpp
+++ b/src/libANGLE/renderer/vulkan/RendererVk.cpp
@@ -220,16 +220,6 @@
                     const VkDebugUtilsMessengerCallbackDataEXT *callbackData,
                     void *userData)
 {
-    constexpr VkDebugUtilsMessageSeverityFlagsEXT kSeveritiesToLog =
-        VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT |
-        VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT;
-
-    // Check if we even care about this message.
-    if ((messageSeverity & kSeveritiesToLog) == 0)
-    {
-        return VK_FALSE;
-    }
-
     // See if it's an issue we are aware of and don't want to be spammed about.
     if (IsIgnoredDebugMessage(callbackData->pMessageIdName))
     {
@@ -753,12 +743,18 @@
         // Create the messenger callback.
         VkDebugUtilsMessengerCreateInfoEXT messengerInfo = {};
 
+        constexpr VkDebugUtilsMessageSeverityFlagsEXT kSeveritiesToLog =
+            VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT |
+            VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT;
+
+        constexpr VkDebugUtilsMessageTypeFlagsEXT kMessagesToLog =
+            VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
+            VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
+            VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
+
         messengerInfo.sType           = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
-        messengerInfo.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT |
-                                        VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT;
-        messengerInfo.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
-                                    VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
-                                    VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
+        messengerInfo.messageSeverity = kSeveritiesToLog;
+        messengerInfo.messageType     = kMessagesToLog;
         messengerInfo.pfnUserCallback = &DebugUtilsMessenger;
         messengerInfo.pUserData       = this;
 
@@ -1834,6 +1830,21 @@
     return hasFormatFeatureBits<&VkFormatProperties::bufferFeatures>(format, featureBits);
 }
 
+void RendererVk::insertDebugMarker(GLenum source, GLuint id, std::string &&marker)
+{
+    mCommandGraph.insertDebugMarker(source, std::move(marker));
+}
+
+void RendererVk::pushDebugMarker(GLenum source, GLuint id, std::string &&marker)
+{
+    mCommandGraph.pushDebugMarker(source, std::move(marker));
+}
+
+void RendererVk::popDebugMarker()
+{
+    mCommandGraph.popDebugMarker();
+}
+
 angle::Result RendererVk::synchronizeCpuGpuTime(vk::Context *context)
 {
     ASSERT(mGpuEventsEnabled);
diff --git a/src/libANGLE/renderer/vulkan/RendererVk.h b/src/libANGLE/renderer/vulkan/RendererVk.h
index 6651bdd..8b85822 100644
--- a/src/libANGLE/renderer/vulkan/RendererVk.h
+++ b/src/libANGLE/renderer/vulkan/RendererVk.h
@@ -205,6 +205,10 @@
     bool hasTextureFormatFeatureBits(VkFormat format, const VkFormatFeatureFlags featureBits);
     bool hasBufferFormatFeatureBits(VkFormat format, const VkFormatFeatureFlags featureBits);
 
+    void insertDebugMarker(GLenum source, GLuint id, std::string &&marker);
+    void pushDebugMarker(GLenum source, GLuint id, std::string &&marker);
+    void popDebugMarker();
+
     static constexpr size_t kMaxExtensionNames = 200;
     using ExtensionNameList = angle::FixedVector<const char *, kMaxExtensionNames>;
 
diff --git a/src/libANGLE/renderer/vulkan/vk_utils.cpp b/src/libANGLE/renderer/vulkan/vk_utils.cpp
index 3562f5b..4b30489 100644
--- a/src/libANGLE/renderer/vulkan/vk_utils.cpp
+++ b/src/libANGLE/renderer/vulkan/vk_utils.cpp
@@ -510,6 +510,9 @@
 // VK_EXT_debug_utils
 PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT   = nullptr;
 PFN_vkDestroyDebugUtilsMessengerEXT vkDestroyDebugUtilsMessengerEXT = nullptr;
+PFN_vkCmdBeginDebugUtilsLabelEXT vkCmdBeginDebugUtilsLabelEXT       = nullptr;
+PFN_vkCmdEndDebugUtilsLabelEXT vkCmdEndDebugUtilsLabelEXT           = nullptr;
+PFN_vkCmdInsertDebugUtilsLabelEXT vkCmdInsertDebugUtilsLabelEXT     = nullptr;
 
 // VK_EXT_debug_report
 PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT   = nullptr;
@@ -534,6 +537,9 @@
 {
     GET_FUNC(vkCreateDebugUtilsMessengerEXT);
     GET_FUNC(vkDestroyDebugUtilsMessengerEXT);
+    GET_FUNC(vkCmdBeginDebugUtilsLabelEXT);
+    GET_FUNC(vkCmdEndDebugUtilsLabelEXT);
+    GET_FUNC(vkCmdInsertDebugUtilsLabelEXT);
 }
 
 void InitDebugReportEXTFunctions(VkInstance instance)
diff --git a/src/libANGLE/renderer/vulkan/vk_utils.h b/src/libANGLE/renderer/vulkan/vk_utils.h
index b3e6826..9e553ad 100644
--- a/src/libANGLE/renderer/vulkan/vk_utils.h
+++ b/src/libANGLE/renderer/vulkan/vk_utils.h
@@ -390,6 +390,9 @@
 // VK_EXT_debug_utils
 extern PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT;
 extern PFN_vkDestroyDebugUtilsMessengerEXT vkDestroyDebugUtilsMessengerEXT;
+extern PFN_vkCmdBeginDebugUtilsLabelEXT vkCmdBeginDebugUtilsLabelEXT;
+extern PFN_vkCmdEndDebugUtilsLabelEXT vkCmdEndDebugUtilsLabelEXT;
+extern PFN_vkCmdInsertDebugUtilsLabelEXT vkCmdInsertDebugUtilsLabelEXT;
 
 // VK_EXT_debug_report
 extern PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT;