Title: [291386] trunk/Source/WebGPU
Revision
291386
Author
mmaxfi...@apple.com
Date
2022-03-16 20:37:11 -0700 (Wed, 16 Mar 2022)

Log Message

[WebGPU] Implement first draft of debug commands according to the spec
https://bugs.webkit.org/show_bug.cgi?id=237879

Reviewed by Kimmo Kinnunen.

Implement insertDebugMarker(), pushDebugGroup(), and popDebugGroup() according to
the algorithms in the spec. There are a few things which the spec lists which we
can't do yet (like making objects invalid), so those things are left with FIXMEs.
Every step is listed with links to the spec where appropriate, and with quotes to
the spec describing what is being implemented. Also, because each class handles
these debug commands slightly differently (CommandEncoders support debug groups
but not debug markers; RenderBundles don't support any of them, and
ComputeEncoders support all of them) I opted to not try to do any code sharing.

* WebGPU/CommandEncoder.h:
* WebGPU/CommandEncoder.mm:
(WebGPU::CommandEncoder::insertDebugMarker):
(WebGPU::CommandEncoder::validatePopDebugGroup const):
(WebGPU::CommandEncoder::popDebugGroup):
(WebGPU::CommandEncoder::pushDebugGroup):
* WebGPU/ComputePassEncoder.h:
* WebGPU/ComputePassEncoder.mm:
(WebGPU::ComputePassEncoder::insertDebugMarker):
(WebGPU::ComputePassEncoder::validatePopDebugGroup const):
(WebGPU::ComputePassEncoder::popDebugGroup):
(WebGPU::ComputePassEncoder::pushDebugGroup):
* WebGPU/RenderBundleEncoder.h:
* WebGPU/RenderBundleEncoder.mm:
(WebGPU::RenderBundleEncoder::insertDebugMarker):
(WebGPU::RenderBundleEncoder::validatePopDebugGroup const):
(WebGPU::RenderBundleEncoder::popDebugGroup):
(WebGPU::RenderBundleEncoder::pushDebugGroup):
* WebGPU/RenderPassEncoder.h:
* WebGPU/RenderPassEncoder.mm:
(WebGPU::RenderPassEncoder::insertDebugMarker):
(WebGPU::RenderPassEncoder::validatePopDebugGroup const):
(WebGPU::RenderPassEncoder::popDebugGroup):
(WebGPU::RenderPassEncoder::pushDebugGroup):

Modified Paths

Diff

Modified: trunk/Source/WebGPU/ChangeLog (291385 => 291386)


--- trunk/Source/WebGPU/ChangeLog	2022-03-17 03:06:12 UTC (rev 291385)
+++ trunk/Source/WebGPU/ChangeLog	2022-03-17 03:37:11 UTC (rev 291386)
@@ -1,5 +1,46 @@
 2022-03-16  Myles C. Maxfield  <mmaxfi...@apple.com>
 
+        [WebGPU] Implement first draft of debug commands according to the spec
+        https://bugs.webkit.org/show_bug.cgi?id=237879
+
+        Reviewed by Kimmo Kinnunen.
+
+        Implement insertDebugMarker(), pushDebugGroup(), and popDebugGroup() according to
+        the algorithms in the spec. There are a few things which the spec lists which we
+        can't do yet (like making objects invalid), so those things are left with FIXMEs.
+        Every step is listed with links to the spec where appropriate, and with quotes to
+        the spec describing what is being implemented. Also, because each class handles
+        these debug commands slightly differently (CommandEncoders support debug groups
+        but not debug markers; RenderBundles don't support any of them, and
+        ComputeEncoders support all of them) I opted to not try to do any code sharing.
+
+        * WebGPU/CommandEncoder.h:
+        * WebGPU/CommandEncoder.mm:
+        (WebGPU::CommandEncoder::insertDebugMarker):
+        (WebGPU::CommandEncoder::validatePopDebugGroup const):
+        (WebGPU::CommandEncoder::popDebugGroup):
+        (WebGPU::CommandEncoder::pushDebugGroup):
+        * WebGPU/ComputePassEncoder.h:
+        * WebGPU/ComputePassEncoder.mm:
+        (WebGPU::ComputePassEncoder::insertDebugMarker):
+        (WebGPU::ComputePassEncoder::validatePopDebugGroup const):
+        (WebGPU::ComputePassEncoder::popDebugGroup):
+        (WebGPU::ComputePassEncoder::pushDebugGroup):
+        * WebGPU/RenderBundleEncoder.h:
+        * WebGPU/RenderBundleEncoder.mm:
+        (WebGPU::RenderBundleEncoder::insertDebugMarker):
+        (WebGPU::RenderBundleEncoder::validatePopDebugGroup const):
+        (WebGPU::RenderBundleEncoder::popDebugGroup):
+        (WebGPU::RenderBundleEncoder::pushDebugGroup):
+        * WebGPU/RenderPassEncoder.h:
+        * WebGPU/RenderPassEncoder.mm:
+        (WebGPU::RenderPassEncoder::insertDebugMarker):
+        (WebGPU::RenderPassEncoder::validatePopDebugGroup const):
+        (WebGPU::RenderPassEncoder::popDebugGroup):
+        (WebGPU::RenderPassEncoder::pushDebugGroup):
+
+2022-03-16  Myles C. Maxfield  <mmaxfi...@apple.com>
+
         [WebGPU] Implement first draft of CommandEncoder::clearBuffer() according to the spec
         https://bugs.webkit.org/show_bug.cgi?id=237877
 

