From ed3a827b5f2865cd06a13bbc1cda42f1ebb9a095 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Mon, 16 Mar 2026 16:41:39 +0100 Subject: [PATCH] Implement `GPUDeviceWebGPU::WaitForGPU` --- .../WebGPU/GPUContextWebGPU.cpp | 2 ++ .../GraphicsDevice/WebGPU/GPUDeviceWebGPU.cpp | 22 ++++++++++++++++++- .../GraphicsDevice/WebGPU/GPUDeviceWebGPU.h | 1 + 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/Source/Engine/GraphicsDevice/WebGPU/GPUContextWebGPU.cpp b/Source/Engine/GraphicsDevice/WebGPU/GPUContextWebGPU.cpp index 0962eb98e..dae0d98ba 100644 --- a/Source/Engine/GraphicsDevice/WebGPU/GPUContextWebGPU.cpp +++ b/Source/Engine/GraphicsDevice/WebGPU/GPUContextWebGPU.cpp @@ -561,6 +561,7 @@ void GPUContextWebGPU::Flush() { wgpuQueueSubmit(_device->Queue, 1, &commandBuffer); wgpuCommandBufferRelease(commandBuffer); + _device->QueueSubmits++; } } @@ -1075,6 +1076,7 @@ void GPUContextWebGPU::FlushRenderPass() _blendFactorDirty = true; _scissorRectDirty |= _scissorRect != Rectangle(0, 0, attachmentSize.Width, attachmentSize.Height); _viewportDirty |= _viewport != Viewport(Float2(attachmentSize.Width, attachmentSize.Height)); + ASSERT_LOW_LAYER(_scissorRect.GetWidth() <= attachmentSize.Width && _scissorRect.GetHeight() <= attachmentSize.Height); } void GPUContextWebGPU::FlushBindGroup() diff --git a/Source/Engine/GraphicsDevice/WebGPU/GPUDeviceWebGPU.cpp b/Source/Engine/GraphicsDevice/WebGPU/GPUDeviceWebGPU.cpp index 7935b5a07..1abf8a386 100644 --- a/Source/Engine/GraphicsDevice/WebGPU/GPUDeviceWebGPU.cpp +++ b/Source/Engine/GraphicsDevice/WebGPU/GPUDeviceWebGPU.cpp @@ -796,7 +796,27 @@ void GPUDeviceWebGPU::Dispose() void GPUDeviceWebGPU::WaitForGPU() { - // TODO: this could use onSubmittedWorkDone (assuming any submit has been already done) + if (QueueSubmits == 0) + return; + QueueSubmits = 0; + AsyncCallbackWebGPU workDone(WGPU_QUEUE_WORK_DONE_CALLBACK_INFO_INIT); + workDone.Info.callback = [](WGPUQueueWorkDoneStatus status, WGPUStringView message, WGPU_NULLABLE void* userdata1, WGPU_NULLABLE void* userdata2) + { + AsyncCallbackDataWebGPU& userData = *reinterpret_cast(userdata1); + userData.Call(status == WGPUQueueWorkDoneStatus_Success, status, message); + }; + wgpuQueueOnSubmittedWorkDone(Queue, workDone.Info); + auto workDoneResult = workDone.Wait(); + if (workDoneResult == WGPUWaitStatus_TimedOut) + { + LOG(Error, "WebGPU queue wait has timed out after {}s", workDone.Data.WaitTime); + return; + } + if (workDoneResult == WGPUWaitStatus_Error) + { + LOG(Error, "Failed to wait for WebGPU queue. Error: {}, 0x{:x}", workDone.Data.Message, workDone.Data.Status); + return; + } } GPUQueryWebGPU GPUDeviceWebGPU::AllocateQuery(GPUQueryType type) diff --git a/Source/Engine/GraphicsDevice/WebGPU/GPUDeviceWebGPU.h b/Source/Engine/GraphicsDevice/WebGPU/GPUDeviceWebGPU.h index 5b56126ac..4527cb0a7 100644 --- a/Source/Engine/GraphicsDevice/WebGPU/GPUDeviceWebGPU.h +++ b/Source/Engine/GraphicsDevice/WebGPU/GPUDeviceWebGPU.h @@ -141,6 +141,7 @@ public: WGPUBuffer DefaultBuffer = nullptr; GPUDataUploaderWebGPU DataUploader; uint32 MinUniformBufferOffsetAlignment = 1; + uint32 QueueSubmits = 0; bool TimestampQuery = false; uint32 QuerySetsCount = 0; GPUQuerySetWebGPU* QuerySets[WEBGPU_MAX_QUERY_SETS] = {};