Skip to content

Commit 318a900

Browse files
committed
webgpu: implement fence
1 parent eb5d9ac commit 318a900

File tree

5 files changed

+120
-8
lines changed

5 files changed

+120
-8
lines changed

filament/backend/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,8 @@ if (FILAMENT_SUPPORTS_WEBGPU)
269269
src/webgpu/WebGPUDescriptorSetLayout.h
270270
src/webgpu/WebGPUDriver.cpp
271271
src/webgpu/WebGPUDriver.h
272+
src/webgpu/WebGPUFence.cpp
273+
src/webgpu/WebGPUFence.h
272274
src/webgpu/WebGPUIndexBuffer.cpp
273275
src/webgpu/WebGPUIndexBuffer.h
274276
src/webgpu/WebGPUPipelineCreation.cpp

filament/backend/src/webgpu/WebGPUDriver.cpp

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "WebGPUBufferObject.h"
1919
#include "WebGPUDescriptorSet.h"
2020
#include "WebGPUDescriptorSetLayout.h"
21+
#include "WebGPUFence.h"
2122
#include "WebGPUIndexBuffer.h"
2223
#include "WebGPUPipelineCreation.h"
2324
#include "WebGPUProgram.h"
@@ -103,6 +104,7 @@ void WebGPUDriver::terminate() {
103104

104105
void WebGPUDriver::tick(int) {
105106
mDevice.Tick();
107+
mAdapter.GetInstance().ProcessEvents();
106108
}
107109

108110
void WebGPUDriver::beginFrame(int64_t monotonic_clock_ns,
@@ -264,7 +266,9 @@ Handle<HwProgram> WebGPUDriver::createProgramS() noexcept {
264266
}
265267

266268
Handle<HwFence> WebGPUDriver::createFenceS() noexcept {
267-
return Handle<HwFence>((Handle<HwFence>::HandleId) mNextFakeHandle++);
269+
// The handle must be constructed here, as a synchronous call to get the status
270+
// might happen before createFenceR is executed.
271+
return allocAndConstructHandle<WebGPUFence, HwFence>();
268272
}
269273

270274
Handle<HwTimerQuery> WebGPUDriver::createTimerQueryS() noexcept {
@@ -455,8 +459,11 @@ void WebGPUDriver::createRenderTargetR(Handle<HwRenderTarget> renderTargetHandle
455459
color, depth, stencil);
456460
}
457461

458-
void WebGPUDriver::createFenceR(Handle<HwFence> fh, int) {
459-
//todo
462+
void WebGPUDriver::createFenceR(Handle<HwFence> fenceHandle, const int /* dummy */) {
463+
// the handle was already constructed in createFenceS
464+
const auto fence = handleCast<WebGPUFence>(fenceHandle);
465+
assert_invariant(mQueue);
466+
fence->addMarkerToQueueState(mQueue);
460467
}
461468

462469
void WebGPUDriver::createTimerQueryR(Handle<HwTimerQuery> tqh, int) {}
@@ -509,13 +516,18 @@ void WebGPUDriver::updateStreams(CommandStream* driver) {
509516
//todo
510517
}
511518

512-
void WebGPUDriver::destroyFence(Handle<HwFence> fh) {
513-
//todo
519+
void WebGPUDriver::destroyFence(Handle<HwFence> fenceHandle) {
520+
if (fenceHandle) {
521+
destructHandle<WebGPUFence>(fenceHandle);
522+
}
514523
}
515524

516-
FenceStatus WebGPUDriver::getFenceStatus(Handle<HwFence> fh) {
517-
//todo
518-
return FenceStatus::CONDITION_SATISFIED;
525+
FenceStatus WebGPUDriver::getFenceStatus(Handle<HwFence> fenceHandle) {
526+
const auto fence = handleCast<WebGPUFence>(fenceHandle);
527+
if (!fence) {
528+
return FenceStatus::ERROR;
529+
}
530+
return fence->getStatus();
519531
}
520532

521533
// We create all textures using VK_IMAGE_TILING_OPTIMAL, so our definition of "supported" is that

filament/backend/src/webgpu/WebGPUDriver.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,11 @@ class WebGPUDriver final : public DriverBase {
121121
return mHandleAllocator.construct<D>(handle, std::forward<ARGS>(args)...);
122122
}
123123

124+
template<typename D, typename B, typename... ARGS>
125+
Handle<B> allocAndConstructHandle(ARGS&&... args) {
126+
return mHandleAllocator.allocateAndConstruct<D>(std::forward<ARGS>(args)...);
127+
}
128+
124129
template<typename D, typename B>
125130
D* handleCast(Handle<B> handle) noexcept {
126131
return mHandleAllocator.handle_cast<D*>(handle);
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright (C) 2025 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include "WebGPUFence.h"
18+
19+
#include <backend/DriverEnums.h>
20+
21+
#include <webgpu/webgpu_cpp.h>
22+
23+
#include <atomic>
24+
25+
namespace filament::backend {
26+
27+
FenceStatus WebGPUFence::getStatus() { return mStatus.load(); }
28+
29+
void WebGPUFence::addMarkerToQueueState(wgpu::Queue const& queue) {
30+
queue.OnSubmittedWorkDone(
31+
wgpu::CallbackMode::AllowSpontaneous,
32+
[](const wgpu::QueueWorkDoneStatus status,
33+
std::atomic<FenceStatus>* const fenceStatus) {
34+
if (!fenceStatus) {
35+
return;
36+
}
37+
switch (status) {
38+
case wgpu::QueueWorkDoneStatus::Success:
39+
fenceStatus->store(FenceStatus::CONDITION_SATISFIED);
40+
break;
41+
case wgpu::QueueWorkDoneStatus::CallbackCancelled:
42+
case wgpu::QueueWorkDoneStatus::Error:
43+
fenceStatus->store(FenceStatus::ERROR);
44+
break;
45+
}
46+
},
47+
&mStatus);
48+
}
49+
50+
} // namespace filament::backend
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright (C) 2025 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#ifndef TNT_FILAMENT_BACKEND_WEBGPUFENCE_H
18+
#define TNT_FILAMENT_BACKEND_WEBGPUFENCE_H
19+
20+
#include "DriverBase.h"
21+
#include <backend/DriverEnums.h>
22+
23+
#include <atomic>
24+
25+
namespace wgpu {
26+
class Queue;
27+
} // namespace wgpu
28+
29+
namespace filament::backend {
30+
31+
class WebGPUFence final : public HwFence {
32+
public:
33+
[[nodiscard]] FenceStatus getStatus();
34+
35+
void addMarkerToQueueState(wgpu::Queue const&);
36+
37+
private:
38+
std::atomic<FenceStatus> mStatus{ FenceStatus::TIMEOUT_EXPIRED };
39+
};
40+
41+
} // namespace filament::backend
42+
43+
#endif // TNT_FILAMENT_BACKEND_WEBGPUFENCE_H

0 commit comments

Comments
 (0)