summaryrefslogtreecommitdiffstats
path: root/dom/webgpu/tests/cts/checkout/src/webgpu/util/texture/data_generation.ts
diff options
context:
space:
mode:
Diffstat (limited to 'dom/webgpu/tests/cts/checkout/src/webgpu/util/texture/data_generation.ts')
-rw-r--r--dom/webgpu/tests/cts/checkout/src/webgpu/util/texture/data_generation.ts83
1 files changed, 83 insertions, 0 deletions
diff --git a/dom/webgpu/tests/cts/checkout/src/webgpu/util/texture/data_generation.ts b/dom/webgpu/tests/cts/checkout/src/webgpu/util/texture/data_generation.ts
new file mode 100644
index 0000000000..7ad7d30e08
--- /dev/null
+++ b/dom/webgpu/tests/cts/checkout/src/webgpu/util/texture/data_generation.ts
@@ -0,0 +1,83 @@
+/**
+ * A helper class that generates ranges of dummy data for buffer or texture operations
+ * efficiently. Tries to minimize allocations and data updates.
+ */
+export class DataArrayGenerator {
+ private dataBuffer = new Uint8Array(256);
+
+ private lastOffset = 0;
+ private lastStart = 0;
+ private lastByteSize = 0;
+
+ /** Find the nearest power of two greater than or equal to the input value. */
+ private nextPowerOfTwo(value: number) {
+ return 1 << (32 - Math.clz32(value - 1));
+ }
+
+ private generateData(byteSize: number, start: number = 0, offset: number = 0) {
+ const prevSize = this.dataBuffer.length;
+
+ if (prevSize < byteSize) {
+ // If the requested data is larger than the allocated buffer, reallocate it to a buffer large
+ // enough to handle the new request.
+ const newData = new Uint8Array(this.nextPowerOfTwo(byteSize));
+
+ if (this.lastOffset === offset && this.lastStart === start && this.lastByteSize) {
+ // Do a fast copy of any previous data that was generated.
+ newData.set(this.dataBuffer);
+ }
+
+ this.dataBuffer = newData;
+ } else if (this.lastOffset < offset) {
+ // Ensure all values up to the offset are zeroed out.
+ this.dataBuffer.fill(0, this.lastOffset, offset);
+ }
+
+ // If the offset or start values have changed, the whole data range needs to be regenerated.
+ if (this.lastOffset !== offset || this.lastStart !== start) {
+ this.lastByteSize = 0;
+ }
+
+ // Generate any new values that are required
+ if (this.lastByteSize < byteSize) {
+ for (let i = this.lastByteSize; i < byteSize - offset; ++i) {
+ this.dataBuffer[i + offset] = ((i ** 3 + i + start) % 251) + 1; // Ensure data is always non-zero
+ }
+
+ this.lastOffset = offset;
+ this.lastStart = start;
+ this.lastByteSize = byteSize;
+ }
+ }
+
+ /**
+ * Returns a new view into the generated data that's the correct length. Because this is a view
+ * previously returned views from the same generator will have their values overwritten as well.
+ * @param {number} byteSize - Number of bytes the returned view should contain.
+ * @param {number} [start] - The value of the first element generated in the view.
+ * @param {number} [offset] - Offset of the generated data within the view. Preceeding values will be 0.
+ * @returns {Uint8Array} A new Uint8Array view into the generated data.
+ */
+ generateView(byteSize: number, start: number = 0, offset: number = 0): Uint8Array {
+ this.generateData(byteSize, start, offset);
+
+ if (this.dataBuffer.length === byteSize) {
+ return this.dataBuffer;
+ }
+ return new Uint8Array(this.dataBuffer.buffer, 0, byteSize);
+ }
+
+ /**
+ * Returns a copy of the generated data. Note that this still changes the underlying buffer, so
+ * any previously generated views will still be overwritten, but the returned copy won't reflect
+ * future generate* calls.
+ * @param {number} byteSize - Number of bytes the returned array should contain.
+ * @param {number} [start] - The value of the first element generated in the view.
+ * @param {number} [offset] - Offset of the generated data within the view. Preceeding values will be 0.
+ * @returns {Uint8Array} A new Uint8Array copy of the generated data.
+ */
+ generateAndCopyView(byteSize: number, start: number = 0, offset: number = 0) {
+ this.generateData(byteSize, start, offset);
+ return this.dataBuffer.slice(0, byteSize);
+ }
+}