@luma.gl/webgl 9.2.0-alpha.1 → 9.2.0-alpha.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/dist/adapter/converters/sampler-parameters.js +13 -2
- package/dist/adapter/converters/sampler-parameters.js.map +1 -1
- package/dist/adapter/converters/webgl-shadertypes.d.ts.map +1 -1
- package/dist/adapter/converters/webgl-shadertypes.js +1 -2
- package/dist/adapter/converters/webgl-shadertypes.js.map +1 -1
- package/dist/adapter/converters/webgl-texture-table.d.ts.map +1 -1
- package/dist/adapter/converters/webgl-texture-table.js +15 -11
- package/dist/adapter/converters/webgl-texture-table.js.map +1 -1
- package/dist/adapter/converters/webgl-vertex-formats.d.ts.map +1 -1
- package/dist/adapter/converters/webgl-vertex-formats.js +1 -2
- package/dist/adapter/converters/webgl-vertex-formats.js.map +1 -1
- package/dist/adapter/helpers/webgl-texture-utils.d.ts +0 -217
- package/dist/adapter/helpers/webgl-texture-utils.d.ts.map +1 -1
- package/dist/adapter/helpers/webgl-texture-utils.js +3 -3
- package/dist/adapter/helpers/webgl-texture-utils.js.map +1 -1
- package/dist/adapter/resources/webgl-buffer.d.ts +7 -7
- package/dist/adapter/resources/webgl-buffer.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-buffer.js +24 -15
- package/dist/adapter/resources/webgl-buffer.js.map +1 -1
- package/dist/adapter/resources/webgl-command-buffer.d.ts +2 -1
- package/dist/adapter/resources/webgl-command-buffer.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-command-buffer.js +1 -0
- package/dist/adapter/resources/webgl-command-buffer.js.map +1 -1
- package/dist/adapter/resources/webgl-framebuffer.d.ts +2 -2
- package/dist/adapter/resources/webgl-framebuffer.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-framebuffer.js.map +1 -1
- package/dist/adapter/resources/webgl-query-set.d.ts +2 -2
- package/dist/adapter/resources/webgl-query-set.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-query-set.js.map +1 -1
- package/dist/adapter/resources/webgl-render-pass.d.ts +1 -0
- package/dist/adapter/resources/webgl-render-pass.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-render-pass.js +1 -0
- package/dist/adapter/resources/webgl-render-pass.js.map +1 -1
- package/dist/adapter/resources/webgl-render-pipeline.d.ts +2 -2
- package/dist/adapter/resources/webgl-render-pipeline.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-render-pipeline.js +2 -1
- package/dist/adapter/resources/webgl-render-pipeline.js.map +1 -1
- package/dist/adapter/resources/webgl-texture.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-texture.js +8 -5
- package/dist/adapter/resources/webgl-texture.js.map +1 -1
- package/dist/adapter/resources/webgl-vertex-array.d.ts +1 -1
- package/dist/adapter/webgl-adapter.d.ts +2 -1
- package/dist/adapter/webgl-adapter.d.ts.map +1 -1
- package/dist/adapter/webgl-adapter.js +35 -25
- package/dist/adapter/webgl-adapter.js.map +1 -1
- package/dist/adapter/webgl-device.d.ts +12 -4
- package/dist/adapter/webgl-device.d.ts.map +1 -1
- package/dist/adapter/webgl-device.js +60 -17
- package/dist/adapter/webgl-device.js.map +1 -1
- package/dist/context/debug/webgl-developer-tools.js +1 -0
- package/dist/context/debug/webgl-developer-tools.js.map +1 -1
- package/dist/dist.dev.js +124 -57
- package/dist/dist.min.js +2 -2
- package/dist/index.cjs +117 -57
- package/dist/index.cjs.map +2 -2
- package/package.json +4 -4
- package/src/adapter/converters/sampler-parameters.ts +13 -2
- package/src/adapter/converters/webgl-shadertypes.ts +1 -2
- package/src/adapter/converters/webgl-texture-table.ts +20 -14
- package/src/adapter/converters/webgl-vertex-formats.ts +1 -2
- package/src/adapter/helpers/webgl-texture-utils.ts +3 -224
- package/src/adapter/resources/webgl-buffer.ts +38 -20
- package/src/adapter/resources/webgl-command-buffer.ts +4 -3
- package/src/adapter/resources/webgl-command-encoder.ts +1 -1
- package/src/adapter/resources/webgl-framebuffer.ts +2 -2
- package/src/adapter/resources/webgl-query-set.ts +2 -2
- package/src/adapter/resources/webgl-render-pass.ts +1 -0
- package/src/adapter/resources/webgl-render-pipeline.ts +7 -3
- package/src/adapter/resources/webgl-texture.ts +8 -5
- package/src/adapter/webgl-adapter.ts +36 -28
- package/src/adapter/webgl-device.ts +85 -31
- package/src/context/debug/webgl-developer-tools.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@luma.gl/webgl",
|
|
3
|
-
"version": "9.2.0-alpha.
|
|
3
|
+
"version": "9.2.0-alpha.3",
|
|
4
4
|
"description": "WebGL2 adapter for the luma.gl core API",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -40,12 +40,12 @@
|
|
|
40
40
|
"prepublishOnly": "npm run build-minified-bundle && npm run build-dev-bundle"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
|
-
"@luma.gl/core": "9.2.0-alpha.
|
|
43
|
+
"@luma.gl/core": "9.2.0-alpha.1"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@luma.gl/constants": "9.2.0-alpha.
|
|
46
|
+
"@luma.gl/constants": "9.2.0-alpha.3",
|
|
47
47
|
"@math.gl/types": "^4.1.0",
|
|
48
48
|
"@probe.gl/env": "^4.0.8"
|
|
49
49
|
},
|
|
50
|
-
"gitHead": "
|
|
50
|
+
"gitHead": "16fcea2620b1fd45cb744de730c2622a724cc15b"
|
|
51
51
|
}
|
|
@@ -99,8 +99,19 @@ function convertMinFilterMode(
|
|
|
99
99
|
case 'none':
|
|
100
100
|
return convertMaxFilterMode(minFilter);
|
|
101
101
|
case 'nearest':
|
|
102
|
-
|
|
102
|
+
switch (minFilter) {
|
|
103
|
+
case 'nearest':
|
|
104
|
+
return GL.NEAREST_MIPMAP_NEAREST;
|
|
105
|
+
case 'linear':
|
|
106
|
+
return GL.LINEAR_MIPMAP_NEAREST;
|
|
107
|
+
}
|
|
108
|
+
break;
|
|
103
109
|
case 'linear':
|
|
104
|
-
|
|
110
|
+
switch (minFilter) {
|
|
111
|
+
case 'nearest':
|
|
112
|
+
return GL.NEAREST_MIPMAP_LINEAR;
|
|
113
|
+
case 'linear':
|
|
114
|
+
return GL.LINEAR_MIPMAP_LINEAR;
|
|
115
|
+
}
|
|
105
116
|
}
|
|
106
117
|
}
|
|
@@ -48,10 +48,9 @@ export function getVertexFormatFromGL(type: GLDataType, components: 1 | 2 | 3 |
|
|
|
48
48
|
const base = getVertexTypeFromGL(type);
|
|
49
49
|
// prettier-ignore
|
|
50
50
|
switch (components) {
|
|
51
|
-
// @ts-expect-error TODO deal with lack of formats
|
|
52
51
|
case 1: return base;
|
|
53
52
|
case 2: return `${base}x2`;
|
|
54
|
-
// @ts-expect-error
|
|
53
|
+
// @ts-expect-error - deal with lack of "unaligned" formats
|
|
55
54
|
case 3: return `${base}x3`;
|
|
56
55
|
case 4: return `${base}x4`;
|
|
57
56
|
}
|
|
@@ -8,7 +8,7 @@ import type {
|
|
|
8
8
|
TextureFormatCapabilities,
|
|
9
9
|
DeviceTextureFormatCapabilities
|
|
10
10
|
} from '@luma.gl/core';
|
|
11
|
-
import {
|
|
11
|
+
import {textureFormatDecoder} from '@luma.gl/core';
|
|
12
12
|
import {GL, GLPixelType, GLExtensions, GLTexelDataFormat} from '@luma.gl/constants';
|
|
13
13
|
import {getWebGLExtension} from '../../context/helpers/webgl-extensions';
|
|
14
14
|
import {getGLFromVertexType} from './webgl-vertex-formats';
|
|
@@ -112,8 +112,8 @@ export const WEBGL_TEXTURE_FORMATS: Record<TextureFormat, WebGLFormatInfo> = {
|
|
|
112
112
|
'r16uint': {gl: GL.R16UI, rb: true},
|
|
113
113
|
'r16sint': {gl: GL.R16I, rb: true},
|
|
114
114
|
'r16float': {gl: GL.R16F, rb: true},
|
|
115
|
-
'r16unorm
|
|
116
|
-
'r16snorm
|
|
115
|
+
'r16unorm': {gl: GL.R16_EXT, rb: true},
|
|
116
|
+
'r16snorm': {gl: GL.R16_SNORM_EXT},
|
|
117
117
|
|
|
118
118
|
// Packed 16-bit formats
|
|
119
119
|
'rgba4unorm-webgl': {gl: GL.RGBA4, rb: true},
|
|
@@ -124,7 +124,7 @@ export const WEBGL_TEXTURE_FORMATS: Record<TextureFormat, WebGLFormatInfo> = {
|
|
|
124
124
|
'rgb8unorm-webgl': {gl: GL.RGB8},
|
|
125
125
|
'rgb8snorm-webgl': {gl: GL.RGB8_SNORM},
|
|
126
126
|
|
|
127
|
-
// 32-bit formats
|
|
127
|
+
// 32-bit formats
|
|
128
128
|
'rgba8unorm': {gl: GL.RGBA8},
|
|
129
129
|
'rgba8unorm-srgb': {gl: GL.SRGB8_ALPHA8},
|
|
130
130
|
'rgba8snorm': {gl: GL.RGBA8_SNORM},
|
|
@@ -137,8 +137,8 @@ export const WEBGL_TEXTURE_FORMATS: Record<TextureFormat, WebGLFormatInfo> = {
|
|
|
137
137
|
'rg16uint': {gl: GL.RG16UI},
|
|
138
138
|
'rg16sint': {gl: GL.RG16I},
|
|
139
139
|
'rg16float': {gl: GL.RG16F, rb: true},
|
|
140
|
-
'rg16unorm
|
|
141
|
-
'rg16snorm
|
|
140
|
+
'rg16unorm': {gl: GL.RG16_EXT},
|
|
141
|
+
'rg16snorm': {gl: GL.RG16_SNORM_EXT},
|
|
142
142
|
|
|
143
143
|
'r32uint': {gl: GL.R32UI, rb: true},
|
|
144
144
|
'r32sint': {gl: GL.R32I, rb: true},
|
|
@@ -149,7 +149,7 @@ export const WEBGL_TEXTURE_FORMATS: Record<TextureFormat, WebGLFormatInfo> = {
|
|
|
149
149
|
'rg11b10ufloat': {gl: GL.R11F_G11F_B10F, rb: true},
|
|
150
150
|
'rgb10a2unorm': {gl: GL.RGB10_A2, rb: true},
|
|
151
151
|
'rgb10a2uint': {gl: GL.RGB10_A2UI, rb: true},
|
|
152
|
-
|
|
152
|
+
|
|
153
153
|
// 48-bit formats
|
|
154
154
|
'rgb16unorm-webgl': {gl: GL.RGB16_EXT}, // rgb not renderable
|
|
155
155
|
'rgb16snorm-webgl': {gl: GL.RGB16_SNORM_EXT}, // rgb not renderable
|
|
@@ -161,12 +161,12 @@ export const WEBGL_TEXTURE_FORMATS: Record<TextureFormat, WebGLFormatInfo> = {
|
|
|
161
161
|
'rgba16uint': {gl: GL.RGBA16UI, rb: true},
|
|
162
162
|
'rgba16sint': {gl: GL.RGBA16I, rb: true},
|
|
163
163
|
'rgba16float': {gl: GL.RGBA16F},
|
|
164
|
-
'rgba16unorm
|
|
165
|
-
'rgba16snorm
|
|
164
|
+
'rgba16unorm': {gl: GL.RGBA16_EXT, rb: true},
|
|
165
|
+
'rgba16snorm': {gl: GL.RGBA16_SNORM_EXT},
|
|
166
166
|
|
|
167
167
|
// 96-bit formats (deprecated!)
|
|
168
168
|
'rgb32float-webgl': {gl: GL.RGB32F, x: EXT_color_buffer_float, dataFormat: GL.RGB, types: [GL.FLOAT]},
|
|
169
|
-
|
|
169
|
+
|
|
170
170
|
// 128-bit formats
|
|
171
171
|
'rgba32uint': {gl: GL.RGBA32UI, rb: true},
|
|
172
172
|
'rgba32sint': {gl: GL.RGBA32I, rb: true},
|
|
@@ -332,7 +332,13 @@ export function getTextureFormatWebGL(format: TextureFormat): {
|
|
|
332
332
|
} {
|
|
333
333
|
const formatData = WEBGL_TEXTURE_FORMATS[format];
|
|
334
334
|
const webglFormat = convertTextureFormatToGL(format);
|
|
335
|
-
const decoded =
|
|
335
|
+
const decoded = textureFormatDecoder.getInfo(format);
|
|
336
|
+
|
|
337
|
+
if (decoded.compressed) {
|
|
338
|
+
// TODO: Unclear whether this is always valid, this may be why ETC2 RGBA8 fails.
|
|
339
|
+
formatData.dataFormat = webglFormat as GLTexelDataFormat;
|
|
340
|
+
}
|
|
341
|
+
|
|
336
342
|
return {
|
|
337
343
|
internalFormat: webglFormat,
|
|
338
344
|
format:
|
|
@@ -349,7 +355,7 @@ export function getTextureFormatWebGL(format: TextureFormat): {
|
|
|
349
355
|
export function getDepthStencilAttachmentWebGL(
|
|
350
356
|
format: TextureFormat
|
|
351
357
|
): GL.DEPTH_ATTACHMENT | GL.STENCIL_ATTACHMENT | GL.DEPTH_STENCIL_ATTACHMENT {
|
|
352
|
-
const formatInfo =
|
|
358
|
+
const formatInfo = textureFormatDecoder.getInfo(format);
|
|
353
359
|
switch (formatInfo.attachment) {
|
|
354
360
|
case 'depth':
|
|
355
361
|
return GL.DEPTH_ATTACHMENT;
|
|
@@ -364,8 +370,8 @@ export function getDepthStencilAttachmentWebGL(
|
|
|
364
370
|
|
|
365
371
|
/** TODO - VERY roundabout legacy way of calculating bytes per pixel */
|
|
366
372
|
export function getTextureFormatBytesPerPixel(format: TextureFormat): number {
|
|
367
|
-
const formatInfo =
|
|
368
|
-
return formatInfo.bytesPerPixel
|
|
373
|
+
const formatInfo = textureFormatDecoder.getInfo(format);
|
|
374
|
+
return formatInfo.bytesPerPixel;
|
|
369
375
|
}
|
|
370
376
|
|
|
371
377
|
// DATA TYPE HELPERS
|
|
@@ -20,10 +20,9 @@ export function getVertexFormatFromGL(type: GLDataType, components: 1 | 2 | 3 |
|
|
|
20
20
|
const base = getVertexTypeFromGL(type);
|
|
21
21
|
// prettier-ignore
|
|
22
22
|
switch (components) {
|
|
23
|
-
// @ts-expect-error TODO deal with lack of formats
|
|
24
23
|
case 1: return base;
|
|
25
24
|
case 2: return `${base}x2`;
|
|
26
|
-
// @ts-expect-error TODO deal with lack of formats
|
|
25
|
+
// @ts-expect-error TODO deal with lack of "unaligned" formats
|
|
27
26
|
case 3: return `${base}x3`;
|
|
28
27
|
case 4: return `${base}x4`;
|
|
29
28
|
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// @ts-nocheck This file will be deleted in upcoming refactor
|
|
6
6
|
|
|
7
7
|
import type {Buffer, Texture, FramebufferProps} from '@luma.gl/core';
|
|
8
|
-
import {Framebuffer,
|
|
8
|
+
import {Framebuffer, getTypedArrayConstructor, getDataType} from '@luma.gl/core';
|
|
9
9
|
import {
|
|
10
10
|
GL,
|
|
11
11
|
GLTextureTarget,
|
|
@@ -156,227 +156,6 @@ export function getWebGLCubeFaceTarget(
|
|
|
156
156
|
): GLTextureTarget | GLTextureCubeMapTarget {
|
|
157
157
|
return dimension === 'cube' ? GL.TEXTURE_CUBE_MAP_POSITIVE_X + level : glTarget;
|
|
158
158
|
}
|
|
159
|
-
|
|
160
|
-
// texImage methods
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* Clear a texture mip level.
|
|
164
|
-
* Wrapper for the messy WebGL texture API
|
|
165
|
-
*
|
|
166
|
-
export function clearMipLevel(gl: WebGL2RenderingContext, options: WebGLSetTextureOptions): void {
|
|
167
|
-
const {dimension, width, height, depth = 0, mipLevel = 0} = options;
|
|
168
|
-
const {glInternalFormat, glFormat, glType, compressed} = options;
|
|
169
|
-
const glTarget = getWebGLCubeFaceTarget(options.glTarget, dimension, depth);
|
|
170
|
-
|
|
171
|
-
switch (dimension) {
|
|
172
|
-
case '2d-array':
|
|
173
|
-
case '3d':
|
|
174
|
-
if (compressed) {
|
|
175
|
-
// prettier-ignore
|
|
176
|
-
gl.compressedTexImage3D(glTarget, mipLevel, glInternalFormat, width, height, depth, BORDER, null);
|
|
177
|
-
} else {
|
|
178
|
-
// prettier-ignore
|
|
179
|
-
gl.texImage3D( glTarget, mipLevel, glInternalFormat, width, height, depth, BORDER, glFormat, glType, null);
|
|
180
|
-
}
|
|
181
|
-
break;
|
|
182
|
-
|
|
183
|
-
case '2d':
|
|
184
|
-
case 'cube':
|
|
185
|
-
if (compressed) {
|
|
186
|
-
// prettier-ignore
|
|
187
|
-
gl.compressedTexImage2D(glTarget, mipLevel, glInternalFormat, width, height, BORDER, null);
|
|
188
|
-
} else {
|
|
189
|
-
// prettier-ignore
|
|
190
|
-
gl.texImage2D(glTarget, mipLevel, glInternalFormat, width, height, BORDER, glFormat, glType, null);
|
|
191
|
-
}
|
|
192
|
-
break;
|
|
193
|
-
|
|
194
|
-
default:
|
|
195
|
-
throw new Error(dimension);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
*/
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* Set a texture mip level to the contents of an external image.
|
|
202
|
-
* Wrapper for the messy WebGL texture API
|
|
203
|
-
* @note Corresponds to WebGPU device.queue.copyExternalImageToTexture()
|
|
204
|
-
*
|
|
205
|
-
export function setMipLevelFromExternalImage(
|
|
206
|
-
gl: WebGL2RenderingContext,
|
|
207
|
-
image: ExternalImage,
|
|
208
|
-
options: WebGLSetTextureOptions
|
|
209
|
-
): void {
|
|
210
|
-
const {dimension, width, height, depth = 0, level = 0} = options;
|
|
211
|
-
const {glInternalFormat, glType} = options;
|
|
212
|
-
|
|
213
|
-
const glTarget = getWebGLCubeFaceTarget(options.glTarget, dimension, depth);
|
|
214
|
-
|
|
215
|
-
// TODO - we can't change texture width (due to WebGPU limitations) -
|
|
216
|
-
// and the width/heigh of an external image is implicit, so why do we need to extract it?
|
|
217
|
-
// So what width height do we supply? The image size or the texture size?
|
|
218
|
-
// const {width, height} = Texture.getExternalImageSize(image);
|
|
219
|
-
|
|
220
|
-
switch (dimension) {
|
|
221
|
-
case '2d-array':
|
|
222
|
-
case '3d':
|
|
223
|
-
// prettier-ignore
|
|
224
|
-
gl.texImage3D(glTarget, level, glInternalFormat, width, height, depth, BORDER, glInternalFormat, glType, image);
|
|
225
|
-
break;
|
|
226
|
-
|
|
227
|
-
case '2d':
|
|
228
|
-
case 'cube':
|
|
229
|
-
// prettier-ignore
|
|
230
|
-
gl.texImage2D(glTarget, level, glInternalFormat, width, height, BORDER, glInternalFormat, glType, image);
|
|
231
|
-
break;
|
|
232
|
-
|
|
233
|
-
default:
|
|
234
|
-
throw new Error(dimension);
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
/**
|
|
239
|
-
* Set a texture mip level from CPU memory
|
|
240
|
-
* Wrapper for the messy WebGL texture API
|
|
241
|
-
* @note Not available (directly) in WebGPU
|
|
242
|
-
*
|
|
243
|
-
export function setMipLevelFromTypedArray(
|
|
244
|
-
gl: WebGL2RenderingContext,
|
|
245
|
-
data: TypedArray,
|
|
246
|
-
parameters: {},
|
|
247
|
-
options: {
|
|
248
|
-
dimension: '1d' | '2d' | '2d-array' | 'cube' | 'cube-array' | '3d';
|
|
249
|
-
height: number;
|
|
250
|
-
width: number;
|
|
251
|
-
depth?: number;
|
|
252
|
-
level?: number;
|
|
253
|
-
offset?: number;
|
|
254
|
-
glTarget: GLTextureTarget;
|
|
255
|
-
glInternalFormat: GL;
|
|
256
|
-
glFormat: GL;
|
|
257
|
-
glType: GL;
|
|
258
|
-
compressed?: boolean;
|
|
259
|
-
}
|
|
260
|
-
): void {
|
|
261
|
-
const {dimension, width, height, depth = 0, level = 0, offset = 0} = options;
|
|
262
|
-
const {glInternalFormat, glFormat, glType, compressed} = options;
|
|
263
|
-
|
|
264
|
-
const glTarget = getWebGLCubeFaceTarget(options.glTarget, dimension, depth);
|
|
265
|
-
|
|
266
|
-
withGLParameters(gl, parameters, () => {
|
|
267
|
-
switch (dimension) {
|
|
268
|
-
case '2d-array':
|
|
269
|
-
case '3d':
|
|
270
|
-
if (compressed) {
|
|
271
|
-
// prettier-ignore
|
|
272
|
-
gl.compressedTexImage3D(glTarget, level, glInternalFormat, width, height, depth, BORDER, data);
|
|
273
|
-
} else {
|
|
274
|
-
// prettier-ignore
|
|
275
|
-
gl.texImage3D( glTarget, level, glInternalFormat, width, height, depth, BORDER, glFormat, glType, data);
|
|
276
|
-
}
|
|
277
|
-
break;
|
|
278
|
-
|
|
279
|
-
case '2d':
|
|
280
|
-
if (compressed) {
|
|
281
|
-
// prettier-ignore
|
|
282
|
-
gl.compressedTexImage2D(glTarget, level, glInternalFormat, width, height, BORDER, data);
|
|
283
|
-
} else {
|
|
284
|
-
// prettier-ignore
|
|
285
|
-
gl.texImage2D( glTarget, level, glInternalFormat, width, height, BORDER, glFormat, glType, data, offset);
|
|
286
|
-
}
|
|
287
|
-
break;
|
|
288
|
-
|
|
289
|
-
default:
|
|
290
|
-
throw new Error(dimension);
|
|
291
|
-
}
|
|
292
|
-
});
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
/**
|
|
296
|
-
* Set a texture level from CPU memory
|
|
297
|
-
* @note Not available (directly) in WebGPU
|
|
298
|
-
_setMipLevelFromTypedArray(
|
|
299
|
-
depth: number,
|
|
300
|
-
level: number,
|
|
301
|
-
data: TextureLevelData,
|
|
302
|
-
offset = 0,
|
|
303
|
-
parameters
|
|
304
|
-
): void {
|
|
305
|
-
withGLParameters(this.gl, parameters, () => {
|
|
306
|
-
switch (this.props.dimension) {
|
|
307
|
-
case '2d-array':
|
|
308
|
-
case '3d':
|
|
309
|
-
if (this.compressed) {
|
|
310
|
-
// prettier-ignore
|
|
311
|
-
this.device.gl.compressedTexImage3D(this.glTarget, level, this.glInternalFormat, data.width, data.height, depth, BORDER, data.data);
|
|
312
|
-
} else {
|
|
313
|
-
// prettier-ignore
|
|
314
|
-
this.gl.texImage3D( this.glTarget, level, this.glInternalFormat, this.width, this.height, depth, BORDER, this.glFormat, this.glType, data.data);
|
|
315
|
-
}
|
|
316
|
-
break;
|
|
317
|
-
|
|
318
|
-
case '2d':
|
|
319
|
-
if (this.compressed) {
|
|
320
|
-
// prettier-ignore
|
|
321
|
-
this.device.gl.compressedTexImage2D(this.glTarget, level, this.glInternalFormat, data.width, data.height, BORDER, data.data);
|
|
322
|
-
} else {
|
|
323
|
-
// prettier-ignore
|
|
324
|
-
this.device.gl.texImage2D( this.glTarget, level, this.glInternalFormat, this.width, this.height, BORDER, this.glFormat, this.glType, data.data, offset);
|
|
325
|
-
}
|
|
326
|
-
break;
|
|
327
|
-
|
|
328
|
-
default:
|
|
329
|
-
throw new Error(this.props.dimension);
|
|
330
|
-
}
|
|
331
|
-
});
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
* Set a texture level from a GPU buffer
|
|
335
|
-
*
|
|
336
|
-
export function setMipLevelFromGPUBuffer(
|
|
337
|
-
gl: WebGL2RenderingContext,
|
|
338
|
-
buffer: Buffer,
|
|
339
|
-
options: WebGLSetTextureOptions
|
|
340
|
-
): void {
|
|
341
|
-
const {dimension, width, height, depth = 0, level = 0, byteOffset = 0} = options;
|
|
342
|
-
const {glInternalFormat, glFormat, glType, compressed} = options;
|
|
343
|
-
const glTarget = getWebGLCubeFaceTarget(options.glTarget, dimension, depth);
|
|
344
|
-
|
|
345
|
-
const webglBuffer = buffer as WEBGLBuffer;
|
|
346
|
-
const imageSize = buffer.byteLength;
|
|
347
|
-
|
|
348
|
-
// In WebGL the source buffer is not a parameter. Instead it needs to be bound to a special bind point
|
|
349
|
-
gl.bindBuffer(GL.PIXEL_UNPACK_BUFFER, webglBuffer.handle);
|
|
350
|
-
|
|
351
|
-
switch (dimension) {
|
|
352
|
-
case '2d-array':
|
|
353
|
-
case '3d':
|
|
354
|
-
if (compressed) {
|
|
355
|
-
// prettier-ignore
|
|
356
|
-
gl.compressedTexImage3D(glTarget, level, glInternalFormat, width, height, depth, BORDER, imageSize, byteOffset);
|
|
357
|
-
} else {
|
|
358
|
-
// prettier-ignore
|
|
359
|
-
gl.texImage3D(glTarget, level, glInternalFormat, width, height, depth, BORDER, glFormat, glType, byteOffset);
|
|
360
|
-
}
|
|
361
|
-
break;
|
|
362
|
-
|
|
363
|
-
case '2d':
|
|
364
|
-
if (compressed) {
|
|
365
|
-
// prettier-ignore
|
|
366
|
-
gl.compressedTexImage2D(glTarget, level, glInternalFormat, width, height, BORDER, imageSize, byteOffset);
|
|
367
|
-
} else {
|
|
368
|
-
// prettier-ignore
|
|
369
|
-
gl.texImage2D(glTarget, level, glInternalFormat, width, height, BORDER, glFormat, glType, byteOffset);
|
|
370
|
-
}
|
|
371
|
-
break;
|
|
372
|
-
|
|
373
|
-
default:
|
|
374
|
-
throw new Error(dimension);
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
gl.bindBuffer(GL.PIXEL_UNPACK_BUFFER, null);
|
|
378
|
-
}
|
|
379
|
-
*/
|
|
380
159
|
export type ReadPixelsToArrayOptions = {
|
|
381
160
|
sourceX?: number;
|
|
382
161
|
sourceY?: number;
|
|
@@ -453,7 +232,7 @@ export function readPixelsToArray(
|
|
|
453
232
|
target = getPixelArray(target, sourceType, sourceFormat, sourceWidth, sourceHeight, sourceDepth);
|
|
454
233
|
|
|
455
234
|
// Pixel array available, if necessary, deduce type from it.
|
|
456
|
-
const signedType =
|
|
235
|
+
const signedType = getDataType(target);
|
|
457
236
|
sourceType = sourceType || convertDataTypeToGLDataType(signedType);
|
|
458
237
|
|
|
459
238
|
// Note: luma.gl overrides bindFramebuffer so that we can reliably restore the previous framebuffer (this is the only function for which we do that)
|
|
@@ -705,7 +484,7 @@ function getPixelArray(
|
|
|
705
484
|
// Allocate pixel array if not already available, using supplied type
|
|
706
485
|
glType ||= GL.UNSIGNED_BYTE;
|
|
707
486
|
const shaderType = convertGLDataTypeToDataType(glType);
|
|
708
|
-
const ArrayType =
|
|
487
|
+
const ArrayType = getTypedArrayConstructor(shaderType);
|
|
709
488
|
const components = glFormatToComponents(glFormat);
|
|
710
489
|
// TODO - check for composite type (components = 1).
|
|
711
490
|
return new ArrayType(width * height * components) as Uint8Array | Uint16Array | Float32Array;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
|
-
import type {BufferProps} from '@luma.gl/core';
|
|
5
|
+
import type {BufferMapCallback, BufferProps} from '@luma.gl/core';
|
|
6
6
|
import {Buffer} from '@luma.gl/core';
|
|
7
7
|
import {GL} from '@luma.gl/constants';
|
|
8
8
|
import {WebGLDevice} from '../webgl-device';
|
|
@@ -52,7 +52,16 @@ export class WEBGLBuffer extends Buffer {
|
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
override destroy(): void {
|
|
56
|
+
if (!this.destroyed && this.handle) {
|
|
57
|
+
this.removeStats();
|
|
58
|
+
this.trackDeallocatedMemory();
|
|
59
|
+
this.gl.deleteBuffer(this.handle);
|
|
60
|
+
this.destroyed = true;
|
|
61
|
+
// @ts-expect-error
|
|
62
|
+
this.handle = null;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
56
65
|
|
|
57
66
|
/** Allocate a new buffer and initialize to contents of typed array */
|
|
58
67
|
_initWithData(
|
|
@@ -102,18 +111,8 @@ export class WEBGLBuffer extends Buffer {
|
|
|
102
111
|
return this;
|
|
103
112
|
}
|
|
104
113
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
this.removeStats();
|
|
108
|
-
this.trackDeallocatedMemory();
|
|
109
|
-
this.gl.deleteBuffer(this.handle);
|
|
110
|
-
this.destroyed = true;
|
|
111
|
-
// @ts-expect-error
|
|
112
|
-
this.handle = null;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
override write(data: ArrayBufferView, byteOffset: number = 0): void {
|
|
114
|
+
write(data: ArrayBufferLike | ArrayBufferView, byteOffset: number = 0): void {
|
|
115
|
+
const dataView = ArrayBuffer.isView(data) ? data : new Uint8Array(data);
|
|
117
116
|
const srcOffset = 0;
|
|
118
117
|
const byteLength = undefined; // data.byteLength;
|
|
119
118
|
|
|
@@ -123,22 +122,41 @@ export class WEBGLBuffer extends Buffer {
|
|
|
123
122
|
this.gl.bindBuffer(glTarget, this.handle);
|
|
124
123
|
// WebGL2: subData supports additional srcOffset and length parameters
|
|
125
124
|
if (srcOffset !== 0 || byteLength !== undefined) {
|
|
126
|
-
this.gl.bufferSubData(glTarget, byteOffset,
|
|
125
|
+
this.gl.bufferSubData(glTarget, byteOffset, dataView, srcOffset, byteLength);
|
|
127
126
|
} else {
|
|
128
|
-
this.gl.bufferSubData(glTarget, byteOffset,
|
|
127
|
+
this.gl.bufferSubData(glTarget, byteOffset, dataView);
|
|
129
128
|
}
|
|
130
129
|
this.gl.bindBuffer(glTarget, null);
|
|
131
130
|
|
|
132
131
|
this._setDebugData(data, byteOffset, data.byteLength);
|
|
133
132
|
}
|
|
134
133
|
|
|
135
|
-
|
|
136
|
-
|
|
134
|
+
async mapAndWriteAsync(
|
|
135
|
+
callback: BufferMapCallback<void>,
|
|
136
|
+
byteOffset: number = 0,
|
|
137
|
+
byteLength: number = this.byteLength - byteOffset
|
|
138
|
+
): Promise<void> {
|
|
139
|
+
const arrayBuffer = new ArrayBuffer(byteLength);
|
|
140
|
+
// eslint-disable-next-line @typescript-eslint/await-thenable
|
|
141
|
+
await callback(arrayBuffer, 'copied');
|
|
142
|
+
this.write(arrayBuffer, byteOffset);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
async readAsync(byteOffset = 0, byteLength?: number): Promise<Uint8Array<ArrayBuffer>> {
|
|
137
146
|
return this.readSyncWebGL(byteOffset, byteLength);
|
|
138
147
|
}
|
|
139
148
|
|
|
140
|
-
|
|
141
|
-
|
|
149
|
+
async mapAndReadAsync<T>(
|
|
150
|
+
callback: BufferMapCallback<T>,
|
|
151
|
+
byteOffset = 0,
|
|
152
|
+
byteLength?: number
|
|
153
|
+
): Promise<T> {
|
|
154
|
+
const data = await this.readAsync(byteOffset, byteLength);
|
|
155
|
+
// eslint-disable-next-line @typescript-eslint/await-thenable
|
|
156
|
+
return await callback(data.buffer, 'copied');
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
readSyncWebGL(byteOffset = 0, byteLength?: number): Uint8Array<ArrayBuffer> {
|
|
142
160
|
byteLength = byteLength ?? this.byteLength - byteOffset;
|
|
143
161
|
const data = new Uint8Array(byteLength);
|
|
144
162
|
const dstOffset = 0;
|
|
@@ -8,7 +8,7 @@ import type {
|
|
|
8
8
|
CopyTextureToBufferOptions,
|
|
9
9
|
CopyTextureToTextureOptions
|
|
10
10
|
// ClearTextureOptions,
|
|
11
|
-
//
|
|
11
|
+
// TextureReadOptions
|
|
12
12
|
} from '@luma.gl/core';
|
|
13
13
|
import {CommandBuffer, Texture, Framebuffer} from '@luma.gl/core';
|
|
14
14
|
import {
|
|
@@ -53,7 +53,7 @@ type ClearTextureCommand = {
|
|
|
53
53
|
|
|
54
54
|
type ReadTextureCommand = {
|
|
55
55
|
name: 'read-texture';
|
|
56
|
-
options: {}; //
|
|
56
|
+
options: {}; // TextureReadOptions;
|
|
57
57
|
};
|
|
58
58
|
|
|
59
59
|
type Command =
|
|
@@ -65,7 +65,8 @@ type Command =
|
|
|
65
65
|
| ReadTextureCommand;
|
|
66
66
|
|
|
67
67
|
export class WEBGLCommandBuffer extends CommandBuffer {
|
|
68
|
-
device: WebGLDevice;
|
|
68
|
+
readonly device: WebGLDevice;
|
|
69
|
+
readonly handle = null;
|
|
69
70
|
commands: Command[] = [];
|
|
70
71
|
|
|
71
72
|
constructor(device: WebGLDevice) {
|
|
@@ -14,9 +14,9 @@ export type Attachment = WEBGLTextureView | WEBGLTexture; // | WEBGLRenderbuffer
|
|
|
14
14
|
|
|
15
15
|
/** luma.gl Framebuffer, WebGL implementation */
|
|
16
16
|
export class WEBGLFramebuffer extends Framebuffer {
|
|
17
|
-
device: WebGLDevice;
|
|
17
|
+
readonly device: WebGLDevice;
|
|
18
18
|
gl: WebGL2RenderingContext;
|
|
19
|
-
handle: WebGLFramebuffer;
|
|
19
|
+
readonly handle: WebGLFramebuffer;
|
|
20
20
|
|
|
21
21
|
colorAttachments: WEBGLTextureView[] = [];
|
|
22
22
|
depthStencilAttachment: WEBGLTextureView | null = null;
|
|
@@ -7,8 +7,8 @@ import {WebGLDevice} from '../webgl-device';
|
|
|
7
7
|
* Asynchronous queries for different kinds of information
|
|
8
8
|
*/
|
|
9
9
|
export class WEBGLQuerySet extends QuerySet {
|
|
10
|
-
device: WebGLDevice;
|
|
11
|
-
handle: WebGLQuery;
|
|
10
|
+
readonly device: WebGLDevice;
|
|
11
|
+
readonly handle: WebGLQuery;
|
|
12
12
|
|
|
13
13
|
target: number | null = null;
|
|
14
14
|
_queryPending = false;
|
|
@@ -15,6 +15,7 @@ const COLOR_CHANNELS: NumberArray4 = [0x1, 0x2, 0x4, 0x8]; // GPUColorWrite RED,
|
|
|
15
15
|
|
|
16
16
|
export class WEBGLRenderPass extends RenderPass {
|
|
17
17
|
readonly device: WebGLDevice;
|
|
18
|
+
readonly handle = null;
|
|
18
19
|
|
|
19
20
|
/** Parameters that should be applied before each draw call */
|
|
20
21
|
glParameters: GLParameters = {};
|
|
@@ -36,9 +36,9 @@ const LOG_PROGRAM_PERF_PRIORITY = 4;
|
|
|
36
36
|
/** Creates a new render pipeline */
|
|
37
37
|
export class WEBGLRenderPipeline extends RenderPipeline {
|
|
38
38
|
/** The WebGL device that created this render pipeline */
|
|
39
|
-
device: WebGLDevice;
|
|
39
|
+
readonly device: WebGLDevice;
|
|
40
40
|
/** Handle to underlying WebGL program */
|
|
41
|
-
handle: WebGLProgram;
|
|
41
|
+
readonly handle: WebGLProgram;
|
|
42
42
|
/** vertex shader */
|
|
43
43
|
vs: WEBGLShader;
|
|
44
44
|
/** fragment shader */
|
|
@@ -344,7 +344,11 @@ export class WEBGLRenderPipeline extends RenderPipeline {
|
|
|
344
344
|
}
|
|
345
345
|
|
|
346
346
|
const linkErrorLog = this.device.gl.getProgramInfoLog(this.handle);
|
|
347
|
-
this.device.reportError(
|
|
347
|
+
this.device.reportError(
|
|
348
|
+
new Error(`${errorType} during ${status}: ${linkErrorLog}`),
|
|
349
|
+
this
|
|
350
|
+
)();
|
|
351
|
+
this.device.debug();
|
|
348
352
|
}
|
|
349
353
|
}
|
|
350
354
|
|
|
@@ -147,10 +147,13 @@ export class WEBGLTexture extends Texture {
|
|
|
147
147
|
const {glFormat, glType, compressed} = this;
|
|
148
148
|
const glTarget = getWebGLCubeFaceTarget(this.glTarget, this.dimension, depth);
|
|
149
149
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
150
|
+
// WebGL automatically ignores these for compressed textures, but we are careful
|
|
151
|
+
const glParameters: GLValueParameters = !this.compressed
|
|
152
|
+
? {
|
|
153
|
+
[GL.UNPACK_ROW_LENGTH]: options.bytesPerRow,
|
|
154
|
+
[GL.UNPACK_IMAGE_HEIGHT]: options.rowsPerImage
|
|
155
|
+
}
|
|
156
|
+
: {};
|
|
154
157
|
|
|
155
158
|
this.gl.bindTexture(glTarget, this.handle);
|
|
156
159
|
|
|
@@ -252,7 +255,7 @@ export class WEBGLTexture extends Texture {
|
|
|
252
255
|
* Sets sampler parameters on texture
|
|
253
256
|
*/
|
|
254
257
|
_setSamplerParameters(parameters: GLSamplerParameters): void {
|
|
255
|
-
log.log(
|
|
258
|
+
log.log(2, `${this.id} sampler parameters`, this.device.getGLKeys(parameters))();
|
|
256
259
|
|
|
257
260
|
this.gl.bindTexture(this.glTarget, this.handle);
|
|
258
261
|
|