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