Add Debug Label Functionality For D3D12/Vk Buffers & Textures

Adds a generic SetDebugName utility for D3D12 and Vulkan. Passes down
debug label set by user for buffers and textures to be labeled by the
appropriate backend method.

Bug: dawn:840
Change-Id: I7158b537a6e37fdf733645e6830dc33833ee683e
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/61588
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Brandon Jones (Intel) <brandon1.jones@intel.com>
diff --git a/src/dawn_native/vulkan/BufferVk.cpp b/src/dawn_native/vulkan/BufferVk.cpp
index 8139b29..75a32fd 100644
--- a/src/dawn_native/vulkan/BufferVk.cpp
+++ b/src/dawn_native/vulkan/BufferVk.cpp
@@ -19,6 +19,7 @@
 #include "dawn_native/vulkan/FencedDeleter.h"
 #include "dawn_native/vulkan/ResourceHeapVk.h"
 #include "dawn_native/vulkan/ResourceMemoryAllocatorVk.h"
+#include "dawn_native/vulkan/UtilsVulkan.h"
 #include "dawn_native/vulkan/VulkanError.h"
 
 #include <cstring>
@@ -229,6 +230,9 @@
                 ClearBuffer(recordingContext, 0, clearOffset, clearSize);
             }
         }
+
+        SetLabelImpl();
+
         return {};
     }
 
@@ -374,6 +378,11 @@
         }
     }
 
+    void Buffer::SetLabelImpl() {
+        SetDebugName(ToBackend(GetDevice()), VK_OBJECT_TYPE_BUFFER,
+                     reinterpret_cast<uint64_t&>(mHandle), "Dawn_Buffer", GetLabel());
+    }
+
     void Buffer::InitializeToZero(CommandRecordingContext* recordingContext) {
         ASSERT(GetDevice()->IsToggleEnabled(Toggle::LazyClearResourceOnFirstUse));
         ASSERT(!IsDataInitialized());
diff --git a/src/dawn_native/vulkan/BufferVk.h b/src/dawn_native/vulkan/BufferVk.h
index 1c40140..3fcab60 100644
--- a/src/dawn_native/vulkan/BufferVk.h
+++ b/src/dawn_native/vulkan/BufferVk.h
@@ -49,6 +49,9 @@
         void EnsureDataInitializedAsDestination(CommandRecordingContext* recordingContext,
                                                 const CopyTextureToBufferCmd* copy);
 
+        // Dawn API
+        void SetLabelImpl() override;
+
       private:
         ~Buffer() override;
         using BufferBase::BufferBase;
diff --git a/src/dawn_native/vulkan/StagingBufferVk.cpp b/src/dawn_native/vulkan/StagingBufferVk.cpp
index cf3129c..c78f0fc 100644
--- a/src/dawn_native/vulkan/StagingBufferVk.cpp
+++ b/src/dawn_native/vulkan/StagingBufferVk.cpp
@@ -17,6 +17,7 @@
 #include "dawn_native/vulkan/FencedDeleter.h"
 #include "dawn_native/vulkan/ResourceHeapVk.h"
 #include "dawn_native/vulkan/ResourceMemoryAllocatorVk.h"
+#include "dawn_native/vulkan/UtilsVulkan.h"
 #include "dawn_native/vulkan/VulkanError.h"
 
 namespace dawn_native { namespace vulkan {
@@ -57,6 +58,9 @@
             return DAWN_INTERNAL_ERROR("Unable to map staging buffer.");
         }
 
+        SetDebugName(mDevice, VK_OBJECT_TYPE_BUFFER, reinterpret_cast<uint64_t&>(mBuffer),
+                     "Dawn_StagingBuffer");
+
         return {};
     }
 
diff --git a/src/dawn_native/vulkan/TextureVk.cpp b/src/dawn_native/vulkan/TextureVk.cpp
index cbb2f2ce..f4be49a 100644
--- a/src/dawn_native/vulkan/TextureVk.cpp
+++ b/src/dawn_native/vulkan/TextureVk.cpp
@@ -577,6 +577,8 @@
                                   GetAllSubresources(), TextureBase::ClearValue::NonZero));
         }
 
+        SetLabelImpl();
+
         return {};
     }
 
@@ -611,11 +613,15 @@
         baseCreateInfo.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
 
         DAWN_TRY_ASSIGN(mHandle, externalMemoryService->CreateImage(descriptor, baseCreateInfo));
