@gnsx/three 0.185.9 → 0.185.11

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.
@@ -33990,6 +33990,16 @@ class RenderContext {
33990
33990
  */
33991
33991
  this.camera = null;
33992
33992
 
33993
+ // WITH_GENESYS
33994
+ /**
33995
+ * An optional label used to identify this render pass in GPU profiler output.
33996
+ *
33997
+ * @type {?string}
33998
+ * @default null
33999
+ */
34000
+ this.gpuProfilerLabel = null;
34001
+ // !WITH_GENESYS
34002
+
33993
34003
  /**
33994
34004
  * This flag can be used for type testing.
33995
34005
  *
@@ -61592,6 +61602,25 @@ class Renderer {
61592
61602
 
61593
61603
  const renderContext = this._renderContexts.get( renderTarget, this._mrt, this._callDepth );
61594
61604
 
61605
+ // WITH_GENESYS
61606
+ // Prefer an explicit scene/pass name; otherwise fall back to the render
61607
+ // target texture name so depth/shadow/RTT work is not an invisible hole.
61608
+ let gpuProfilerLabel = scene.name !== '' ? scene.name : null;
61609
+ if ( gpuProfilerLabel === null && renderTarget !== null ) {
61610
+
61611
+ const textureName = renderTarget.texture?.name;
61612
+ if ( textureName !== undefined && textureName !== null && textureName !== '' ) {
61613
+
61614
+ gpuProfilerLabel = textureName;
61615
+
61616
+ }
61617
+
61618
+ }
61619
+
61620
+ renderContext.gpuProfilerLabel = gpuProfilerLabel;
61621
+ // !WITH_GENESYS
61622
+ // renderContext.gpuProfilerLabel = scene.name !== '' ? scene.name : null;
61623
+
61595
61624
  this._currentRenderContext = renderContext;
61596
61625
  this._currentRenderObjectFunction = this._renderObjectFunction || this.renderObject;
61597
61626
  this._handleObjectFunction = this._renderObjectDirect;
@@ -62591,7 +62620,7 @@ class Renderer {
62591
62620
 
62592
62621
  // WITH_GENESYS
62593
62622
  // Drop the strong reference to the active `RenderContext` so module-level
62594
- // `WeakMap<RenderContext, �?>` caches can release entries once
62623
+ // `WeakMap<RenderContext, ...>` caches can release entries once
62595
62624
  // `_renderContexts.dispose()` has cleared its dictionary.
62596
62625
  this._currentRenderContext = null;
62597
62626
  // !WITH_GENESYS
@@ -67058,6 +67087,15 @@ class Backend {
67058
67087
  [ TimestampQuery.COMPUTE ]: null
67059
67088
  };
67060
67089
 
67090
+ // WITH_GENESYS
67091
+ /**
67092
+ * Listeners notified after a timestamp query is successfully allocated.
67093
+ *
67094
+ * @type {Set<function(string, string, ?string): void>}
67095
+ */
67096
+ this.timestampQueryListeners = new Set();
67097
+ // !WITH_GENESYS
67098
+
67061
67099
  /**
67062
67100
  * Whether to track timestamps with a Timestamp Query API or not.
67063
67101
  *
@@ -67496,6 +67534,41 @@ class Backend {
67496
67534
 
67497
67535
  }
67498
67536
 
67537
+ // WITH_GENESYS
67538
+ /**
67539
+ * @param {function(string, string, ?string): void} listener
67540
+ */
67541
+ addTimestampQueryListener( listener ) {
67542
+
67543
+ this.timestampQueryListeners.add( listener );
67544
+
67545
+ }
67546
+
67547
+ /**
67548
+ * @param {function(string, string, ?string): void} listener
67549
+ */
67550
+ removeTimestampQueryListener( listener ) {
67551
+
67552
+ this.timestampQueryListeners.delete( listener );
67553
+
67554
+ }
67555
+
67556
+ /**
67557
+ * @param {string} type
67558
+ * @param {string} uid
67559
+ * @param {?string} [label=null]
67560
+ */
67561
+ notifyTimestampQuery( type, uid, label = null ) {
67562
+
67563
+ for ( const listener of this.timestampQueryListeners ) {
67564
+
67565
+ listener( type, uid, label );
67566
+
67567
+ }
67568
+
67569
+ }
67570
+ // !WITH_GENESYS
67571
+
67499
67572
  /**
67500
67573
  * Returns all timestamp frames for the given type.
67501
67574
  *
@@ -67539,6 +67612,22 @@ class Backend {
67539
67612
 
67540
67613
  }
67541
67614
 
67615
+ // WITH_GENESYS
67616
+ /**
67617
+ * Returns the raw GPU timestamp range for the given uid when supported.
67618
+ *
67619
+ * @param {string} uid - The unique identifier.
67620
+ * @return {?{start: bigint, end: bigint}} The raw timestamp range.
67621
+ */
67622
+ getTimestampRange( uid ) {
67623
+
67624
+ const queryPool = this._getQueryPool( uid );
67625
+
67626
+ return queryPool.getTimestampRange( uid );
67627
+
67628
+ }
67629
+ // !WITH_GENESYS
67630
+
67542
67631
  /**
67543
67632
  * Whether the backend supports query timestamps or not.
67544
67633
  *
@@ -71534,6 +71623,15 @@ class TimestampQueryPool {
71534
71623
  */
71535
71624
  this.timestamps = new Map();
71536
71625
 
71626
+ // WITH_GENESYS
71627
+ /**
71628
+ * Stores raw GPU timestamp ranges for each render context when supported.
71629
+ *
71630
+ * @type {Map<string, {start: bigint, end: bigint}>}
71631
+ */
71632
+ this.timestampRanges = new Map();
71633
+ // !WITH_GENESYS
71634
+
71537
71635
  }