Modified: trunk/Source/WebGPU/WebGPU/CommandEncoder.h (291385 => 291386)


--- trunk/Source/WebGPU/WebGPU/CommandEncoder.h	2022-03-17 03:06:12 UTC (rev 291385)
+++ trunk/Source/WebGPU/WebGPU/CommandEncoder.h	2022-03-17 03:37:11 UTC (rev 291386)
@@ -67,6 +67,7 @@
     CommandEncoder(id<MTLCommandBuffer>);
 
     bool validateFinish() const;
+    bool validatePopDebugGroup() const;
 
     void ensureBlitCommandEncoder();
     void finalizeBlitCommandEncoder();
@@ -73,6 +74,8 @@
 
     id<MTLCommandBuffer> m_commandBuffer { nil };
     id<MTLBlitCommandEncoder> m_blitCommandEncoder { nil };
+
+    uint64_t m_debugGroupStackSize { 0 };
 };
 
 } // namespace WebGPU

Modified: trunk/Source/WebGPU/WebGPU/CommandEncoder.mm (291385 => 291386)


--- trunk/Source/WebGPU/WebGPU/CommandEncoder.mm	2022-03-17 03:06:12 UTC (rev 291385)
+++ trunk/Source/WebGPU/WebGPU/CommandEncoder.mm	2022-03-17 03:37:11 UTC (rev 291386)
@@ -273,16 +273,62 @@
 
 void CommandEncoder::insertDebugMarker(String&& markerLabel)
 {
-    UNUSED_PARAM(markerLabel);
+    // https://gpuweb.github.io/gpuweb/#dom-gpudebugcommandsmixin-insertdebugmarker
+
+    // "Prepare the encoder state of this. If it returns false, stop."
+    if (!prepareTheEncoderState())
+        return;
+
+    finalizeBlitCommandEncoder();
+
+    // There's no direct way of doing this, so we just push/pop an empty debug group.
+    [m_commandBuffer pushDebugGroup:markerLabel];
+    [m_commandBuffer popDebugGroup];
 }
 
+bool CommandEncoder::validatePopDebugGroup() const
+{
+    // "this.[[debug_group_stack]] must not be empty."
+    if (!m_debugGroupStackSize)
+        return false;
+
+    return true;
+}
+
 void CommandEncoder::popDebugGroup()
 {
+    // https://gpuweb.github.io/gpuweb/#dom-gpudebugcommandsmixin-popdebuggroup
+
+    // "Prepare the encoder state of this. If it returns false, stop."
+    if (!prepareTheEncoderState())
+        return;
+
+    // "If any of the following requirements are unmet"
+    if (!validatePopDebugGroup()) {
+        // FIXME: "make this invalid, and stop."
+        return;
+    }
+
+    finalizeBlitCommandEncoder();
+
+    // "Pop an entry off of this.[[debug_group_stack]]."
+    --m_debugGroupStackSize;
+    [m_commandBuffer popDebugGroup];
 }
 
 void CommandEncoder::pushDebugGroup(String&& groupLabel)
 {
-    UNUSED_PARAM(groupLabel);
+    // https://gpuweb.github.io/gpuweb/#dom-gpudebugcommandsmixin-pushdebuggroup
+
+    // "Prepare the encoder state of this. If it returns false, stop."
+    if (!prepareTheEncoderState())
+        return;
+    
+    finalizeBlitCommandEncoder();
+
+    // "Push groupLabel onto this.[[debug_group_stack]]."
+    ++m_debugGroupStackSize;
+    [m_commandBuffer pushDebugGroup:groupLabel];
 }
 
 void CommandEncoder::resolveQuerySet(const QuerySet& querySet, uint32_t firstQuery, uint32_t queryCount, const Buffer& destination, uint64_t destinationOffset)

