Skip to content

Commit 4c3fb08

Browse files
committed
Deploying to gh-pages from @ 530c33a 🚀
1 parent 36f3d69 commit 4c3fb08

File tree

5 files changed

+132
-144
lines changed

5 files changed

+132
-144
lines changed

‎sample/timestampQuery/TimestampQueryManager.ts

Lines changed: 50 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -4,94 +4,106 @@ export default class TimestampQueryManager {
44
// class does nothing.
55
timestampSupported: boolean;
66

7-
// Number of timestamp counters
8-
timestampCount: number;
9-
107
// The query objects. This is meant to be used in a ComputePassDescriptor's
118
// or RenderPassDescriptor's 'timestampWrites' field.
12-
timestampQuerySet: GPUQuerySet;
9+
#timestampQuerySet: GPUQuerySet;
1310

1411
// A buffer where to store query results
15-
timestampBuffer: GPUBuffer;
12+
#timestampBuffer: GPUBuffer;
1613

1714
// A buffer to map this result back to CPU
18-
timestampMapBuffer: GPUBuffer;
15+
#timestampMapBuffer: GPUBuffer;
1916

20-
// State used to avoid firing concurrent readback of timestamp values
21-
hasOngoingTimestampReadback: boolean;
17+
// Last queried elapsed time of the pass in nanoseconds.
18+
passDurationMeasurementNs: number;
2219

2320
// Device must have the "timestamp-query" feature
24-
constructor(device: GPUDevice, timestampCount: number) {
21+
constructor(device: GPUDevice) {
2522
this.timestampSupported = device.features.has('timestamp-query');
2623
if (!this.timestampSupported) return;
2724

28-
this.timestampCount = timestampCount;
25+
this.passDurationMeasurementNs = 0;
2926

3027
// Create timestamp queries
31-
this.timestampQuerySet = device.createQuerySet({
28+
this.#timestampQuerySet = device.createQuerySet({
3229
type: 'timestamp',
33-
count: timestampCount, // begin and end
30+
count: 2, // begin and end
3431
});
3532

3633
// Create a buffer where to store the result of GPU queries
3734
const timestampByteSize = 8; // timestamps are uint64
38-
const timestampBufferSize = timestampCount * timestampByteSize;
39-
this.timestampBuffer = device.createBuffer({
40-
size: timestampBufferSize,
35+
this.#timestampBuffer = device.createBuffer({
36+
size: this.#timestampQuerySet.count * timestampByteSize,
4137
usage: GPUBufferUsage.COPY_SRC | GPUBufferUsage.QUERY_RESOLVE,
4238
});
4339

4440
// Create a buffer to map the result back to the CPU
45-
this.timestampMapBuffer = device.createBuffer({
46-
size: timestampBufferSize,
41+
this.#timestampMapBuffer = device.createBuffer({
42+
size: this.#timestampBuffer.size,
4743
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ,
4844
});
45+
}
4946

50-
this.hasOngoingTimestampReadback = false;
47+
// Add both a start and end timestamp.
48+
addTimestampWrite(
49+
passDescriptor: GPURenderPassDescriptor | GPUComputePassDescriptor
50+
) {
51+
if (this.timestampSupported) {
52+
// We instruct the render pass to write to the timestamp query before/after
53+
passDescriptor.timestampWrites = {
54+
querySet: this.#timestampQuerySet,
55+
beginningOfPassWriteIndex: 0,
56+
endOfPassWriteIndex: 1,
57+
};
58+
}
59+
return passDescriptor;
5160
}
5261

53-
// Resolve all timestamp queries and copy the result into the map buffer
54-
resolveAll(commandEncoder: GPUCommandEncoder) {
62+
// Resolve the timestamp queries and copy the result into the mappable buffer if possible.
63+
resolve(commandEncoder: GPUCommandEncoder) {
5564
if (!this.timestampSupported) return;
5665

5766
// After the end of the measured render pass, we resolve queries into a
5867
// dedicated buffer.
5968
commandEncoder.resolveQuerySet(
60-
this.timestampQuerySet,
69+
this.#timestampQuerySet,
6170
0 /* firstQuery */,
62-
this.timestampCount /* queryCount */,
63-
this.timestampBuffer,
71+
this.#timestampQuerySet.count /* queryCount */,
72+
this.#timestampBuffer,
6473
0 /* destinationOffset */
6574
);
6675

67-
if (!this.hasOngoingTimestampReadback) {
68-
// Copy values to the mapped buffer
76+
if (this.#timestampMapBuffer.mapState === 'unmapped') {
77+
// Copy values to the mappable buffer
6978
commandEncoder.copyBufferToBuffer(
70-
this.timestampBuffer,
79+
this.#timestampBuffer,
7180
0,
72-
this.timestampMapBuffer,
81+
this.#timestampMapBuffer,
7382
0,
74-
this.timestampBuffer.size
83+
this.#timestampBuffer.size
7584
);
7685
}
7786
}
7887

79-
// Once resolved, we can read back the value of timestamps
80-
readAsync(onTimestampReadBack: (timestamps: BigUint64Array) => void): void {
88+
// Read the values of timestamps.
89+
tryInitiateTimestampDownload(): void {
8190
if (!this.timestampSupported) return;
82-
if (this.hasOngoingTimestampReadback) return;
91+
if (this.#timestampMapBuffer.mapState !== 'unmapped') return;
8392

84-
this.hasOngoingTimestampReadback = true;
85-
86-
const buffer = this.timestampMapBuffer;
93+
const buffer = this.#timestampMapBuffer;
8794
void buffer.mapAsync(GPUMapMode.READ).then(() => {
8895
const rawData = buffer.getMappedRange();
8996
const timestamps = new BigUint64Array(rawData);
90-
91-
onTimestampReadBack(timestamps);
92-
97+
// Subtract the begin time from the end time.
98+
// Cast into number. Number can be 9007199254740991 as max integer
99+
// which is 109 days of nano seconds.
100+
const elapsedNs = Number(timestamps[1] - timestamps[0]);
101+
// It's possible elapsedNs is negative which means it's invalid
102+
// (see spec https://gpuweb.github.io/gpuweb/#timestamp)
103+
if (elapsedNs >= 0) {
104+
this.passDurationMeasurementNs = elapsedNs;
105+
}
93106
buffer.unmap();
94-
this.hasOngoingTimestampReadback = false;
95107
});
96108
}
97109
}

‎sample/timestampQuery/index.html

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,24 @@
2020
max-width: 100%;
2121
display: block;
2222
}
23+
#info {
24+
color: white;
25+
background-color: black;
26+
position: absolute;
27+
top: 10px;
28+
left: 10px;
29+
}
30+
#info pre {
31+
margin: 0.5em;
32+
}
2333
</style>
2434
<script defer src="main.js" type="module"></script>
2535
<script defer type="module" src="../../js/iframe-helper.js"></script>
2636
</head>
2737
<body>
2838
<canvas></canvas>
39+
<div id="info">
40+
<pre></pre>
41+
</div>
2942
</body>
3043
</html>

‎sample/timestampQuery/main.js

Lines changed: 55 additions & 65 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎sample/timestampQuery/main.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)