71538
71636
 
71539
71637
  /**
@@ -71569,6 +71667,20 @@ class TimestampQueryPool {
71569
71667
 
71570
71668
  }
71571
71669
 
71670
+ // WITH_GENESYS
71671
+ /**
71672
+ * Returns the raw GPU timestamp range for a render context.
71673
+ *
71674
+ * @param {string} uid - A unique identifier for the render context.
71675
+ * @return {?{start: bigint, end: bigint}} The raw timestamp range, or null when unsupported.
71676
+ */
71677
+ getTimestampRange( uid ) {
71678
+
71679
+ return this.timestampRanges.get( uid ) ?? null;
71680
+
71681
+ }
71682
+ // !WITH_GENESYS
71683
+
71572
71684
  /**
71573
71685
  * Returns whether a timestamp is available for a given render context.
71574
71686
  *
@@ -71689,33 +71801,34 @@ class WebGLTimestampQueryPool extends TimestampQueryPool {
71689
71801
  * Begins a timestamp query for the specified render context.
71690
71802
  *
71691
71803
  * @param {string} uid - A unique identifier for the render context.
71804
+ * @return {boolean} Whether the query was started.
71692
71805
  */
71693
71806
  beginQuery( uid ) {
71694
71807
 
71695
71808
  if ( ! this.trackTimestamp || this.isDisposed ) {
71696
71809
 
71697
- return;
71810
+ return false;
71698
71811
 
71699
71812
  }
71700
71813
 
71701
71814
  const baseOffset = this.queryOffsets.get( uid );
71702
71815
  if ( baseOffset == null ) {
71703
71816
 
71704
- return;
71817
+ return false;
71705
71818
 
71706
71819
  }
71707
71820
 
71708
71821
  // Don't start a new query if there's an active one
71709
71822
  if ( this.activeQuery !== null ) {
71710
71823
 
71711
- return;
71824
+ return false;
71712
71825
 
71713
71826
  }
71714
71827
 
71715
71828
  const query = this.queries[ baseOffset ];
71716
71829
  if ( ! query ) {
71717
71830
 
71718
- return;
71831
+ return false;
71719
71832
 
71720
71833
  }
71721
71834
 
@@ -71727,6 +71840,7 @@ class WebGLTimestampQueryPool extends TimestampQueryPool {
71727
71840
  this.gl.beginQuery( this.ext.TIME_ELAPSED_EXT, query );
71728
71841
  this.activeQuery = baseOffset;
71729
71842
  this.queryStates.set( baseOffset, 'started' );
71843
+ return true;
71730
71844
 
71731
71845
  }
71732
71846
 
@@ -71738,6 +71852,8 @@ class WebGLTimestampQueryPool extends TimestampQueryPool {
71738
71852
 
71739
71853
  }
71740
71854
 
71855
+ return false;
71856
+
71741
71857
  }
