Compare commits
2 Commits
pf/cmd-buf
...
jc/enableT
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c7da1c0ad5 | ||
|
|
04ff88fab2 |
@@ -283,6 +283,8 @@ if (FILAMENT_SUPPORTS_WEBGPU)
|
||||
src/webgpu/WebGPUSwapChain.h
|
||||
src/webgpu/WebGPUTexture.cpp
|
||||
src/webgpu/WebGPUTexture.h
|
||||
src/webgpu/WebGPUTimerQuery.cpp
|
||||
src/webgpu/WebGPUTimerQuery.h
|
||||
src/webgpu/WebGPUVertexBuffer.cpp
|
||||
src/webgpu/WebGPUVertexBuffer.h
|
||||
src/webgpu/WebGPUVertexBufferInfo.cpp
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "WebGPURenderTarget.h"
|
||||
#include "WebGPUSwapChain.h"
|
||||
#include "WebGPUTexture.h"
|
||||
#include "WebGPUTimerQuery.h"
|
||||
#include "WebGPUVertexBuffer.h"
|
||||
#include "WebGPUVertexBufferInfo.h"
|
||||
#include <backend/platforms/WebGPUPlatform.h>
|
||||
@@ -101,8 +102,9 @@ template class ConcreteDispatcher<WebGPUDriver>;
|
||||
void WebGPUDriver::terminate() {
|
||||
}
|
||||
|
||||
void WebGPUDriver::tick(int) {
|
||||
void WebGPUDriver::tick(int /*dummy*/) {
|
||||
mDevice.Tick();
|
||||
mAdapter.GetInstance().ProcessEvents();
|
||||
}
|
||||
|
||||
void WebGPUDriver::beginFrame(int64_t monotonic_clock_ns,
|
||||
@@ -216,9 +218,6 @@ void WebGPUDriver::destroyStream(Handle<HwStream> sh) {
|
||||
//TODO
|
||||
}
|
||||
|
||||
void WebGPUDriver::destroyTimerQuery(Handle<HwTimerQuery> tqh) {
|
||||
}
|
||||
|
||||
void WebGPUDriver::destroyDescriptorSetLayout(
|
||||
Handle<HwDescriptorSetLayout> descriptorSetLayoutHandle) {
|
||||
if (descriptorSetLayoutHandle) {
|
||||
@@ -268,7 +267,31 @@ Handle<HwFence> WebGPUDriver::createFenceS() noexcept {
|
||||
}
|
||||
|
||||
Handle<HwTimerQuery> WebGPUDriver::createTimerQueryS() noexcept {
|
||||
return Handle<HwTimerQuery>((Handle<HwTimerQuery>::HandleId) mNextFakeHandle++);
|
||||
return allocAndConstructHandle<WebGPUTimerQuery, HwTimerQuery>();
|
||||
}
|
||||
|
||||
void WebGPUDriver::createTimerQueryR(Handle<HwTimerQuery> timerQueryHandle, int /*dummy*/) {
|
||||
// nothing to do, timer query was constructed in createTimerQueryS
|
||||
}
|
||||
|
||||
void WebGPUDriver::destroyTimerQuery(Handle<HwTimerQuery> timerQueryHandle) {
|
||||
if (timerQueryHandle) {
|
||||
destructHandle<WebGPUTimerQuery>(timerQueryHandle);
|
||||
}
|
||||
}
|
||||
|
||||
TimerQueryResult WebGPUDriver::getTimerQueryValue(Handle<HwTimerQuery> timerQueryHandle, uint64_t* elapsedTime) {
|
||||
auto* timerQuery = handleCast<WebGPUTimerQuery>(timerQueryHandle);
|
||||
return timerQuery->getQueryResult(elapsedTime) ? TimerQueryResult::AVAILABLE
|
||||
: TimerQueryResult::NOT_READY;
|
||||
}
|
||||
|
||||
void WebGPUDriver::beginTimerQuery(Handle<HwTimerQuery> timerQueryHandle) {
|
||||
mTimerQuery = handleCast<WebGPUTimerQuery>(timerQueryHandle);
|
||||
}
|
||||
|
||||
void WebGPUDriver::endTimerQuery(Handle<HwTimerQuery> timerQueryHandle) {
|
||||
mTimerQuery = handleCast<WebGPUTimerQuery>(timerQueryHandle);
|
||||
}
|
||||
|
||||
Handle<HwIndexBuffer> WebGPUDriver::createIndexBufferS() noexcept {
|
||||
@@ -462,8 +485,6 @@ void WebGPUDriver::createFenceR(Handle<HwFence> fh, int) {
|
||||
//todo
|
||||
}
|
||||
|
||||
void WebGPUDriver::createTimerQueryR(Handle<HwTimerQuery> tqh, int) {}
|
||||
|
||||
void WebGPUDriver::createDescriptorSetLayoutR(
|
||||
Handle<HwDescriptorSetLayout> descriptorSetLayoutHandle,
|
||||
backend::DescriptorSetLayout&& info) {
|
||||
@@ -727,10 +748,6 @@ void WebGPUDriver::setupExternalImage(void* image) {
|
||||
//todo
|
||||
}
|
||||
|
||||
TimerQueryResult WebGPUDriver::getTimerQueryValue(Handle<HwTimerQuery> tqh, uint64_t* elapsedTime) {
|
||||
return TimerQueryResult::ERROR;
|
||||
}
|
||||
|
||||
void WebGPUDriver::setupExternalImage2(Platform::ExternalImageHandleRef image) {
|
||||
//todo
|
||||
}
|
||||
@@ -924,8 +941,10 @@ void WebGPUDriver::commit(Handle<HwSwapChain> sch) {
|
||||
mCommandBuffer = mCommandEncoder.Finish(&commandBufferDescriptor);
|
||||
assert_invariant(mCommandBuffer);
|
||||
mCommandEncoder = nullptr;
|
||||
if (mTimerQuery) {
|
||||
mTimerQuery->beginTimeElapsedQuery();
|
||||
}
|
||||
mQueue.Submit(1, &mCommandBuffer);
|
||||
|
||||
static bool firstRender = true;
|
||||
// For the first frame rendered, we need to make sure the work is done before presenting or we
|
||||
// get a purple flash
|
||||
@@ -940,6 +959,15 @@ void WebGPUDriver::commit(Handle<HwSwapChain> sch) {
|
||||
<< static_cast<uint32_t>(wStatus);
|
||||
}
|
||||
firstRender = false;
|
||||
} else {
|
||||
mQueue.OnSubmittedWorkDone(wgpu::CallbackMode::AllowSpontaneous,
|
||||
[=](wgpu::QueueWorkDoneStatus status) {
|
||||
if (status == wgpu::QueueWorkDoneStatus::Success) {
|
||||
if (mTimerQuery) {
|
||||
mTimerQuery->endTimeElapsedQuery();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
mCommandBuffer = nullptr;
|
||||
mTextureView = nullptr;
|
||||
@@ -1151,12 +1179,6 @@ void WebGPUDriver::scissor(
|
||||
//todo
|
||||
}
|
||||
|
||||
void WebGPUDriver::beginTimerQuery(Handle<HwTimerQuery> tqh) {
|
||||
}
|
||||
|
||||
void WebGPUDriver::endTimerQuery(Handle<HwTimerQuery> tqh) {
|
||||
}
|
||||
|
||||
void WebGPUDriver::resetState(int) {
|
||||
//todo
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
namespace filament::backend {
|
||||
|
||||
class WebGPUSwapChain;
|
||||
class WebGPUTimerQuery;
|
||||
|
||||
/**
|
||||
* WebGPU backend (driver) implementation
|
||||
@@ -78,6 +79,7 @@ private:
|
||||
WebGPURenderTarget* mDefaultRenderTarget = nullptr;
|
||||
WebGPURenderTarget* mCurrentRenderTarget = nullptr;
|
||||
spd::MipmapGenerator mMipMapGenerator;
|
||||
WebGPUTimerQuery* mTimerQuery = nullptr;
|
||||
|
||||
tsl::robin_map<uint32_t, wgpu::RenderPipeline> mPipelineMap;
|
||||
|
||||
@@ -116,6 +118,11 @@ private:
|
||||
return mHandleAllocator.allocate<D>();
|
||||
}
|
||||
|
||||
template<typename D, typename B, typename... ARGS>
|
||||
Handle<B> allocAndConstructHandle(ARGS&&... args) {
|
||||
return mHandleAllocator.allocateAndConstruct<D>(std::forward<ARGS>(args)...);
|
||||
}
|
||||
|
||||
template<typename D, typename B, typename... ARGS>
|
||||
D* constructHandle(Handle<B>& handle, ARGS&&... args) noexcept {
|
||||
return mHandleAllocator.construct<D>(handle, std::forward<ARGS>(args)...);
|
||||
|
||||
60
filament/backend/src/webgpu/WebGPUTimerQuery.cpp
Normal file
60
filament/backend/src/webgpu/WebGPUTimerQuery.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2025 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "WebGPUTimerQuery.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
void WebGPUTimerQuery::beginTimeElapsedQuery() {
|
||||
mStatus->elapsedNanoseconds = 0;
|
||||
// Capture the timer query status via a weak_ptr because the WGPUTimerQuery could be destroyed
|
||||
// before the block executes.
|
||||
std::weak_ptr<WebGPUTimerQuery::Status> statusPtr = mStatus;
|
||||
|
||||
if (auto s = statusPtr.lock()) {
|
||||
s->elapsedNanoseconds = std::chrono::steady_clock::now().time_since_epoch().count();
|
||||
}
|
||||
}
|
||||
|
||||
void WebGPUTimerQuery::endTimeElapsedQuery() {
|
||||
// Capture the timer query status via a weak_ptr because the WGPUTimerQuery could be destroyed
|
||||
// before the block executes.
|
||||
if (mStatus->elapsedNanoseconds != 0) {
|
||||
std::weak_ptr<WebGPUTimerQuery::Status> statusPtr = mStatus;
|
||||
if (auto s = statusPtr.lock()) {
|
||||
s->previousElapsed = s->elapsedNanoseconds =
|
||||
std::chrono::steady_clock::now().time_since_epoch().count() -
|
||||
s->elapsedNanoseconds;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool WebGPUTimerQuery::getQueryResult(uint64_t* outElapsedTime) {
|
||||
if (mStatus->previousElapsed == 0) {
|
||||
return false;
|
||||
}
|
||||
if (outElapsedTime) {
|
||||
*outElapsedTime = mStatus->previousElapsed;
|
||||
mStatus->previousElapsed = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}// namespace filament::backend
|
||||
50
filament/backend/src/webgpu/WebGPUTimerQuery.h
Normal file
50
filament/backend/src/webgpu/WebGPUTimerQuery.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2025 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TNT_FILAMENT_BACKEND_WEBGPUTIMERQUERY_H
|
||||
#define TNT_FILAMENT_BACKEND_WEBGPUTIMERQUERY_H
|
||||
|
||||
#include "DriverBase.h"
|
||||
|
||||
#include <webgpu/webgpu_cpp.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
class WebGPUTimerQuery : public HwTimerQuery {
|
||||
public:
|
||||
WebGPUTimerQuery()
|
||||
: mStatus(std::make_shared<Status>()) {}
|
||||
|
||||
void beginTimeElapsedQuery();
|
||||
void endTimeElapsedQuery();
|
||||
bool getQueryResult(uint64_t* outElapsedTimeNanoseconds);
|
||||
|
||||
private:
|
||||
struct Status {
|
||||
std::atomic<uint64_t> elapsedNanoseconds{ 0 };
|
||||
std::atomic<uint64_t> previousElapsed{ 0 };
|
||||
};
|
||||
|
||||
std::shared_ptr<Status> mStatus;
|
||||
};
|
||||
|
||||
} // namespace filament::backend
|
||||
|
||||
#endif //TNT_FILAMENT_BACKEND_WEBGPUTIMERQUERY_H
|
||||
Reference in New Issue
Block a user