Implementation of Debug Marker APIs

Introduces pushDebugGroup, popDebugGroup, and insertDebugMarker implementations
for Vulkan and Metal using VK_EXT_debug_marker and XCode, respectively.

Bug: dawn:44
Change-Id: I0ae56c4d67aa832123f27a1fcdddf65746261e57
Reviewed-on: https://dawn-review.googlesource.com/c/4241
Commit-Queue: Brandon Jones <brandon1.jones@intel.com>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
diff --git a/src/dawn_native/CommandEncoder.cpp b/src/dawn_native/CommandEncoder.cpp
index 7a5c81d..2498820 100644
--- a/src/dawn_native/CommandEncoder.cpp
+++ b/src/dawn_native/CommandEncoder.cpp
@@ -94,6 +94,29 @@
             return {};
         }
 
+        inline MaybeError PushDebugMarkerStack(unsigned int* counter) {
+            *counter += 1;
+            return {};
+        }
+
+        inline MaybeError PopDebugMarkerStack(unsigned int* counter) {
+            if (*counter == 0) {
+                return DAWN_VALIDATION_ERROR("Pop must be balanced by a corresponding Push.");
+            } else {
+                *counter -= 1;
+            }
+
+            return {};
+        }
+
+        inline MaybeError ValidateDebugGroups(const unsigned int counter) {
+            if (counter != 0) {
+                return DAWN_VALIDATION_ERROR("Each Push must be balanced by a corresponding Pop.");
+            }
+
+            return {};
+        }
+
         MaybeError ComputeTextureCopyBufferSize(const Extent3D& copySize,
                                                 uint32_t rowPitch,
                                                 uint32_t imageHeight,
@@ -635,6 +658,8 @@
                 case Command::EndComputePass: {
                     mIterator.NextCommand<EndComputePassCmd>();
 
+                    DAWN_TRY(ValidateDebugGroups(mDebugGroupStackSize));
+
                     DAWN_TRY(usageTracker.ValidateUsages(PassType::Compute));
                     mResourceUsages.perPass.push_back(usageTracker.AcquireResourceUsage());
                     return {};
@@ -645,6 +670,22 @@
                     DAWN_TRY(persistentState.ValidateCanDispatch());
                 } break;
 
+                case Command::InsertDebugMarker: {
+                    InsertDebugMarkerCmd* cmd = mIterator.NextCommand<InsertDebugMarkerCmd>();
+                    mIterator.NextData<char>(cmd->length + 1);
+                } break;
+
+                case Command::PopDebugGroup: {
+                    mIterator.NextCommand<PopDebugGroupCmd>();
+                    DAWN_TRY(PopDebugMarkerStack(&mDebugGroupStackSize));
+                } break;
+
+                case Command::PushDebugGroup: {
+                    PushDebugGroupCmd* cmd = mIterator.NextCommand<PushDebugGroupCmd>();
+                    mIterator.NextData<char>(cmd->length + 1);
+                    DAWN_TRY(PushDebugMarkerStack(&mDebugGroupStackSize));
+                } break;
+
                 case Command::SetComputePipeline: {
                     SetComputePipelineCmd* cmd = mIterator.NextCommand<SetComputePipelineCmd>();
                     ComputePipelineBase* pipeline = cmd->pipeline.Get();
@@ -701,6 +742,8 @@
                 case Command::EndRenderPass: {
                     mIterator.NextCommand<EndRenderPassCmd>();
 
+                    DAWN_TRY(ValidateDebugGroups(mDebugGroupStackSize));
+
                     DAWN_TRY(usageTracker.ValidateUsages(PassType::Render));
                     mResourceUsages.perPass.push_back(usageTracker.AcquireResourceUsage());
                     return {};
@@ -716,6 +759,22 @@
                     DAWN_TRY(persistentState.ValidateCanDrawIndexed());
                 } break;
 
+                case Command::InsertDebugMarker: {
+                    InsertDebugMarkerCmd* cmd = mIterator.NextCommand<InsertDebugMarkerCmd>();
+                    mIterator.NextData<char>(cmd->length + 1);
+                } break;
+
+                case Command::PopDebugGroup: {
+                    mIterator.NextCommand<PopDebugGroupCmd>();
+                    DAWN_TRY(PopDebugMarkerStack(&mDebugGroupStackSize));
+                } break;
+
+                case Command::PushDebugGroup: {
+                    PushDebugGroupCmd* cmd = mIterator.NextCommand<PushDebugGroupCmd>();
+                    mIterator.NextData<char>(cmd->length + 1);
+                    DAWN_TRY(PushDebugMarkerStack(&mDebugGroupStackSize));
+                } break;
+
                 case Command::SetRenderPipeline: {
                     SetRenderPipelineCmd* cmd = mIterator.NextCommand<SetRenderPipelineCmd>();
                     RenderPipelineBase* pipeline = cmd->pipeline.Get();