Modified: trunk/Source/WebGPU/WebGPU/ComputePassEncoder.h (291385 => 291386)


--- trunk/Source/WebGPU/WebGPU/ComputePassEncoder.h	2022-03-17 03:06:12 UTC (rev 291385)
+++ trunk/Source/WebGPU/WebGPU/ComputePassEncoder.h	2022-03-17 03:37:11 UTC (rev 291386)
@@ -25,6 +25,7 @@
 
 #pragma once
 
+#import "CommandsMixin.h"
 #import <wtf/FastMalloc.h>
 #import <wtf/Ref.h>
 #import <wtf/RefCounted.h>
@@ -36,7 +37,7 @@
 class ComputePipeline;
 class QuerySet;
 
-class ComputePassEncoder : public RefCounted<ComputePassEncoder> {
+class ComputePassEncoder : public RefCounted<ComputePassEncoder>, public CommandsMixin {
     WTF_MAKE_FAST_ALLOCATED;
 public:
     static Ref<ComputePassEncoder> create(id<MTLComputeCommandEncoder> computeCommandEncoder)
@@ -61,7 +62,11 @@
 private:
     ComputePassEncoder(id<MTLComputeCommandEncoder>);
 
+    bool validatePopDebugGroup() const;
+
     id<MTLComputeCommandEncoder> m_computeCommandEncoder { nil };
+
+    uint64_t m_debugGroupStackSize { 0 };
 };
 
 } // namespace WebGPU

Modified: trunk/Source/WebGPU/WebGPU/ComputePassEncoder.mm (291385 => 291386)


--- trunk/Source/WebGPU/WebGPU/ComputePassEncoder.mm	2022-03-17 03:06:12 UTC (rev 291385)
+++ trunk/Source/WebGPU/WebGPU/ComputePassEncoder.mm	2022-03-17 03:37:11 UTC (rev 291386)
@@ -70,16 +70,54 @@
 
 void ComputePassEncoder::insertDebugMarker(String&& markerLabel)
 {
-    UNUSED_PARAM(markerLabel);
+    // https://gpuweb.github.io/gpuweb/#dom-gpudebugcommandsmixin-insertdebugmarker
+
+    // "Prepare the encoder state of this. If it returns false, stop."
+    if (!prepareTheEncoderState())
+        return;
+
+    [m_computeCommandEncoder insertDebugSignpost:markerLabel];
 }
 
+bool ComputePassEncoder::validatePopDebugGroup() const
+{
+    // "this.[[debug_group_stack]] must not be empty."
+    if (!m_debugGroupStackSize)
+        return false;
+
+    return true;
+}
+
 void ComputePassEncoder::popDebugGroup()
 {
+    // https://gpuweb.github.io/gpuweb/#dom-gpudebugcommandsmixin-popdebuggroup
+
+    // "Prepare the encoder state of this. If it returns false, stop."
+    if (!prepareTheEncoderState())
+        return;
+
+    // "If any of the following requirements are unmet"
+    if (!validatePopDebugGroup()) {
+        // FIXME: "make this invalid, and stop."
+        return;
+    }
+
+    // "Pop an entry off of this.[[debug_group_stack]]."
+    --m_debugGroupStackSize;
+    [m_computeCommandEncoder popDebugGroup];
 }
 
 void ComputePassEncoder::pushDebugGroup(String&& groupLabel)
 {
-    UNUSED_PARAM(groupLabel);
+    // https://gpuweb.github.io/gpuweb/#dom-gpudebugcommandsmixin-pushdebuggroup
+
+    // "Prepare the encoder state of this. If it returns false, stop."
+    if (!prepareTheEncoderState())
+        return;
+
+    // "Push groupLabel onto this.[[debug_group_stack]]."
+    ++m_debugGroupStackSize;
+    [m_computeCommandEncoder pushDebugGroup:groupLabel];
 }
 
 void ComputePassEncoder::setBindGroup(uint32_t groupIndex, const BindGroup& group, uint32_t dynamicOffsetCount, const uint32_t* dynamicOffsets)

