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

Log Message

[WebGPU] Implement queue submission methods according to the spec
https://bugs.webkit.org/show_bug.cgi?id=237869

Reviewed by Kimmo Kinnunen.

Now that we can enqueue tasks to the main thread (https://bugs.webkit.org/show_bug.cgi?id=237852)
we can now implement Queue::onSubmittedWorkDone() and Queue::submit(). The way it works is pretty
simple - there's a count of the number of submitted command buffers (m_submittedCommandBufferCount)
and the number of completed command buffers (m_completedCommandBufferCount). When the two values
are equal, the queue is idle, and the onSubmittedWorkDone() work should happen the next time the
runloop turns. Otherwise, we stick the work in a HashMap, keyed by the value that
m_completedCommandBufferCount will have to become at the point this callback should run.

* WebGPU/Queue.h:
(WebGPU::Queue::commandQueue const):
* WebGPU/Queue.mm:
(WebGPU::Queue::onSubmittedWorkDone):
(WebGPU::Queue::validateSubmit const):
(WebGPU::Queue::submit):
* WebGPU/TextureView.mm:

Modified Paths

Diff

Modified: trunk/Source/WebGPU/ChangeLog (291365 => 291366)


--- trunk/Source/WebGPU/ChangeLog	2022-03-16 21:06:26 UTC (rev 291365)
+++ trunk/Source/WebGPU/ChangeLog	2022-03-16 21:20:01 UTC (rev 291366)
@@ -1,5 +1,28 @@
 2022-03-16  Myles C. Maxfield  <mmaxfi...@apple.com>
 
+        [WebGPU] Implement queue submission methods according to the spec
+        https://bugs.webkit.org/show_bug.cgi?id=237869
+
+        Reviewed by Kimmo Kinnunen.
+
+        Now that we can enqueue tasks to the main thread (https://bugs.webkit.org/show_bug.cgi?id=237852)
+        we can now implement Queue::onSubmittedWorkDone() and Queue::submit(). The way it works is pretty
+        simple - there's a count of the number of submitted command buffers (m_submittedCommandBufferCount)
+        and the number of completed command buffers (m_completedCommandBufferCount). When the two values
+        are equal, the queue is idle, and the onSubmittedWorkDone() work should happen the next time the
+        runloop turns. Otherwise, we stick the work in a HashMap, keyed by the value that
+        m_completedCommandBufferCount will have to become at the point this callback should run.
+
+        * WebGPU/Queue.h:
+        (WebGPU::Queue::commandQueue const):
+        * WebGPU/Queue.mm:
+        (WebGPU::Queue::onSubmittedWorkDone):
+        (WebGPU::Queue::validateSubmit const):
+        (WebGPU::Queue::submit):
+        * WebGPU/TextureView.mm:
+
+2022-03-16  Myles C. Maxfield  <mmaxfi...@apple.com>
+
         [WebGPU] Create a path of Ref<>s between Instance and Queue
         https://bugs.webkit.org/show_bug.cgi?id=237864
 

Modified: trunk/Source/WebGPU/WebGPU/Queue.h (291365 => 291366)


--- trunk/Source/WebGPU/WebGPU/Queue.h	2022-03-16 21:06:26 UTC (rev 291365)
+++ trunk/Source/WebGPU/WebGPU/Queue.h	2022-03-16 21:20:01 UTC (rev 291366)
@@ -28,6 +28,7 @@
 #import "Instance.h"
 #import <wtf/CompletionHandler.h>
 #import <wtf/FastMalloc.h>
+#import <wtf/HashMap.h>
 #import <wtf/Ref.h>
 #import <wtf/ThreadSafeRefCounted.h>
 #import <wtf/Vector.h>
@@ -54,14 +55,23 @@
     void writeTexture(const WGPUImageCopyTexture& destination, const void* data, size_t dataSize, const WGPUTextureDataLayout&, const WGPUExtent3D& writeSize);
     void setLabel(const char*);
 
+    id<MTLCommandQueue> commandQueue() const { return m_commandQueue; }
+
 private:
     Queue(id<MTLCommandQueue>, Device&);
 
+    bool validateSubmit() const;
+
     // This can be called on a background thread.
     void scheduleWork(Instance::WorkItem&&);
 
     id<MTLCommandQueue> m_commandQueue { nil };
     Device& m_device; // The only kind of queues that exist right now are default queues, which are owned by Devices.
+
+    uint64_t m_submittedCommandBufferCount { 0 };
+    uint64_t m_completedCommandBufferCount { 0 };
+    using _OnSubmittedWorkDoneCallbacks_ = Vector<WTF::Function<void(WGPUQueueWorkDoneStatus)>>;
+    HashMap<uint64_t, OnSubmittedWorkDoneCallbacks> m_onSubmittedWorkDoneCallbacks;
 };
 
 } // namespace WebGPU

