@woosh/meep-engine 3.63.2 → 3.63.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "description": "Advanced 3D game engine",
7
7
  "type": "module",
8
8
  "author": "Alexander Goldring",
9
- "version": "3.63.2",
9
+ "version": "3.63.3",
10
10
  "exports": {
11
11
  "./build/*": "./build/*",
12
12
  "./src/*": "./src/*",
@@ -30,6 +30,23 @@ export class SoftwareGPUCommandEncoder extends SoftwareGPUObjectBase implements
30
30
  * @type {(SoftwareGPUComputePassEncoder|SoftwareGPURenderPassEncoder)[]}
31
31
  */
32
32
  passes: (SoftwareGPUComputePassEncoder | SoftwareGPURenderPassEncoder)[];
33
+ /**
34
+ * Everything encoded on this encoder, in the order it was encoded: each pass begun and each copy,
35
+ * clear and query resolve the encoder accepted. A device runs them in this order, so what one
36
+ * command finds in a buffer depends on where it sits among the rest — which {@link passes} alone
37
+ * cannot show for a pass and a copy or clear around it.
38
+ *
39
+ * Each entry names its method and carries that call's arguments, with any size the caller left
40
+ * out filled in:
41
+ * - `{ method: 'beginComputePass' | 'beginRenderPass', pass }`
42
+ * - `{ method: 'copyBufferToBuffer', source, source_offset, destination, destination_offset, size }`
43
+ * - `{ method: 'clearBuffer', buffer, offset, size }`
44
+ * - `{ method: 'copyTextureToTexture' | 'copyBufferToTexture' | 'copyTextureToBuffer', source, destination, size }`
45
+ * - `{ method: 'resolveQuerySet', query_set, first_query, query_count, destination, destination_offset }`
46
+ *
47
+ * @type {Object[]}
48
+ */
49
+ operations: any[];
33
50
  finish(): SoftwareGPUCommandBuffer;
34
51
  /**
35
52
  * Called by a pass this encoder opened, when that pass ends. Releases the lock.
@@ -1 +1 @@
1
- {"version":3,"file":"SoftwareGPUCommandEncoder.d.ts","sourceRoot":"","sources":["../../../../../src/shade/device/mock/SoftwareGPUCommandEncoder.js"],"names":[],"mappings":"AAgGA;;;;GAIG;AACH,gFAFgB,iBAAiB;IA+D7B;;;;OAIG;IACH,iFAIC;IAzDD;;;;OAIG;IACH,gBAFU,6BAA6B,EAAE,CAErB;IAEpB;;;;OAIG;IACH,eAFU,4BAA4B,EAAE,CAErB;IAEnB;;;;;;OAMG;IACH,QAFU,CAAC,6BAA6B,GAAC,4BAA4B,CAAC,EAAE,CAE5D;IA0EZ,mCAiBC;IAqBD;;;;;OAKG;IACH,wBAHW,6BAA6B,GAAC,4BAA4B,GACxD,IAAI,CAMhB;IAED;;;;;OAKG;IACH,gCAEC;IAED;;;;;;;;;OASG;IACH,sCAHW,MAAM,GACJ,IAAI,CAIhB;IAED;;;;;;;OAOG;IACH,+EAeC;IAED;;;;;;;;;;;;;OAaG;IACH,4BAHW,CAAC,sCAAoC,CAAC,EAAE,GACtC,IAAI,CAUhB;IAkBD;;;;;;;OAOG;IACH,4EAmCC;IAED;;;;;;;;OAQG;IACH,oHAFa,IAAI,CAuBhB;IAED;;;;;OAKG;IACH,kHAFa,IAAI,CAuBhB;IAED;;;;;OAKG;IACH,kHAFa,IAAI,CAuBhB;IAED;;;;;;;;;OASG;IACH,2DANW,MAAM,cACN,MAAM,qDAEN,MAAM,GACJ,IAAI,CAwBhB;IAwCD;;;;OAIG;IACH,sBAFW,MAAM,QAIhB;IAED,sBAEC;IAED;;OAEG;IACH,yBAFW,MAAM,QAIhB;IAyED;;;;;;;;OAQG;IACH,4DANW,MAAM,qDAEN,MAAM,QACN,MAAM,GACJ,IAAI,CAgChB;IAED;;;;;;;OAOG;IACH,gDAJW,MAAM,SACN,MAAM,GACJ,IAAI,CA6BhB;IAGL;;;OAGG;IACH,sCAFU,OAAO,CAE8C;;CAN9D;sCA/sBqC,4BAA4B;8CAFpB,oCAAoC;6CAGrC,mCAAmC;yCAJvC,+BAA+B"}
1
+ {"version":3,"file":"SoftwareGPUCommandEncoder.d.ts","sourceRoot":"","sources":["../../../../../src/shade/device/mock/SoftwareGPUCommandEncoder.js"],"names":[],"mappings":"AAgGA;;;;GAIG;AACH,gFAFgB,iBAAiB;IAiF7B;;;;OAIG;IACH,iFAIC;IA3ED;;;;OAIG;IACH,gBAFU,6BAA6B,EAAE,CAErB;IAEpB;;;;OAIG;IACH,eAFU,4BAA4B,EAAE,CAErB;IAEnB;;;;;;OAMG;IACH,QAFU,CAAC,6BAA6B,GAAC,4BAA4B,CAAC,EAAE,CAE5D;IAEZ;;;;;;;;;;;;;;;OAeG;IACH,YAFU,KAAQ,CAEF;IA0EhB,mCAiBC;IAqBD;;;;;OAKG;IACH,wBAHW,6BAA6B,GAAC,4BAA4B,GACxD,IAAI,CAMhB;IAED;;;;;OAKG;IACH,gCAEC;IAED;;;;;;;;;OASG;IACH,sCAHW,MAAM,GACJ,IAAI,CAIhB;IAED;;;;;;;OAOG;IACH,+EAgBC;IAED;;;;;;;;;;;;;OAaG;IACH,4BAHW,CAAC,sCAAoC,CAAC,EAAE,GACtC,IAAI,CAUhB;IAkBD;;;;;;;OAOG;IACH,4EAoCC;IAED;;;;;;;;OAQG;IACH,oHAFa,IAAI,CAyBhB;IAED;;;;;OAKG;IACH,kHAFa,IAAI,CAyBhB;IAED;;;;;OAKG;IACH,kHAFa,IAAI,CAyBhB;IAED;;;;;;;;;OASG;IACH,2DANW,MAAM,cACN,MAAM,qDAEN,MAAM,GACJ,IAAI,CAiChB;IAwCD;;;;OAIG;IACH,sBAFW,MAAM,QAIhB;IAED,sBAEC;IAED;;OAEG;IACH,yBAFW,MAAM,QAIhB;IAyED;;;;;;;;OAQG;IACH,4DANW,MAAM,qDAEN,MAAM,QACN,MAAM,GACJ,IAAI,CAyChB;IAED;;;;;;;OAOG;IACH,gDAJW,MAAM,SACN,MAAM,GACJ,IAAI,CA+BhB;IAGL;;;OAGG;IACH,sCAFU,OAAO,CAE8C;;CAN9D;sCA7vBqC,4BAA4B;8CAFpB,oCAAoC;6CAGrC,mCAAmC;yCAJvC,+BAA+B"}
@@ -135,6 +135,24 @@ export class SoftwareGPUCommandEncoder extends SoftwareGPUObjectBase {
135
135
  */
136
136
  passes = [];
137
137
 
138
+ /**
139
+ * Everything encoded on this encoder, in the order it was encoded: each pass begun and each copy,
140
+ * clear and query resolve the encoder accepted. A device runs them in this order, so what one
141
+ * command finds in a buffer depends on where it sits among the rest — which {@link passes} alone
142
+ * cannot show for a pass and a copy or clear around it.
143
+ *
144
+ * Each entry names its method and carries that call's arguments, with any size the caller left
145
+ * out filled in:
146
+ * - `{ method: 'beginComputePass' | 'beginRenderPass', pass }`
147
+ * - `{ method: 'copyBufferToBuffer', source, source_offset, destination, destination_offset, size }`
148
+ * - `{ method: 'clearBuffer', buffer, offset, size }`
149
+ * - `{ method: 'copyTextureToTexture' | 'copyBufferToTexture' | 'copyTextureToBuffer', source, destination, size }`
150
+ * - `{ method: 'resolveQuerySet', query_set, first_query, query_count, destination, destination_offset }`
151
+ *
152
+ * @type {Object[]}
153
+ */
154
+ operations = [];
155
+
138
156
  /**
139
157
  * The pass currently open on this encoder, `null` when none is.
140
158
  *
@@ -302,6 +320,7 @@ export class SoftwareGPUCommandEncoder extends SoftwareGPUObjectBase {
302
320
 
303
321
  this.compute_passes.push(pass);
304
322
  this.passes.push(pass);
323
+ this.operations.push({ method: 'beginComputePass', pass });
305
324
 
306
325
  return pass;
307
326
  }
@@ -387,6 +406,7 @@ export class SoftwareGPUCommandEncoder extends SoftwareGPUObjectBase {
387
406
 
388
407
  this.render_passes.push(pass);
389
408
  this.passes.push(pass);
409
+ this.operations.push({ method: 'beginRenderPass', pass });
390
410
 
391
411
  return pass;
392
412
  }
@@ -421,6 +441,8 @@ export class SoftwareGPUCommandEncoder extends SoftwareGPUObjectBase {
421
441
  texture_copy_execute({ texture_source: source, texture_destination: destination, size: copySize });
422
442
  }
423
443
  });
444
+
445
+ this.operations.push({ method: 'copyTextureToTexture', source, destination, size: copySize });
424
446
  }
425
447
 
426
448
  /**
@@ -450,6 +472,8 @@ export class SoftwareGPUCommandEncoder extends SoftwareGPUObjectBase {
450
472
  texture_copy_execute({ buffer_source: source, texture_destination: destination, size: copySize });
451
473
  }
452
474
  });
475
+
476
+ this.operations.push({ method: 'copyBufferToTexture', source, destination, size: copySize });
453
477
  }
454
478
 
455
479
  /**
@@ -479,6 +503,8 @@ export class SoftwareGPUCommandEncoder extends SoftwareGPUObjectBase {
479
503
  texture_copy_execute({ texture_source: source, buffer_destination: destination, size: copySize });
480
504
  }
481
505
  });
506
+
507
+ this.operations.push({ method: 'copyTextureToBuffer', source, destination, size: copySize });
482
508
  }
483
509
 
484
510
  /**
@@ -513,6 +539,15 @@ export class SoftwareGPUCommandEncoder extends SoftwareGPUObjectBase {
513
539
  .set(querySet.read(firstQuery, queryCount));
514
540
  }
515
541
  });
542
+
543
+ this.operations.push({
544
+ method: 'resolveQuerySet',
545
+ query_set: querySet,
546
+ first_query: firstQuery,
547
+ query_count: queryCount,
548
+ destination,
549
+ destination_offset: destinationOffset,
550
+ });
516
551
  }
517
552
 
518
553
  /**
@@ -683,6 +718,15 @@ export class SoftwareGPUCommandEncoder extends SoftwareGPUObjectBase {
683
718
  array_buffer_copy(source.data, sourceOffset, destination.data, destinationOffset, _size);
684
719
  }
685
720
  });
721
+
722
+ this.operations.push({
723
+ method: 'copyBufferToBuffer',
724
+ source,
725
+ source_offset: sourceOffset,
726
+ destination,
727
+ destination_offset: destinationOffset,
728
+ size: _size,
729
+ });
686
730
  }
687
731
 
688
732
  /**
@@ -720,6 +764,8 @@ export class SoftwareGPUCommandEncoder extends SoftwareGPUObjectBase {
720
764
  new Uint8Array(buffer.data, offset, clear_size).fill(0);
721
765
  }
722
766
  });
767
+
768
+ this.operations.push({ method: 'clearBuffer', buffer, offset, size: clear_size });
723
769
  }
724
770
  }
725
771
 
@@ -7,6 +7,18 @@
7
7
  * Note: GPU and CPU-side states are allowed to diverge but must eventually be synchronized.
8
8
  * This means that a modification on one side must propagate to the other.
9
9
  * see "Rendering 'Assassin's Creed Shadows'" GDC 2025 by Nicolas Lopez
10
+ *
11
+ * **What a row nobody occupies reads as on the GPU.** A shader may read a row by its index without
12
+ * asking the page's occupancy bitmap. To GPU work encoded after {@link update} on the same encoder:
13
+ * - a row of a page that has no slot reads as a record of zeros: the generated readers refuse it;
14
+ * - a row nothing has written, on a page that has a slot, reads as zeros too: a page's records are
15
+ * cleared when it is given a slot, whichever page of whichever table held that slot before;
16
+ * - a row freed with {@link GPUTypedTable#remove} reads as the freed record: zeros, with
17
+ * `GPU_DATABASE_NULL` in its link words and in the first word of its ranges.
18
+ *
19
+ * So a link word of an unoccupied row holds 0 or NULL depending on the row's history, and a reader
20
+ * that skips occupancy must not follow one. {@link GPUTypedTable#clear} sends nothing, so the rows it
21
+ * frees keep their last record on a page that stays allocated.
10
22
  */
11
23
  export class GPUDatabase {
12
24
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"GPUDatabase.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/buffer/table/GPUDatabase.js"],"names":[],"mappings":"AA4CA;;;;;;;;;GASG;AACH;IAEI;;;;OAIG;IACH,iCAFW,eAAe,QAKzB;IA8FD;;;;;;OAMG;IACH;QAL0C,UAAU,EAAzC,qBAAqB;QACF,MAAM;QACR,KAAK,GAAtB,MAAM;QACW,uBAAuB,GAAxC,MAAM;OAkJhB;IAlPD;;;OAGG;IACH,YAFU,qBAAqB,CAEpB;IAEX;;;;OAIG;IACH,QAFU,oBAAe,CAElB;IASP;;;OAGG;IACH,kBAAO;IAmDP;;OAEG;IACH,8BAEC;IAED;;;;OAIG;IACH,oBAEC;IA2JD;;;;;OAKG;IACH,UAHW,MAAM,GACJ,qBAAc,SAAS,CAUnC;IAGD;;;;;;;;;;;OAWG;IACH,oCAcC;IAED;;;;;OAKG;IACH,gCAEC;IAoPD;;;;;;;;;;;OAWG;IACH,kCAeC;IAED;;;OAGG;IACH,gBAFW,sBAAsB,QA6FhC;IAkPD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;IACH,2BAJW,MAAM,GACJ,QAAQ,KAAG,CAAC,CA6HxB;IAED;;;;;;;OAOG;IACH,+BAJW,MAAM,iBACN,MAAM,GACJ,YAAU,CAkCtB;IAED;;;OAGG;IACH,+BAQC;IAED;;OAEG;IACH,gBASC;;CACJ;8BAvpCY,OAAO,6CAA6C,EAAE,eAAe;qCACrE,OAAO,2CAA2C,EAAE,sBAAsB;oCAC1E,OAAO,4BAA4B,EAAE,qBAAqB;8BAPzC,oBAAoB;oCALd,0BAA0B"}
1
+ {"version":3,"file":"GPUDatabase.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/buffer/table/GPUDatabase.js"],"names":[],"mappings":"AA4CA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH;IAEI;;;;OAIG;IACH,iCAFW,eAAe,QAKzB;IA8GD;;;;;;OAMG;IACH;QAL0C,UAAU,EAAzC,qBAAqB;QACF,MAAM;QACR,KAAK,GAAtB,MAAM;QACW,uBAAuB,GAAxC,MAAM;OAkJhB;IAlQD;;;OAGG;IACH,YAFU,qBAAqB,CAEpB;IAEX;;;;OAIG;IACH,QAFU,oBAAe,CAElB;IASP;;;OAGG;IACH,kBAAO;IAmEP;;OAEG;IACH,8BAEC;IAED;;;;OAIG;IACH,oBAEC;IA2JD;;;;;OAKG;IACH,UAHW,MAAM,GACJ,qBAAc,SAAS,CAUnC;IAGD;;;;;;;;;;;OAWG;IACH,oCAcC;IAED;;;;;OAKG;IACH,gCAEC;IA4PD;;;;;;;;;;;OAWG;IACH,kCAeC;IAED;;;OAGG;IACH,gBAFW,sBAAsB,QAgGhC;IAgSD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;IACH,2BAJW,MAAM,GACJ,QAAQ,KAAG,CAAC,CA6HxB;IAED;;;;;;;OAOG;IACH,+BAJW,MAAM,iBACN,MAAM,GACJ,YAAU,CAkCtB;IAED;;;OAGG;IACH,+BAQC;IAED;;OAEG;IACH,gBASC;;CACJ;8BA5uCY,OAAO,6CAA6C,EAAE,eAAe;qCACrE,OAAO,2CAA2C,EAAE,sBAAsB;oCAC1E,OAAO,4BAA4B,EAAE,qBAAqB;8BAPzC,oBAAoB;oCALd,0BAA0B"}
@@ -51,6 +51,18 @@ const UPLOAD_CHUNK_SIZE = 256 * KILOBYTE;
51
51
  * Note: GPU and CPU-side states are allowed to diverge but must eventually be synchronized.
