|
25 | 25 | #include "WebGPURenderTarget.h" |
26 | 26 | #include "WebGPUSwapChain.h" |
27 | 27 | #include "WebGPUTexture.h" |
| 28 | +#include "WebGPUTimerQuery.h" |
28 | 29 | #include "WebGPUVertexBuffer.h" |
29 | 30 | #include "WebGPUVertexBufferInfo.h" |
30 | 31 | #include <backend/platforms/WebGPUPlatform.h> |
@@ -216,9 +217,6 @@ void WebGPUDriver::destroyStream(Handle<HwStream> sh) { |
216 | 217 | //TODO |
217 | 218 | } |
218 | 219 |
|
219 | | -void WebGPUDriver::destroyTimerQuery(Handle<HwTimerQuery> tqh) { |
220 | | -} |
221 | | - |
222 | 220 | void WebGPUDriver::destroyDescriptorSetLayout( |
223 | 221 | Handle<HwDescriptorSetLayout> descriptorSetLayoutHandle) { |
224 | 222 | if (descriptorSetLayoutHandle) { |
@@ -268,7 +266,31 @@ Handle<HwFence> WebGPUDriver::createFenceS() noexcept { |
268 | 266 | } |
269 | 267 |
|
270 | 268 | Handle<HwTimerQuery> WebGPUDriver::createTimerQueryS() noexcept { |
271 | | - return Handle<HwTimerQuery>((Handle<HwTimerQuery>::HandleId) mNextFakeHandle++); |
| 269 | + return allocAndConstructHandle<WebGPUTimerQuery, HwTimerQuery>(); |
| 270 | +} |
| 271 | + |
| 272 | +void WebGPUDriver::createTimerQueryR(Handle<HwTimerQuery> timerQueryHandle, int /*dummy*/) { |
| 273 | + // nothing to do, timer query was constructed in createTimerQueryS |
| 274 | +} |
| 275 | + |
| 276 | +void WebGPUDriver::destroyTimerQuery(Handle<HwTimerQuery> timerQueryHandle) { |
| 277 | + if (timerQueryHandle) { |
| 278 | + destructHandle<WebGPUTimerQuery>(timerQueryHandle); |
| 279 | + } |
| 280 | +} |
| 281 | + |
| 282 | +TimerQueryResult WebGPUDriver::getTimerQueryValue(Handle<HwTimerQuery> timerQueryHandle, uint64_t* elapsedTime) { |
| 283 | + auto* timerQuery = handleCast<WebGPUTimerQuery>(timerQueryHandle); |
| 284 | + return timerQuery->getQueryResult(elapsedTime) ? TimerQueryResult::AVAILABLE |
| 285 | + : TimerQueryResult::NOT_READY; |
| 286 | +} |
| 287 | + |
| 288 | +void WebGPUDriver::beginTimerQuery(Handle<HwTimerQuery> timerQueryHandle) { |
| 289 | + mTimerQuery = handleCast<WebGPUTimerQuery>(timerQueryHandle); |
| 290 | +} |
| 291 | + |
| 292 | +void WebGPUDriver::endTimerQuery(Handle<HwTimerQuery> timerQueryHandle) { |
| 293 | + mTimerQuery = handleCast<WebGPUTimerQuery>(timerQueryHandle); |
272 | 294 | } |
273 | 295 |
|
274 | 296 | Handle<HwIndexBuffer> WebGPUDriver::createIndexBufferS() noexcept { |
@@ -462,8 +484,6 @@ void WebGPUDriver::createFenceR(Handle<HwFence> fh, int) { |
462 | 484 | //todo |
463 | 485 | } |
464 | 486 |
|
465 | | -void WebGPUDriver::createTimerQueryR(Handle<HwTimerQuery> tqh, int) {} |
466 | | - |
467 | 487 | void WebGPUDriver::createDescriptorSetLayoutR( |
468 | 488 | Handle<HwDescriptorSetLayout> descriptorSetLayoutHandle, |
469 | 489 | backend::DescriptorSetLayout&& info) { |
@@ -727,10 +747,6 @@ void WebGPUDriver::setupExternalImage(void* image) { |
727 | 747 | //todo |
728 | 748 | } |
729 | 749 |
|
730 | | -TimerQueryResult WebGPUDriver::getTimerQueryValue(Handle<HwTimerQuery> tqh, uint64_t* elapsedTime) { |
731 | | - return TimerQueryResult::ERROR; |
732 | | -} |
733 | | - |
734 | 750 | void WebGPUDriver::setupExternalImage2(Platform::ExternalImageHandleRef image) { |
735 | 751 | //todo |
736 | 752 | } |
@@ -924,23 +940,26 @@ void WebGPUDriver::commit(Handle<HwSwapChain> sch) { |
924 | 940 | mCommandBuffer = mCommandEncoder.Finish(&commandBufferDescriptor); |
925 | 941 | assert_invariant(mCommandBuffer); |
926 | 942 | mCommandEncoder = nullptr; |
| 943 | + if (mTimerQuery) { |
| 944 | + mTimerQuery->beginTimeElapsedQuery(); |
| 945 | + } |
927 | 946 | mQueue.Submit(1, &mCommandBuffer); |
928 | | - |
929 | | - static bool firstRender = true; |
930 | | - // For the first frame rendered, we need to make sure the work is done before presenting or we |
931 | | - // get a purple flash |
932 | | - if (firstRender) { |
933 | | - auto f = mQueue.OnSubmittedWorkDone(wgpu::CallbackMode::WaitAnyOnly, |
934 | | - [=](wgpu::QueueWorkDoneStatus) {}); |
| 947 | + auto f = mQueue.OnSubmittedWorkDone(wgpu::CallbackMode::WaitAnyOnly, |
| 948 | + [=](wgpu::QueueWorkDoneStatus status) { |
| 949 | + if (status == wgpu::QueueWorkDoneStatus::Success) { |
| 950 | + if (mTimerQuery) { |
| 951 | + mTimerQuery->endTimeElapsedQuery(); |
| 952 | + } |
| 953 | + } |
| 954 | + }); |
935 | 955 | const wgpu::Instance instance = mAdapter.GetInstance(); |
936 | 956 | auto wStatus = instance.WaitAny(f, |
937 | 957 | std::chrono::duration_cast<std::chrono::nanoseconds>(1s).count()); |
938 | 958 | if (wStatus != wgpu::WaitStatus::Success) { |
939 | 959 | FWGPU_LOGW << "Waiting for first frame work to finish resulted in an error" |
940 | 960 | << static_cast<uint32_t>(wStatus); |
941 | 961 | } |
942 | | - firstRender = false; |
943 | | - } |
| 962 | + |
944 | 963 | mCommandBuffer = nullptr; |
945 | 964 | mTextureView = nullptr; |
946 | 965 | assert_invariant(mSwapChain); |
@@ -1151,12 +1170,6 @@ void WebGPUDriver::scissor( |
1151 | 1170 | //todo |
1152 | 1171 | } |
1153 | 1172 |
|
1154 | | -void WebGPUDriver::beginTimerQuery(Handle<HwTimerQuery> tqh) { |
1155 | | -} |
1156 | | - |
1157 | | -void WebGPUDriver::endTimerQuery(Handle<HwTimerQuery> tqh) { |
1158 | | -} |
1159 | | - |
1160 | 1173 | void WebGPUDriver::resetState(int) { |
1161 | 1174 | //todo |
1162 | 1175 | } |
|
0 commit comments