| 105 | } |
| 106 | |
| 107 | bool GPUQuerySetWebGPU::Read(uint32 index, uint64& result, bool wait) |
| 108 | { |
| 109 | if (_state == Resolved) |
| 110 | { |
| 111 | // Start mapping the buffer |
| 112 | ASSERT(!wait); // TODO: impl wgpuBufferMapAsync with waiting (see GPUBufferWebGPU::Map) |
| 113 | WGPUBufferMapCallbackInfo callback = WGPU_BUFFER_MAP_CALLBACK_INFO_INIT; |
| 114 | callback.mode = WGPUCallbackMode_AllowSpontaneous; |
| 115 | callback.userdata1 = this; |
| 116 | callback.callback = [](WGPUMapAsyncStatus status, WGPUStringView message, WGPU_NULLABLE void* userdata1, WGPU_NULLABLE void* userdata2) |
| 117 | { |
| 118 | if (status == WGPUMapAsyncStatus_Success) |
| 119 | { |
| 120 | auto set = (GPUQuerySetWebGPU*)userdata1; |
| 121 | set->OnRead(); |
| 122 | } |
| 123 | #if !BUILD_RELEASE |
| 124 | else |
| 125 | { |
| 126 | LOG(Error, "Query Set map failed with status {}, {}", (uint32)status, WEBGPU_TO_STR(message)); |
| 127 | } |
| 128 | #endif |
| 129 | }; |
| 130 | wgpuBufferMapAsync(_readBuffer, WGPUMapMode_Read, 0, _index * sizeof(uint64), callback); |
| 131 | _state = Mapping; |
| 132 | } |
| 133 | else if (_state == Mapped) |
| 134 | { |
| 135 | // Read the results from mapped buffer |
| 136 | if (Type == GPUQueryType::Timer) |
| 137 | { |
| 138 | // Timestamp calculates a difference between two queries (begin/end) in nanoseconds (result is in microseconds) |
| 139 | result = Math::Max(_mapped[index + 1] - _mapped[index], 0ull) / 1000; |
| 140 | } |
| 141 | else |
| 142 | { |
| 143 | // Occlusion outputs number of fragment samples that pass all the tests (scissor, stencil, depth, etc.) |
| 144 | result = _mapped[index]; |
| 145 | } |
| 146 | return true; |
| 147 | } |
| 148 | return false; |
| 149 | } |
| 150 | |
| 151 | void GPUQuerySetWebGPU::OnRead() |
| 152 | { |
no test coverage detected