52
52
  * This means that a modification on one side must propagate to the other.
53
53
  * see "Rendering 'Assassin's Creed Shadows'" GDC 2025 by Nicolas Lopez
54
+ *
55
+ * **What a row nobody occupies reads as on the GPU.** A shader may read a row by its index without
56
+ * asking the page's occupancy bitmap. To GPU work encoded after {@link update} on the same encoder:
57
+ * - a row of a page that has no slot reads as a record of zeros: the generated readers refuse it;
58
+ * - a row nothing has written, on a page that has a slot, reads as zeros too: a page's records are
59
+ * cleared when it is given a slot, whichever page of whichever table held that slot before;
60
+ * - a row freed with {@link GPUTypedTable#remove} reads as the freed record: zeros, with
61
+ * `GPU_DATABASE_NULL` in its link words and in the first word of its ranges.
62
+ *
63
+ * So a link word of an unoccupied row holds 0 or NULL depending on the row's history, and a reader
64
+ * that skips occupancy must not follow one. {@link GPUTypedTable#clear} sends nothing, so the rows it
65
+ * frees keep their last record on a page that stays allocated.
54
66
  */
55
67
  export class GPUDatabase {
56
68
 
@@ -130,6 +142,22 @@ export class GPUDatabase {
130
142
  */
131
143
  #page_buffer_pool;
132
144
 
145
+ /**
146
+ * The pages given a slot since {@link #clear_new_page_records} last ran, each after its table,
147
+ * flattened as `[table, page, table, page, …]` over the first {@link #pages_given_slots_length}
148
+ * entries. Entries past that are `null`. The array is never shortened, so it keeps its storage
149
+ * from one update to the next.
150
+ *
151
+ * @type {Array<GPUTypedTable|GPUPageMetadata|null>}
152
+ */
153
+ #pages_given_slots = [];
154
+
155
+ /**
156
+ * How many entries of {@link #pages_given_slots} are live: twice the number of pages.
157
+ * @type {number}
158
+ */
159
+ #pages_given_slots_length = 0;
160
+
133
161
  /**
134
162
  * Batched row readback, built on first use.
135
163
  *
@@ -557,6 +585,14 @@ export class GPUDatabase {
557
585
 
558
586
  page.slot_offset = slot_offset;
559
587
 
588
+ const given = this.#pages_given_slots;
589
+ const given_length = this.#pages_given_slots_length;
590
+
591
+ given[given_length] = table;
592
+ given[given_length + 1] = page;
593
+
594
+ this.#pages_given_slots_length = given_length + 2;
595
+
560
596
  const alloc_idx = table.descriptor.page_lookup_address + page_index;
561
597
 
562
598
  this.#allocation_table[alloc_idx] = slot_offset + this.#data_start_offset;
@@ -675,6 +711,9 @@ export class GPUDatabase {
675
711
  this.#deallocate_empty_pages(table);
676
712
  }
677
713
 
714
+ // after every page has its slot, and before the record uploads that land on top
715
+ this.#clear_new_page_records(encoder);
716
+
678
717
  // update allocation table — only the dirty range
679
718
  if (this.#alloc_table_dirty_min <= this.#alloc_table_dirty_max) {
680
719
  const min_byte = this.#alloc_table_dirty_min * Uint32Array.BYTES_PER_ELEMENT;
@@ -732,6 +771,52 @@ export class GPUDatabase {
732
771
  }
733
772
  }
734
773
 
774
+ /**
775
+ * Clear the records of every page given a slot since this last ran, so that a row nothing has
776
+ * written reads as a record of zeros and not as whatever the slot's previous page, of this table
777
+ * or any other, left there. See the class documentation for what an unoccupied row reads as.
778
+ *
779
+ * Called once every page has its slot: growing the buffer moves pages to new slots, so a clear
780
+ * encoded before the move would land in the buffer being replaced. The header is left alone
781
+ * because it goes up through the queue, and a queue write lands ahead of the whole submission —
782
+ * a clear over it would erase it. The record uploads, encoded after this, land on top.
783
+ *
784
+ * @param {ShadeGPUCommandContext} encoder
785
+ */
786
+ #clear_new_page_records(encoder) {
787
+ const pages = this.#pages_given_slots;
788
+ const length = this.#pages_given_slots_length;
789
+
790
+ if (length === 0) {
791
+ return;
792
+ }
793
+
794
+ const word_size = GPU_DATABASE_BUFFER_ELEMENT_TYPE.size;
795
+ const data_start = this.#data_start_offset;
796
+
797
+ for (let i = 0; i < length; i += 2) {
798
+ const descriptor = /** @type {GPUTypedTable} */ (pages[i]).descriptor;
799
+ const slot_offset = /** @type {GPUPageMetadata} */ (pages[i + 1]).slot_offset;
800
+
801
+ // let go of both, so a freed page is not kept alive by the list
802
+ pages[i] = null;
803
+ pages[i + 1] = null;
804
+
805
+ if (slot_offset === -1) {
806
+ // emptied in the same update, and its slot already given back
807
+ continue;
808
+ }
809
+
810
+ encoder.clearBuffer(
811
+ this.buffer,
812
+ (slot_offset + data_start + descriptor.page_header_words) * word_size,
813
+ descriptor.elements_per_page * descriptor.packed_element_size_bytes
814
+ );
815
+ }
816
+
817
+ this.#pages_given_slots_length = 0;
818
+ }
819
+
735
820
  /**
736
821
  * Dispatch a table's pending whole-record writes, chunked so no single transient buffer grows
737
822
  * past {@link UPLOAD_CHUNK_SIZE}. Rewinds the buffer.
@@ -48,7 +48,8 @@ export class GPUDatabaseDefinition {
48
48
  * it into every link word the row has, whatever `nullable` says, because a freed row points
49
49
  * nowhere; a new page starts with it in every link word too. So a link no write has touched names
50
50
  * no row, on a row never written as on one freed, and a value that leaves a link out leaves it
51
- * naming nothing.
51
+ * naming nothing. That holds on the GPU for every occupied row and every freed one; a row the GPU
52
+ * has never been sent reads 0 there instead (see {@link GPUDatabase}).
52
53
  *
53
54
  * `owning` means one thing: removing the row that holds the link removes the row it names, and
54
55
  * that row's owned rows in turn ({@link GPUTypedTable#remove}). Nothing else follows it.
@@ -1 +1 @@
1
- {"version":3,"file":"GPUDatabaseDefinition.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/buffer/table/GPUDatabaseDefinition.js"],"names":[],"mappings":"AAwCA;;;;;;;;;;GAUG;AACH;IA0DI;;;;;OAKG;IACH,0CAHW,MAAM,GACJ,qBAAqB,CAIjC;IA9BD;;;OAGG;IACH,2CAFW,MAAM,EAkBhB;IAvDD;;OAEG;IACH,aAFU,uBAAuB,EAAE,CAElB;IAOjB;;;OAGG;IACH,iBAFU,MAAM,CAEA;IA8FhB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8CG;IACH,eAVW;QACV,KAAW,EAAE,MAAM,CAAC;QACpB,KAAW,EAAE,MAAM,CAAC;QACpB,eAAqB,EAAE,qBAAqB,CAAC;QAC7C,YAAkB,EAAE,MAAM,CAAC;QAC3B,QAAc,EAAE,OAAO,CAAC;QACxB,MAAY,EAAE,OAAO,CAAC;KACnB,GACS,YAAY,CAgDxB;IAED;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,gBAVW;QACV,KAAW,EAAE,MAAM,CAAC;QACpB,WAAiB,EAAE,MAAM,CAAC;QAC1B,WAAiB,EAAE,MAAM,CAAC;QAC1B,eAAqB,EAAE,qBAAqB,CAAC;QAC7C,YAAkB,EAAE,MAAM,CAAC;QAC3B,MAAY,EAAE,OAAO,CAAC;KACnB,GACS,aAAa,CAmDzB;IAiCD;;;OAGG;IACH,4BAEC;IAED;;;OAGG;IACH,8BAEC;IAED;;;;;OAKG;IACH,iBAHW,uBAAuB,GACrB,aAAa,EAAE,CAM3B;IAED;;;;;OAKG;IACH,gBAHW,uBAAuB,GACrB,YAAY,EAAE,CAM1B;IAED;;;;OAIG;IACH,sBAEC;IAED;;;;;;;OAOG;IACH,aAiEC;IAED;;;;OAIG;IACH,UAHW,MAAM,GACJ,OAAO,CAMnB;IAED;;;OAGG;IACH,UAHW,MAAM,GACJ,uBAAuB,GAAC,SAAS,CAM7C;IAED;;OAEG;IACH,0BAEC;IAGL;;;OAGG;IACH,kCAFU,OAAO,CAEsC;;CANtD;wCA5fuC,8BAA8B;6BAFzC,mBAAmB;8BAClB,oBAAoB"}
1
+ {"version":3,"file":"GPUDatabaseDefinition.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/buffer/table/GPUDatabaseDefinition.js"],"names":[],"mappings":"AAwCA;;;;;;;;;;GAUG;AACH;IA0DI;;;;;OAKG;IACH,0CAHW,MAAM,GACJ,qBAAqB,CAIjC;IA9BD;;;OAGG;IACH,2CAFW,MAAM,EAkBhB;IAvDD;;OAEG;IACH,aAFU,uBAAuB,EAAE,CAElB;IAOjB;;;OAGG;IACH,iBAFU,MAAM,CAEA;IA8FhB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA+CG;IACH,eAVW;QACV,KAAW,EAAE,MAAM,CAAC;QACpB,KAAW,EAAE,MAAM,CAAC;QACpB,eAAqB,EAAE,qBAAqB,CAAC;QAC7C,YAAkB,EAAE,MAAM,CAAC;QAC3B,QAAc,EAAE,OAAO,CAAC;QACxB,MAAY,EAAE,OAAO,CAAC;KACnB,GACS,YAAY,CAgDxB;IAED;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,gBAVW;QACV,KAAW,EAAE,MAAM,CAAC;QACpB,WAAiB,EAAE,MAAM,CAAC;QAC1B,WAAiB,EAAE,MAAM,CAAC;QAC1B,eAAqB,EAAE,qBAAqB,CAAC;QAC7C,YAAkB,EAAE,MAAM,CAAC;QAC3B,MAAY,EAAE,OAAO,CAAC;KACnB,GACS,aAAa,CAmDzB;IAiCD;;;OAGG;IACH,4BAEC;IAED;;;OAGG;IACH,8BAEC;IAED;;;;;OAKG;IACH,iBAHW,uBAAuB,GACrB,aAAa,EAAE,CAM3B;IAED;;;;;OAKG;IACH,gBAHW,uBAAuB,GACrB,YAAY,EAAE,CAM1B;IAED;;;;OAIG;IACH,sBAEC;IAED;;;;;;;OAOG;IACH,aAiEC;IAED;;;;OAIG;IACH,UAHW,MAAM,GACJ,OAAO,CAMnB;IAED;;;OAGG;IACH,UAHW,MAAM,GACJ,uBAAuB,GAAC,SAAS,CAM7C;IAED;;OAEG;IACH,0BAEC;IAGL;;;OAGG;IACH,kCAFU,OAAO,CAEsC;;CANtD;wCA7fuC,8BAA8B;6BAFzC,mBAAmB;8BAClB,oBAAoB"}
@@ -175,7 +175,8 @@ export class GPUDatabaseDefinition {
175
175
  * it into every link word the row has, whatever `nullable` says, because a freed row points
176
176
  * nowhere; a new page starts with it in every link word too. So a link no write has touched names
177
177
  * no row, on a row never written as on one freed, and a value that leaves a link out leaves it
178
- * naming nothing.
178
+ * naming nothing. That holds on the GPU for every occupied row and every freed one; a row the GPU
179
+ * has never been sent reads 0 there instead (see {@link GPUDatabase}).
179
180
  *
180
181
  * `owning` means one thing: removing the row that holds the link removes the row it names, and
181
182
  * that row's owned rows in turn ({@link GPUTypedTable#remove}). Nothing else follows it.