Modified: trunk/Source/WebGPU/WebGPU/RenderBundleEncoder.h (291385 => 291386)


--- trunk/Source/WebGPU/WebGPU/RenderBundleEncoder.h	2022-03-17 03:06:12 UTC (rev 291385)
+++ trunk/Source/WebGPU/WebGPU/RenderBundleEncoder.h	2022-03-17 03:37:11 UTC (rev 291386)
@@ -25,6 +25,7 @@
 
 #pragma once
 
+#import "CommandsMixin.h"
 #import <wtf/FastMalloc.h>
 #import <wtf/Ref.h>
 #import <wtf/RefCounted.h>
@@ -37,7 +38,7 @@
 class RenderBundle;
 class RenderPipeline;
 
-class RenderBundleEncoder : public RefCounted<RenderBundleEncoder> {
+class RenderBundleEncoder : public RefCounted<RenderBundleEncoder>, public CommandsMixin {
     WTF_MAKE_FAST_ALLOCATED;
 public:
     static Ref<RenderBundleEncoder> create(id<MTLIndirectCommandBuffer> indirectCommandBuffer)
@@ -64,7 +65,11 @@
 private:
     RenderBundleEncoder(id<MTLIndirectCommandBuffer>);
 
+    bool validatePopDebugGroup() const;
+
     id<MTLIndirectCommandBuffer> m_indirectCommandBuffer { nil };
+
+    uint64_t m_debugGroupStackSize { 0 };
 };
 
 } // namespace WebGPU

Modified: trunk/Source/WebGPU/WebGPU/RenderBundleEncoder.mm (291385 => 291386)


--- trunk/Source/WebGPU/WebGPU/RenderBundleEncoder.mm	2022-03-17 03:06:12 UTC (rev 291385)
+++ trunk/Source/WebGPU/WebGPU/RenderBundleEncoder.mm	2022-03-17 03:37:11 UTC (rev 291386)
@@ -83,19 +83,56 @@
     return RenderBundle::create(nil);
 }
 
-void RenderBundleEncoder::insertDebugMarker(String&& markerLabel)
+void RenderBundleEncoder::insertDebugMarker(String&&)
 {
-    UNUSED_PARAM(markerLabel);
+    // https://gpuweb.github.io/gpuweb/#dom-gpudebugcommandsmixin-insertdebugmarker
+
+    // "Prepare the encoder state of this. If it returns false, stop."
+    if (!prepareTheEncoderState())
+        return;
+
+    // MTLIndirectCommandBuffers don't support debug commands.
 }
 
+bool RenderBundleEncoder::validatePopDebugGroup() const
+{
+    // "this.[[debug_group_stack]] must not be empty."
+    if (!m_debugGroupStackSize)
+        return false;
+
+    return true;
+}
+
 void RenderBundleEncoder::popDebugGroup()
 {
+    // https://gpuweb.github.io/gpuweb/#dom-gpudebugcommandsmixin-popdebuggroup
 
+    // "Prepare the encoder state of this. If it returns false, stop."
+    if (!prepareTheEncoderState())
+        return;
+
+    // "If any of the following requirements are unmet"
+    if (!validatePopDebugGroup()) {
+        // FIXME: "make this invalid, and stop."
+        return;
+    }
+
+    // "Pop an entry off of this.[[debug_group_stack]]."
+    --m_debugGroupStackSize;
+    // MTLIndirectCommandBuffers don't support debug commands.
 }
 
-void RenderBundleEncoder::pushDebugGroup(String&& groupLabel)
+void RenderBundleEncoder::pushDebugGroup(String&&)
 {
-    UNUSED_PARAM(groupLabel);
+    // https://gpuweb.github.io/gpuweb/#dom-gpudebugcommandsmixin-pushdebuggroup
+
+    // "Prepare the encoder state of this. If it returns false, stop."
+    if (!prepareTheEncoderState())
+        return;
+
+    // "Push groupLabel onto this.[[debug_group_stack]]."
+    ++m_debugGroupStackSize;
+    // MTLIndirectCommandBuffers don't support debug commands.
 }
 
 void RenderBundleEncoder::setBindGroup(uint32_t groupIndex, const BindGroup& group, uint32_t dynamicOffsetCount, const uint32_t* dynamicOffsets)