+
+        SetLabelHelper("Dawn_ExternalTexture");
+
         return {};
     }
 
     void Texture::InitializeForSwapChain(VkImage nativeImage) {
         mHandle = nativeImage;
+        SetLabelHelper("Dawn_SwapChainTexture");
     }
 
     MaybeError Texture::BindExternalMemory(const ExternalImageDescriptorVk* descriptor,
@@ -720,6 +726,15 @@
         DestroyInternal();
     }
 
+    void Texture::SetLabelHelper(const char* prefix) {
+        SetDebugName(ToBackend(GetDevice()), VK_OBJECT_TYPE_IMAGE,
+                     reinterpret_cast<uint64_t&>(mHandle), prefix, GetLabel());
+    }
+
+    void Texture::SetLabelImpl() {
+        SetLabelHelper("Dawn_InternalTexture");
+    }
+
     void Texture::DestroyImpl() {
         if (GetTextureState() == TextureState::OwnedInternal) {
             Device* device = ToBackend(GetDevice());
diff --git a/src/dawn_native/vulkan/TextureVk.h b/src/dawn_native/vulkan/TextureVk.h
index e985c55..779d51b 100644
--- a/src/dawn_native/vulkan/TextureVk.h
+++ b/src/dawn_native/vulkan/TextureVk.h
@@ -93,6 +93,11 @@
                                          VkImageLayout* releasedOldLayout,
                                          VkImageLayout* releasedNewLayout);
 
+        void SetLabelHelper(const char* prefix);
+
+        // Dawn API
+        void SetLabelImpl() override;
+
       private:
         ~Texture() override;
         Texture(Device* device, const TextureDescriptor* descriptor, TextureState state);
diff --git a/src/dawn_native/vulkan/UtilsVulkan.cpp b/src/dawn_native/vulkan/UtilsVulkan.cpp
index c6952d4..eb46180 100644
--- a/src/dawn_native/vulkan/UtilsVulkan.cpp
+++ b/src/dawn_native/vulkan/UtilsVulkan.cpp
@@ -17,8 +17,10 @@
 #include "common/Assert.h"
 #include "dawn_native/EnumMaskIterator.h"
 #include "dawn_native/Format.h"
+#include "dawn_native/vulkan/DeviceVk.h"
 #include "dawn_native/vulkan/Forward.h"
 #include "dawn_native/vulkan/TextureVk.h"
+#include "dawn_native/vulkan/VulkanError.h"
 
 namespace dawn_native { namespace vulkan {
 
@@ -162,4 +164,30 @@
 
         return region;
     }
+
+    void SetDebugName(Device* device,
+                      VkObjectType objectType,
+                      uint64_t objectHandle,
+                      const char* prefix,
+                      std::string label) {
+        if (device->GetGlobalInfo().HasExt(InstanceExt::DebugUtils)) {
+            VkDebugUtilsObjectNameInfoEXT objectNameInfo;
+            objectNameInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
+            objectNameInfo.pNext = nullptr;
+            objectNameInfo.objectType = objectType;
+            objectNameInfo.objectHandle = objectHandle;
+
+            if (label.empty() || !device->IsToggleEnabled(Toggle::UseUserDefinedLabelsInBackend)) {
+                objectNameInfo.pObjectName = prefix;
+                device->fn.SetDebugUtilsObjectNameEXT(device->GetVkDevice(), &objectNameInfo);
+                return;
+            }
+
+            std::string objectName = prefix;
+            objectName += "_";
+            objectName += label;
+            objectNameInfo.pObjectName = objectName.c_str();
+            device->fn.SetDebugUtilsObjectNameEXT(device->GetVkDevice(), &objectNameInfo);
+        }
+    }
 }}  // namespace dawn_native::vulkan
diff --git a/src/dawn_native/vulkan/UtilsVulkan.h b/src/dawn_native/vulkan/UtilsVulkan.h
index e57e3f4..23c36a9 100644
--- a/src/dawn_native/vulkan/UtilsVulkan.h
+++ b/src/dawn_native/vulkan/UtilsVulkan.h
@@ -21,6 +21,8 @@
 
 namespace dawn_native { namespace vulkan {
 
+    class Device;
+
     // A Helper type used to build a pNext chain of extension structs.
     // Usage is:
     //   1) Create instance, passing the address of the first struct in the
@@ -99,6 +101,12 @@
                                                    const TextureCopy& textureCopy,
                                                    const Extent3D& copySize);
 
+    void SetDebugName(Device* device,
+                      VkObjectType objectType,
+                      uint64_t objectHandle,
+                      const char* prefix,
+                      std::string label = "");
+
 }}  // namespace dawn_native::vulkan
 
 #endif  // DAWNNATIVE_VULKAN_UTILSVULKAN_H_