71742
71858
 
71743
71859
  /**
@@ -72393,7 +72509,11 @@ class WebGLBackend extends Backend {
72393
72509
  * @param {string} type - The type of the timestamp query.
72394
72510
  * @param {string} uid - A unique identifier for the timestamp query.
72395
72511
  */
72396
- initTimestampQuery( type, uid ) {
72512
+ // WITH_GENESYS
72513
+ initTimestampQuery( type, uid, label = null ) {
72514
+
72515
+ // !WITH_GENESYS
72516
+ // initTimestampQuery( type, uid ) {
72397
72517
 
72398
72518
  if ( ! this.disjoint || ! this.trackTimestamp ) return;
72399
72519
 
@@ -72410,7 +72530,11 @@ class WebGLBackend extends Backend {
72410
72530
 
72411
72531
  if ( baseOffset !== null ) {
72412
72532
 
72413
- timestampQueryPool.beginQuery( uid );
72533
+ const started = timestampQueryPool.beginQuery( uid );
72534
+
72535
+ // WITH_GENESYS
72536
+ if ( started ) this.notifyTimestampQuery( type, uid, label );
72537
+ // !WITH_GENESYS
72414
72538
 
72415
72539
  }
72416
72540
 
@@ -72483,7 +72607,10 @@ class WebGLBackend extends Backend {
72483
72607
 
72484
72608
  //
72485
72609
 
72486
- this.initTimestampQuery( TimestampQuery.RENDER, this.getTimestampUID( renderContext ) );
72610
+ // WITH_GENESYS
72611
+ this.initTimestampQuery( TimestampQuery.RENDER, this.getTimestampUID( renderContext ), renderContext.gpuProfilerLabel );
72612
+ // !WITH_GENESYS
72613
+ // this.initTimestampQuery( TimestampQuery.RENDER, this.getTimestampUID( renderContext ) );
72487
72614
 
72488
72615
  renderContextData.previousContext = this._currentContext;
72489
72616
  this._currentContext = renderContext;
@@ -84226,7 +84353,20 @@ class WebGPUTimestampQueryPool extends TimestampQueryPool {
84226
84353
  const baseOffset = this.currentQueryIndex;
84227
84354
  this.currentQueryIndex += 2;
84228
84355
 
84229
- this.queryOffsets.set( uid, baseOffset );
84356
+ // WITH_GENESYS
84357
+ // One logical uid can own multiple GPU passes (nested interrupt /
84358
+ // copyFramebuffer restart). Keep every offset; resolve sums them.
84359
+ let offsets = this.queryOffsets.get( uid );
84360
+ if ( offsets === undefined ) {
84361
+
84362
+ offsets = [];
84363
+ this.queryOffsets.set( uid, offsets );
84364
+
84365
+ }
84366
+
84367
+ offsets.push( baseOffset );
84368
+ // !WITH_GENESYS
84369
+ // this.queryOffsets.set( uid, baseOffset );
84230
84370
 
84231
84371
  return baseOffset;
84232
84372
 
@@ -84348,7 +84488,7 @@ class WebGPUTimestampQueryPool extends TimestampQueryPool {
84348
84488
 
84349
84489
  const frames = [];
84350
84490
 
84351
- for ( const [ uid, baseOffset ] of currentOffsets ) {
84491
+ for ( const [ uid, offsetOrOffsets ] of currentOffsets ) {
84352
84492
 
84353
84493
  const match = uid.match( /^(.*):f(\d+)$/ );
84354
84494
  const frame = parseInt( match[ 2 ] );
@@ -84361,11 +84501,34 @@ class WebGPUTimestampQueryPool extends TimestampQueryPool {
84361
84501
 
84362
84502
  if ( framesDuration[ frame ] === undefined ) framesDuration[ frame ] = 0;
84363
84503
 
84364
- const startTime = times[ baseOffset ];
84365
- const endTime = times[ baseOffset + 1 ];
84366
- const duration = Number( endTime - startTime ) / 1e6;
84504
+ // WITH_GENESYS
84505
+ const offsets = Array.isArray( offsetOrOffsets ) ? offsetOrOffsets : [ offsetOrOffsets ];
84506
+ let duration = 0;
84507
+ let rangeStart = null;
84508
+ let rangeEnd = null;
84509
+
84510
+ for ( const baseOffset of offsets ) {
84511
+
84512
+ const startTime = times[ baseOffset ];
84513
+ const endTime = times[ baseOffset + 1 ];
84514
+ duration += Number( endTime - startTime ) / 1e6;
84515
+
84516
+ if ( rangeStart === null || startTime < rangeStart ) rangeStart = startTime;
84517
+ if ( rangeEnd === null || endTime > rangeEnd ) rangeEnd = endTime;
84518
+
84519
+ }
84367
84520
 
84368
84521
  this.timestamps.set( uid, duration );
84522
+ if ( rangeStart !== null && rangeEnd !== null ) {
84523
+
84524
+ this.timestampRanges.set( uid, { start: rangeStart, end: rangeEnd } );
84525
+
84526
+ }
84527
+ // !WITH_GENESYS
84528
+ // const startTime = times[ baseOffset ];
84529
+ // const endTime = times[ baseOffset + 1 ];
84530
+ // const duration = Number( endTime - startTime ) / 1e6;
84531
+ // this.timestamps.set( uid, duration );
84369
84532
 
84370
84533
  framesDuration[ frame ] += duration;
84371
84534
 
@@ -84464,6 +84627,9 @@ class WebGPUTimestampQueryPool extends TimestampQueryPool {
84464
84627
  }
84465
84628
 
84466
84629
  this.queryOffsets.clear();
84630
+ // WITH_GENESYS
84631
+ this.timestampRanges.clear();
84632
+ // !WITH_GENESYS
84467
84633
  this.pendingResolve = null;
84468
84634
 
84469
84635
  }
@@ -84605,54 +84771,6 @@ class GPURenderPassDepthStencilAttachment {
84605
84771
 
84606
84772
  }
84607
84773
 
84608
- /**
84609
- * Reusable descriptor for `GPURenderPassTimestampWrites`, the
84610
- * `timestampWrites` field of `GPURenderPassDescriptor`. The same shape is
84611
- * also accepted as `GPUComputePassTimestampWrites`.
84612
- *
84613
- * @private
84614
- */
84615
- class GPURenderPassTimestampWrites {
84616
-
84617
- constructor() {
84618
-
84619
- /**
84620
- * The query set the timestamps are written to.
84621
- *
84622
- * @type {?GPUQuerySet}
84623
- * @default null
84624
- */
84625
- this.querySet = null;
84626
-
84627
- /**
84628
- * The index in the query set the beginning timestamp is written to.
84629
- *
84630
- * @type {number|undefined}
84631
- */
84632
- this.beginningOfPassWriteIndex = undefined;
84633
-
84634
- /**
84635
- * The index in the query set the ending timestamp is written to.
84636
- *
84637
- * @type {number|undefined}
84638
- */
84639
- this.endOfPassWriteIndex = undefined;
84640
-
84641
- }
84642
-
84643
- /**
84644
- * Resets the descriptor to its default state.
84645
- */
84646
- reset() {
84647
-
84648
- this.querySet = null;
84649
- this.beginningOfPassWriteIndex = undefined;
84650
- this.endOfPassWriteIndex = undefined;
84651
-
84652
- }
84653
-
84654
- }
84655
-
84656
84774
  // debugger tools
84657
84775
  // import 'https://greggman.github.io/webgpu-avoid-redundant-state-setting/webgpu-check-redundant-state-setting.js';
84658
84776
 
@@ -84663,7 +84781,7 @@ const _commandEncoderDescriptor = new GPUCommandEncoderDescriptor();
84663
84781
  const _computePassDescriptor = new GPUComputePassDescriptor();
84664
84782
  const _querySetDescriptor = new GPUQuerySetDescriptor();
84665
84783
  const _shaderModuleDescriptor = new GPUShaderModuleDescriptor();
84666
- const _renderPassTimestampWrites = new GPURenderPassTimestampWrites();
84784
+ // const _renderPassTimestampWrites = new GPURenderPassTimestampWrites();
84667
84785
  const _texelCopyTextureInfoSrc = new GPUTexelCopyTextureInfo();
84668
84786
  const _texelCopyTextureInfoDst = new GPUTexelCopyTextureInfo();
84669
84787
  const _viewDescriptor = new GPUTextureViewDescriptor();
@@ -85463,7 +85581,10 @@ class WebGPUBackend extends Backend {
85463
85581
 
85464
85582
  }
85465
85583
 
85466
- this.initTimestampQuery( TimestampQuery.RENDER, this.getTimestampUID( renderContext ), descriptor );
85584
+ // WITH_GENESYS
85585
+ this.initTimestampQuery( TimestampQuery.RENDER, this.getTimestampUID( renderContext ), descriptor, renderContext.gpuProfilerLabel );
85586
+ // !WITH_GENESYS
85587
+ // this.initTimestampQuery( TimestampQuery.RENDER, this.getTimestampUID( renderContext ), descriptor );
85467
85588
 
85468
85589
  descriptor.occlusionQuerySet = occlusionQuerySet;
85469
85590
 
@@ -86879,7 +87000,11 @@ class WebGPUBackend extends Backend {
86879
87000
  * @param {number} uid - Unique id for the context (e.g. render context id).
86880
87001
  * @param {Object} descriptor - The query descriptor.
86881
87002
  */
86882
- initTimestampQuery( type, uid, descriptor ) {
87003
+ // WITH_GENESYS
87004
+ initTimestampQuery( type, uid, descriptor, label = null ) {
87005
+
87006
+ // !WITH_GENESYS
87007
+ // initTimestampQuery( type, uid, descriptor ) {
86883
87008
 
86884
87009
  if ( ! this.trackTimestamp ) return;
86885
87010
 
@@ -86899,11 +87024,22 @@ class WebGPUBackend extends Backend {
86899
87024
  if ( baseOffset === null || timestampQueryPool.querySet === null ) return;
86900
87025
  // !WITH_GENESYS
86901
87026
 
86902
- _renderPassTimestampWrites.querySet = timestampQueryPool.querySet;
86903
- _renderPassTimestampWrites.beginningOfPassWriteIndex = baseOffset;
86904
- _renderPassTimestampWrites.endOfPassWriteIndex = baseOffset + 1;
87027
+ // WITH_GENESYS
87028
+ // Per-pass object: a shared descriptor is mutated by nested beginRender /
87029
+ // copyFramebuffer restarts and can make unrelated passes write the same
87030
+ // query indices (shadow maps collapsing to ~1µs is the common symptom).
87031
+ descriptor.timestampWrites = {
87032
+ querySet: timestampQueryPool.querySet,
87033
+ beginningOfPassWriteIndex: baseOffset,
87034
+ endOfPassWriteIndex: baseOffset + 1,
87035
+ };
86905
87036
 
86906
- descriptor.timestampWrites = _renderPassTimestampWrites;
87037
+ this.notifyTimestampQuery( type, uid, label );
87038
+ // !WITH_GENESYS
87039
+ // _renderPassTimestampWrites.querySet = timestampQueryPool.querySet;
87040
+ // _renderPassTimestampWrites.beginningOfPassWriteIndex = baseOffset;
87041
+ // _renderPassTimestampWrites.endOfPassWriteIndex = baseOffset + 1;
87042
+ // descriptor.timestampWrites = _renderPassTimestampWrites;
86907
87043
 
86908
87044
  }
86909
87045
 
@@ -87464,6 +87600,17 @@ class WebGPUBackend extends Backend {
87464
87600
  if ( renderContext.depth ) descriptor.depthStencilAttachment.depthLoadOp = GPULoadOp.Load;
87465
87601
  if ( renderContext.stencil ) descriptor.depthStencilAttachment.stencilLoadOp = GPULoadOp.Load;
87466
87602
 
87603
+ // WITH_GENESYS
87604
+ // Restarted passes need fresh timestamp slots; reusing the previous
87605
+ // timestampWrites overwrites the first segment's query results.
87606
+ this.initTimestampQuery(
87607
+ TimestampQuery.RENDER,
87608
+ this.getTimestampUID( renderContext ),
87609
+ descriptor,
87610
+ renderContext.gpuProfilerLabel
87611
+ );
87612
+ // !WITH_GENESYS
87613
+
87467
87614
  renderContextData.currentPass = encoder.beginRenderPass( descriptor );
87468
87615
  renderContextData.currentSets = { attributes: {}, bindingGroups: [], pipeline: null, index: null };
87469
87616