Modified: trunk/Source/WebGPU/WebGPU/RenderPassEncoder.h (291385 => 291386)


--- trunk/Source/WebGPU/WebGPU/RenderPassEncoder.h	2022-03-17 03:06:12 UTC (rev 291385)
+++ trunk/Source/WebGPU/WebGPU/RenderPassEncoder.h	2022-03-17 03:37:11 UTC (rev 291386)
@@ -25,6 +25,7 @@
 
 #pragma once
 
+#import "CommandsMixin.h"
 #import <wtf/FastMalloc.h>
 #import <wtf/Ref.h>
 #import <wtf/RefCounted.h>
@@ -38,7 +39,7 @@
 class RenderBundle;
 class RenderPipeline;
 
-class RenderPassEncoder : public RefCounted<RenderPassEncoder> {
+class RenderPassEncoder : public RefCounted<RenderPassEncoder>, public CommandsMixin {
     WTF_MAKE_FAST_ALLOCATED;
 public:
     static Ref<RenderPassEncoder> create(id<MTLRenderCommandEncoder> renderCommandEncoder)
@@ -74,7 +75,11 @@
 private:
     RenderPassEncoder(id<MTLRenderCommandEncoder>);
 
+    bool validatePopDebugGroup() const;
+
     id<MTLRenderCommandEncoder> m_renderCommandEncoder { nil };
+
+    uint64_t m_debugGroupStackSize { 0 };
 };
 
 } // namespace WebGPU

Modified: trunk/Source/WebGPU/WebGPU/RenderPassEncoder.mm (291385 => 291386)


--- trunk/Source/WebGPU/WebGPU/RenderPassEncoder.mm	2022-03-17 03:06:12 UTC (rev 291385)
+++ trunk/Source/WebGPU/WebGPU/RenderPassEncoder.mm	2022-03-17 03:37:11 UTC (rev 291386)
@@ -104,17 +104,54 @@
 
 void RenderPassEncoder::insertDebugMarker(String&& markerLabel)
 {
-    UNUSED_PARAM(markerLabel);
+    // https://gpuweb.github.io/gpuweb/#dom-gpudebugcommandsmixin-insertdebugmarker
+
+    // "Prepare the encoder state of this. If it returns false, stop."
+    if (!prepareTheEncoderState())
+        return;
+
+    [m_renderCommandEncoder insertDebugSignpost:markerLabel];
 }
 
+bool RenderPassEncoder::validatePopDebugGroup() const
+{
+    // "this.[[debug_group_stack]] must not be empty."
+    if (!m_debugGroupStackSize)
+        return false;
+
+    return true;
+}
+
 void RenderPassEncoder::popDebugGroup()
 {
+    // https://gpuweb.github.io/gpuweb/#dom-gpudebugcommandsmixin-popdebuggroup
 
+    // "Prepare the encoder state of this. If it returns false, stop."
+    if (!prepareTheEncoderState())
+        return;
+
+    // "If any of the following requirements are unmet"
+    if (!validatePopDebugGroup()) {
+        // FIXME: "make this invalid, and stop."
+        return;
+    }
+
+    // "Pop an entry off of this.[[debug_group_stack]]."
+    --m_debugGroupStackSize;
+    [m_renderCommandEncoder popDebugGroup];
 }
 
 void RenderPassEncoder::pushDebugGroup(String&& groupLabel)
 {
-    UNUSED_PARAM(groupLabel);
+    // https://gpuweb.github.io/gpuweb/#dom-gpudebugcommandsmixin-pushdebuggroup
+
+    // "Prepare the encoder state of this. If it returns false, stop."
+    if (!prepareTheEncoderState())
+        return;
+
+    // "Push groupLabel onto this.[[debug_group_stack]]."
+    ++m_debugGroupStackSize;
+    [m_renderCommandEncoder pushDebugGroup:groupLabel];
 }
 
 void RenderPassEncoder::setBindGroup(uint32_t groupIndex, const BindGroup& group, uint32_t dynamicOffsetCount, const uint32_t* dynamicOffsets)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to