@luma.gl/webgpu 9.3.0-alpha.4 → 9.3.0-alpha.6

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.
Files changed (93) hide show
  1. package/dist/adapter/helpers/cpu-hotspot-profiler.d.ts +54 -0
  2. package/dist/adapter/helpers/cpu-hotspot-profiler.d.ts.map +1 -0
  3. package/dist/adapter/helpers/cpu-hotspot-profiler.js +26 -0
  4. package/dist/adapter/helpers/cpu-hotspot-profiler.js.map +1 -0
  5. package/dist/adapter/helpers/generate-mipmaps-webgpu.d.ts +7 -0
  6. package/dist/adapter/helpers/generate-mipmaps-webgpu.d.ts.map +1 -0
  7. package/dist/adapter/helpers/generate-mipmaps-webgpu.js +490 -0
  8. package/dist/adapter/helpers/generate-mipmaps-webgpu.js.map +1 -0
  9. package/dist/adapter/helpers/get-bind-group.d.ts +2 -1
  10. package/dist/adapter/helpers/get-bind-group.d.ts.map +1 -1
  11. package/dist/adapter/helpers/get-bind-group.js +22 -18
  12. package/dist/adapter/helpers/get-bind-group.js.map +1 -1
  13. package/dist/adapter/resources/webgpu-buffer.d.ts.map +1 -1
  14. package/dist/adapter/resources/webgpu-buffer.js +19 -3
  15. package/dist/adapter/resources/webgpu-buffer.js.map +1 -1
  16. package/dist/adapter/resources/webgpu-command-buffer.js +1 -1
  17. package/dist/adapter/resources/webgpu-command-buffer.js.map +1 -1
  18. package/dist/adapter/resources/webgpu-command-encoder.d.ts +5 -4
  19. package/dist/adapter/resources/webgpu-command-encoder.d.ts.map +1 -1
  20. package/dist/adapter/resources/webgpu-command-encoder.js +23 -5
  21. package/dist/adapter/resources/webgpu-command-encoder.js.map +1 -1
  22. package/dist/adapter/resources/webgpu-compute-pass.d.ts +1 -1
  23. package/dist/adapter/resources/webgpu-compute-pass.d.ts.map +1 -1
  24. package/dist/adapter/resources/webgpu-compute-pass.js +14 -6
  25. package/dist/adapter/resources/webgpu-compute-pass.js.map +1 -1
  26. package/dist/adapter/resources/webgpu-compute-pipeline.d.ts.map +1 -1
  27. package/dist/adapter/resources/webgpu-compute-pipeline.js +19 -3
  28. package/dist/adapter/resources/webgpu-compute-pipeline.js.map +1 -1
  29. package/dist/adapter/resources/webgpu-framebuffer.d.ts +6 -0
  30. package/dist/adapter/resources/webgpu-framebuffer.d.ts.map +1 -1
  31. package/dist/adapter/resources/webgpu-framebuffer.js +16 -0
  32. package/dist/adapter/resources/webgpu-framebuffer.js.map +1 -1
  33. package/dist/adapter/resources/webgpu-query-set.d.ts +33 -4
  34. package/dist/adapter/resources/webgpu-query-set.d.ts.map +1 -1
  35. package/dist/adapter/resources/webgpu-query-set.js +145 -4
  36. package/dist/adapter/resources/webgpu-query-set.js.map +1 -1
  37. package/dist/adapter/resources/webgpu-render-pass.d.ts +3 -0
  38. package/dist/adapter/resources/webgpu-render-pass.d.ts.map +1 -1
  39. package/dist/adapter/resources/webgpu-render-pass.js +74 -30
  40. package/dist/adapter/resources/webgpu-render-pass.js.map +1 -1
  41. package/dist/adapter/resources/webgpu-render-pipeline.d.ts +7 -4
  42. package/dist/adapter/resources/webgpu-render-pipeline.d.ts.map +1 -1
  43. package/dist/adapter/resources/webgpu-render-pipeline.js +26 -15
  44. package/dist/adapter/resources/webgpu-render-pipeline.js.map +1 -1
  45. package/dist/adapter/resources/webgpu-sampler.d.ts.map +1 -1
  46. package/dist/adapter/resources/webgpu-sampler.js +4 -0
  47. package/dist/adapter/resources/webgpu-sampler.js.map +1 -1
  48. package/dist/adapter/resources/webgpu-texture-view.d.ts +6 -0
  49. package/dist/adapter/resources/webgpu-texture-view.d.ts.map +1 -1
  50. package/dist/adapter/resources/webgpu-texture-view.js +47 -11
  51. package/dist/adapter/resources/webgpu-texture-view.js.map +1 -1
  52. package/dist/adapter/resources/webgpu-texture.d.ts +10 -4
  53. package/dist/adapter/resources/webgpu-texture.d.ts.map +1 -1
  54. package/dist/adapter/resources/webgpu-texture.js +116 -57
  55. package/dist/adapter/resources/webgpu-texture.js.map +1 -1
  56. package/dist/adapter/resources/webgpu-vertex-array.js +1 -1
  57. package/dist/adapter/resources/webgpu-vertex-array.js.map +1 -1
  58. package/dist/adapter/webgpu-canvas-context.d.ts +2 -0
  59. package/dist/adapter/webgpu-canvas-context.d.ts.map +1 -1
  60. package/dist/adapter/webgpu-canvas-context.js +78 -19
  61. package/dist/adapter/webgpu-canvas-context.js.map +1 -1
  62. package/dist/adapter/webgpu-device.d.ts +5 -1
  63. package/dist/adapter/webgpu-device.d.ts.map +1 -1
  64. package/dist/adapter/webgpu-device.js +113 -9
  65. package/dist/adapter/webgpu-device.js.map +1 -1
  66. package/dist/adapter/webgpu-presentation-context.d.ts +25 -0
  67. package/dist/adapter/webgpu-presentation-context.d.ts.map +1 -0
  68. package/dist/adapter/webgpu-presentation-context.js +144 -0
  69. package/dist/adapter/webgpu-presentation-context.js.map +1 -0
  70. package/dist/dist.dev.js +2815 -1681
  71. package/dist/dist.min.js +167 -8
  72. package/dist/index.cjs +1314 -199
  73. package/dist/index.cjs.map +4 -4
  74. package/package.json +4 -4
  75. package/src/adapter/helpers/cpu-hotspot-profiler.ts +70 -0
  76. package/src/adapter/helpers/generate-mipmaps-webgpu.ts +583 -0
  77. package/src/adapter/helpers/get-bind-group.ts +26 -24
  78. package/src/adapter/resources/webgpu-buffer.ts +18 -3
  79. package/src/adapter/resources/webgpu-command-buffer.ts +1 -1
  80. package/src/adapter/resources/webgpu-command-encoder.ts +32 -6
  81. package/src/adapter/resources/webgpu-compute-pass.ts +14 -6
  82. package/src/adapter/resources/webgpu-compute-pipeline.ts +21 -3
  83. package/src/adapter/resources/webgpu-framebuffer.ts +21 -0
  84. package/src/adapter/resources/webgpu-query-set.ts +185 -9
  85. package/src/adapter/resources/webgpu-render-pass.ts +82 -34
  86. package/src/adapter/resources/webgpu-render-pipeline.ts +36 -19
  87. package/src/adapter/resources/webgpu-sampler.ts +5 -0
  88. package/src/adapter/resources/webgpu-texture-view.ts +51 -11
  89. package/src/adapter/resources/webgpu-texture.ts +142 -93
  90. package/src/adapter/resources/webgpu-vertex-array.ts +1 -1
  91. package/src/adapter/webgpu-canvas-context.ts +91 -26
  92. package/src/adapter/webgpu-device.ts +128 -9
  93. package/src/adapter/webgpu-presentation-context.ts +180 -0
