@luma.gl/webgl 9.0.0-alpha.26 → 9.0.0-alpha.29
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/dist/adapter/helpers/get-shader-layout.d.ts +8 -5
- package/dist/adapter/helpers/get-shader-layout.d.ts.map +1 -1
- package/dist/adapter/helpers/get-shader-layout.js +59 -16
- package/dist/adapter/helpers/get-shader-layout.js.map +1 -1
- package/dist/adapter/helpers/get-vertex-buffer-layout.d.ts +12 -0
- package/dist/adapter/helpers/get-vertex-buffer-layout.d.ts.map +1 -0
- package/dist/adapter/helpers/get-vertex-buffer-layout.js +84 -0
- package/dist/adapter/helpers/get-vertex-buffer-layout.js.map +1 -0
- package/dist/adapter/objects/webgl-vertex-array-object.d.ts +35 -8
- package/dist/adapter/objects/webgl-vertex-array-object.d.ts.map +1 -1
- package/dist/adapter/objects/webgl-vertex-array-object.js +116 -16
- package/dist/adapter/objects/webgl-vertex-array-object.js.map +1 -1
- package/dist/adapter/resources/webgl-buffer.d.ts +13 -4
- package/dist/adapter/resources/webgl-buffer.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-buffer.js +23 -21
- package/dist/adapter/resources/webgl-buffer.js.map +1 -1
- package/dist/adapter/resources/webgl-external-texture.js.map +1 -1
- package/dist/adapter/resources/webgl-render-pipeline.d.ts +38 -5
- package/dist/adapter/resources/webgl-render-pipeline.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-render-pipeline.js +35 -7
- package/dist/adapter/resources/webgl-render-pipeline.js.map +1 -1
- package/dist/adapter/webgl-device.d.ts.map +1 -1
- package/dist/adapter/webgl-device.js +5 -2
- package/dist/adapter/webgl-device.js.map +1 -1
- package/dist/classic/buffer-with-accessor.d.ts +5 -15
- package/dist/classic/buffer-with-accessor.d.ts.map +1 -1
- package/dist/classic/buffer-with-accessor.js +25 -30
- package/dist/classic/buffer-with-accessor.js.map +1 -1
- package/dist/classic/copy-and-blit.d.ts.map +1 -1
- package/dist/classic/copy-and-blit.js +2 -2
- package/dist/classic/copy-and-blit.js.map +1 -1
- package/dist/context/debug/webgl-developer-tools.d.ts.map +1 -1
- package/dist/context/debug/webgl-developer-tools.js +2 -1
- package/dist/context/debug/webgl-developer-tools.js.map +1 -1
- package/dist/context/parameters/webgl-parameter-tables.js +2 -2
- package/dist/context/parameters/webgl-parameter-tables.js.map +1 -1
- package/dist/dist.dev.js +350 -99
- package/dist/index.cjs +343 -157
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist.min.js +22 -22
- package/package.json +5 -5
- package/src/adapter/helpers/get-shader-layout.ts +93 -33
- package/src/adapter/helpers/get-vertex-buffer-layout.ts +123 -0
- package/src/adapter/objects/webgl-vertex-array-object.ts +192 -28
- package/src/adapter/resources/webgl-buffer.ts +40 -41
- package/src/adapter/resources/webgl-external-texture.ts +1 -1
- package/src/adapter/resources/webgl-render-pipeline.ts +73 -36
- package/src/adapter/webgl-device.ts +4 -2
- package/src/classic/buffer-with-accessor.ts +42 -43
- package/src/classic/copy-and-blit.ts +2 -3
- package/src/context/debug/webgl-developer-tools.ts +8 -2
- package/src/context/parameters/webgl-parameter-tables.ts +2 -2
- package/src/index.ts +1 -1
|
@@ -11,17 +11,21 @@ export class WEBGLBuffer extends Buffer {
|
|
|
11
11
|
readonly gl: WebGLRenderingContext;
|
|
12
12
|
readonly gl2: WebGL2RenderingContext | null;
|
|
13
13
|
readonly handle: WebGLBuffer;
|
|
14
|
-
readonly target: number;
|
|
15
14
|
|
|
15
|
+
/** Target in OpenGL defines the type of buffer */
|
|
16
|
+
readonly glTarget: GL.ARRAY_BUFFER | GL.ELEMENT_ARRAY_BUFFER | GL.UNIFORM_BUFFER;
|
|
17
|
+
/** Usage is a hint on how frequently the buffer will be updates */
|
|
18
|
+
readonly glUsage: GL.STATIC_DRAW | GL.DYNAMIC_DRAW;
|
|
19
|
+
/** Index type is needed when issuing draw calls, so we pre-compute it */
|
|
20
|
+
readonly glIndexType: GL.UNSIGNED_SHORT | GL.UNSIGNED_INT = GL.UNSIGNED_SHORT;
|
|
21
|
+
|
|
22
|
+
/** Number of bytes allocated on the GPU for this buffer */
|
|
16
23
|
byteLength: number;
|
|
24
|
+
/** Number of bytes used */
|
|
17
25
|
bytesUsed: number;
|
|
26
|
+
/** A partial CPU-side copy of the data in this buffer, for debugging purposes */
|
|
18
27
|
debugData: ArrayBuffer | null = null;
|
|
19
28
|
|
|
20
|
-
webglUsage: number;
|
|
21
|
-
|
|
22
|
-
// accessor: {};
|
|
23
|
-
|
|
24
|
-
|
|
25
29
|
constructor(device: WebGLDevice, props: BufferProps = {}) {
|
|
26
30
|
super(device, props);
|
|
27
31
|
|
|
@@ -33,13 +37,13 @@ export class WEBGLBuffer extends Buffer {
|
|
|
33
37
|
this.handle = handle || this.gl.createBuffer();
|
|
34
38
|
device.setSpectorMetadata(this.handle, {...this.props, data: typeof this.props.data});
|
|
35
39
|
|
|
36
|
-
// In WebGL1, need to make sure we use GL.ELEMENT_ARRAY_BUFFER when initializing element buffers
|
|
37
|
-
//
|
|
38
|
-
// In WebGL2, we can use GL.COPY_READ_BUFFER which avoids locking the type here
|
|
39
|
-
|
|
40
|
-
this.
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
// - In WebGL1, need to make sure we use GL.ELEMENT_ARRAY_BUFFER when initializing element buffers
|
|
41
|
+
// otherwise buffer type will lock to generic (non-element) buffer
|
|
42
|
+
// - In WebGL2, we can use GL.COPY_READ_BUFFER which avoids locking the type here
|
|
43
|
+
this.glTarget = getWebGLTarget(this.props.usage);
|
|
44
|
+
this.glUsage = getWebGLUsage(this.props.usage);
|
|
45
|
+
this.glIndexType = this.props.indexType === 'uint32' ? GL.UNSIGNED_INT : GL.UNSIGNED_SHORT;
|
|
46
|
+
|
|
43
47
|
this.debugData = null;
|
|
44
48
|
|
|
45
49
|
// Set data: (re)initializes the buffer
|
|
@@ -48,25 +52,19 @@ export class WEBGLBuffer extends Buffer {
|
|
|
48
52
|
} else {
|
|
49
53
|
this._initWithByteLength(props.byteLength || 0);
|
|
50
54
|
}
|
|
51
|
-
|
|
52
|
-
// Deprecated: Merge main props and accessor
|
|
53
|
-
// this.accessor = {...props.accessor};
|
|
54
|
-
|
|
55
|
-
// Object.seal(this);
|
|
56
55
|
}
|
|
57
56
|
|
|
58
57
|
// PRIVATE METHODS
|
|
59
58
|
|
|
60
|
-
|
|
59
|
+
/** Allocate a new buffer and initialize to contents of typed array */
|
|
61
60
|
_initWithData(data, byteOffset: number = 0, byteLength: number = data.byteLength + byteOffset): this {
|
|
62
61
|
assert(ArrayBuffer.isView(data));
|
|
63
62
|
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
this.gl.
|
|
67
|
-
this.gl.
|
|
68
|
-
this.gl.
|
|
69
|
-
this.gl.bindBuffer(target, null);
|
|
63
|
+
const glTarget = this._getWriteTarget();
|
|
64
|
+
this.gl.bindBuffer(glTarget, this.handle);
|
|
65
|
+
this.gl.bufferData(glTarget, byteLength, this.glUsage);
|
|
66
|
+
this.gl.bufferSubData(glTarget, byteOffset, data);
|
|
67
|
+
this.gl.bindBuffer(glTarget, null);
|
|
70
68
|
|
|
71
69
|
this.debugData = data.slice(0, DEBUG_DATA_LENGTH);
|
|
72
70
|
this.bytesUsed = byteLength;
|
|
@@ -88,11 +86,11 @@ export class WEBGLBuffer extends Buffer {
|
|
|
88
86
|
data = new Float32Array(0);
|
|
89
87
|
}
|
|
90
88
|
|
|
91
|
-
const
|
|
89
|
+
const glTarget = this._getWriteTarget();
|
|
92
90
|
|
|
93
|
-
this.gl.bindBuffer(
|
|
94
|
-
this.gl.bufferData(
|
|
95
|
-
this.gl.bindBuffer(
|
|
91
|
+
this.gl.bindBuffer(glTarget, this.handle);
|
|
92
|
+
this.gl.bufferData(glTarget, data, this.glUsage);
|
|
93
|
+
this.gl.bindBuffer(glTarget, null);
|
|
96
94
|
|
|
97
95
|
this.debugData = null;
|
|
98
96
|
this.bytesUsed = byteLength;
|
|
@@ -118,16 +116,16 @@ export class WEBGLBuffer extends Buffer {
|
|
|
118
116
|
|
|
119
117
|
// Create the buffer - binding it here for the first time locks the type
|
|
120
118
|
// In WebGL2, use GL.COPY_WRITE_BUFFER to avoid locking the type
|
|
121
|
-
const
|
|
122
|
-
this.gl.bindBuffer(
|
|
119
|
+
const glTarget = this.device.isWebGL2 ? GL.COPY_WRITE_BUFFER : this.glTarget;
|
|
120
|
+
this.gl.bindBuffer(glTarget, this.handle);
|
|
123
121
|
// WebGL2: subData supports additional srcOffset and length parameters
|
|
124
122
|
if (srcOffset !== 0 || byteLength !== undefined) {
|
|
125
123
|
this.device.assertWebGL2();
|
|
126
|
-
this.gl2.bufferSubData(
|
|
124
|
+
this.gl2.bufferSubData(glTarget, byteOffset, data, srcOffset, byteLength);
|
|
127
125
|
} else {
|
|
128
|
-
this.gl.bufferSubData(
|
|
126
|
+
this.gl.bufferSubData(glTarget, byteOffset, data);
|
|
129
127
|
}
|
|
130
|
-
this.gl.bindBuffer(
|
|
128
|
+
this.gl.bindBuffer(glTarget, null);
|
|
131
129
|
|
|
132
130
|
// TODO - update local `data` if offsets are right
|
|
133
131
|
// this.debugData = data.slice(byteOffset, 40);
|
|
@@ -161,13 +159,13 @@ export class WEBGLBuffer extends Buffer {
|
|
|
161
159
|
}
|
|
162
160
|
|
|
163
161
|
_getWriteTarget() {
|
|
164
|
-
return this.
|
|
165
|
-
// return this.device.isWebGL2 ? GL.COPY_WRITE_BUFFER : this.
|
|
162
|
+
return this.glTarget;
|
|
163
|
+
// return this.device.isWebGL2 ? GL.COPY_WRITE_BUFFER : this.glTarget;
|
|
166
164
|
}
|
|
167
165
|
|
|
168
166
|
_getReadTarget() {
|
|
169
|
-
return this.
|
|
170
|
-
// return this.device.isWebGL2 ? GL.COPY_READ_BUFFER : this.
|
|
167
|
+
return this.glTarget;
|
|
168
|
+
// return this.device.isWebGL2 ? GL.COPY_READ_BUFFER : this.glTarget;
|
|
171
169
|
}
|
|
172
170
|
}
|
|
173
171
|
|
|
@@ -182,7 +180,7 @@ export class WEBGLBuffer extends Buffer {
|
|
|
182
180
|
// static INDIRECT = 0x0100;
|
|
183
181
|
// static QUERY_RESOLVE = 0x0200;
|
|
184
182
|
|
|
185
|
-
function getWebGLTarget(usage: number): GL {
|
|
183
|
+
function getWebGLTarget(usage: number): GL.ARRAY_BUFFER | GL.ELEMENT_ARRAY_BUFFER | GL.UNIFORM_BUFFER {
|
|
186
184
|
if (usage & Buffer.INDEX) {
|
|
187
185
|
return GL.ELEMENT_ARRAY_BUFFER;
|
|
188
186
|
}
|
|
@@ -204,7 +202,8 @@ function getWebGLTarget(usage: number): GL {
|
|
|
204
202
|
return GL.ARRAY_BUFFER;
|
|
205
203
|
}
|
|
206
204
|
|
|
207
|
-
|
|
205
|
+
/** @todo usage is not passed correctly */
|
|
206
|
+
function getWebGLUsage(usage: number): GL.STATIC_DRAW | GL.DYNAMIC_DRAW {
|
|
208
207
|
if (usage & Buffer.INDEX) {
|
|
209
208
|
return GL.STATIC_DRAW;
|
|
210
209
|
}
|
|
@@ -214,5 +213,5 @@ function getWebGLUsage(usage: number): GL {
|
|
|
214
213
|
if (usage & Buffer.UNIFORM) {
|
|
215
214
|
return GL.DYNAMIC_DRAW;
|
|
216
215
|
}
|
|
217
|
-
return GL.
|
|
216
|
+
return GL.STATIC_DRAW;
|
|
218
217
|
}
|
|
@@ -53,7 +53,7 @@ export class WEBGLExternalTexture extends WEBGLTexture {
|
|
|
53
53
|
constructor(device: Device | WebGLRenderingContext, props: TextureProps) {
|
|
54
54
|
super(WebGLDevice.attach(device), {id: uid('texture'), ...props});
|
|
55
55
|
|
|
56
|
-
this.
|
|
56
|
+
this.glTarget = getWebGLTextureTarget(props);
|
|
57
57
|
|
|
58
58
|
this.device = WebGLDevice.attach(device);
|
|
59
59
|
this.gl = this.device.gl;
|
|
@@ -6,13 +6,15 @@ import type {
|
|
|
6
6
|
ShaderLayout,
|
|
7
7
|
PrimitiveTopology,
|
|
8
8
|
// BindingLayout,
|
|
9
|
-
AttributeLayout
|
|
9
|
+
AttributeLayout,
|
|
10
|
+
TypedArray,
|
|
11
|
+
BufferMapping
|
|
10
12
|
} from '@luma.gl/api';
|
|
11
13
|
import {RenderPipeline, cast, log, decodeVertexFormat} from '@luma.gl/api';
|
|
12
14
|
import {GL} from '@luma.gl/constants';
|
|
13
15
|
|
|
14
16
|
import {getWebGLDataType} from '../converters/texture-formats';
|
|
15
|
-
import {getShaderLayout} from '../helpers/get-shader-layout';
|
|
17
|
+
import {getShaderLayout, mergeShaderLayout, mergeBufferMap} from '../helpers/get-shader-layout';
|
|
16
18
|
import {withDeviceParameters, withGLParameters} from '../converters/device-parameters';
|
|
17
19
|
import {setUniform} from '../helpers/set-uniform';
|
|
18
20
|
// import {copyUniform, checkUniformValues} from '../../classes/uniforms';
|
|
@@ -28,19 +30,35 @@ const LOG_PROGRAM_PERF_PRIORITY = 4;
|
|
|
28
30
|
|
|
29
31
|
/** Creates a new render pipeline */
|
|
30
32
|
export class WEBGLRenderPipeline extends RenderPipeline {
|
|
33
|
+
/** The WebGL device that created this render pipeline */
|
|
31
34
|
device: WebGLDevice;
|
|
35
|
+
/** Handle to underlying WebGL program */
|
|
32
36
|
handle: WebGLProgram;
|
|
37
|
+
/** vertex shader */
|
|
33
38
|
vs: WEBGLShader;
|
|
39
|
+
/** fragment shader */
|
|
34
40
|
fs: WEBGLShader;
|
|
41
|
+
/** The merged layout */
|
|
35
42
|
layout: ShaderLayout;
|
|
43
|
+
/** The layout extracted from shader by WebGL introspection APIs */
|
|
44
|
+
introspectedLayout: ShaderLayout;
|
|
45
|
+
/** Buffer map describing buffer interleaving etc */
|
|
46
|
+
bufferMap: BufferMapping[];
|
|
36
47
|
|
|
37
|
-
|
|
38
|
-
// Experimental flag to avoid deleting Program object while it is cached
|
|
39
|
-
varyings: string[] | null = null;
|
|
40
|
-
vertexArrayObject: WEBGLVertexArrayObject;
|
|
41
|
-
_indexBuffer?: Buffer;
|
|
48
|
+
/** Uniforms set on this model */
|
|
42
49
|
uniforms: Record<string, any> = {};
|
|
50
|
+
/** Bindings set on this model */
|
|
43
51
|
bindings: Record<string, any> = {};
|
|
52
|
+
/** Any constant attributes */
|
|
53
|
+
constantAttributes: Record<string, TypedArray> = {};
|
|
54
|
+
/** Index buffer is stored separately */
|
|
55
|
+
_indexBuffer?: WEBGLBuffer;
|
|
56
|
+
/** WebGL varyings */
|
|
57
|
+
varyings: string[] | null = null;
|
|
58
|
+
|
|
59
|
+
/** Stores attribute bindings */
|
|
60
|
+
vertexArrayObject: WEBGLVertexArrayObject;
|
|
61
|
+
|
|
44
62
|
_textureUniforms: Record<string, any> = {};
|
|
45
63
|
_textureIndexCounter: number = 0;
|
|
46
64
|
_uniformCount: number = 0;
|
|
@@ -69,7 +87,12 @@ export class WEBGLRenderPipeline extends RenderPipeline {
|
|
|
69
87
|
|
|
70
88
|
this._compileAndLink();
|
|
71
89
|
|
|
72
|
-
this.
|
|
90
|
+
this.introspectedLayout = getShaderLayout(this.device.gl, this.handle);
|
|
91
|
+
// Merge provided layout with introspected layout
|
|
92
|
+
this.layout = mergeShaderLayout(this.introspectedLayout, props.layout);
|
|
93
|
+
// Merge layout with any buffer map overrides
|
|
94
|
+
this.bufferMap = props.bufferMap || [];
|
|
95
|
+
this.layout = mergeBufferMap(this.layout, this.bufferMap);
|
|
73
96
|
this.vertexArrayObject = new WEBGLVertexArrayObject(this.device);
|
|
74
97
|
}
|
|
75
98
|
|
|
@@ -84,7 +107,7 @@ export class WEBGLRenderPipeline extends RenderPipeline {
|
|
|
84
107
|
setIndexBuffer(indexBuffer: Buffer): void {
|
|
85
108
|
const webglBuffer = cast<WEBGLBuffer>(indexBuffer);
|
|
86
109
|
this.vertexArrayObject.setElementBuffer(webglBuffer);
|
|
87
|
-
this._indexBuffer =
|
|
110
|
+
this._indexBuffer = webglBuffer;
|
|
88
111
|
}
|
|
89
112
|
|
|
90
113
|
/** @todo needed for portable model */
|
|
@@ -112,7 +135,28 @@ export class WEBGLRenderPipeline extends RenderPipeline {
|
|
|
112
135
|
}
|
|
113
136
|
}
|
|
114
137
|
|
|
115
|
-
/**
|
|
138
|
+
/**
|
|
139
|
+
* Constant attributes are only supported in WebGL, not in WebGPU
|
|
140
|
+
* Any attribute that is disabled in the current vertex array object
|
|
141
|
+
* is read from the context's global constant value for that attribute location.
|
|
142
|
+
* @param attributes
|
|
143
|
+
*/
|
|
144
|
+
setConstantAttributes(attributes: Record<string, TypedArray>): void {
|
|
145
|
+
for (const [name, value] of Object.entries(attributes)) {
|
|
146
|
+
const attribute = getAttributeLayout(this.layout, name);
|
|
147
|
+
if (!attribute) {
|
|
148
|
+
log.warn(`Ignoring constant value supplied for unknown attribute "${name}" in pipeline "${this.id}"`)();
|
|
149
|
+
continue; // eslint-disable-line no-continue
|
|
150
|
+
}
|
|
151
|
+
this.vertexArrayObject.setConstant(attribute.location, value);
|
|
152
|
+
}
|
|
153
|
+
Object.assign(this.constantAttributes, attributes);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Bindings include: textures, samplers and uniform buffers
|
|
158
|
+
* @todo needed for portable model
|
|
159
|
+
*/
|
|
116
160
|
setBindings(bindings: Record<string, Binding>): void {
|
|
117
161
|
// if (log.priority >= 2) {
|
|
118
162
|
// checkUniformValues(uniforms, this.id, this._uniformSetters);
|
|
@@ -182,7 +226,7 @@ export class WEBGLRenderPipeline extends RenderPipeline {
|
|
|
182
226
|
|
|
183
227
|
const drawMode = getDrawMode(this.props.topology);
|
|
184
228
|
const isIndexed: boolean = Boolean(this._indexBuffer);
|
|
185
|
-
const indexType = this._indexBuffer?.
|
|
229
|
+
const indexType = this._indexBuffer?.glIndexType;
|
|
186
230
|
const isInstanced: boolean = Number(options.instanceCount) > 0;
|
|
187
231
|
|
|
188
232
|
// Avoid WebGL draw call when not rendering any data or values are incomplete
|
|
@@ -206,6 +250,7 @@ export class WEBGLRenderPipeline extends RenderPipeline {
|
|
|
206
250
|
// We have to apply bindings before every draw call since other draw calls will overwrite
|
|
207
251
|
this._applyBindings();
|
|
208
252
|
this._applyUniforms();
|
|
253
|
+
this._applyConstantAttributes();
|
|
209
254
|
|
|
210
255
|
const webglRenderPass = renderPass as WEBGLRenderPass;
|
|
211
256
|
|
|
@@ -365,9 +410,25 @@ export class WEBGLRenderPipeline extends RenderPipeline {
|
|
|
365
410
|
}
|
|
366
411
|
}
|
|
367
412
|
}
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
* Constant attributes are only supported in WebGL, not in WebGPU
|
|
416
|
+
* Any attribute that is disabled in the current vertex array object
|
|
417
|
+
* is read from the context's global constant value for that attribute location.
|
|
418
|
+
*/
|
|
419
|
+
_applyConstantAttributes(): void {
|
|
420
|
+
for (const [name, value] of Object.entries(this.constantAttributes)) {
|
|
421
|
+
const attribute = getAttributeLayout(this.layout, name);
|
|
422
|
+
if (!attribute) {
|
|
423
|
+
log.warn(`Ignoring constant value supplied for unknown attribute "${name}" in pipeline "${this.id}"`)();
|
|
424
|
+
continue; // eslint-disable-line no-continue
|
|
425
|
+
}
|
|
426
|
+
this.vertexArrayObject.setConstant(attribute.location, value);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
368
429
|
}
|
|
369
430
|
|
|
370
|
-
/** Get the primitive type for
|
|
431
|
+
/** Get the primitive type for draw */
|
|
371
432
|
function getDrawMode(
|
|
372
433
|
topology: PrimitiveTopology
|
|
373
434
|
): GL.POINTS | GL.LINES | GL.LINE_STRIP | GL.LINE_LOOP | GL.TRIANGLES | GL.TRIANGLE_STRIP | GL.TRIANGLE_FAN {
|
|
@@ -399,30 +460,6 @@ function getGLPrimitive(topology: PrimitiveTopology): GL.POINTS | GL.LINES | GL.
|
|
|
399
460
|
}
|
|
400
461
|
}
|
|
401
462
|
|
|
402
|
-
// function getAttributesByLocation(
|
|
403
|
-
// attributes: Record<string, Buffer>,
|
|
404
|
-
// layout: ShaderLayout
|
|
405
|
-
// ): Record<number, Buffer> {
|
|
406
|
-
// const byLocation: Record<number, Buffer> = {};
|
|
407
|
-
// for (const [name, buffer] of Object.entries(attributes)) {
|
|
408
|
-
// const attribute = getAttributeLayout(layout, name);
|
|
409
|
-
// if (attribute) {
|
|
410
|
-
// byLocation[attribute.location] = buffer;
|
|
411
|
-
// }
|
|
412
|
-
// }
|
|
413
|
-
// return byLocation;
|
|
414
|
-
// }
|
|
415
|
-
|
|
416
463
|
function getAttributeLayout(layout: ShaderLayout, name: string): AttributeLayout | null {
|
|
417
464
|
return layout.attributes.find((binding) => binding.name === name) || null;
|
|
418
465
|
}
|
|
419
|
-
|
|
420
|
-
/* TODO
|
|
421
|
-
function getBindingLayout(layout: ShaderLayout, name: string): BindingLayout {
|
|
422
|
-
const binding = layout.bindings.find((binding) => binding.name === name);
|
|
423
|
-
if (!binding) {
|
|
424
|
-
throw new Error(`Unknown binding ${name}`);
|
|
425
|
-
}
|
|
426
|
-
return binding;
|
|
427
|
-
}
|
|
428
|
-
*/
|
|
@@ -130,11 +130,13 @@ export class WebGLDevice extends Device {
|
|
|
130
130
|
}
|
|
131
131
|
|
|
132
132
|
// Load webgl and spector debug scripts from CDN if requested
|
|
133
|
-
if (props.debug) {
|
|
133
|
+
if (log.get('debug') || props.debug) {
|
|
134
134
|
await loadWebGLDeveloperTools();
|
|
135
135
|
}
|
|
136
|
+
|
|
136
137
|
// @ts-expect-error spector not on props
|
|
137
|
-
|
|
138
|
+
const {spector} = props;
|
|
139
|
+
if (log.get('spector') || spector) {
|
|
138
140
|
await loadSpectorJS();
|
|
139
141
|
}
|
|
140
142
|
|
|
@@ -55,9 +55,9 @@ function getWEBGLBufferProps(props: BufferWithAccessorProps | ArrayBufferView |
|
|
|
55
55
|
|
|
56
56
|
props = checkProps('Buffer', props, PROP_CHECKS_INITIALIZE);
|
|
57
57
|
const bufferProps = {...props };
|
|
58
|
-
if (bufferProps.offset) {
|
|
59
|
-
|
|
60
|
-
}
|
|
58
|
+
// if (bufferProps.offset) {
|
|
59
|
+
// bufferProps.byteOffset = bufferProps.offset;
|
|
60
|
+
// }
|
|
61
61
|
return bufferProps;
|
|
62
62
|
}
|
|
63
63
|
|
|
@@ -65,19 +65,18 @@ function getWEBGLBufferProps(props: BufferWithAccessorProps | ArrayBufferView |
|
|
|
65
65
|
export type BufferWithAccessorProps = BufferProps & {
|
|
66
66
|
handle?: WebGLBuffer;
|
|
67
67
|
|
|
68
|
-
target?: number;
|
|
69
|
-
webglUsage?: number;
|
|
70
|
-
|
|
71
68
|
accessor?: AccessorObject;
|
|
72
69
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
/** @deprecated */
|
|
76
|
-
|
|
77
|
-
/** @deprecated */
|
|
78
|
-
|
|
79
|
-
/** @deprecated */
|
|
80
|
-
|
|
70
|
+
// target?: number;
|
|
71
|
+
// glUsage?: number;
|
|
72
|
+
// /** @deprecated */
|
|
73
|
+
// index?: number;
|
|
74
|
+
// /** @deprecated */
|
|
75
|
+
// offset?: number;
|
|
76
|
+
// /** @deprecated */
|
|
77
|
+
// size?: number;
|
|
78
|
+
// /** @deprecated */
|
|
79
|
+
// type?: number
|
|
81
80
|
}
|
|
82
81
|
|
|
83
82
|
/** WebGL Buffer interface */
|
|
@@ -141,7 +140,8 @@ export class BufferWithAccessor extends WEBGLBuffer {
|
|
|
141
140
|
props = checkProps('Buffer', props, PROP_CHECKS_INITIALIZE);
|
|
142
141
|
|
|
143
142
|
// Initialize member fields
|
|
144
|
-
|
|
143
|
+
// @ts-expect-error readonly field
|
|
144
|
+
this.glUsage = props.glUsage || GL.STATIC_DRAW;
|
|
145
145
|
this.debugData = null;
|
|
146
146
|
|
|
147
147
|
// Deprecated: Merge main props and accessor
|
|
@@ -149,7 +149,7 @@ export class BufferWithAccessor extends WEBGLBuffer {
|
|
|
149
149
|
|
|
150
150
|
// Set data: (re)initializes the buffer
|
|
151
151
|
if (props.data) {
|
|
152
|
-
this._setData(props.data, props.
|
|
152
|
+
this._setData(props.data, props.byteOffset, props.byteLength);
|
|
153
153
|
} else {
|
|
154
154
|
this._setByteLength(props.byteLength || 0);
|
|
155
155
|
}
|
|
@@ -220,17 +220,17 @@ export class BufferWithAccessor extends WEBGLBuffer {
|
|
|
220
220
|
// Create the buffer - binding it here for the first time locks the type
|
|
221
221
|
// In WebGL2, use GL.COPY_WRITE_BUFFER to avoid locking the type
|
|
222
222
|
// @ts-expect-error
|
|
223
|
-
const
|
|
224
|
-
this.gl.bindBuffer(
|
|
223
|
+
const glTarget = this.gl.webgl2 ? GL.COPY_WRITE_BUFFER : this.glTarget;
|
|
224
|
+
this.gl.bindBuffer(glTarget, this.handle);
|
|
225
225
|
// WebGL2: subData supports additional srcOffset and length parameters
|
|
226
226
|
if (srcOffset !== 0 || byteLength !== undefined) {
|
|
227
227
|
assertWebGL2Context(this.gl);
|
|
228
228
|
// @ts-expect-error
|
|
229
|
-
this.gl.bufferSubData(this.
|
|
229
|
+
this.gl.bufferSubData(this.glTarget, offset, data, srcOffset, byteLength);
|
|
230
230
|
} else {
|
|
231
|
-
this.gl.bufferSubData(
|
|
231
|
+
this.gl.bufferSubData(glTarget, offset, data);
|
|
232
232
|
}
|
|
233
|
-
this.gl.bindBuffer(
|
|
233
|
+
this.gl.bindBuffer(glTarget, null);
|
|
234
234
|
|
|
235
235
|
// TODO - update local `data` if offsets are right
|
|
236
236
|
this.debugData = null;
|
|
@@ -321,9 +321,9 @@ export class BufferWithAccessor extends WEBGLBuffer {
|
|
|
321
321
|
* - GL.UNIFORM_BUFFER: `offset` must be aligned to GL.UNIFORM_BUFFER_OFFSET_ALIGNMENT.
|
|
322
322
|
* - GL.UNIFORM_BUFFER: `size` must be a minimum of GL.UNIFORM_BLOCK_SIZE_DATA.
|
|
323
323
|
*/
|
|
324
|
-
bind(options?: {
|
|
324
|
+
bind(options?: {glTarget?: number; index?: any; offset?: number; size?: any}): this {
|
|
325
325
|
const {
|
|
326
|
-
|
|
326
|
+
glTarget = this.glTarget, // target for the bind operation
|
|
327
327
|
index = this.accessor && this.accessor.index, // index = index of target (indexed bind point)
|
|
328
328
|
offset = 0,
|
|
329
329
|
size
|
|
@@ -331,27 +331,27 @@ export class BufferWithAccessor extends WEBGLBuffer {
|
|
|
331
331
|
// NOTE: While GL.TRANSFORM_FEEDBACK_BUFFER and GL.UNIFORM_BUFFER could
|
|
332
332
|
// be used as direct binding points, they will not affect transform feedback or
|
|
333
333
|
// uniform buffer state. Instead indexed bindings need to be made.
|
|
334
|
-
if (
|
|
334
|
+
if (glTarget === GL.UNIFORM_BUFFER || glTarget === GL.TRANSFORM_FEEDBACK_BUFFER) {
|
|
335
335
|
if (size !== undefined) {
|
|
336
|
-
this.gl2?.bindBufferRange(
|
|
336
|
+
this.gl2?.bindBufferRange(glTarget, index, this.handle, offset, size);
|
|
337
337
|
} else {
|
|
338
338
|
assert(offset === 0); // Make sure offset wasn't supplied
|
|
339
|
-
this.gl2?.bindBufferBase(
|
|
339
|
+
this.gl2?.bindBufferBase(glTarget, index, this.handle);
|
|
340
340
|
}
|
|
341
341
|
} else {
|
|
342
|
-
this.gl.bindBuffer(
|
|
342
|
+
this.gl.bindBuffer(glTarget, this.handle);
|
|
343
343
|
}
|
|
344
344
|
|
|
345
345
|
return this;
|
|
346
346
|
}
|
|
347
347
|
|
|
348
|
-
unbind(options?: {
|
|
349
|
-
const {
|
|
350
|
-
const isIndexedBuffer =
|
|
348
|
+
unbind(options?: {glTarget?: any; index?: any}): this {
|
|
349
|
+
const {glTarget = this.glTarget, index = this.accessor && this.accessor.index} = options || {};
|
|
350
|
+
const isIndexedBuffer = glTarget === GL.UNIFORM_BUFFER || glTarget === GL.TRANSFORM_FEEDBACK_BUFFER;
|
|
351
351
|
if (isIndexedBuffer) {
|
|
352
|
-
this.gl2?.bindBufferBase(
|
|
352
|
+
this.gl2?.bindBufferBase(glTarget, index, null);
|
|
353
353
|
} else {
|
|
354
|
-
this.gl.bindBuffer(
|
|
354
|
+
this.gl.bindBuffer(glTarget, null);
|
|
355
355
|
}
|
|
356
356
|
return this;
|
|
357
357
|
}
|
|
@@ -384,7 +384,7 @@ export class BufferWithAccessor extends WEBGLBuffer {
|
|
|
384
384
|
|
|
385
385
|
const target = this._getTarget();
|
|
386
386
|
this.gl.bindBuffer(target, this.handle);
|
|
387
|
-
this.gl.bufferData(target, byteLength, this.
|
|
387
|
+
this.gl.bufferData(target, byteLength, this.glUsage);
|
|
388
388
|
this.gl.bufferSubData(target, offset, data);
|
|
389
389
|
this.gl.bindBuffer(target, null);
|
|
390
390
|
|
|
@@ -401,7 +401,7 @@ export class BufferWithAccessor extends WEBGLBuffer {
|
|
|
401
401
|
}
|
|
402
402
|
|
|
403
403
|
// Allocate a GPU buffer of specified size.
|
|
404
|
-
_setByteLength(byteLength: number
|
|
404
|
+
_setByteLength(byteLength: number): this {
|
|
405
405
|
assert(byteLength >= 0);
|
|
406
406
|
|
|
407
407
|
this.trackDeallocatedMemory();
|
|
@@ -414,12 +414,11 @@ export class BufferWithAccessor extends WEBGLBuffer {
|
|
|
414
414
|
data = new Float32Array(0);
|
|
415
415
|
}
|
|
416
416
|
|
|
417
|
-
const
|
|
418
|
-
this.gl.bindBuffer(
|
|
419
|
-
this.gl.bufferData(
|
|
420
|
-
this.gl.bindBuffer(
|
|
417
|
+
const glTarget = this._getTarget();
|
|
418
|
+
this.gl.bindBuffer(glTarget, this.handle);
|
|
419
|
+
this.gl.bufferData(glTarget, data, this.glUsage);
|
|
420
|
+
this.gl.bindBuffer(glTarget, null);
|
|
421
421
|
|
|
422
|
-
this.webglUsage = webglUsage;
|
|
423
422
|
this.debugData = null;
|
|
424
423
|
this.bytesUsed = byteLength;
|
|
425
424
|
this.byteLength = byteLength;
|
|
@@ -433,7 +432,7 @@ export class BufferWithAccessor extends WEBGLBuffer {
|
|
|
433
432
|
// In WebGL2, use GL.COPY_WRITE_BUFFER to avoid locking the type
|
|
434
433
|
_getTarget() {
|
|
435
434
|
// @ts-expect-error
|
|
436
|
-
return this.gl.webgl2 ? GL.COPY_WRITE_BUFFER : this.
|
|
435
|
+
return this.gl.webgl2 ? GL.COPY_WRITE_BUFFER : this.glTarget;
|
|
437
436
|
}
|
|
438
437
|
|
|
439
438
|
_getAvailableElementCount(srcByteOffset: number) {
|
|
@@ -453,9 +452,9 @@ export class BufferWithAccessor extends WEBGLBuffer {
|
|
|
453
452
|
// RESOURCE METHODS
|
|
454
453
|
|
|
455
454
|
getParameter(pname: GL): any {
|
|
456
|
-
this.gl.bindBuffer(this.
|
|
457
|
-
const value = this.gl.getBufferParameter(this.
|
|
458
|
-
this.gl.bindBuffer(this.
|
|
455
|
+
this.gl.bindBuffer(this.glTarget, this.handle);
|
|
456
|
+
const value = this.gl.getBufferParameter(this.glTarget, pname);
|
|
457
|
+
this.gl.bindBuffer(this.glTarget, null);
|
|
459
458
|
return value;
|
|
460
459
|
}
|
|
461
460
|
|
|
@@ -121,8 +121,7 @@ export function readPixelsToBuffer(
|
|
|
121
121
|
target = new Buffer(gl2, {byteLength, accessor: {type: sourceType, size: components}});
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
-
|
|
125
|
-
target.bind({target: GL.PIXEL_PACK_BUFFER});
|
|
124
|
+
target.bind({glTarget: GL.PIXEL_PACK_BUFFER});
|
|
126
125
|
withParameters(gl2, {framebuffer}, () => {
|
|
127
126
|
gl2.readPixels(
|
|
128
127
|
sourceX,
|
|
@@ -134,7 +133,7 @@ export function readPixelsToBuffer(
|
|
|
134
133
|
targetByteOffset
|
|
135
134
|
);
|
|
136
135
|
});
|
|
137
|
-
target.unbind({
|
|
136
|
+
target.unbind({glTarget: GL.PIXEL_PACK_BUFFER});
|
|
138
137
|
if (deleteFramebuffer) {
|
|
139
138
|
framebuffer.destroy();
|
|
140
139
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// luma.gl, MIT license
|
|
2
2
|
import {log, loadScript} from '@luma.gl/api';
|
|
3
3
|
import {GL} from '@luma.gl/constants';
|
|
4
|
+
import {isBrowser} from '@probe.gl/env'
|
|
4
5
|
|
|
5
6
|
const WEBGL_DEBUG_CDN_URL = 'https://unpkg.com/webgl-debug@2.0.1/index.js';
|
|
6
7
|
|
|
@@ -18,8 +19,13 @@ type DebugContextProps = {
|
|
|
18
19
|
// webgl2: false,
|
|
19
20
|
// }
|
|
20
21
|
|
|
22
|
+
type ContextData = {
|
|
23
|
+
realContext?: WebGLRenderingContext;
|
|
24
|
+
debugContext?: WebGLRenderingContext;
|
|
25
|
+
}
|
|
26
|
+
|
|
21
27
|
// Helper to get shared context data
|
|
22
|
-
function getContextData(gl: any) {
|
|
28
|
+
function getContextData(gl: any): ContextData {
|
|
23
29
|
gl.luma = gl.luma || {};
|
|
24
30
|
return gl.luma;
|
|
25
31
|
}
|
|
@@ -36,7 +42,7 @@ declare global {
|
|
|
36
42
|
* @see https://github.com/vorg/webgl-debug
|
|
37
43
|
*/
|
|
38
44
|
export async function loadWebGLDeveloperTools(): Promise<void> {
|
|
39
|
-
if (!globalThis.WebGLDebugUtils) {
|
|
45
|
+
if (isBrowser() && !globalThis.WebGLDebugUtils) {
|
|
40
46
|
globalThis.global = globalThis.global || globalThis;
|
|
41
47
|
// @ts-expect-error Developer tools expects global to be set
|
|
42
48
|
globalThis.global.module = {};
|
|
@@ -116,9 +116,9 @@ const bindBuffer = (gl: WebGLRenderingContext, value: unknown, key: GL) => {
|
|
|
116
116
|
[GL.PIXEL_PACK_BUFFER_BINDING]: GL.PIXEL_PACK_BUFFER,
|
|
117
117
|
[GL.PIXEL_UNPACK_BUFFER_BINDING]: GL.PIXEL_UNPACK_BUFFER
|
|
118
118
|
};
|
|
119
|
-
const
|
|
119
|
+
const glTarget = bindingMap[key];
|
|
120
120
|
|
|
121
|
-
gl.bindBuffer(
|
|
121
|
+
gl.bindBuffer(glTarget, value);
|
|
122
122
|
};
|
|
123
123
|
|
|
124
124
|
// Utility
|
package/src/index.ts
CHANGED
|
@@ -73,7 +73,7 @@ export {
|
|
|
73
73
|
export {polyfillContext} from './context/polyfill/polyfill-context';
|
|
74
74
|
|
|
75
75
|
// HELPERS - EXPERIMENTAL
|
|
76
|
-
export {getShaderLayout,
|
|
76
|
+
export {getShaderLayout, mergeShaderLayout} from './adapter/helpers/get-shader-layout';
|
|
77
77
|
export {convertGLToTextureFormat, _checkFloat32ColorAttachment} from './adapter/converters/texture-formats';
|
|
78
78
|
|
|
79
79
|
// TEST EXPORTS
|