Modified: trunk/Source/WebGPU/WebGPU/Queue.mm (291365 => 291366)


--- trunk/Source/WebGPU/WebGPU/Queue.mm	2022-03-16 21:06:26 UTC (rev 291365)
+++ trunk/Source/WebGPU/WebGPU/Queue.mm	2022-03-16 21:20:01 UTC (rev 291366)
@@ -40,15 +40,63 @@
 
 Queue::~Queue() = default;
 
-void Queue::onSubmittedWorkDone(uint64_t signalValue, CompletionHandler<void(WGPUQueueWorkDoneStatus)>&& callback)
+void Queue::onSubmittedWorkDone(uint64_t, CompletionHandler<void(WGPUQueueWorkDoneStatus)>&& callback)
 {
-    UNUSED_PARAM(signalValue);
-    UNUSED_PARAM(callback);
+    // https://gpuweb.github.io/gpuweb/#dom-gpuqueue-onsubmittedworkdone
+
+    ASSERT(m_submittedCommandBufferCount >= m_completedCommandBufferCount);
+
+    if (m_submittedCommandBufferCount == m_completedCommandBufferCount) {
+        scheduleWork([callback = WTFMove(callback)]() mutable {
+            callback(WGPUQueueWorkDoneStatus_Success);
+        });
+        return;
+    }
+
+    auto& callbacks = m_onSubmittedWorkDoneCallbacks.add(m_submittedCommandBufferCount, OnSubmittedWorkDoneCallbacks()).iterator->value;
+    callbacks.append(WTFMove(callback));
 }
 
+bool Queue::validateSubmit() const
+{
+    // FIXME: "Every {{GPUCommandBuffer}} in |commandBuffers| is [$valid to use with$] |this|."
+
+    // FIXME: "Every GPUBuffer referenced in any element of commandBuffers is in the "unmapped" buffer state."
+
+    // FIXME: "Every GPUQuerySet referenced in a command in any element of commandBuffers is in the available state."
+    // FIXME: "For occlusion queries, occlusionQuerySet in beginRenderPass() does not constitute a reference, while beginOcclusionQuery() does."
+
+    // There's only one queue right now, so there is no need to make sure that the command buffers are being submitted to the correct queue.
+
+    return true;
+}
+
 void Queue::submit(Vector<std::reference_wrapper<const CommandBuffer>>&& commands)
 {
-    UNUSED_PARAM(commands);
+    // https://gpuweb.github.io/gpuweb/#dom-gpuqueue-submit
+
+    // "If any of the following conditions are unsatisfied"
+    if (!validateSubmit()) {
+        // FIXME: "generate a validation error and stop."
+        return;
+    }
+
+    // "For each commandBuffer in commandBuffers:"
+    for (auto commandBuffer : commands) {
+        ASSERT(commandBuffer.get().commandBuffer().commandQueue == m_commandQueue); //
+        [commandBuffer.get().commandBuffer() addCompletedHandler:[protectedThis = Ref { *this }] (id<MTLCommandBuffer>) {
+            protectedThis->scheduleWork([protectedThis = protectedThis.copyRef()]() {
+                ++(protectedThis->m_completedCommandBufferCount);
+                for (auto& callback : protectedThis->m_onSubmittedWorkDoneCallbacks.take(protectedThis->m_completedCommandBufferCount))
+                    callback(WGPUQueueWorkDoneStatus_Success);
+            });
+        }];
+
+        // "Execute each command in commandBuffer.[[command_list]]."
+        [commandBuffer.get().commandBuffer() commit];
+    }
+
+    m_submittedCommandBufferCount += commands.size();
 }
 
 void Queue::writeBuffer(const Buffer& buffer, uint64_t bufferOffset, const void* data, size_t size)

Modified: trunk/Source/WebGPU/WebGPU/TextureView.mm (291365 => 291366)


--- trunk/Source/WebGPU/WebGPU/TextureView.mm	2022-03-16 21:06:26 UTC (rev 291365)
+++ trunk/Source/WebGPU/WebGPU/TextureView.mm	2022-03-16 21:20:01 UTC (rev 291366)
@@ -40,7 +40,7 @@
     m_texture.label = [NSString stringWithCString:label encoding:NSUTF8StringEncoding];
 }
 
-}
+} // namespace WebGPU
 
 void wgpuTextureViewRelease(WGPUTextureView textureView)
 {
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to