@@ -11,59 +11,107 @@ import {WebGPUBuffer} from './webgpu-buffer';
11
11
  import {WebGPURenderPipeline} from './webgpu-render-pipeline';
12
12
  import {WebGPUQuerySet} from './webgpu-query-set';
13
13
  import {WebGPUFramebuffer} from './webgpu-framebuffer';
14
+ import {getCpuHotspotProfiler, getTimestamp} from '../helpers/cpu-hotspot-profiler';
14
15
 
15
16
  export class WebGPURenderPass extends RenderPass {
16
17
  readonly device: WebGPUDevice;
17
18
  readonly handle: GPURenderPassEncoder;
19
+ readonly framebuffer: WebGPUFramebuffer;
18
20
 
19
21
  /** Active pipeline */
20
22
  pipeline: WebGPURenderPipeline | null = null;
21
23
 
24
+ /** Latest bindings applied to this pass */
25
+ bindings: Record<string, Binding> = {};
26
+
22
27
  constructor(device: WebGPUDevice, props: RenderPassProps = {}) {
23
28
  super(device, props);
24
29
  this.device = device;
25
- const framebuffer =
26
- (props.framebuffer as WebGPUFramebuffer) || device.getCanvasContext().getCurrentFramebuffer();
27
-
28
- const renderPassDescriptor = this.getRenderPassDescriptor(framebuffer);
30
+ const {props: renderPassProps} = this;
31
+ this.framebuffer =
32
+ (renderPassProps.framebuffer as WebGPUFramebuffer) ||
33
+ device.getCanvasContext().getCurrentFramebuffer();
29
34
 
30
- const webgpuQuerySet = props.timestampQuerySet as WebGPUQuerySet;
31
- if (webgpuQuerySet) {
32
- renderPassDescriptor.occlusionQuerySet = webgpuQuerySet.handle;
35
+ const profiler = getCpuHotspotProfiler(this.device);
36
+ if (profiler) {
37
+ const counterName:
38
+ | 'explicitFramebufferRenderPassCount'
39
+ | 'defaultFramebufferRenderPassCount' = renderPassProps.framebuffer
40
+ ? 'explicitFramebufferRenderPassCount'
41
+ : 'defaultFramebufferRenderPassCount';
42
+ profiler[counterName] = (profiler[counterName] || 0) + 1;
33
43
  }
34
44
 
35
- if (device.features.has('timestamp-query')) {
36
- const webgpuTSQuerySet = props.timestampQuerySet as WebGPUQuerySet;
37
- renderPassDescriptor.timestampWrites = webgpuTSQuerySet
38
- ? ({
39
- querySet: webgpuTSQuerySet.handle,
40
- beginningOfPassWriteIndex: props.beginTimestampIndex,
41
- endOfPassWriteIndex: props.endTimestampIndex
42
- } as GPUComputePassTimestampWrites)
43
- : undefined;
44
- }
45
+ const startTime = profiler ? getTimestamp() : 0;
46
+ try {
47
+ const descriptorAssemblyStartTime = profiler ? getTimestamp() : 0;
48
+ const renderPassDescriptor = this.getRenderPassDescriptor(this.framebuffer);
45
49
 
46
- if (!device.commandEncoder) {
47
- throw new Error('commandEncoder not available');
48
- }
50
+ if (renderPassProps.occlusionQuerySet) {
51
+ renderPassDescriptor.occlusionQuerySet = (
52
+ renderPassProps.occlusionQuerySet as WebGPUQuerySet
53
+ ).handle;
54
+ }
49
55
 
50
- this.device.pushErrorScope('validation');
51
- this.handle =
52
- this.props.handle || device.commandEncoder.handle.beginRenderPass(renderPassDescriptor);
53
- this.device.popErrorScope((error: GPUError) => {
54
- this.device.reportError(new Error(`${this} creation failed:\n"${error.message}"`), this)();
55
- this.device.debug();
56
- });
57
- this.handle.label = this.props.id;
58
- log.groupCollapsed(3, `new WebGPURenderPass(${this.id})`)();
59
- log.probe(3, JSON.stringify(renderPassDescriptor, null, 2))();
60
- log.groupEnd(3)();
56
+ if (renderPassProps.timestampQuerySet) {
57
+ const webgpuTSQuerySet = renderPassProps.timestampQuerySet as WebGPUQuerySet;
58
+ webgpuTSQuerySet?._invalidateResults();
59
+ renderPassDescriptor.timestampWrites = webgpuTSQuerySet
60
+ ? ({
61
+ querySet: webgpuTSQuerySet.handle,
62
+ beginningOfPassWriteIndex: renderPassProps.beginTimestampIndex,
63
+ endOfPassWriteIndex: renderPassProps.endTimestampIndex
64
+ } as GPURenderPassTimestampWrites)
65
+ : undefined;
66
+ }
67
+ if (profiler) {
68
+ profiler.renderPassDescriptorAssemblyCount =
69
+ (profiler.renderPassDescriptorAssemblyCount || 0) + 1;
70
+ profiler.renderPassDescriptorAssemblyTimeMs =
71
+ (profiler.renderPassDescriptorAssemblyTimeMs || 0) +
72
+ (getTimestamp() - descriptorAssemblyStartTime);
73
+ }
74
+
75
+ if (!device.commandEncoder) {
76
+ throw new Error('commandEncoder not available');
77
+ }
78
+
79
+ this.device.pushErrorScope('validation');
80
+ const beginRenderPassStartTime = profiler ? getTimestamp() : 0;
81
+ this.handle =
82
+ this.props.handle || device.commandEncoder.handle.beginRenderPass(renderPassDescriptor);
83
+ if (profiler) {
84
+ profiler.renderPassBeginCount = (profiler.renderPassBeginCount || 0) + 1;
85
+ profiler.renderPassBeginTimeMs =
86
+ (profiler.renderPassBeginTimeMs || 0) + (getTimestamp() - beginRenderPassStartTime);
87
+ }
88
+ this.device.popErrorScope((error: GPUError) => {
89
+ this.device.reportError(new Error(`${this} creation failed:\n"${error.message}"`), this)();
90
+ this.device.debug();
91
+ });
92
+ this.handle.label = this.props.id;
93
+ log.groupCollapsed(3, `new WebGPURenderPass(${this.id})`)();
94
+ log.probe(3, JSON.stringify(renderPassDescriptor, null, 2))();
95
+ log.groupEnd(3)();
96
+ } finally {
97
+ if (profiler) {
98
+ profiler.renderPassSetupCount = (profiler.renderPassSetupCount || 0) + 1;
99
+ profiler.renderPassSetupTimeMs =
100
+ (profiler.renderPassSetupTimeMs || 0) + (getTimestamp() - startTime);
101
+ }
102
+ }
61
103
  }
62
104
 
63
- override destroy(): void {}
105
+ override destroy(): void {
106
+ this.destroyResource();
107
+ }
64
108
 
65
109
  end(): void {
110
+ if (this.destroyed) {
111
+ return;
112
+ }
66
113
  this.handle.end();
114
+ this.destroy();
67
115
  }
68
116
 
69
117
  setPipeline(pipeline: RenderPipeline): void {
@@ -78,8 +126,8 @@ export class WebGPURenderPass extends RenderPass {
78
126
 
79
127
  /** Sets an array of bindings (uniform buffers, samplers, textures, ...) */
80
128
  setBindings(bindings: Record<string, Binding>): void {
81
- this.pipeline?.setBindings(bindings);
82
- const bindGroup = this.pipeline?._getBindGroup();
129
+ this.bindings = bindings;
130
+ const bindGroup = this.pipeline?._getBindGroup(bindings);
83
131
  if (bindGroup) {
84
132
  this.handle.setBindGroup(0, bindGroup);
85
133
  }
@@ -15,6 +15,8 @@ import type {WebGPUDevice} from '../webgpu-device';
15
15
  import type {WebGPUShader} from './webgpu-shader';
16
16
  import type {WebGPURenderPass} from './webgpu-render-pass';
17
17
 
18
+ const EMPTY_BINDINGS: Record<string, Binding> = {};
19
+
18
20
  // RENDER PIPELINE
19
21
 
20
22
  /** Creates a new render pipeline when parameters change */
@@ -25,8 +27,9 @@ export class WebGPURenderPipeline extends RenderPipeline {
25
27
  readonly vs: WebGPUShader;
26
28
  readonly fs: WebGPUShader | null = null;
27
29
 
28
- /** For internal use to create BindGroups */
30
+ /** Compatibility path for direct pipeline.setBindings() usage */
29
31
  private _bindings: Record<string, Binding>;
32
+ /** For internal use to create BindGroups */
30
33
  private _bindGroupLayout: GPUBindGroupLayout | null = null;
31
34
  private _bindGroup: GPUBindGroup | null = null;
32
35
 
@@ -56,8 +59,7 @@ export class WebGPURenderPipeline extends RenderPipeline {
56
59
  // Note: Often the same shader in WebGPU
57
60
  this.vs = props.vs as WebGPUShader;
58
61
  this.fs = props.fs as WebGPUShader;
59
-
60
- this._bindings = {...this.props.bindings};
62
+ this._bindings = props.bindings || EMPTY_BINDINGS;
61
63
  }
62
64
 
63
65
  override destroy(): void {
@@ -67,17 +69,25 @@ export class WebGPURenderPipeline extends RenderPipeline {
67
69
  }
68
70
 
69
71
  /**
70
- * @todo Use renderpass.setBindings() ?
71
- * @todo Do we want to expose BindGroups in the API and remove this?
72
+ * Compatibility shim for code paths that still set bindings on the pipeline.
73
+ * The shared-model path passes bindings per draw and does not rely on this state.
72
74
  */
73
75
  setBindings(bindings: Record<string, Binding>): void {
74
- // Invalidate the cached bind group if any value has changed
76
+ let bindingsChanged = false;
75
77
  for (const [name, binding] of Object.entries(bindings)) {
76
78
  if (this._bindings[name] !== binding) {
77
- this._bindGroup = null;
79
+ if (!bindingsChanged) {
80
+ if (this._bindings === this.props.bindings || this._bindings === EMPTY_BINDINGS) {
81
+ this._bindings = {...this._bindings};
82
+ }
83
+ bindingsChanged = true;
84
+ }
85
+ this._bindings[name] = binding;
78
86
  }
79
87
  }
80
- Object.assign(this._bindings, bindings);
88
+ if (bindingsChanged) {
89
+ this._bindGroup = null;
90
+ }
81
91
  }
82
92
 
83
93
  /** @todo - should this be moved to renderpass? */
@@ -91,8 +101,12 @@ export class WebGPURenderPipeline extends RenderPipeline {
91
101
  firstIndex?: number;
92
102
  firstInstance?: number;
93
103
  baseVertex?: number;
104
+ bindings?: Record<string, Binding>;
105
+ uniforms?: Record<string, unknown>;
94
106
  }): boolean {
95
107
  const webgpuRenderPass = options.renderPass as WebGPURenderPass;
108
+ const instanceCount =
109
+ options.instanceCount && options.instanceCount > 0 ? options.instanceCount : 1;
96
110
 
97
111
  // Set pipeline
98
112
  this.device.pushErrorScope('validation');
@@ -103,7 +117,7 @@ export class WebGPURenderPipeline extends RenderPipeline {
103
117
  });
104
118
 
105
119
  // Set bindings (uniform buffers, textures etc)
106
- const bindGroup = this._getBindGroup();
120
+ const bindGroup = this._getBindGroup(options.bindings);
107
121
  if (bindGroup) {
108
122
  webgpuRenderPass.handle.setBindGroup(0, bindGroup);
109
123
  }
@@ -116,16 +130,17 @@ export class WebGPURenderPipeline extends RenderPipeline {
116
130
  if (options.indexCount) {
117
131
  webgpuRenderPass.handle.drawIndexed(
118
132
  options.indexCount,
119
- options.instanceCount,
120
- options.firstIndex,
121
- options.baseVertex,
122
- options.firstInstance
133
+ instanceCount,
134
+ options.firstIndex || 0,
135
+ options.baseVertex || 0,
136
+ options.firstInstance || 0
123
137
  );
124
138
  } else {
125
139
  webgpuRenderPass.handle.draw(
126
140
  options.vertexCount || 0,
127
- options.instanceCount || 1, // If 0, nothing will be drawn
128
- options.firstInstance
141
+ instanceCount,
142
+ options.firstVertex || 0,
143
+ options.firstInstance || 0
129
144
  );
130
145
  }
131
146
 
@@ -136,7 +151,7 @@ export class WebGPURenderPipeline extends RenderPipeline {
136
151
  }
137
152
 
138
153
  /** Return a bind group created by setBindings */
139
- _getBindGroup() {
154
+ _getBindGroup(bindings?: Record<string, Binding>) {
140
155
  if (this.shaderLayout.bindings.length === 0) {
141
156
  return null;
142
157
  }
@@ -144,11 +159,13 @@ export class WebGPURenderPipeline extends RenderPipeline {
144
159
  // Get hold of the bind group layout. We don't want to do this unless we know there is at least one bind group
145
160
  this._bindGroupLayout = this._bindGroupLayout || this.handle.getBindGroupLayout(0);
146
161
 
147
- // Set up the bindings
148
- // TODO what if bindings change? We need to rebuild the bind group!
162
+ if (bindings) {
163
+ return getBindGroup(this.device, this._bindGroupLayout, this.shaderLayout, bindings);
164
+ }
165
+
149
166
  this._bindGroup =
150
167
  this._bindGroup ||
151
- getBindGroup(this.device.handle, this._bindGroupLayout, this.shaderLayout, this._bindings);
168
+ getBindGroup(this.device, this._bindGroupLayout, this.shaderLayout, this._bindings);
152
169
 
153
170
  return this._bindGroup;
154
171
  }
@@ -40,6 +40,11 @@ export class WebGPUSampler extends Sampler {
40
40
  }
41
41
 
42
42
  override destroy(): void {
43
+ if (this.destroyed) {
44
+ return;
45
+ }
46
+
47
+ this.destroyResource();
43
48
  // GPUSampler does not have a destroy method
44
49
  // this.handle.destroy();
45
50
  // @ts-expect-error readonly
@@ -5,6 +5,7 @@
5
5
  import {TextureView, TextureViewProps} from '@luma.gl/core';
6
6
  import type {WebGPUDevice} from '../webgpu-device';
7
7
  import type {WebGPUTexture} from './webgpu-texture';
8
+ import {getCpuHotspotProfiler, getTimestamp} from '../helpers/cpu-hotspot-profiler';
8
9
 
9
10
  /*
10
11
  // type = sampler
@@ -39,17 +40,15 @@ export class WebGPUTextureView extends TextureView {
39
40
  this.texture = props.texture;
40
41
 
41
42
  this.device.pushErrorScope('validation');
42
- this.handle =
43
- // props.handle ||
44
- this.texture.handle.createView({
45
- format: (this.props.format || this.texture.format) as GPUTextureFormat,
46
- dimension: this.props.dimension || this.texture.dimension,
47
- aspect: this.props.aspect,
48
- baseMipLevel: this.props.baseMipLevel,
49
- mipLevelCount: this.props.mipLevelCount,
50
- baseArrayLayer: this.props.baseArrayLayer,
51
- arrayLayerCount: this.props.arrayLayerCount
52
- });
43
+ this.handle = this.texture.handle.createView({
44
+ format: (this.props.format || this.texture.format) as GPUTextureFormat,
45
+ dimension: this.props.dimension || this.texture.dimension,
46
+ aspect: this.props.aspect,
47
+ baseMipLevel: this.props.baseMipLevel,
48
+ mipLevelCount: this.props.mipLevelCount,
49
+ baseArrayLayer: this.props.baseArrayLayer,
50
+ arrayLayerCount: this.props.arrayLayerCount
51
+ });
53
52
  this.device.popErrorScope((error: GPUError) => {
54
53
  this.device.reportError(new Error(`TextureView constructor: ${error.message}`), this)();
55
54
  this.device.debug();
@@ -59,9 +58,50 @@ export class WebGPUTextureView extends TextureView {
59
58
  }
60
59
 
61
60
  override destroy(): void {
61
+ if (this.destroyed) {
62
+ return;
63
+ }
64
+
65
+ this.destroyResource();
62
66
  // GPUTextureView does not have a destroy method
63
67
  // this.handle.destroy();
64
68
  // @ts-expect-error readonly
65
69
  this.handle = null;
66
70
  }
71
+
72
+ /**
73
+ * Internal-only hook for the cached CanvasContext/PresentationContext swapchain path.
74
+ * Rebuilds the default view when the per-frame canvas texture handle changes, without
75
+ * replacing the long-lived luma.gl wrapper object.
76
+ */
77
+ _reinitialize(texture: WebGPUTexture): void {
78
+ // @ts-expect-error readonly
79
+ this.texture = texture;
80
+
81
+ const profiler = getCpuHotspotProfiler(this.device);
82
+ this.device.pushErrorScope('validation');
83
+ const createViewStartTime = profiler ? getTimestamp() : 0;
84
+ const handle = this.texture.handle.createView({
85
+ format: (this.props.format || this.texture.format) as GPUTextureFormat,
86
+ dimension: this.props.dimension || this.texture.dimension,
87
+ aspect: this.props.aspect,
88
+ baseMipLevel: this.props.baseMipLevel,
89
+ mipLevelCount: this.props.mipLevelCount,
90
+ baseArrayLayer: this.props.baseArrayLayer,
91
+ arrayLayerCount: this.props.arrayLayerCount
92
+ });
93
+ if (profiler) {
94
+ profiler.textureViewReinitializeCount = (profiler.textureViewReinitializeCount || 0) + 1;
95
+ profiler.textureViewReinitializeTimeMs =
96
+ (profiler.textureViewReinitializeTimeMs || 0) + (getTimestamp() - createViewStartTime);
97
+ }
98
+ this.device.popErrorScope((error: GPUError) => {
99
+ this.device.reportError(new Error(`TextureView constructor: ${error.message}`), this)();
100
+ this.device.debug();
101
+ });
102
+
103
+ handle.label = this.props.id;
104
+ // @ts-expect-error readonly
105
+ this.handle = handle;
106
+ }
67
107
  }