@luma.gl/webgl 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.
- package/dist/adapter/converters/webgl-texture-table.d.ts +7 -1
- package/dist/adapter/converters/webgl-texture-table.d.ts.map +1 -1
- package/dist/adapter/converters/webgl-texture-table.js +121 -43
- package/dist/adapter/converters/webgl-texture-table.js.map +1 -1
- package/dist/adapter/device-helpers/webgl-device-features.d.ts.map +1 -1
- package/dist/adapter/device-helpers/webgl-device-features.js +1 -2
- package/dist/adapter/device-helpers/webgl-device-features.js.map +1 -1
- package/dist/adapter/device-helpers/webgl-device-info.js +5 -0
- package/dist/adapter/device-helpers/webgl-device-info.js.map +1 -1
- package/dist/adapter/helpers/get-shader-layout-from-glsl.js +16 -17
- package/dist/adapter/helpers/get-shader-layout-from-glsl.js.map +1 -1
- package/dist/adapter/resources/webgl-buffer.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-buffer.js +19 -4
- package/dist/adapter/resources/webgl-buffer.js.map +1 -1
- package/dist/adapter/resources/webgl-command-buffer.d.ts +2 -2
- package/dist/adapter/resources/webgl-command-buffer.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-command-buffer.js +2 -2
- package/dist/adapter/resources/webgl-command-buffer.js.map +1 -1
- package/dist/adapter/resources/webgl-command-encoder.d.ts +5 -4
- package/dist/adapter/resources/webgl-command-encoder.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-command-encoder.js +20 -7
- package/dist/adapter/resources/webgl-command-encoder.js.map +1 -1
- package/dist/adapter/resources/webgl-query-set.d.ts +29 -31
- package/dist/adapter/resources/webgl-query-set.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-query-set.js +193 -97
- package/dist/adapter/resources/webgl-query-set.js.map +1 -1
- package/dist/adapter/resources/webgl-render-pass.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-render-pass.js +12 -0
- package/dist/adapter/resources/webgl-render-pass.js.map +1 -1
- package/dist/adapter/resources/webgl-render-pipeline.d.ts +13 -19
- package/dist/adapter/resources/webgl-render-pipeline.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-render-pipeline.js +35 -152
- package/dist/adapter/resources/webgl-render-pipeline.js.map +1 -1
- package/dist/adapter/resources/webgl-shared-render-pipeline.d.ts +24 -0
- package/dist/adapter/resources/webgl-shared-render-pipeline.d.ts.map +1 -0
- package/dist/adapter/resources/webgl-shared-render-pipeline.js +152 -0
- package/dist/adapter/resources/webgl-shared-render-pipeline.js.map +1 -0
- package/dist/adapter/resources/webgl-texture.d.ts +23 -4
- package/dist/adapter/resources/webgl-texture.d.ts.map +1 -1
- package/dist/adapter/resources/webgl-texture.js +203 -100
- package/dist/adapter/resources/webgl-texture.js.map +1 -1
- package/dist/adapter/webgl-device.d.ts +4 -2
- package/dist/adapter/webgl-device.d.ts.map +1 -1
- package/dist/adapter/webgl-device.js +31 -3
- package/dist/adapter/webgl-device.js.map +1 -1
- package/dist/adapter/webgl-presentation-context.d.ts +21 -0
- package/dist/adapter/webgl-presentation-context.d.ts.map +1 -0
- package/dist/adapter/webgl-presentation-context.js +64 -0
- package/dist/adapter/webgl-presentation-context.js.map +1 -0
- package/dist/dist.dev.js +1332 -788
- package/dist/dist.min.js +2 -2
- package/dist/index.cjs +1247 -797
- package/dist/index.cjs.map +4 -4
- package/package.json +3 -3
- package/src/adapter/converters/webgl-texture-table.ts +159 -47
- package/src/adapter/device-helpers/webgl-device-features.ts +1 -2
- package/src/adapter/device-helpers/webgl-device-info.ts +6 -0
- package/src/adapter/helpers/get-shader-layout-from-glsl.ts +18 -19
- package/src/adapter/resources/webgl-buffer.ts +16 -4
- package/src/adapter/resources/webgl-command-buffer.ts +3 -2
- package/src/adapter/resources/webgl-command-encoder.ts +22 -7
- package/src/adapter/resources/webgl-query-set.ts +229 -102
- package/src/adapter/resources/webgl-render-pass.ts +13 -0
- package/src/adapter/resources/webgl-render-pipeline.ts +45 -179
- package/src/adapter/resources/webgl-shared-render-pipeline.ts +208 -0
- package/src/adapter/resources/webgl-texture.ts +326 -121
- package/src/adapter/webgl-device.ts +40 -4
- package/src/adapter/webgl-presentation-context.ts +93 -0
package/dist/dist.dev.js
CHANGED
|
@@ -1983,6 +1983,8 @@ var __exports__ = (() => {
|
|
|
1983
1983
|
}
|
|
1984
1984
|
const gpuVendor = identifyGPUVendor(vendor, renderer);
|
|
1985
1985
|
switch (gpuVendor) {
|
|
1986
|
+
case "apple":
|
|
1987
|
+
return isAppleSiliconGPU(vendor, renderer) ? "integrated" : "unknown";
|
|
1986
1988
|
case "intel":
|
|
1987
1989
|
return "integrated";
|
|
1988
1990
|
case "software":
|
|
@@ -1993,6 +1995,9 @@ var __exports__ = (() => {
|
|
|
1993
1995
|
return "discrete";
|
|
1994
1996
|
}
|
|
1995
1997
|
}
|
|
1998
|
+
function isAppleSiliconGPU(vendor, renderer) {
|
|
1999
|
+
return /Apple (M\d|A\d|GPU)/i.test(`${vendor} ${renderer}`);
|
|
2000
|
+
}
|
|
1996
2001
|
var init_webgl_device_info = __esm({
|
|
1997
2002
|
"src/adapter/device-helpers/webgl-device-info.ts"() {
|
|
1998
2003
|
"use strict";
|
|
@@ -2041,8 +2046,27 @@ var __exports__ = (() => {
|
|
|
2041
2046
|
return feature in TEXTURE_FEATURES;
|
|
2042
2047
|
}
|
|
2043
2048
|
function checkTextureFeature(gl, feature, extensions) {
|
|
2044
|
-
|
|
2045
|
-
|
|
2049
|
+
return hasTextureFeature(gl, feature, extensions, /* @__PURE__ */ new Set());
|
|
2050
|
+
}
|
|
2051
|
+
function hasTextureFeature(gl, feature, extensions, seenFeatures) {
|
|
2052
|
+
const definition = TEXTURE_FEATURES[feature];
|
|
2053
|
+
if (!definition) {
|
|
2054
|
+
return false;
|
|
2055
|
+
}
|
|
2056
|
+
if (seenFeatures.has(feature)) {
|
|
2057
|
+
return false;
|
|
2058
|
+
}
|
|
2059
|
+
seenFeatures.add(feature);
|
|
2060
|
+
const hasDependentFeatures = (definition.features || []).every(
|
|
2061
|
+
(dependentFeature) => hasTextureFeature(gl, dependentFeature, extensions, seenFeatures)
|
|
2062
|
+
);
|
|
2063
|
+
seenFeatures.delete(feature);
|
|
2064
|
+
if (!hasDependentFeatures) {
|
|
2065
|
+
return false;
|
|
2066
|
+
}
|
|
2067
|
+
return (definition.extensions || []).every(
|
|
2068
|
+
(extension) => Boolean(getWebGLExtension(gl, extension, extensions))
|
|
2069
|
+
);
|
|
2046
2070
|
}
|
|
2047
2071
|
function getTextureFormatCapabilitiesWebGL(gl, formatSupport, extensions) {
|
|
2048
2072
|
let supported = formatSupport.create;
|
|
@@ -2053,12 +2077,17 @@ var __exports__ = (() => {
|
|
|
2053
2077
|
if (webglFormatInfo?.x) {
|
|
2054
2078
|
supported = supported && Boolean(getWebGLExtension(gl, webglFormatInfo.x, extensions));
|
|
2055
2079
|
}
|
|
2080
|
+
if (formatSupport.format === "stencil8") {
|
|
2081
|
+
supported = false;
|
|
2082
|
+
}
|
|
2083
|
+
const renderFeatureSupported = webglFormatInfo?.r === false ? false : webglFormatInfo?.r === void 0 || checkTextureFeature(gl, webglFormatInfo.r, extensions);
|
|
2084
|
+
const renderable = supported && formatSupport.render && renderFeatureSupported && isColorRenderableTextureFormat(gl, formatSupport.format, extensions);
|
|
2056
2085
|
return {
|
|
2057
2086
|
format: formatSupport.format,
|
|
2058
2087
|
// @ts-ignore
|
|
2059
2088
|
create: supported && formatSupport.create,
|
|
2060
2089
|
// @ts-ignore
|
|
2061
|
-
render:
|
|
2090
|
+
render: renderable,
|
|
2062
2091
|
// @ts-ignore
|
|
2063
2092
|
filter: supported && formatSupport.filter,
|
|
2064
2093
|
// @ts-ignore
|
|
@@ -2067,6 +2096,45 @@ var __exports__ = (() => {
|
|
|
2067
2096
|
store: supported && formatSupport.store
|
|
2068
2097
|
};
|
|
2069
2098
|
}
|
|
2099
|
+
function isColorRenderableTextureFormat(gl, format, extensions) {
|
|
2100
|
+
const webglFormatInfo = WEBGL_TEXTURE_FORMATS[format];
|
|
2101
|
+
const internalFormat = webglFormatInfo?.gl;
|
|
2102
|
+
if (internalFormat === void 0) {
|
|
2103
|
+
return false;
|
|
2104
|
+
}
|
|
2105
|
+
if (webglFormatInfo?.x && !getWebGLExtension(gl, webglFormatInfo.x, extensions)) {
|
|
2106
|
+
return false;
|
|
2107
|
+
}
|
|
2108
|
+
const previousTexture = gl.getParameter(32873 /* TEXTURE_BINDING_2D */);
|
|
2109
|
+
const previousFramebuffer = gl.getParameter(36006 /* FRAMEBUFFER_BINDING */);
|
|
2110
|
+
const texture = gl.createTexture();
|
|
2111
|
+
const framebuffer = gl.createFramebuffer();
|
|
2112
|
+
if (!texture || !framebuffer) {
|
|
2113
|
+
return false;
|
|
2114
|
+
}
|
|
2115
|
+
const noError = Number(0 /* NO_ERROR */);
|
|
2116
|
+
let error = Number(gl.getError());
|
|
2117
|
+
while (error !== noError) {
|
|
2118
|
+
error = gl.getError();
|
|
2119
|
+
}
|
|
2120
|
+
let renderable = false;
|
|
2121
|
+
try {
|
|
2122
|
+
gl.bindTexture(3553 /* TEXTURE_2D */, texture);
|
|
2123
|
+
gl.texStorage2D(3553 /* TEXTURE_2D */, 1, internalFormat, 1, 1);
|
|
2124
|
+
if (Number(gl.getError()) !== noError) {
|
|
2125
|
+
return false;
|
|
2126
|
+
}
|
|
2127
|
+
gl.bindFramebuffer(36160 /* FRAMEBUFFER */, framebuffer);
|
|
2128
|
+
gl.framebufferTexture2D(36160 /* FRAMEBUFFER */, 36064 /* COLOR_ATTACHMENT0 */, 3553 /* TEXTURE_2D */, texture, 0);
|
|
2129
|
+
renderable = Number(gl.checkFramebufferStatus(36160 /* FRAMEBUFFER */)) === Number(36053 /* FRAMEBUFFER_COMPLETE */) && Number(gl.getError()) === noError;
|
|
2130
|
+
} finally {
|
|
2131
|
+
gl.bindFramebuffer(36160 /* FRAMEBUFFER */, previousFramebuffer);
|
|
2132
|
+
gl.deleteFramebuffer(framebuffer);
|
|
2133
|
+
gl.bindTexture(3553 /* TEXTURE_2D */, previousTexture);
|
|
2134
|
+
gl.deleteTexture(texture);
|
|
2135
|
+
}
|
|
2136
|
+
return renderable;
|
|
2137
|
+
}
|
|
2070
2138
|
function getTextureFormatWebGL(format) {
|
|
2071
2139
|
const formatData = WEBGL_TEXTURE_FORMATS[format];
|
|
2072
2140
|
const webglFormat = convertTextureFormatToGL(format);
|
|
@@ -2122,7 +2190,7 @@ var __exports__ = (() => {
|
|
|
2122
2190
|
}
|
|
2123
2191
|
return webglFormat;
|
|
2124
2192
|
}
|
|
2125
|
-
var import_core3, X_S3TC, X_S3TC_SRGB, X_RGTC, X_BPTC, X_ETC2, X_ASTC, X_ETC1, X_PVRTC, X_ATC, EXT_texture_norm16, EXT_render_snorm, EXT_color_buffer_float, TEXTURE_FEATURES, WEBGL_TEXTURE_FORMATS;
|
|
2193
|
+
var import_core3, X_S3TC, X_S3TC_SRGB, X_RGTC, X_BPTC, X_ETC2, X_ASTC, X_ETC1, X_PVRTC, X_ATC, EXT_texture_norm16, EXT_render_snorm, EXT_color_buffer_float, SNORM8_COLOR_RENDERABLE, NORM16_COLOR_RENDERABLE, SNORM16_COLOR_RENDERABLE, FLOAT16_COLOR_RENDERABLE, FLOAT32_COLOR_RENDERABLE, RGB9E5UFLOAT_COLOR_RENDERABLE, TEXTURE_FEATURES, WEBGL_TEXTURE_FORMATS;
|
|
2126
2194
|
var init_webgl_texture_table = __esm({
|
|
2127
2195
|
"src/adapter/converters/webgl-texture-table.ts"() {
|
|
2128
2196
|
"use strict";
|
|
@@ -2141,44 +2209,51 @@ var __exports__ = (() => {
|
|
|
2141
2209
|
EXT_texture_norm16 = "EXT_texture_norm16";
|
|
2142
2210
|
EXT_render_snorm = "EXT_render_snorm";
|
|
2143
2211
|
EXT_color_buffer_float = "EXT_color_buffer_float";
|
|
2212
|
+
SNORM8_COLOR_RENDERABLE = "snorm8-renderable-webgl";
|
|
2213
|
+
NORM16_COLOR_RENDERABLE = "norm16-renderable-webgl";
|
|
2214
|
+
SNORM16_COLOR_RENDERABLE = "snorm16-renderable-webgl";
|
|
2215
|
+
FLOAT16_COLOR_RENDERABLE = "float16-renderable-webgl";
|
|
2216
|
+
FLOAT32_COLOR_RENDERABLE = "float32-renderable-webgl";
|
|
2217
|
+
RGB9E5UFLOAT_COLOR_RENDERABLE = "rgb9e5ufloat-renderable-webgl";
|
|
2144
2218
|
TEXTURE_FEATURES = {
|
|
2145
|
-
"float32-renderable-webgl": [
|
|
2146
|
-
"float16-renderable-webgl": ["EXT_color_buffer_half_float"],
|
|
2147
|
-
"rgb9e5ufloat-renderable-webgl": ["WEBGL_render_shared_exponent"],
|
|
2148
|
-
"snorm8-renderable-webgl": [EXT_render_snorm],
|
|
2149
|
-
"norm16-
|
|
2150
|
-
"
|
|
2151
|
-
"
|
|
2152
|
-
"
|
|
2153
|
-
"
|
|
2154
|
-
"texture-
|
|
2155
|
-
"texture-
|
|
2219
|
+
"float32-renderable-webgl": { extensions: [EXT_color_buffer_float] },
|
|
2220
|
+
"float16-renderable-webgl": { extensions: ["EXT_color_buffer_half_float"] },
|
|
2221
|
+
"rgb9e5ufloat-renderable-webgl": { extensions: ["WEBGL_render_shared_exponent"] },
|
|
2222
|
+
"snorm8-renderable-webgl": { extensions: [EXT_render_snorm] },
|
|
2223
|
+
"norm16-webgl": { extensions: [EXT_texture_norm16] },
|
|
2224
|
+
"norm16-renderable-webgl": { features: ["norm16-webgl"] },
|
|
2225
|
+
"snorm16-renderable-webgl": { features: ["norm16-webgl"], extensions: [EXT_render_snorm] },
|
|
2226
|
+
"float32-filterable": { extensions: ["OES_texture_float_linear"] },
|
|
2227
|
+
"float16-filterable-webgl": { extensions: ["OES_texture_half_float_linear"] },
|
|
2228
|
+
"texture-filterable-anisotropic-webgl": { extensions: ["EXT_texture_filter_anisotropic"] },
|
|
2229
|
+
"texture-blend-float-webgl": { extensions: ["EXT_float_blend"] },
|
|
2230
|
+
"texture-compression-bc": { extensions: [X_S3TC, X_S3TC_SRGB, X_RGTC, X_BPTC] },
|
|
2156
2231
|
// 'texture-compression-bc3-srgb-webgl': [X_S3TC_SRGB],
|
|
2157
2232
|
// 'texture-compression-bc3-webgl': [X_S3TC],
|
|
2158
|
-
"texture-compression-bc5-webgl": [X_RGTC],
|
|
2159
|
-
"texture-compression-bc7-webgl": [X_BPTC],
|
|
2160
|
-
"texture-compression-etc2": [X_ETC2],
|
|
2161
|
-
"texture-compression-astc": [X_ASTC],
|
|
2162
|
-
"texture-compression-etc1-webgl": [X_ETC1],
|
|
2163
|
-
"texture-compression-pvrtc-webgl": [X_PVRTC],
|
|
2164
|
-
"texture-compression-atc-webgl": [X_ATC]
|
|
2233
|
+
"texture-compression-bc5-webgl": { extensions: [X_RGTC] },
|
|
2234
|
+
"texture-compression-bc7-webgl": { extensions: [X_BPTC] },
|
|
2235
|
+
"texture-compression-etc2": { extensions: [X_ETC2] },
|
|
2236
|
+
"texture-compression-astc": { extensions: [X_ASTC] },
|
|
2237
|
+
"texture-compression-etc1-webgl": { extensions: [X_ETC1] },
|
|
2238
|
+
"texture-compression-pvrtc-webgl": { extensions: [X_PVRTC] },
|
|
2239
|
+
"texture-compression-atc-webgl": { extensions: [X_ATC] }
|
|
2165
2240
|
};
|
|
2166
2241
|
WEBGL_TEXTURE_FORMATS = {
|
|
2167
2242
|
// 8-bit formats
|
|
2168
2243
|
"r8unorm": { gl: 33321 /* R8 */, rb: true },
|
|
2169
|
-
"r8snorm": { gl: 36756 /* R8_SNORM
|
|
2244
|
+
"r8snorm": { gl: 36756 /* R8_SNORM */, r: SNORM8_COLOR_RENDERABLE },
|
|
2170
2245
|
"r8uint": { gl: 33330 /* R8UI */, rb: true },
|
|
2171
2246
|
"r8sint": { gl: 33329 /* R8I */, rb: true },
|
|
2172
2247
|
// 16-bit formats
|
|
2173
2248
|
"rg8unorm": { gl: 33323 /* RG8 */, rb: true },
|
|
2174
|
-
"rg8snorm": { gl: 36757 /* RG8_SNORM
|
|
2249
|
+
"rg8snorm": { gl: 36757 /* RG8_SNORM */, r: SNORM8_COLOR_RENDERABLE },
|
|
2175
2250
|
"rg8uint": { gl: 33336 /* RG8UI */, rb: true },
|
|
2176
2251
|
"rg8sint": { gl: 33335 /* RG8I */, rb: true },
|
|
2177
2252
|
"r16uint": { gl: 33332 /* R16UI */, rb: true },
|
|
2178
2253
|
"r16sint": { gl: 33331 /* R16I */, rb: true },
|
|
2179
|
-
"r16float": { gl: 33325 /* R16F */, rb: true },
|
|
2180
|
-
"r16unorm": { gl: 33322 /* R16_EXT */, rb: true },
|
|
2181
|
-
"r16snorm": { gl: 36760 /* R16_SNORM_EXT
|
|
2254
|
+
"r16float": { gl: 33325 /* R16F */, rb: true, r: FLOAT16_COLOR_RENDERABLE },
|
|
2255
|
+
"r16unorm": { gl: 33322 /* R16_EXT */, rb: true, r: NORM16_COLOR_RENDERABLE },
|
|
2256
|
+
"r16snorm": { gl: 36760 /* R16_SNORM_EXT */, r: SNORM16_COLOR_RENDERABLE },
|
|
2182
2257
|
// Packed 16-bit formats
|
|
2183
2258
|
"rgba4unorm-webgl": { gl: 32854 /* RGBA4 */, rb: true },
|
|
2184
2259
|
"rgb565unorm-webgl": { gl: 36194 /* RGB565 */, rb: true },
|
|
@@ -2189,7 +2264,7 @@ var __exports__ = (() => {
|
|
|
2189
2264
|
// 32-bit formats
|
|
2190
2265
|
"rgba8unorm": { gl: 32856 /* RGBA8 */ },
|
|
2191
2266
|
"rgba8unorm-srgb": { gl: 35907 /* SRGB8_ALPHA8 */ },
|
|
2192
|
-
"rgba8snorm": { gl: 36759 /* RGBA8_SNORM
|
|
2267
|
+
"rgba8snorm": { gl: 36759 /* RGBA8_SNORM */, r: SNORM8_COLOR_RENDERABLE },
|
|
2193
2268
|
"rgba8uint": { gl: 36220 /* RGBA8UI */ },
|
|
2194
2269
|
"rgba8sint": { gl: 36238 /* RGBA8I */ },
|
|
2195
2270
|
// reverse colors, webgpu only
|
|
@@ -2197,38 +2272,38 @@ var __exports__ = (() => {
|
|
|
2197
2272
|
"bgra8unorm-srgb": {},
|
|
2198
2273
|
"rg16uint": { gl: 33338 /* RG16UI */ },
|
|
2199
2274
|
"rg16sint": { gl: 33337 /* RG16I */ },
|
|
2200
|
-
"rg16float": { gl: 33327 /* RG16F */, rb: true },
|
|
2201
|
-
"rg16unorm": { gl: 33324 /* RG16_EXT
|
|
2202
|
-
"rg16snorm": { gl: 36761 /* RG16_SNORM_EXT
|
|
2275
|
+
"rg16float": { gl: 33327 /* RG16F */, rb: true, r: FLOAT16_COLOR_RENDERABLE },
|
|
2276
|
+
"rg16unorm": { gl: 33324 /* RG16_EXT */, r: NORM16_COLOR_RENDERABLE },
|
|
2277
|
+
"rg16snorm": { gl: 36761 /* RG16_SNORM_EXT */, r: SNORM16_COLOR_RENDERABLE },
|
|
2203
2278
|
"r32uint": { gl: 33334 /* R32UI */, rb: true },
|
|
2204
2279
|
"r32sint": { gl: 33333 /* R32I */, rb: true },
|
|
2205
|
-
"r32float": { gl: 33326 /* R32F
|
|
2280
|
+
"r32float": { gl: 33326 /* R32F */, r: FLOAT32_COLOR_RENDERABLE },
|
|
2206
2281
|
// Packed 32-bit formats
|
|
2207
|
-
"rgb9e5ufloat": { gl: 35901 /* RGB9_E5
|
|
2282
|
+
"rgb9e5ufloat": { gl: 35901 /* RGB9_E5 */, r: RGB9E5UFLOAT_COLOR_RENDERABLE },
|
|
2208
2283
|
// , filter: true},
|
|
2209
2284
|
"rg11b10ufloat": { gl: 35898 /* R11F_G11F_B10F */, rb: true },
|
|
2210
2285
|
"rgb10a2unorm": { gl: 32857 /* RGB10_A2 */, rb: true },
|
|
2211
2286
|
"rgb10a2uint": { gl: 36975 /* RGB10_A2UI */, rb: true },
|
|
2212
2287
|
// 48-bit formats
|
|
2213
|
-
"rgb16unorm-webgl": { gl: 32852 /* RGB16_EXT
|
|
2288
|
+
"rgb16unorm-webgl": { gl: 32852 /* RGB16_EXT */, r: false },
|
|
2214
2289
|
// rgb not renderable
|
|
2215
|
-
"rgb16snorm-webgl": { gl: 36762 /* RGB16_SNORM_EXT
|
|
2290
|
+
"rgb16snorm-webgl": { gl: 36762 /* RGB16_SNORM_EXT */, r: false },
|
|
2216
2291
|
// rgb not renderable
|
|
2217
2292
|
// 64-bit formats
|
|
2218
2293
|
"rg32uint": { gl: 33340 /* RG32UI */, rb: true },
|
|
2219
2294
|
"rg32sint": { gl: 33339 /* RG32I */, rb: true },
|
|
2220
|
-
"rg32float": { gl: 33328 /* RG32F */, rb: true },
|
|
2295
|
+
"rg32float": { gl: 33328 /* RG32F */, rb: true, r: FLOAT32_COLOR_RENDERABLE },
|
|
2221
2296
|
"rgba16uint": { gl: 36214 /* RGBA16UI */, rb: true },
|
|
2222
2297
|
"rgba16sint": { gl: 36232 /* RGBA16I */, rb: true },
|
|
2223
|
-
"rgba16float": { gl: 34842 /* RGBA16F
|
|
2224
|
-
"rgba16unorm": { gl: 32859 /* RGBA16_EXT */, rb: true },
|
|
2225
|
-
"rgba16snorm": { gl: 36763 /* RGBA16_SNORM_EXT
|
|
2298
|
+
"rgba16float": { gl: 34842 /* RGBA16F */, r: FLOAT16_COLOR_RENDERABLE },
|
|
2299
|
+
"rgba16unorm": { gl: 32859 /* RGBA16_EXT */, rb: true, r: NORM16_COLOR_RENDERABLE },
|
|
2300
|
+
"rgba16snorm": { gl: 36763 /* RGBA16_SNORM_EXT */, r: SNORM16_COLOR_RENDERABLE },
|
|
2226
2301
|
// 96-bit formats (deprecated!)
|
|
2227
|
-
"rgb32float-webgl": { gl: 34837 /* RGB32F */, x: EXT_color_buffer_float, dataFormat: 6407 /* RGB */, types: [5126 /* FLOAT */] },
|
|
2302
|
+
"rgb32float-webgl": { gl: 34837 /* RGB32F */, x: EXT_color_buffer_float, r: FLOAT32_COLOR_RENDERABLE, dataFormat: 6407 /* RGB */, types: [5126 /* FLOAT */] },
|
|
2228
2303
|
// 128-bit formats
|
|
2229
2304
|
"rgba32uint": { gl: 36208 /* RGBA32UI */, rb: true },
|
|
2230
2305
|
"rgba32sint": { gl: 36226 /* RGBA32I */, rb: true },
|
|
2231
|
-
"rgba32float": { gl: 34836 /* RGBA32F */, rb: true },
|
|
2306
|
+
"rgba32float": { gl: 34836 /* RGBA32F */, rb: true, r: FLOAT32_COLOR_RENDERABLE },
|
|
2232
2307
|
// Depth and stencil formats
|
|
2233
2308
|
"stencil8": { gl: 36168 /* STENCIL_INDEX8 */, rb: true },
|
|
2234
2309
|
// 8 stencil bits
|
|
@@ -2286,8 +2361,8 @@ var __exports__ = (() => {
|
|
|
2286
2361
|
"astc-8x6-unorm-srgb": { gl: 37846 /* COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR */ },
|
|
2287
2362
|
"astc-8x8-unorm": { gl: 37815 /* COMPRESSED_RGBA_ASTC_8x8_KHR */ },
|
|
2288
2363
|
"astc-8x8-unorm-srgb": { gl: 37847 /* COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR */ },
|
|
2289
|
-
"astc-10x5-unorm": { gl:
|
|
2290
|
-
"astc-10x5-unorm-srgb": { gl:
|
|
2364
|
+
"astc-10x5-unorm": { gl: 37816 /* COMPRESSED_RGBA_ASTC_10x5_KHR */ },
|
|
2365
|
+
"astc-10x5-unorm-srgb": { gl: 37848 /* COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR */ },
|
|
2291
2366
|
"astc-10x6-unorm": { gl: 37817 /* COMPRESSED_RGBA_ASTC_10x6_KHR */ },
|
|
2292
2367
|
"astc-10x6-unorm-srgb": { gl: 37849 /* COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR */ },
|
|
2293
2368
|
"astc-10x8-unorm": { gl: 37818 /* COMPRESSED_RGBA_ASTC_10x8_KHR */ },
|
|
@@ -2301,7 +2376,7 @@ var __exports__ = (() => {
|
|
|
2301
2376
|
// WEBGL_compressed_texture_pvrtc
|
|
2302
2377
|
"pvrtc-rgb4unorm-webgl": { gl: 35840 /* COMPRESSED_RGB_PVRTC_4BPPV1_IMG */ },
|
|
2303
2378
|
"pvrtc-rgba4unorm-webgl": { gl: 35842 /* COMPRESSED_RGBA_PVRTC_4BPPV1_IMG */ },
|
|
2304
|
-
"pvrtc-
|
|
2379
|
+
"pvrtc-rgb2unorm-webgl": { gl: 35841 /* COMPRESSED_RGB_PVRTC_2BPPV1_IMG */ },
|
|
2305
2380
|
"pvrtc-rgba2unorm-webgl": { gl: 35843 /* COMPRESSED_RGBA_PVRTC_2BPPV1_IMG */ },
|
|
2306
2381
|
// WEBGL_compressed_texture_etc1
|
|
2307
2382
|
"etc1-rbg-unorm-webgl": { gl: 36196 /* COMPRESSED_RGB_ETC1_WEBGL */ },
|
|
@@ -2325,12 +2400,11 @@ var __exports__ = (() => {
|
|
|
2325
2400
|
// optional WebGPU features
|
|
2326
2401
|
"depth-clip-control": "EXT_depth_clamp",
|
|
2327
2402
|
// TODO these seem subtly different
|
|
2328
|
-
|
|
2403
|
+
"timestamp-query": "EXT_disjoint_timer_query_webgl2",
|
|
2329
2404
|
// "indirect-first-instance"
|
|
2330
2405
|
// Textures are handled by getTextureFeatures()
|
|
2331
2406
|
// 'depth32float-stencil8' // GPUTextureFormat 'depth32float-stencil8'
|
|
2332
2407
|
// optional WebGL features
|
|
2333
|
-
"timer-query-webgl": "EXT_disjoint_timer_query_webgl2",
|
|
2334
2408
|
"compilation-status-async-webgl": "KHR_parallel_shader_compile",
|
|
2335
2409
|
"polygon-mode-webgl": "WEBGL_polygon_mode",
|
|
2336
2410
|
"provoking-vertex-webgl": "WEBGL_provoking_vertex",
|
|
@@ -2675,6 +2749,65 @@ var __exports__ = (() => {
|
|
|
2675
2749
|
}
|
|
2676
2750
|
});
|
|
2677
2751
|
|
|
2752
|
+
// src/adapter/webgl-presentation-context.ts
|
|
2753
|
+
var import_core8, WebGLPresentationContext;
|
|
2754
|
+
var init_webgl_presentation_context = __esm({
|
|
2755
|
+
"src/adapter/webgl-presentation-context.ts"() {
|
|
2756
|
+
"use strict";
|
|
2757
|
+
import_core8 = __toESM(require_core(), 1);
|
|
2758
|
+
WebGLPresentationContext = class extends import_core8.PresentationContext {
|
|
2759
|
+
device;
|
|
2760
|
+
handle = null;
|
|
2761
|
+
context2d;
|
|
2762
|
+
get [Symbol.toStringTag]() {
|
|
2763
|
+
return "WebGLPresentationContext";
|
|
2764
|
+
}
|
|
2765
|
+
constructor(device, props = {}) {
|
|
2766
|
+
super(props);
|
|
2767
|
+
this.device = device;
|
|
2768
|
+
const contextLabel = `${this[Symbol.toStringTag]}(${this.id})`;
|
|
2769
|
+
const defaultCanvasContext = this.device.getDefaultCanvasContext();
|
|
2770
|
+
if (!defaultCanvasContext.offscreenCanvas) {
|
|
2771
|
+
throw new Error(
|
|
2772
|
+
`${contextLabel}: WebGL PresentationContext requires the default CanvasContext canvas to be an OffscreenCanvas`
|
|
2773
|
+
);
|
|
2774
|
+
}
|
|
2775
|
+
const context2d = this.canvas.getContext("2d");
|
|
2776
|
+
if (!context2d) {
|
|
2777
|
+
throw new Error(`${contextLabel}: Failed to create 2d presentation context`);
|
|
2778
|
+
}
|
|
2779
|
+
this.context2d = context2d;
|
|
2780
|
+
this._setAutoCreatedCanvasId(`${this.device.id}-presentation-canvas`);
|
|
2781
|
+
this._configureDevice();
|
|
2782
|
+
this._startObservers();
|
|
2783
|
+
}
|
|
2784
|
+
present() {
|
|
2785
|
+
this._resizeDrawingBufferIfNeeded();
|
|
2786
|
+
this.device.submit();
|
|
2787
|
+
const defaultCanvasContext = this.device.getDefaultCanvasContext();
|
|
2788
|
+
const [sourceWidth, sourceHeight] = defaultCanvasContext.getDrawingBufferSize();
|
|
2789
|
+
if (this.drawingBufferWidth === 0 || this.drawingBufferHeight === 0 || sourceWidth === 0 || sourceHeight === 0 || defaultCanvasContext.canvas.width === 0 || defaultCanvasContext.canvas.height === 0) {
|
|
2790
|
+
return;
|
|
2791
|
+
}
|
|
2792
|
+
if (sourceWidth !== this.drawingBufferWidth || sourceHeight !== this.drawingBufferHeight || defaultCanvasContext.canvas.width !== this.drawingBufferWidth || defaultCanvasContext.canvas.height !== this.drawingBufferHeight) {
|
|
2793
|
+
throw new Error(
|
|
2794
|
+
`${this[Symbol.toStringTag]}(${this.id}): Default canvas context size ${sourceWidth}x${sourceHeight} does not match presentation size ${this.drawingBufferWidth}x${this.drawingBufferHeight}`
|
|
2795
|
+
);
|
|
2796
|
+
}
|
|
2797
|
+
this.context2d.clearRect(0, 0, this.drawingBufferWidth, this.drawingBufferHeight);
|
|
2798
|
+
this.context2d.drawImage(defaultCanvasContext.canvas, 0, 0);
|
|
2799
|
+
}
|
|
2800
|
+
_configureDevice() {
|
|
2801
|
+
}
|
|
2802
|
+
_getCurrentFramebuffer(options) {
|
|
2803
|
+
const defaultCanvasContext = this.device.getDefaultCanvasContext();
|
|
2804
|
+
defaultCanvasContext.setDrawingBufferSize(this.drawingBufferWidth, this.drawingBufferHeight);
|
|
2805
|
+
return defaultCanvasContext.getCurrentFramebuffer(options);
|
|
2806
|
+
}
|
|
2807
|
+
};
|
|
2808
|
+
}
|
|
2809
|
+
});
|
|
2810
|
+
|
|
2678
2811
|
// src/utils/uid.ts
|
|
2679
2812
|
function uid(id = "id") {
|
|
2680
2813
|
uidCounters[id] = uidCounters[id] || 1;
|
|
@@ -2691,35 +2824,35 @@ var __exports__ = (() => {
|
|
|
2691
2824
|
|
|
2692
2825
|
// src/adapter/resources/webgl-buffer.ts
|
|
2693
2826
|
function getWebGLTarget(usage) {
|
|
2694
|
-
if (usage &
|
|
2827
|
+
if (usage & import_core9.Buffer.INDEX) {
|
|
2695
2828
|
return 34963 /* ELEMENT_ARRAY_BUFFER */;
|
|
2696
2829
|
}
|
|
2697
|
-
if (usage &
|
|
2830
|
+
if (usage & import_core9.Buffer.VERTEX) {
|
|
2698
2831
|
return 34962 /* ARRAY_BUFFER */;
|
|
2699
2832
|
}
|
|
2700
|
-
if (usage &
|
|
2833
|
+
if (usage & import_core9.Buffer.UNIFORM) {
|
|
2701
2834
|
return 35345 /* UNIFORM_BUFFER */;
|
|
2702
2835
|
}
|
|
2703
2836
|
return 34962 /* ARRAY_BUFFER */;
|
|
2704
2837
|
}
|
|
2705
2838
|
function getWebGLUsage(usage) {
|
|
2706
|
-
if (usage &
|
|
2839
|
+
if (usage & import_core9.Buffer.INDEX) {
|
|
2707
2840
|
return 35044 /* STATIC_DRAW */;
|
|
2708
2841
|
}
|
|
2709
|
-
if (usage &
|
|
2842
|
+
if (usage & import_core9.Buffer.VERTEX) {
|
|
2710
2843
|
return 35044 /* STATIC_DRAW */;
|
|
2711
2844
|
}
|
|
2712
|
-
if (usage &
|
|
2845
|
+
if (usage & import_core9.Buffer.UNIFORM) {
|
|
2713
2846
|
return 35048 /* DYNAMIC_DRAW */;
|
|
2714
2847
|
}
|
|
2715
2848
|
return 35044 /* STATIC_DRAW */;
|
|
2716
2849
|
}
|
|
2717
|
-
var
|
|
2850
|
+
var import_core9, WEBGLBuffer;
|
|
2718
2851
|
var init_webgl_buffer = __esm({
|
|
2719
2852
|
"src/adapter/resources/webgl-buffer.ts"() {
|
|
2720
2853
|
"use strict";
|
|
2721
|
-
|
|
2722
|
-
WEBGLBuffer = class extends
|
|
2854
|
+
import_core9 = __toESM(require_core(), 1);
|
|
2855
|
+
WEBGLBuffer = class extends import_core9.Buffer {
|
|
2723
2856
|
device;
|
|
2724
2857
|
gl;
|
|
2725
2858
|
handle;
|
|
@@ -2754,8 +2887,12 @@ var __exports__ = (() => {
|
|
|
2754
2887
|
destroy() {
|
|
2755
2888
|
if (!this.destroyed && this.handle) {
|
|
2756
2889
|
this.removeStats();
|
|
2757
|
-
this.
|
|
2758
|
-
|
|
2890
|
+
if (!this.props.handle) {
|
|
2891
|
+
this.trackDeallocatedMemory();
|
|
2892
|
+
this.gl.deleteBuffer(this.handle);
|
|
2893
|
+
} else {
|
|
2894
|
+
this.trackDeallocatedReferencedMemory("Buffer");
|
|
2895
|
+
}
|
|
2759
2896
|
this.destroyed = true;
|
|
2760
2897
|
this.handle = null;
|
|
2761
2898
|
}
|
|
@@ -2770,7 +2907,11 @@ var __exports__ = (() => {
|
|
|
2770
2907
|
this.bytesUsed = byteLength;
|
|
2771
2908
|
this.byteLength = byteLength;
|
|
2772
2909
|
this._setDebugData(data, byteOffset, byteLength);
|
|
2773
|
-
this.
|
|
2910
|
+
if (!this.props.handle) {
|
|
2911
|
+
this.trackAllocatedMemory(byteLength);
|
|
2912
|
+
} else {
|
|
2913
|
+
this.trackReferencedMemory(byteLength, "Buffer");
|
|
2914
|
+
}
|
|
2774
2915
|
}
|
|
2775
2916
|
// Allocate a GPU buffer of specified size.
|
|
2776
2917
|
_initWithByteLength(byteLength) {
|
|
@@ -2785,7 +2926,11 @@ var __exports__ = (() => {
|
|
|
2785
2926
|
this.bytesUsed = byteLength;
|
|
2786
2927
|
this.byteLength = byteLength;
|
|
2787
2928
|
this._setDebugData(null, 0, byteLength);
|
|
2788
|
-
this.
|
|
2929
|
+
if (!this.props.handle) {
|
|
2930
|
+
this.trackAllocatedMemory(byteLength);
|
|
2931
|
+
} else {
|
|
2932
|
+
this.trackReferencedMemory(byteLength, "Buffer");
|
|
2933
|
+
}
|
|
2789
2934
|
return this;
|
|
2790
2935
|
}
|
|
2791
2936
|
write(data, byteOffset = 0) {
|
|
@@ -2898,13 +3043,13 @@ var __exports__ = (() => {
|
|
|
2898
3043
|
});
|
|
2899
3044
|
|
|
2900
3045
|
// src/adapter/resources/webgl-shader.ts
|
|
2901
|
-
var
|
|
3046
|
+
var import_core10, WEBGLShader;
|
|
2902
3047
|
var init_webgl_shader = __esm({
|
|
2903
3048
|
"src/adapter/resources/webgl-shader.ts"() {
|
|
2904
3049
|
"use strict";
|
|
2905
|
-
|
|
3050
|
+
import_core10 = __toESM(require_core(), 1);
|
|
2906
3051
|
init_parse_shader_compiler_log();
|
|
2907
|
-
WEBGLShader = class extends
|
|
3052
|
+
WEBGLShader = class extends import_core10.Shader {
|
|
2908
3053
|
device;
|
|
2909
3054
|
handle;
|
|
2910
3055
|
constructor(device, props) {
|
|
@@ -2970,9 +3115,9 @@ ${source}`;
|
|
|
2970
3115
|
}
|
|
2971
3116
|
return;
|
|
2972
3117
|
}
|
|
2973
|
-
|
|
3118
|
+
import_core10.log.once(1, "Shader compilation is asynchronous")();
|
|
2974
3119
|
await this._waitForCompilationComplete();
|
|
2975
|
-
|
|
3120
|
+
import_core10.log.info(2, `Shader ${this.id} - async compilation complete: ${this.compilationStatus}`)();
|
|
2976
3121
|
this._getCompilationStatus();
|
|
2977
3122
|
this.debugShader();
|
|
2978
3123
|
}
|
|
@@ -3139,7 +3284,7 @@ ${source}`;
|
|
|
3139
3284
|
gl.stencilMaskSeparate(1029 /* BACK */, mask);
|
|
3140
3285
|
}
|
|
3141
3286
|
if (parameters.stencilReadMask) {
|
|
3142
|
-
|
|
3287
|
+
import_core11.log.warn("stencilReadMask not supported under WebGL");
|
|
3143
3288
|
}
|
|
3144
3289
|
if (parameters.stencilCompare) {
|
|
3145
3290
|
const mask = parameters.stencilReadMask || 4294967295;
|
|
@@ -3273,11 +3418,11 @@ ${source}`;
|
|
|
3273
3418
|
}
|
|
3274
3419
|
return isEmpty;
|
|
3275
3420
|
}
|
|
3276
|
-
var
|
|
3421
|
+
var import_core11;
|
|
3277
3422
|
var init_device_parameters = __esm({
|
|
3278
3423
|
"src/adapter/converters/device-parameters.ts"() {
|
|
3279
3424
|
"use strict";
|
|
3280
|
-
|
|
3425
|
+
import_core11 = __toESM(require_core(), 1);
|
|
3281
3426
|
init_unified_parameter_api();
|
|
3282
3427
|
}
|
|
3283
3428
|
});
|
|
@@ -3370,13 +3515,13 @@ ${source}`;
|
|
|
3370
3515
|
});
|
|
3371
3516
|
|
|
3372
3517
|
// src/adapter/resources/webgl-sampler.ts
|
|
3373
|
-
var
|
|
3518
|
+
var import_core12, WEBGLSampler;
|
|
3374
3519
|
var init_webgl_sampler = __esm({
|
|
3375
3520
|
"src/adapter/resources/webgl-sampler.ts"() {
|
|
3376
3521
|
"use strict";
|
|
3377
|
-
|
|
3522
|
+
import_core12 = __toESM(require_core(), 1);
|
|
3378
3523
|
init_sampler_parameters();
|
|
3379
|
-
WEBGLSampler = class extends
|
|
3524
|
+
WEBGLSampler = class extends import_core12.Sampler {
|
|
3380
3525
|
device;
|
|
3381
3526
|
handle;
|
|
3382
3527
|
parameters;
|
|
@@ -3452,19 +3597,19 @@ ${source}`;
|
|
|
3452
3597
|
});
|
|
3453
3598
|
|
|
3454
3599
|
// src/adapter/resources/webgl-texture-view.ts
|
|
3455
|
-
var
|
|
3600
|
+
var import_core13, WEBGLTextureView;
|
|
3456
3601
|
var init_webgl_texture_view = __esm({
|
|
3457
3602
|
"src/adapter/resources/webgl-texture-view.ts"() {
|
|
3458
3603
|
"use strict";
|
|
3459
|
-
|
|
3460
|
-
WEBGLTextureView = class extends
|
|
3604
|
+
import_core13 = __toESM(require_core(), 1);
|
|
3605
|
+
WEBGLTextureView = class extends import_core13.TextureView {
|
|
3461
3606
|
device;
|
|
3462
3607
|
gl;
|
|
3463
3608
|
handle;
|
|
3464
3609
|
// Does not have a WebGL representation
|
|
3465
3610
|
texture;
|
|
3466
3611
|
constructor(device, props) {
|
|
3467
|
-
super(device, { ...
|
|
3612
|
+
super(device, { ...import_core13.Texture.defaultProps, ...props });
|
|
3468
3613
|
this.device = device;
|
|
3469
3614
|
this.gl = this.device.gl;
|
|
3470
3615
|
this.handle = null;
|
|
@@ -3474,98 +3619,6 @@ ${source}`;
|
|
|
3474
3619
|
}
|
|
3475
3620
|
});
|
|
3476
3621
|
|
|
3477
|
-
// src/adapter/converters/webgl-shadertypes.ts
|
|
3478
|
-
function convertDataTypeToGLDataType(normalizedType) {
|
|
3479
|
-
return NORMALIZED_SHADER_TYPE_TO_WEBGL[normalizedType];
|
|
3480
|
-
}
|
|
3481
|
-
function convertGLUniformTypeToShaderVariableType(glUniformType) {
|
|
3482
|
-
return WEBGL_SHADER_TYPES[glUniformType];
|
|
3483
|
-
}
|
|
3484
|
-
function isGLSamplerType(type) {
|
|
3485
|
-
return Boolean(WEBGL_SAMPLER_TO_TEXTURE_BINDINGS[type]);
|
|
3486
|
-
}
|
|
3487
|
-
function getTextureBindingFromGLSamplerType(glSamplerType) {
|
|
3488
|
-
return WEBGL_SAMPLER_TO_TEXTURE_BINDINGS[glSamplerType];
|
|
3489
|
-
}
|
|
3490
|
-
var WEBGL_SHADER_TYPES, WEBGL_SAMPLER_TO_TEXTURE_BINDINGS, NORMALIZED_SHADER_TYPE_TO_WEBGL, WEBGL_TO_NORMALIZED_DATA_TYPE;
|
|
3491
|
-
var init_webgl_shadertypes = __esm({
|
|
3492
|
-
"src/adapter/converters/webgl-shadertypes.ts"() {
|
|
3493
|
-
"use strict";
|
|
3494
|
-
WEBGL_SHADER_TYPES = {
|
|
3495
|
-
[5126 /* FLOAT */]: "f32",
|
|
3496
|
-
[35664 /* FLOAT_VEC2 */]: "vec2<f32>",
|
|
3497
|
-
[35665 /* FLOAT_VEC3 */]: "vec3<f32>",
|
|
3498
|
-
[35666 /* FLOAT_VEC4 */]: "vec4<f32>",
|
|
3499
|
-
[5124 /* INT */]: "i32",
|
|
3500
|
-
[35667 /* INT_VEC2 */]: "vec2<i32>",
|
|
3501
|
-
[35668 /* INT_VEC3 */]: "vec3<i32>",
|
|
3502
|
-
[35669 /* INT_VEC4 */]: "vec4<i32>",
|
|
3503
|
-
[5125 /* UNSIGNED_INT */]: "u32",
|
|
3504
|
-
[36294 /* UNSIGNED_INT_VEC2 */]: "vec2<u32>",
|
|
3505
|
-
[36295 /* UNSIGNED_INT_VEC3 */]: "vec3<u32>",
|
|
3506
|
-
[36296 /* UNSIGNED_INT_VEC4 */]: "vec4<u32>",
|
|
3507
|
-
[35670 /* BOOL */]: "f32",
|
|
3508
|
-
[35671 /* BOOL_VEC2 */]: "vec2<f32>",
|
|
3509
|
-
[35672 /* BOOL_VEC3 */]: "vec3<f32>",
|
|
3510
|
-
[35673 /* BOOL_VEC4 */]: "vec4<f32>",
|
|
3511
|
-
// TODO - are sizes/components below correct?
|
|
3512
|
-
[35674 /* FLOAT_MAT2 */]: "mat2x2<f32>",
|
|
3513
|
-
[35685 /* FLOAT_MAT2x3 */]: "mat2x3<f32>",
|
|
3514
|
-
[35686 /* FLOAT_MAT2x4 */]: "mat2x4<f32>",
|
|
3515
|
-
[35687 /* FLOAT_MAT3x2 */]: "mat3x2<f32>",
|
|
3516
|
-
[35675 /* FLOAT_MAT3 */]: "mat3x3<f32>",
|
|
3517
|
-
[35688 /* FLOAT_MAT3x4 */]: "mat3x4<f32>",
|
|
3518
|
-
[35689 /* FLOAT_MAT4x2 */]: "mat4x2<f32>",
|
|
3519
|
-
[35690 /* FLOAT_MAT4x3 */]: "mat4x3<f32>",
|
|
3520
|
-
[35676 /* FLOAT_MAT4 */]: "mat4x4<f32>"
|
|
3521
|
-
};
|
|
3522
|
-
WEBGL_SAMPLER_TO_TEXTURE_BINDINGS = {
|
|
3523
|
-
[35678 /* SAMPLER_2D */]: { viewDimension: "2d", sampleType: "float" },
|
|
3524
|
-
[35680 /* SAMPLER_CUBE */]: { viewDimension: "cube", sampleType: "float" },
|
|
3525
|
-
[35679 /* SAMPLER_3D */]: { viewDimension: "3d", sampleType: "float" },
|
|
3526
|
-
[35682 /* SAMPLER_2D_SHADOW */]: { viewDimension: "3d", sampleType: "depth" },
|
|
3527
|
-
[36289 /* SAMPLER_2D_ARRAY */]: { viewDimension: "2d-array", sampleType: "float" },
|
|
3528
|
-
[36292 /* SAMPLER_2D_ARRAY_SHADOW */]: { viewDimension: "2d-array", sampleType: "depth" },
|
|
3529
|
-
[36293 /* SAMPLER_CUBE_SHADOW */]: { viewDimension: "cube", sampleType: "float" },
|
|
3530
|
-
[36298 /* INT_SAMPLER_2D */]: { viewDimension: "2d", sampleType: "sint" },
|
|
3531
|
-
[36299 /* INT_SAMPLER_3D */]: { viewDimension: "3d", sampleType: "sint" },
|
|
3532
|
-
[36300 /* INT_SAMPLER_CUBE */]: { viewDimension: "cube", sampleType: "sint" },
|
|
3533
|
-
[36303 /* INT_SAMPLER_2D_ARRAY */]: { viewDimension: "2d-array", sampleType: "uint" },
|
|
3534
|
-
[36306 /* UNSIGNED_INT_SAMPLER_2D */]: { viewDimension: "2d", sampleType: "uint" },
|
|
3535
|
-
[36307 /* UNSIGNED_INT_SAMPLER_3D */]: { viewDimension: "3d", sampleType: "uint" },
|
|
3536
|
-
[36308 /* UNSIGNED_INT_SAMPLER_CUBE */]: { viewDimension: "cube", sampleType: "uint" },
|
|
3537
|
-
[36311 /* UNSIGNED_INT_SAMPLER_2D_ARRAY */]: { viewDimension: "2d-array", sampleType: "uint" }
|
|
3538
|
-
};
|
|
3539
|
-
NORMALIZED_SHADER_TYPE_TO_WEBGL = {
|
|
3540
|
-
uint8: 5121 /* UNSIGNED_BYTE */,
|
|
3541
|
-
sint8: 5120 /* BYTE */,
|
|
3542
|
-
unorm8: 5121 /* UNSIGNED_BYTE */,
|
|
3543
|
-
snorm8: 5120 /* BYTE */,
|
|
3544
|
-
uint16: 5123 /* UNSIGNED_SHORT */,
|
|
3545
|
-
sint16: 5122 /* SHORT */,
|
|
3546
|
-
unorm16: 5123 /* UNSIGNED_SHORT */,
|
|
3547
|
-
snorm16: 5122 /* SHORT */,
|
|
3548
|
-
uint32: 5125 /* UNSIGNED_INT */,
|
|
3549
|
-
sint32: 5124 /* INT */,
|
|
3550
|
-
// WebGPU does not support normalized 32 bit integer attributes
|
|
3551
|
-
// 'unorm32': GL.UNSIGNED_INT,
|
|
3552
|
-
// 'snorm32': GL.INT,
|
|
3553
|
-
float16: 5131 /* HALF_FLOAT */,
|
|
3554
|
-
float32: 5126 /* FLOAT */
|
|
3555
|
-
};
|
|
3556
|
-
WEBGL_TO_NORMALIZED_DATA_TYPE = {
|
|
3557
|
-
[5120 /* BYTE */]: ["sint8", "snorm16"],
|
|
3558
|
-
[5121 /* UNSIGNED_BYTE */]: ["uint8", "unorm8"],
|
|
3559
|
-
[5122 /* SHORT */]: ["sint16", "unorm16"],
|
|
3560
|
-
[5123 /* UNSIGNED_SHORT */]: ["uint16", "unorm16"],
|
|
3561
|
-
[5124 /* INT */]: ["sint32", "sint32"],
|
|
3562
|
-
[5125 /* UNSIGNED_INT */]: ["uint32", "uint32"],
|
|
3563
|
-
[5126 /* FLOAT */]: ["float32", "float32"],
|
|
3564
|
-
[5131 /* HALF_FLOAT */]: ["float16", "float16"]
|
|
3565
|
-
};
|
|
3566
|
-
}
|
|
3567
|
-
});
|
|
3568
|
-
|
|
3569
3622
|
// src/adapter/converters/shader-formats.ts
|
|
3570
3623
|
function convertGLDataTypeToDataType(type) {
|
|
3571
3624
|
return GL_DATA_TYPE_MAP[type];
|
|
@@ -3596,6 +3649,24 @@ ${source}`;
|
|
|
3596
3649
|
});
|
|
3597
3650
|
|
|
3598
3651
|
// src/adapter/resources/webgl-texture.ts
|
|
3652
|
+
function getArrayBufferView(typedArray, byteOffset = 0) {
|
|
3653
|
+
if (!byteOffset) {
|
|
3654
|
+
return typedArray;
|
|
3655
|
+
}
|
|
3656
|
+
return new typedArray.constructor(
|
|
3657
|
+
typedArray.buffer,
|
|
3658
|
+
typedArray.byteOffset + byteOffset,
|
|
3659
|
+
(typedArray.byteLength - byteOffset) / typedArray.BYTES_PER_ELEMENT
|
|
3660
|
+
);
|
|
3661
|
+
}
|
|
3662
|
+
function getWebGLTextureSourceElementOffset(typedArray, byteOffset) {
|
|
3663
|
+
if (byteOffset % typedArray.BYTES_PER_ELEMENT !== 0) {
|
|
3664
|
+
throw new Error(
|
|
3665
|
+
`Texture byteOffset ${byteOffset} must align to typed array element size ${typedArray.BYTES_PER_ELEMENT}`
|
|
3666
|
+
);
|
|
3667
|
+
}
|
|
3668
|
+
return byteOffset / typedArray.BYTES_PER_ELEMENT;
|
|
3669
|
+
}
|
|
3599
3670
|
function getWebGLTextureTarget(dimension) {
|
|
3600
3671
|
switch (dimension) {
|
|
3601
3672
|
case "1d":
|
|
@@ -3616,19 +3687,18 @@ ${source}`;
|
|
|
3616
3687
|
function getWebGLCubeFaceTarget(glTarget, dimension, level) {
|
|
3617
3688
|
return dimension === "cube" ? 34069 /* TEXTURE_CUBE_MAP_POSITIVE_X */ + level : glTarget;
|
|
3618
3689
|
}
|
|
3619
|
-
var
|
|
3690
|
+
var import_core14, import_core15, WEBGLTexture;
|
|
3620
3691
|
var init_webgl_texture = __esm({
|
|
3621
3692
|
"src/adapter/resources/webgl-texture.ts"() {
|
|
3622
3693
|
"use strict";
|
|
3623
|
-
|
|
3694
|
+
import_core14 = __toESM(require_core(), 1);
|
|
3624
3695
|
init_webgl_texture_table();
|
|
3625
3696
|
init_sampler_parameters();
|
|
3626
3697
|
init_with_parameters();
|
|
3627
3698
|
init_webgl_texture_view();
|
|
3628
|
-
init_webgl_shadertypes();
|
|
3629
3699
|
init_shader_formats();
|
|
3630
|
-
|
|
3631
|
-
WEBGLTexture = class extends
|
|
3700
|
+
import_core15 = __toESM(require_core(), 1);
|
|
3701
|
+
WEBGLTexture = class extends import_core14.Texture {
|
|
3632
3702
|
// readonly MAX_ATTRIBUTES: number;
|
|
3633
3703
|
device;
|
|
3634
3704
|
gl;
|
|
@@ -3657,8 +3727,10 @@ ${source}`;
|
|
|
3657
3727
|
// state
|
|
3658
3728
|
/** Texture binding slot - TODO - move to texture view? */
|
|
3659
3729
|
_textureUnit = 0;
|
|
3660
|
-
/**
|
|
3730
|
+
/** Cached framebuffer reused for color texture readback. */
|
|
3661
3731
|
_framebuffer = null;
|
|
3732
|
+
/** Cache key for the currently attached readback subresource `${mipLevel}:${layer}`. */
|
|
3733
|
+
_framebufferAttachmentKey = null;
|
|
3662
3734
|
constructor(device, props) {
|
|
3663
3735
|
super(device, props, { byteAlignment: 1 });
|
|
3664
3736
|
this.device = device;
|
|
@@ -3673,20 +3745,27 @@ ${source}`;
|
|
|
3673
3745
|
this.device._setWebGLDebugMetadata(this.handle, this, { spector: this.props });
|
|
3674
3746
|
this.gl.bindTexture(this.glTarget, this.handle);
|
|
3675
3747
|
const { dimension, width, height, depth, mipLevels, glTarget, glInternalFormat } = this;
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
|
|
3748
|
+
if (!this.compressed) {
|
|
3749
|
+
switch (dimension) {
|
|
3750
|
+
case "2d":
|
|
3751
|
+
case "cube":
|
|
3752
|
+
this.gl.texStorage2D(glTarget, mipLevels, glInternalFormat, width, height);
|
|
3753
|
+
break;
|
|
3754
|
+
case "2d-array":
|
|
3755
|
+
case "3d":
|
|
3756
|
+
this.gl.texStorage3D(glTarget, mipLevels, glInternalFormat, width, height, depth);
|
|
3757
|
+
break;
|
|
3758
|
+
default:
|
|
3759
|
+
throw new Error(dimension);
|
|
3760
|
+
}
|
|
3687
3761
|
}
|
|
3688
3762
|
this.gl.bindTexture(this.glTarget, null);
|
|
3689
3763
|
this._initializeData(props.data);
|
|
3764
|
+
if (!this.props.handle) {
|
|
3765
|
+
this.trackAllocatedMemory(this.getAllocatedByteLength(), "Texture");
|
|
3766
|
+
} else {
|
|
3767
|
+
this.trackReferencedMemory(this.getAllocatedByteLength(), "Texture");
|
|
3768
|
+
}
|
|
3690
3769
|
this.setSampler(this.props.sampler);
|
|
3691
3770
|
this.view = new WEBGLTextureView(this.device, { ...this.props, texture: this });
|
|
3692
3771
|
Object.seal(this);
|
|
@@ -3695,9 +3774,14 @@ ${source}`;
|
|
|
3695
3774
|
if (this.handle) {
|
|
3696
3775
|
this._framebuffer?.destroy();
|
|
3697
3776
|
this._framebuffer = null;
|
|
3698
|
-
this.
|
|
3777
|
+
this._framebufferAttachmentKey = null;
|
|
3699
3778
|
this.removeStats();
|
|
3700
|
-
this.
|
|
3779
|
+
if (!this.props.handle) {
|
|
3780
|
+
this.gl.deleteTexture(this.handle);
|
|
3781
|
+
this.trackDeallocatedMemory("Texture");
|
|
3782
|
+
} else {
|
|
3783
|
+
this.trackDeallocatedReferencedMemory("Texture");
|
|
3784
|
+
}
|
|
3701
3785
|
this.destroyed = true;
|
|
3702
3786
|
}
|
|
3703
3787
|
}
|
|
@@ -3736,99 +3820,180 @@ ${source}`;
|
|
|
3736
3820
|
return { width: options.width, height: options.height };
|
|
3737
3821
|
}
|
|
3738
3822
|
copyImageData(options_) {
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
|
|
3742
|
-
|
|
3823
|
+
super.copyImageData(options_);
|
|
3824
|
+
}
|
|
3825
|
+
/**
|
|
3826
|
+
* Reads a color texture subresource into a GPU buffer using `PIXEL_PACK_BUFFER`.
|
|
3827
|
+
*
|
|
3828
|
+
* @note Only first-pass color readback is supported. Unsupported formats and aspects throw
|
|
3829
|
+
* before any WebGL calls are issued.
|
|
3830
|
+
*/
|
|
3831
|
+
readBuffer(options = {}, buffer) {
|
|
3832
|
+
const normalizedOptions = this._getSupportedColorReadOptions(options);
|
|
3833
|
+
const memoryLayout = this.computeMemoryLayout(normalizedOptions);
|
|
3834
|
+
const readBuffer = buffer || this.device.createBuffer({
|
|
3835
|
+
byteLength: memoryLayout.byteLength,
|
|
3836
|
+
usage: import_core14.Buffer.COPY_DST | import_core14.Buffer.MAP_READ
|
|
3837
|
+
});
|
|
3838
|
+
if (readBuffer.byteLength < memoryLayout.byteLength) {
|
|
3839
|
+
throw new Error(
|
|
3840
|
+
`${this} readBuffer target is too small (${readBuffer.byteLength} < ${memoryLayout.byteLength})`
|
|
3841
|
+
);
|
|
3842
|
+
}
|
|
3843
|
+
const webglBuffer = readBuffer;
|
|
3844
|
+
this.gl.bindBuffer(35051 /* PIXEL_PACK_BUFFER */, webglBuffer.handle);
|
|
3845
|
+
try {
|
|
3846
|
+
this._readColorTextureLayers(normalizedOptions, memoryLayout, (destinationByteOffset) => {
|
|
3847
|
+
this.gl.readPixels(
|
|
3848
|
+
normalizedOptions.x,
|
|
3849
|
+
normalizedOptions.y,
|
|
3850
|
+
normalizedOptions.width,
|
|
3851
|
+
normalizedOptions.height,
|
|
3852
|
+
this.glFormat,
|
|
3853
|
+
this.glType,
|
|
3854
|
+
destinationByteOffset
|
|
3855
|
+
);
|
|
3856
|
+
});
|
|
3857
|
+
} finally {
|
|
3858
|
+
this.gl.bindBuffer(35051 /* PIXEL_PACK_BUFFER */, null);
|
|
3859
|
+
}
|
|
3860
|
+
return readBuffer;
|
|
3861
|
+
}
|
|
3862
|
+
async readDataAsync(options = {}) {
|
|
3863
|
+
const buffer = this.readBuffer(options);
|
|
3864
|
+
const data = await buffer.readAsync();
|
|
3865
|
+
buffer.destroy();
|
|
3866
|
+
return data.buffer;
|
|
3867
|
+
}
|
|
3868
|
+
writeBuffer(buffer, options_ = {}) {
|
|
3869
|
+
const options = this._normalizeTextureWriteOptions(options_);
|
|
3870
|
+
const { width, height, depthOrArrayLayers, mipLevel, byteOffset, x, y, z } = options;
|
|
3743
3871
|
const { glFormat, glType, compressed } = this;
|
|
3744
3872
|
const glTarget = getWebGLCubeFaceTarget(this.glTarget, this.dimension, z);
|
|
3745
|
-
|
|
3746
|
-
|
|
3747
|
-
const { bytesPerPixel } = this.device.getTextureFormatInfo(this.format);
|
|
3748
|
-
if (bytesPerPixel) {
|
|
3749
|
-
if (options.bytesPerRow % bytesPerPixel !== 0) {
|
|
3750
|
-
throw new Error(
|
|
3751
|
-
`bytesPerRow (${options.bytesPerRow}) must be a multiple of bytesPerPixel (${bytesPerPixel}) for ${this.format}`
|
|
3752
|
-
);
|
|
3753
|
-
}
|
|
3754
|
-
unpackRowLength = options.bytesPerRow / bytesPerPixel;
|
|
3755
|
-
}
|
|
3873
|
+
if (compressed) {
|
|
3874
|
+
throw new Error("writeBuffer for compressed textures is not implemented in WebGL");
|
|
3756
3875
|
}
|
|
3757
|
-
const
|
|
3876
|
+
const { bytesPerPixel } = this.device.getTextureFormatInfo(this.format);
|
|
3877
|
+
const unpackRowLength = bytesPerPixel ? options.bytesPerRow / bytesPerPixel : void 0;
|
|
3878
|
+
const glParameters = {
|
|
3758
3879
|
[3317 /* UNPACK_ALIGNMENT */]: this.byteAlignment,
|
|
3759
3880
|
...unpackRowLength !== void 0 ? { [3314 /* UNPACK_ROW_LENGTH */]: unpackRowLength } : {},
|
|
3760
3881
|
[32878 /* UNPACK_IMAGE_HEIGHT */]: options.rowsPerImage
|
|
3761
|
-
}
|
|
3882
|
+
};
|
|
3762
3883
|
this.gl.bindTexture(this.glTarget, this.handle);
|
|
3884
|
+
this.gl.bindBuffer(35052 /* PIXEL_UNPACK_BUFFER */, buffer.handle);
|
|
3763
3885
|
withGLParameters(this.gl, glParameters, () => {
|
|
3764
3886
|
switch (this.dimension) {
|
|
3765
3887
|
case "2d":
|
|
3766
3888
|
case "cube":
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
3889
|
+
this.gl.texSubImage2D(
|
|
3890
|
+
glTarget,
|
|
3891
|
+
mipLevel,
|
|
3892
|
+
x,
|
|
3893
|
+
y,
|
|
3894
|
+
width,
|
|
3895
|
+
height,
|
|
3896
|
+
glFormat,
|
|
3897
|
+
glType,
|
|
3898
|
+
byteOffset
|
|
3899
|
+
);
|
|
3772
3900
|
break;
|
|
3773
3901
|
case "2d-array":
|
|
3774
3902
|
case "3d":
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
|
|
3779
|
-
|
|
3903
|
+
this.gl.texSubImage3D(
|
|
3904
|
+
glTarget,
|
|
3905
|
+
mipLevel,
|
|
3906
|
+
x,
|
|
3907
|
+
y,
|
|
3908
|
+
z,
|
|
3909
|
+
width,
|
|
3910
|
+
height,
|
|
3911
|
+
depthOrArrayLayers,
|
|
3912
|
+
glFormat,
|
|
3913
|
+
glType,
|
|
3914
|
+
byteOffset
|
|
3915
|
+
);
|
|
3780
3916
|
break;
|
|
3781
3917
|
default:
|
|
3782
3918
|
}
|
|
3783
3919
|
});
|
|
3920
|
+
this.gl.bindBuffer(35052 /* PIXEL_UNPACK_BUFFER */, null);
|
|
3784
3921
|
this.gl.bindTexture(this.glTarget, null);
|
|
3785
3922
|
}
|
|
3786
|
-
readBuffer(options = {}, buffer) {
|
|
3787
|
-
throw new Error("readBuffer not implemented");
|
|
3788
|
-
}
|
|
3789
|
-
async readDataAsync(options = {}) {
|
|
3790
|
-
return this.readDataSyncWebGL(options);
|
|
3791
|
-
}
|
|
3792
|
-
writeBuffer(buffer, options_ = {}) {
|
|
3793
|
-
}
|
|
3794
3923
|
writeData(data, options_ = {}) {
|
|
3795
3924
|
const options = this._normalizeTextureWriteOptions(options_);
|
|
3796
3925
|
const typedArray = ArrayBuffer.isView(data) ? data : new Uint8Array(data);
|
|
3797
|
-
const {} =
|
|
3798
|
-
const { width, height, mipLevel, x, y, z } = options;
|
|
3926
|
+
const { width, height, depthOrArrayLayers, mipLevel, x, y, z, byteOffset } = options;
|
|
3799
3927
|
const { glFormat, glType, compressed } = this;
|
|
3800
|
-
const
|
|
3801
|
-
|
|
3928
|
+
const glTarget = getWebGLCubeFaceTarget(this.glTarget, this.dimension, z);
|
|
3929
|
+
let unpackRowLength;
|
|
3930
|
+
if (!compressed) {
|
|
3931
|
+
const { bytesPerPixel } = this.device.getTextureFormatInfo(this.format);
|
|
3932
|
+
if (bytesPerPixel) {
|
|
3933
|
+
unpackRowLength = options.bytesPerRow / bytesPerPixel;
|
|
3934
|
+
}
|
|
3935
|
+
}
|
|
3802
3936
|
const glParameters = !this.compressed ? {
|
|
3803
|
-
|
|
3804
|
-
[
|
|
3805
|
-
|
|
3806
|
-
// [GL.UNPACK_IMAGE_HEIGHT]: rowsPerImage
|
|
3937
|
+
[3317 /* UNPACK_ALIGNMENT */]: this.byteAlignment,
|
|
3938
|
+
...unpackRowLength !== void 0 ? { [3314 /* UNPACK_ROW_LENGTH */]: unpackRowLength } : {},
|
|
3939
|
+
[32878 /* UNPACK_IMAGE_HEIGHT */]: options.rowsPerImage
|
|
3807
3940
|
} : {};
|
|
3808
|
-
|
|
3941
|
+
const sourceElementOffset = getWebGLTextureSourceElementOffset(typedArray, byteOffset);
|
|
3942
|
+
const compressedData = compressed ? getArrayBufferView(typedArray, byteOffset) : typedArray;
|
|
3943
|
+
const mipLevelSize = this._getMipLevelSize(mipLevel);
|
|
3944
|
+
const isFullMipUpload = x === 0 && y === 0 && z === 0 && width === mipLevelSize.width && height === mipLevelSize.height && depthOrArrayLayers === mipLevelSize.depthOrArrayLayers;
|
|
3945
|
+
this.gl.bindTexture(this.glTarget, this.handle);
|
|
3809
3946
|
this.gl.bindBuffer(35052 /* PIXEL_UNPACK_BUFFER */, null);
|
|
3810
3947
|
withGLParameters(this.gl, glParameters, () => {
|
|
3811
3948
|
switch (this.dimension) {
|
|
3812
3949
|
case "2d":
|
|
3813
3950
|
case "cube":
|
|
3814
3951
|
if (compressed) {
|
|
3815
|
-
|
|
3952
|
+
if (isFullMipUpload) {
|
|
3953
|
+
this.gl.compressedTexImage2D(glTarget, mipLevel, glFormat, width, height, 0, compressedData);
|
|
3954
|
+
} else {
|
|
3955
|
+
this.gl.compressedTexSubImage2D(glTarget, mipLevel, x, y, width, height, glFormat, compressedData);
|
|
3956
|
+
}
|
|
3816
3957
|
} else {
|
|
3817
|
-
this.gl.texSubImage2D(glTarget, mipLevel, x, y, width, height, glFormat, glType, typedArray);
|
|
3958
|
+
this.gl.texSubImage2D(glTarget, mipLevel, x, y, width, height, glFormat, glType, typedArray, sourceElementOffset);
|
|
3818
3959
|
}
|
|
3819
3960
|
break;
|
|
3820
3961
|
case "2d-array":
|
|
3821
3962
|
case "3d":
|
|
3822
3963
|
if (compressed) {
|
|
3823
|
-
|
|
3964
|
+
if (isFullMipUpload) {
|
|
3965
|
+
this.gl.compressedTexImage3D(
|
|
3966
|
+
glTarget,
|
|
3967
|
+
mipLevel,
|
|
3968
|
+
glFormat,
|
|
3969
|
+
width,
|
|
3970
|
+
height,
|
|
3971
|
+
depthOrArrayLayers,
|
|
3972
|
+
0,
|
|
3973
|
+
compressedData
|
|
3974
|
+
);
|
|
3975
|
+
} else {
|
|
3976
|
+
this.gl.compressedTexSubImage3D(
|
|
3977
|
+
glTarget,
|
|
3978
|
+
mipLevel,
|
|
3979
|
+
x,
|
|
3980
|
+
y,
|
|
3981
|
+
z,
|
|
3982
|
+
width,
|
|
3983
|
+
height,
|
|
3984
|
+
depthOrArrayLayers,
|
|
3985
|
+
glFormat,
|
|
3986
|
+
compressedData
|
|
3987
|
+
);
|
|
3988
|
+
}
|
|
3824
3989
|
} else {
|
|
3825
|
-
this.gl.texSubImage3D(glTarget, mipLevel, x, y, z, width, height,
|
|
3990
|
+
this.gl.texSubImage3D(glTarget, mipLevel, x, y, z, width, height, depthOrArrayLayers, glFormat, glType, typedArray, sourceElementOffset);
|
|
3826
3991
|
}
|
|
3827
3992
|
break;
|
|
3828
3993
|
default:
|
|
3829
3994
|
}
|
|
3830
3995
|
});
|
|
3831
|
-
this.gl.bindTexture(glTarget, null);
|
|
3996
|
+
this.gl.bindTexture(this.glTarget, null);
|
|
3832
3997
|
}
|
|
3833
3998
|
// IMPLEMENTATION SPECIFIC
|
|
3834
3999
|
/** @todo - for now we always use 1 for maximum compatibility, we can fine tune later */
|
|
@@ -3850,30 +4015,107 @@ ${source}`;
|
|
|
3850
4015
|
}
|
|
3851
4016
|
// WEBGL SPECIFIC
|
|
3852
4017
|
readDataSyncWebGL(options_ = {}) {
|
|
3853
|
-
const options = this.
|
|
4018
|
+
const options = this._getSupportedColorReadOptions(options_);
|
|
3854
4019
|
const memoryLayout = this.computeMemoryLayout(options);
|
|
3855
4020
|
const shaderType = convertGLDataTypeToDataType(this.glType);
|
|
3856
|
-
const ArrayType = (0,
|
|
3857
|
-
const targetArray = new ArrayType(memoryLayout.byteLength);
|
|
3858
|
-
|
|
3859
|
-
|
|
4021
|
+
const ArrayType = (0, import_core15.getTypedArrayConstructor)(shaderType);
|
|
4022
|
+
const targetArray = new ArrayType(memoryLayout.byteLength / ArrayType.BYTES_PER_ELEMENT);
|
|
4023
|
+
this._readColorTextureLayers(options, memoryLayout, (destinationByteOffset) => {
|
|
4024
|
+
const layerView = new ArrayType(
|
|
4025
|
+
targetArray.buffer,
|
|
4026
|
+
targetArray.byteOffset + destinationByteOffset,
|
|
4027
|
+
memoryLayout.bytesPerImage / ArrayType.BYTES_PER_ELEMENT
|
|
4028
|
+
);
|
|
4029
|
+
this.gl.readPixels(
|
|
4030
|
+
options.x,
|
|
4031
|
+
options.y,
|
|
4032
|
+
options.width,
|
|
4033
|
+
options.height,
|
|
4034
|
+
this.glFormat,
|
|
4035
|
+
this.glType,
|
|
4036
|
+
layerView
|
|
4037
|
+
);
|
|
4038
|
+
});
|
|
4039
|
+
return targetArray.buffer;
|
|
4040
|
+
}
|
|
4041
|
+
/**
|
|
4042
|
+
* Iterates the requested mip/layer/slice range, reattaching the cached read framebuffer as
|
|
4043
|
+
* needed before delegating the actual `readPixels()` call to the supplied callback.
|
|
4044
|
+
*/
|
|
4045
|
+
_readColorTextureLayers(options, memoryLayout, readLayer) {
|
|
3860
4046
|
const framebuffer = this._getFramebuffer();
|
|
4047
|
+
const packRowLength = memoryLayout.bytesPerRow / memoryLayout.bytesPerPixel;
|
|
4048
|
+
const glParameters = {
|
|
4049
|
+
[3333 /* PACK_ALIGNMENT */]: this.byteAlignment,
|
|
4050
|
+
...packRowLength !== options.width ? { [3330 /* PACK_ROW_LENGTH */]: packRowLength } : {}
|
|
4051
|
+
};
|
|
4052
|
+
const prevReadBuffer = this.gl.getParameter(3074 /* READ_BUFFER */);
|
|
3861
4053
|
const prevHandle = this.gl.bindFramebuffer(
|
|
3862
4054
|
36160 /* FRAMEBUFFER */,
|
|
3863
4055
|
framebuffer.handle
|
|
3864
4056
|
);
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
4057
|
+
try {
|
|
4058
|
+
this.gl.readBuffer(36064 /* COLOR_ATTACHMENT0 */);
|
|
4059
|
+
withGLParameters(this.gl, glParameters, () => {
|
|
4060
|
+
for (let layerIndex = 0; layerIndex < options.depthOrArrayLayers; layerIndex++) {
|
|
4061
|
+
this._attachReadSubresource(framebuffer, options.mipLevel, options.z + layerIndex);
|
|
4062
|
+
readLayer(layerIndex * memoryLayout.bytesPerImage);
|
|
4063
|
+
}
|
|
4064
|
+
});
|
|
4065
|
+
} finally {
|
|
4066
|
+
this.gl.bindFramebuffer(36160 /* FRAMEBUFFER */, prevHandle || null);
|
|
4067
|
+
this.gl.readBuffer(prevReadBuffer);
|
|
4068
|
+
}
|
|
4069
|
+
}
|
|
4070
|
+
/**
|
|
4071
|
+
* Attaches a single color subresource to the cached read framebuffer.
|
|
4072
|
+
*
|
|
4073
|
+
* @note Repeated attachments of the same `(mipLevel, layer)` tuple are skipped.
|
|
4074
|
+
*/
|
|
4075
|
+
_attachReadSubresource(framebuffer, mipLevel, layer) {
|
|
4076
|
+
const attachmentKey = `${mipLevel}:${layer}`;
|
|
4077
|
+
if (this._framebufferAttachmentKey === attachmentKey) {
|
|
4078
|
+
return;
|
|
4079
|
+
}
|
|
4080
|
+
switch (this.dimension) {
|
|
4081
|
+
case "2d":
|
|
4082
|
+
this.gl.framebufferTexture2D(
|
|
4083
|
+
36160 /* FRAMEBUFFER */,
|
|
4084
|
+
36064 /* COLOR_ATTACHMENT0 */,
|
|
4085
|
+
3553 /* TEXTURE_2D */,
|
|
4086
|
+
this.handle,
|
|
4087
|
+
mipLevel
|
|
4088
|
+
);
|
|
4089
|
+
break;
|
|
4090
|
+
case "cube":
|
|
4091
|
+
this.gl.framebufferTexture2D(
|
|
4092
|
+
36160 /* FRAMEBUFFER */,
|
|
4093
|
+
36064 /* COLOR_ATTACHMENT0 */,
|
|
4094
|
+
getWebGLCubeFaceTarget(this.glTarget, this.dimension, layer),
|
|
4095
|
+
this.handle,
|
|
4096
|
+
mipLevel
|
|
4097
|
+
);
|
|
4098
|
+
break;
|
|
4099
|
+
case "2d-array":
|
|
4100
|
+
case "3d":
|
|
4101
|
+
this.gl.framebufferTextureLayer(
|
|
4102
|
+
36160 /* FRAMEBUFFER */,
|
|
4103
|
+
36064 /* COLOR_ATTACHMENT0 */,
|
|
4104
|
+
this.handle,
|
|
4105
|
+
mipLevel,
|
|
4106
|
+
layer
|
|
4107
|
+
);
|
|
4108
|
+
break;
|
|
4109
|
+
default:
|
|
4110
|
+
throw new Error(`${this} color readback does not support ${this.dimension} textures`);
|
|
4111
|
+
}
|
|
4112
|
+
if (this.device.props.debug) {
|
|
4113
|
+
const status = Number(this.gl.checkFramebufferStatus(36160 /* FRAMEBUFFER */));
|
|
4114
|
+
if (status !== Number(36053 /* FRAMEBUFFER_COMPLETE */)) {
|
|
4115
|
+
throw new Error(`${framebuffer} incomplete for ${this} readback (${status})`);
|
|
4116
|
+
}
|
|
4117
|
+
}
|
|
4118
|
+
this._framebufferAttachmentKey = attachmentKey;
|
|
3877
4119
|
}
|
|
3878
4120
|
/**
|
|
3879
4121
|
* @note - this is used by the DynamicTexture class to generate mipmaps on WebGL
|
|
@@ -3881,7 +4123,7 @@ ${source}`;
|
|
|
3881
4123
|
generateMipmapsWebGL(options) {
|
|
3882
4124
|
const isFilterableAndRenderable = this.device.isTextureFormatRenderable(this.props.format) && this.device.isTextureFormatFilterable(this.props.format);
|
|
3883
4125
|
if (!isFilterableAndRenderable) {
|
|
3884
|
-
|
|
4126
|
+
import_core14.log.warn(`${this} is not renderable or filterable, may not be able to generate mipmaps`)();
|
|
3885
4127
|
if (!options?.force) {
|
|
3886
4128
|
return;
|
|
3887
4129
|
}
|
|
@@ -3890,7 +4132,7 @@ ${source}`;
|
|
|
3890
4132
|
this.gl.bindTexture(this.glTarget, this.handle);
|
|
3891
4133
|
this.gl.generateMipmap(this.glTarget);
|
|
3892
4134
|
} catch (error) {
|
|
3893
|
-
|
|
4135
|
+
import_core14.log.warn(`Error generating mipmap for ${this}: ${error.message}`)();
|
|
3894
4136
|
} finally {
|
|
3895
4137
|
this.gl.bindTexture(this.glTarget, null);
|
|
3896
4138
|
}
|
|
@@ -3900,7 +4142,7 @@ ${source}`;
|
|
|
3900
4142
|
* Sets sampler parameters on texture
|
|
3901
4143
|
*/
|
|
3902
4144
|
_setSamplerParameters(parameters) {
|
|
3903
|
-
|
|
4145
|
+
import_core14.log.log(2, `${this.id} sampler parameters`, this.device.getGLKeys(parameters))();
|
|
3904
4146
|
this.gl.bindTexture(this.glTarget, this.handle);
|
|
3905
4147
|
for (const [pname, pvalue] of Object.entries(parameters)) {
|
|
3906
4148
|
const param = Number(pname);
|
|
@@ -3957,210 +4199,6 @@ ${source}`;
|
|
|
3957
4199
|
}
|
|
3958
4200
|
});
|
|
3959
4201
|
|
|
3960
|
-
// src/adapter/helpers/get-shader-layout-from-glsl.ts
|
|
3961
|
-
function getShaderLayoutFromGLSL(gl, program) {
|
|
3962
|
-
const shaderLayout = {
|
|
3963
|
-
attributes: [],
|
|
3964
|
-
bindings: []
|
|
3965
|
-
};
|
|
3966
|
-
shaderLayout.attributes = readAttributeDeclarations(gl, program);
|
|
3967
|
-
const uniformBlocks = readUniformBlocks(gl, program);
|
|
3968
|
-
for (const uniformBlock of uniformBlocks) {
|
|
3969
|
-
const uniforms2 = uniformBlock.uniforms.map((uniform) => ({
|
|
3970
|
-
name: uniform.name,
|
|
3971
|
-
format: uniform.format,
|
|
3972
|
-
byteOffset: uniform.byteOffset,
|
|
3973
|
-
byteStride: uniform.byteStride,
|
|
3974
|
-
arrayLength: uniform.arrayLength
|
|
3975
|
-
}));
|
|
3976
|
-
shaderLayout.bindings.push({
|
|
3977
|
-
type: "uniform",
|
|
3978
|
-
name: uniformBlock.name,
|
|
3979
|
-
group: 0,
|
|
3980
|
-
location: uniformBlock.location,
|
|
3981
|
-
visibility: (uniformBlock.vertex ? 1 : 0) & (uniformBlock.fragment ? 2 : 0),
|
|
3982
|
-
minBindingSize: uniformBlock.byteLength,
|
|
3983
|
-
uniforms: uniforms2
|
|
3984
|
-
});
|
|
3985
|
-
}
|
|
3986
|
-
const uniforms = readUniformBindings(gl, program);
|
|
3987
|
-
let textureUnit = 0;
|
|
3988
|
-
for (const uniform of uniforms) {
|
|
3989
|
-
if (isGLSamplerType(uniform.type)) {
|
|
3990
|
-
const { viewDimension, sampleType } = getTextureBindingFromGLSamplerType(uniform.type);
|
|
3991
|
-
shaderLayout.bindings.push({
|
|
3992
|
-
type: "texture",
|
|
3993
|
-
name: uniform.name,
|
|
3994
|
-
group: 0,
|
|
3995
|
-
location: textureUnit,
|
|
3996
|
-
viewDimension,
|
|
3997
|
-
sampleType
|
|
3998
|
-
});
|
|
3999
|
-
uniform.textureUnit = textureUnit;
|
|
4000
|
-
textureUnit += 1;
|
|
4001
|
-
}
|
|
4002
|
-
}
|
|
4003
|
-
if (uniforms.length) {
|
|
4004
|
-
shaderLayout.uniforms = uniforms;
|
|
4005
|
-
}
|
|
4006
|
-
const varyings = readVaryings(gl, program);
|
|
4007
|
-
if (varyings?.length) {
|
|
4008
|
-
shaderLayout.varyings = varyings;
|
|
4009
|
-
}
|
|
4010
|
-
return shaderLayout;
|
|
4011
|
-
}
|
|
4012
|
-
function readAttributeDeclarations(gl, program) {
|
|
4013
|
-
const attributes = [];
|
|
4014
|
-
const count = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES);
|
|
4015
|
-
for (let index = 0; index < count; index++) {
|
|
4016
|
-
const activeInfo = gl.getActiveAttrib(program, index);
|
|
4017
|
-
if (!activeInfo) {
|
|
4018
|
-
throw new Error("activeInfo");
|
|
4019
|
-
}
|
|
4020
|
-
const {
|
|
4021
|
-
name,
|
|
4022
|
-
type: compositeType
|
|
4023
|
-
/* , size*/
|
|
4024
|
-
} = activeInfo;
|
|
4025
|
-
const location = gl.getAttribLocation(program, name);
|
|
4026
|
-
if (location >= 0) {
|
|
4027
|
-
const attributeType = convertGLUniformTypeToShaderVariableType(compositeType);
|
|
4028
|
-
const stepMode = /instance/i.test(name) ? "instance" : "vertex";
|
|
4029
|
-
attributes.push({
|
|
4030
|
-
name,
|
|
4031
|
-
location,
|
|
4032
|
-
stepMode,
|
|
4033
|
-
type: attributeType
|
|
4034
|
-
// size - for arrays, size is the number of elements in the array
|
|
4035
|
-
});
|
|
4036
|
-
}
|
|
4037
|
-
}
|
|
4038
|
-
attributes.sort((a, b) => a.location - b.location);
|
|
4039
|
-
return attributes;
|
|
4040
|
-
}
|
|
4041
|
-
function readVaryings(gl, program) {
|
|
4042
|
-
const varyings = [];
|
|
4043
|
-
const count = gl.getProgramParameter(program, 35971 /* TRANSFORM_FEEDBACK_VARYINGS */);
|
|
4044
|
-
for (let location = 0; location < count; location++) {
|
|
4045
|
-
const activeInfo = gl.getTransformFeedbackVarying(program, location);
|
|
4046
|
-
if (!activeInfo) {
|
|
4047
|
-
throw new Error("activeInfo");
|
|
4048
|
-
}
|
|
4049
|
-
const { name, type: glUniformType, size } = activeInfo;
|
|
4050
|
-
const uniformType = convertGLUniformTypeToShaderVariableType(glUniformType);
|
|
4051
|
-
const { type, components } = (0, import_core15.getVariableShaderTypeInfo)(uniformType);
|
|
4052
|
-
varyings.push({ location, name, type, size: size * components });
|
|
4053
|
-
}
|
|
4054
|
-
varyings.sort((a, b) => a.location - b.location);
|
|
4055
|
-
return varyings;
|
|
4056
|
-
}
|
|
4057
|
-
function readUniformBindings(gl, program) {
|
|
4058
|
-
const uniforms = [];
|
|
4059
|
-
const uniformCount = gl.getProgramParameter(program, 35718 /* ACTIVE_UNIFORMS */);
|
|
4060
|
-
for (let i = 0; i < uniformCount; i++) {
|
|
4061
|
-
const activeInfo = gl.getActiveUniform(program, i);
|
|
4062
|
-
if (!activeInfo) {
|
|
4063
|
-
throw new Error("activeInfo");
|
|
4064
|
-
}
|
|
4065
|
-
const { name: rawName, size, type } = activeInfo;
|
|
4066
|
-
const { name, isArray: isArray3 } = parseUniformName(rawName);
|
|
4067
|
-
let webglLocation = gl.getUniformLocation(program, name);
|
|
4068
|
-
const uniformInfo = {
|
|
4069
|
-
// WebGL locations are uniquely typed but just numbers
|
|
4070
|
-
location: webglLocation,
|
|
4071
|
-
name,
|
|
4072
|
-
size,
|
|
4073
|
-
type,
|
|
4074
|
-
isArray: isArray3
|
|
4075
|
-
};
|
|
4076
|
-
uniforms.push(uniformInfo);
|
|
4077
|
-
if (uniformInfo.size > 1) {
|
|
4078
|
-
for (let j = 0; j < uniformInfo.size; j++) {
|
|
4079
|
-
const elementName = `${name}[${j}]`;
|
|
4080
|
-
webglLocation = gl.getUniformLocation(program, elementName);
|
|
4081
|
-
const arrayElementUniformInfo = {
|
|
4082
|
-
...uniformInfo,
|
|
4083
|
-
name: elementName,
|
|
4084
|
-
location: webglLocation
|
|
4085
|
-
};
|
|
4086
|
-
uniforms.push(arrayElementUniformInfo);
|
|
4087
|
-
}
|
|
4088
|
-
}
|
|
4089
|
-
}
|
|
4090
|
-
return uniforms;
|
|
4091
|
-
}
|
|
4092
|
-
function readUniformBlocks(gl, program) {
|
|
4093
|
-
const getBlockParameter = (blockIndex, pname) => gl.getActiveUniformBlockParameter(program, blockIndex, pname);
|
|
4094
|
-
const uniformBlocks = [];
|
|
4095
|
-
const blockCount = gl.getProgramParameter(program, 35382 /* ACTIVE_UNIFORM_BLOCKS */);
|
|
4096
|
-
for (let blockIndex = 0; blockIndex < blockCount; blockIndex++) {
|
|
4097
|
-
const blockInfo = {
|
|
4098
|
-
name: gl.getActiveUniformBlockName(program, blockIndex) || "",
|
|
4099
|
-
location: getBlockParameter(blockIndex, 35391 /* UNIFORM_BLOCK_BINDING */),
|
|
4100
|
-
byteLength: getBlockParameter(blockIndex, 35392 /* UNIFORM_BLOCK_DATA_SIZE */),
|
|
4101
|
-
vertex: getBlockParameter(blockIndex, 35396 /* UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER */),
|
|
4102
|
-
fragment: getBlockParameter(blockIndex, 35398 /* UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER */),
|
|
4103
|
-
uniformCount: getBlockParameter(blockIndex, 35394 /* UNIFORM_BLOCK_ACTIVE_UNIFORMS */),
|
|
4104
|
-
uniforms: []
|
|
4105
|
-
};
|
|
4106
|
-
const uniformIndices = getBlockParameter(blockIndex, 35395 /* UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES */) || [];
|
|
4107
|
-
const uniformType = gl.getActiveUniforms(program, uniformIndices, 35383 /* UNIFORM_TYPE */);
|
|
4108
|
-
const uniformArrayLength = gl.getActiveUniforms(program, uniformIndices, 35384 /* UNIFORM_SIZE */);
|
|
4109
|
-
const uniformOffset = gl.getActiveUniforms(program, uniformIndices, 35387 /* UNIFORM_OFFSET */);
|
|
4110
|
-
const uniformStride = gl.getActiveUniforms(program, uniformIndices, 35388 /* UNIFORM_ARRAY_STRIDE */);
|
|
4111
|
-
for (let i = 0; i < blockInfo.uniformCount; ++i) {
|
|
4112
|
-
const uniformIndex = uniformIndices[i];
|
|
4113
|
-
if (uniformIndex === void 0) {
|
|
4114
|
-
continue;
|
|
4115
|
-
}
|
|
4116
|
-
const activeInfo = gl.getActiveUniform(program, uniformIndex);
|
|
4117
|
-
if (!activeInfo) {
|
|
4118
|
-
throw new Error("activeInfo");
|
|
4119
|
-
}
|
|
4120
|
-
const format = convertGLUniformTypeToShaderVariableType(uniformType[i]);
|
|
4121
|
-
blockInfo.uniforms.push({
|
|
4122
|
-
name: activeInfo.name,
|
|
4123
|
-
format,
|
|
4124
|
-
type: uniformType[i],
|
|
4125
|
-
arrayLength: uniformArrayLength[i],
|
|
4126
|
-
byteOffset: uniformOffset[i],
|
|
4127
|
-
byteStride: uniformStride[i]
|
|
4128
|
-
// matrixStride: uniformStride[i],
|
|
4129
|
-
// rowMajor: uniformRowMajor[i]
|
|
4130
|
-
});
|
|
4131
|
-
}
|
|
4132
|
-
uniformBlocks.push(blockInfo);
|
|
4133
|
-
}
|
|
4134
|
-
uniformBlocks.sort((a, b) => a.location - b.location);
|
|
4135
|
-
return uniformBlocks;
|
|
4136
|
-
}
|
|
4137
|
-
function parseUniformName(name) {
|
|
4138
|
-
if (name[name.length - 1] !== "]") {
|
|
4139
|
-
return {
|
|
4140
|
-
name,
|
|
4141
|
-
length: 1,
|
|
4142
|
-
isArray: false
|
|
4143
|
-
};
|
|
4144
|
-
}
|
|
4145
|
-
const UNIFORM_NAME_REGEXP = /([^[]*)(\[[0-9]+\])?/;
|
|
4146
|
-
const matches = UNIFORM_NAME_REGEXP.exec(name);
|
|
4147
|
-
const uniformName = (0, import_core15.assertDefined)(matches?.[1], `Failed to parse GLSL uniform name ${name}`);
|
|
4148
|
-
return {
|
|
4149
|
-
name: uniformName,
|
|
4150
|
-
// TODO - is this a bug, shouldn't we return the value?
|
|
4151
|
-
length: matches?.[2] ? 1 : 0,
|
|
4152
|
-
isArray: Boolean(matches?.[2])
|
|
4153
|
-
};
|
|
4154
|
-
}
|
|
4155
|
-
var import_core15;
|
|
4156
|
-
var init_get_shader_layout_from_glsl = __esm({
|
|
4157
|
-
"src/adapter/helpers/get-shader-layout-from-glsl.ts"() {
|
|
4158
|
-
"use strict";
|
|
4159
|
-
import_core15 = __toESM(require_core(), 1);
|
|
4160
|
-
init_webgl_shadertypes();
|
|
4161
|
-
}
|
|
4162
|
-
});
|
|
4163
|
-
|
|
4164
4202
|
// src/adapter/helpers/set-uniform.ts
|
|
4165
4203
|
function setUniform(gl, location, type, value) {
|
|
4166
4204
|
const gl2 = gl;
|
|
@@ -4307,12 +4345,11 @@ ${source}`;
|
|
|
4307
4345
|
}
|
|
4308
4346
|
return mergedLayout;
|
|
4309
4347
|
}
|
|
4310
|
-
var import_core16,
|
|
4348
|
+
var import_core16, WEBGLRenderPipeline;
|
|
4311
4349
|
var init_webgl_render_pipeline = __esm({
|
|
4312
4350
|
"src/adapter/resources/webgl-render-pipeline.ts"() {
|
|
4313
4351
|
"use strict";
|
|
4314
4352
|
import_core16 = __toESM(require_core(), 1);
|
|
4315
|
-
init_get_shader_layout_from_glsl();
|
|
4316
4353
|
init_device_parameters();
|
|
4317
4354
|
init_set_uniform();
|
|
4318
4355
|
init_webgl_buffer();
|
|
@@ -4320,7 +4357,6 @@ ${source}`;
|
|
|
4320
4357
|
init_webgl_texture();
|
|
4321
4358
|
init_webgl_texture_view();
|
|
4322
4359
|
init_webgl_topology_utils();
|
|
4323
|
-
LOG_PROGRAM_PERF_PRIORITY = 4;
|
|
4324
4360
|
WEBGLRenderPipeline = class extends import_core16.RenderPipeline {
|
|
4325
4361
|
/** The WebGL device that created this render pipeline */
|
|
4326
4362
|
device;
|
|
@@ -4332,10 +4368,10 @@ ${source}`;
|
|
|
4332
4368
|
fs;
|
|
4333
4369
|
/** The layout extracted from shader by WebGL introspection APIs */
|
|
4334
4370
|
introspectedLayout;
|
|
4335
|
-
/**
|
|
4336
|
-
uniforms = {};
|
|
4337
|
-
/** Bindings set on this model */
|
|
4371
|
+
/** Compatibility path for direct pipeline.setBindings() usage */
|
|
4338
4372
|
bindings = {};
|
|
4373
|
+
/** Compatibility path for direct pipeline.uniforms usage */
|
|
4374
|
+
uniforms = {};
|
|
4339
4375
|
/** WebGL varyings */
|
|
4340
4376
|
varyings = null;
|
|
4341
4377
|
_uniformCount = 0;
|
|
@@ -4347,33 +4383,28 @@ ${source}`;
|
|
|
4347
4383
|
constructor(device, props) {
|
|
4348
4384
|
super(device, props);
|
|
4349
4385
|
this.device = device;
|
|
4350
|
-
|
|
4386
|
+
const webglSharedRenderPipeline = this.sharedRenderPipeline || this.device._createSharedRenderPipelineWebGL(props);
|
|
4387
|
+
this.sharedRenderPipeline = webglSharedRenderPipeline;
|
|
4388
|
+
this.handle = webglSharedRenderPipeline.handle;
|
|
4389
|
+
this.vs = webglSharedRenderPipeline.vs;
|
|
4390
|
+
this.fs = webglSharedRenderPipeline.fs;
|
|
4391
|
+
this.linkStatus = webglSharedRenderPipeline.linkStatus;
|
|
4392
|
+
this.introspectedLayout = webglSharedRenderPipeline.introspectedLayout;
|
|
4351
4393
|
this.device._setWebGLDebugMetadata(this.handle, this, { spector: { id: this.props.id } });
|
|
4352
|
-
this.vs = props.vs;
|
|
4353
|
-
this.fs = props.fs;
|
|
4354
|
-
const { varyings, bufferMode = 35981 /* SEPARATE_ATTRIBS */ } = props;
|
|
4355
|
-
if (varyings && varyings.length > 0) {
|
|
4356
|
-
this.varyings = varyings;
|
|
4357
|
-
this.device.gl.transformFeedbackVaryings(this.handle, varyings, bufferMode);
|
|
4358
|
-
}
|
|
4359
|
-
this._linkShaders();
|
|
4360
|
-
import_core16.log.time(3, `RenderPipeline ${this.id} - shaderLayout introspection`)();
|
|
4361
|
-
this.introspectedLayout = getShaderLayoutFromGLSL(this.device.gl, this.handle);
|
|
4362
|
-
import_core16.log.timeEnd(3, `RenderPipeline ${this.id} - shaderLayout introspection`)();
|
|
4363
4394
|
this.shaderLayout = props.shaderLayout ? mergeShaderLayout(this.introspectedLayout, props.shaderLayout) : this.introspectedLayout;
|
|
4364
4395
|
}
|
|
4365
4396
|
destroy() {
|
|
4366
|
-
if (this.
|
|
4367
|
-
|
|
4368
|
-
|
|
4369
|
-
|
|
4370
|
-
this.
|
|
4371
|
-
this.handle = null;
|
|
4397
|
+
if (this.destroyed) {
|
|
4398
|
+
return;
|
|
4399
|
+
}
|
|
4400
|
+
if (this.sharedRenderPipeline && !this.props._sharedRenderPipeline) {
|
|
4401
|
+
this.sharedRenderPipeline.destroy();
|
|
4372
4402
|
}
|
|
4403
|
+
this.destroyResource();
|
|
4373
4404
|
}
|
|
4374
4405
|
/**
|
|
4375
|
-
*
|
|
4376
|
-
*
|
|
4406
|
+
* Compatibility shim for code paths that still set bindings on the pipeline.
|
|
4407
|
+
* Shared-model draws pass bindings per draw and do not rely on this state.
|
|
4377
4408
|
*/
|
|
4378
4409
|
setBindings(bindings, options) {
|
|
4379
4410
|
for (const [name, value] of Object.entries(bindings)) {
|
|
@@ -4416,6 +4447,7 @@ ${source}`;
|
|
|
4416
4447
|
* This function unifies those ways into a single call using common parameters with sane defaults
|
|
4417
4448
|
*/
|
|
4418
4449
|
draw(options) {
|
|
4450
|
+
this._syncLinkStatus();
|
|
4419
4451
|
const {
|
|
4420
4452
|
renderPass,
|
|
4421
4453
|
parameters = this.props.parameters,
|
|
@@ -4429,7 +4461,9 @@ ${source}`;
|
|
|
4429
4461
|
// firstIndex,
|
|
4430
4462
|
// firstInstance,
|
|
4431
4463
|
// baseVertex,
|
|
4432
|
-
transformFeedback
|
|
4464
|
+
transformFeedback,
|
|
4465
|
+
bindings = this.bindings,
|
|
4466
|
+
uniforms = this.uniforms
|
|
4433
4467
|
} = options;
|
|
4434
4468
|
const glDrawMode = getGLDrawMode(topology);
|
|
4435
4469
|
const isIndexed = Boolean(vertexArray.indexBuffer);
|
|
@@ -4438,71 +4472,506 @@ ${source}`;
|
|
|
4438
4472
|
import_core16.log.info(2, `RenderPipeline:${this.id}.draw() aborted - waiting for shader linking`)();
|
|
4439
4473
|
return false;
|
|
4440
4474
|
}
|
|
4441
|
-
if (!this._areTexturesRenderable()) {
|
|
4475
|
+
if (!this._areTexturesRenderable(bindings)) {
|
|
4442
4476
|
import_core16.log.info(2, `RenderPipeline:${this.id}.draw() aborted - textures not yet loaded`)();
|
|
4443
4477
|
return false;
|
|
4444
4478
|
}
|
|
4445
|
-
this.device.gl.useProgram(this.handle);
|
|
4446
|
-
vertexArray.bindBeforeRender(renderPass);
|
|
4447
|
-
if (transformFeedback) {
|
|
4448
|
-
transformFeedback.begin(this.props.topology);
|
|
4479
|
+
this.device.gl.useProgram(this.handle);
|
|
4480
|
+
vertexArray.bindBeforeRender(renderPass);
|
|
4481
|
+
if (transformFeedback) {
|
|
4482
|
+
transformFeedback.begin(this.props.topology);
|
|
4483
|
+
}
|
|
4484
|
+
this._applyBindings(bindings, { disableWarnings: this.props.disableWarnings });
|
|
4485
|
+
this._applyUniforms(uniforms);
|
|
4486
|
+
const webglRenderPass = renderPass;
|
|
4487
|
+
withDeviceAndGLParameters(this.device, parameters, webglRenderPass.glParameters, () => {
|
|
4488
|
+
if (isIndexed && isInstanced) {
|
|
4489
|
+
this.device.gl.drawElementsInstanced(
|
|
4490
|
+
glDrawMode,
|
|
4491
|
+
vertexCount || 0,
|
|
4492
|
+
// indexCount?
|
|
4493
|
+
glIndexType,
|
|
4494
|
+
firstVertex,
|
|
4495
|
+
instanceCount || 0
|
|
4496
|
+
);
|
|
4497
|
+
} else if (isIndexed) {
|
|
4498
|
+
this.device.gl.drawElements(glDrawMode, vertexCount || 0, glIndexType, firstVertex);
|
|
4499
|
+
} else if (isInstanced) {
|
|
4500
|
+
this.device.gl.drawArraysInstanced(
|
|
4501
|
+
glDrawMode,
|
|
4502
|
+
firstVertex,
|
|
4503
|
+
vertexCount || 0,
|
|
4504
|
+
instanceCount || 0
|
|
4505
|
+
);
|
|
4506
|
+
} else {
|
|
4507
|
+
this.device.gl.drawArrays(glDrawMode, firstVertex, vertexCount || 0);
|
|
4508
|
+
}
|
|
4509
|
+
if (transformFeedback) {
|
|
4510
|
+
transformFeedback.end();
|
|
4511
|
+
}
|
|
4512
|
+
});
|
|
4513
|
+
vertexArray.unbindAfterRender(renderPass);
|
|
4514
|
+
return true;
|
|
4515
|
+
}
|
|
4516
|
+
/**
|
|
4517
|
+
* Checks if all texture-values uniforms are renderable (i.e. loaded)
|
|
4518
|
+
* Update a texture if needed (e.g. from video)
|
|
4519
|
+
* Note: This is currently done before every draw call
|
|
4520
|
+
*/
|
|
4521
|
+
_areTexturesRenderable(bindings) {
|
|
4522
|
+
let texturesRenderable = true;
|
|
4523
|
+
for (const bindingInfo of this.shaderLayout.bindings) {
|
|
4524
|
+
if (!bindings[bindingInfo.name] && !bindings[bindingInfo.name.replace(/Uniforms$/, "")]) {
|
|
4525
|
+
import_core16.log.warn(`Binding ${bindingInfo.name} not found in ${this.id}`)();
|
|
4526
|
+
texturesRenderable = false;
|
|
4527
|
+
}
|
|
4528
|
+
}
|
|
4529
|
+
return texturesRenderable;
|
|
4530
|
+
}
|
|
4531
|
+
/** Apply any bindings (before each draw call) */
|
|
4532
|
+
_applyBindings(bindings, _options) {
|
|
4533
|
+
this._syncLinkStatus();
|
|
4534
|
+
if (this.linkStatus !== "success") {
|
|
4535
|
+
return;
|
|
4536
|
+
}
|
|
4537
|
+
const { gl } = this.device;
|
|
4538
|
+
gl.useProgram(this.handle);
|
|
4539
|
+
let textureUnit = 0;
|
|
4540
|
+
let uniformBufferIndex = 0;
|
|
4541
|
+
for (const binding of this.shaderLayout.bindings) {
|
|
4542
|
+
const value = bindings[binding.name] || bindings[binding.name.replace(/Uniforms$/, "")];
|
|
4543
|
+
if (!value) {
|
|
4544
|
+
throw new Error(`No value for binding ${binding.name} in ${this.id}`);
|
|
4545
|
+
}
|
|
4546
|
+
switch (binding.type) {
|
|
4547
|
+
case "uniform":
|
|
4548
|
+
const { name } = binding;
|
|
4549
|
+
const location = gl.getUniformBlockIndex(this.handle, name);
|
|
4550
|
+
if (location === 4294967295 /* INVALID_INDEX */) {
|
|
4551
|
+
throw new Error(`Invalid uniform block name ${name}`);
|
|
4552
|
+
}
|
|
4553
|
+
gl.uniformBlockBinding(this.handle, location, uniformBufferIndex);
|
|
4554
|
+
if (value instanceof WEBGLBuffer) {
|
|
4555
|
+
gl.bindBufferBase(35345 /* UNIFORM_BUFFER */, uniformBufferIndex, value.handle);
|
|
4556
|
+
} else {
|
|
4557
|
+
gl.bindBufferRange(
|
|
4558
|
+
35345 /* UNIFORM_BUFFER */,
|
|
4559
|
+
uniformBufferIndex,
|
|
4560
|
+
// @ts-expect-error
|
|
4561
|
+
value.buffer.handle,
|
|
4562
|
+
// @ts-expect-error
|
|
4563
|
+
value.offset || 0,
|
|
4564
|
+
// @ts-expect-error
|
|
4565
|
+
value.size || value.buffer.byteLength - value.offset
|
|
4566
|
+
);
|
|
4567
|
+
}
|
|
4568
|
+
uniformBufferIndex += 1;
|
|
4569
|
+
break;
|
|
4570
|
+
case "texture":
|
|
4571
|
+
if (!(value instanceof WEBGLTextureView || value instanceof WEBGLTexture || value instanceof WEBGLFramebuffer)) {
|
|
4572
|
+
throw new Error("texture");
|
|
4573
|
+
}
|
|
4574
|
+
let texture;
|
|
4575
|
+
if (value instanceof WEBGLTextureView) {
|
|
4576
|
+
texture = value.texture;
|
|
4577
|
+
} else if (value instanceof WEBGLTexture) {
|
|
4578
|
+
texture = value;
|
|
4579
|
+
} else if (value instanceof WEBGLFramebuffer && value.colorAttachments[0] instanceof WEBGLTextureView) {
|
|
4580
|
+
import_core16.log.warn(
|
|
4581
|
+
"Passing framebuffer in texture binding may be deprecated. Use fbo.colorAttachments[0] instead"
|
|
4582
|
+
)();
|
|
4583
|
+
texture = value.colorAttachments[0].texture;
|
|
4584
|
+
} else {
|
|
4585
|
+
throw new Error("No texture");
|
|
4586
|
+
}
|
|
4587
|
+
gl.activeTexture(33984 /* TEXTURE0 */ + textureUnit);
|
|
4588
|
+
gl.bindTexture(texture.glTarget, texture.handle);
|
|
4589
|
+
textureUnit += 1;
|
|
4590
|
+
break;
|
|
4591
|
+
case "sampler":
|
|
4592
|
+
break;
|
|
4593
|
+
case "storage":
|
|
4594
|
+
case "read-only-storage":
|
|
4595
|
+
throw new Error(`binding type '${binding.type}' not supported in WebGL`);
|
|
4596
|
+
}
|
|
4597
|
+
}
|
|
4598
|
+
}
|
|
4599
|
+
/**
|
|
4600
|
+
* Due to program sharing, uniforms need to be reset before every draw call
|
|
4601
|
+
* (though caching will avoid redundant WebGL calls)
|
|
4602
|
+
*/
|
|
4603
|
+
_applyUniforms(uniforms) {
|
|
4604
|
+
for (const uniformLayout of this.shaderLayout.uniforms || []) {
|
|
4605
|
+
const { name, location, type, textureUnit } = uniformLayout;
|
|
4606
|
+
const value = uniforms[name] ?? textureUnit;
|
|
4607
|
+
if (value !== void 0) {
|
|
4608
|
+
setUniform(this.device.gl, location, type, value);
|
|
4609
|
+
}
|
|
4610
|
+
}
|
|
4611
|
+
}
|
|
4612
|
+
_syncLinkStatus() {
|
|
4613
|
+
this.linkStatus = this.sharedRenderPipeline.linkStatus;
|
|
4614
|
+
}
|
|
4615
|
+
};
|
|
4616
|
+
}
|
|
4617
|
+
});
|
|
4618
|
+
|
|
4619
|
+
// src/adapter/converters/webgl-shadertypes.ts
|
|
4620
|
+
function convertDataTypeToGLDataType(normalizedType) {
|
|
4621
|
+
return NORMALIZED_SHADER_TYPE_TO_WEBGL[normalizedType];
|
|
4622
|
+
}
|
|
4623
|
+
function convertGLUniformTypeToShaderVariableType(glUniformType) {
|
|
4624
|
+
return WEBGL_SHADER_TYPES[glUniformType];
|
|
4625
|
+
}
|
|
4626
|
+
function isGLSamplerType(type) {
|
|
4627
|
+
return Boolean(WEBGL_SAMPLER_TO_TEXTURE_BINDINGS[type]);
|
|
4628
|
+
}
|
|
4629
|
+
function getTextureBindingFromGLSamplerType(glSamplerType) {
|
|
4630
|
+
return WEBGL_SAMPLER_TO_TEXTURE_BINDINGS[glSamplerType];
|
|
4631
|
+
}
|
|
4632
|
+
var WEBGL_SHADER_TYPES, WEBGL_SAMPLER_TO_TEXTURE_BINDINGS, NORMALIZED_SHADER_TYPE_TO_WEBGL, WEBGL_TO_NORMALIZED_DATA_TYPE;
|
|
4633
|
+
var init_webgl_shadertypes = __esm({
|
|
4634
|
+
"src/adapter/converters/webgl-shadertypes.ts"() {
|
|
4635
|
+
"use strict";
|
|
4636
|
+
WEBGL_SHADER_TYPES = {
|
|
4637
|
+
[5126 /* FLOAT */]: "f32",
|
|
4638
|
+
[35664 /* FLOAT_VEC2 */]: "vec2<f32>",
|
|
4639
|
+
[35665 /* FLOAT_VEC3 */]: "vec3<f32>",
|
|
4640
|
+
[35666 /* FLOAT_VEC4 */]: "vec4<f32>",
|
|
4641
|
+
[5124 /* INT */]: "i32",
|
|
4642
|
+
[35667 /* INT_VEC2 */]: "vec2<i32>",
|
|
4643
|
+
[35668 /* INT_VEC3 */]: "vec3<i32>",
|
|
4644
|
+
[35669 /* INT_VEC4 */]: "vec4<i32>",
|
|
4645
|
+
[5125 /* UNSIGNED_INT */]: "u32",
|
|
4646
|
+
[36294 /* UNSIGNED_INT_VEC2 */]: "vec2<u32>",
|
|
4647
|
+
[36295 /* UNSIGNED_INT_VEC3 */]: "vec3<u32>",
|
|
4648
|
+
[36296 /* UNSIGNED_INT_VEC4 */]: "vec4<u32>",
|
|
4649
|
+
[35670 /* BOOL */]: "f32",
|
|
4650
|
+
[35671 /* BOOL_VEC2 */]: "vec2<f32>",
|
|
4651
|
+
[35672 /* BOOL_VEC3 */]: "vec3<f32>",
|
|
4652
|
+
[35673 /* BOOL_VEC4 */]: "vec4<f32>",
|
|
4653
|
+
// TODO - are sizes/components below correct?
|
|
4654
|
+
[35674 /* FLOAT_MAT2 */]: "mat2x2<f32>",
|
|
4655
|
+
[35685 /* FLOAT_MAT2x3 */]: "mat2x3<f32>",
|
|
4656
|
+
[35686 /* FLOAT_MAT2x4 */]: "mat2x4<f32>",
|
|
4657
|
+
[35687 /* FLOAT_MAT3x2 */]: "mat3x2<f32>",
|
|
4658
|
+
[35675 /* FLOAT_MAT3 */]: "mat3x3<f32>",
|
|
4659
|
+
[35688 /* FLOAT_MAT3x4 */]: "mat3x4<f32>",
|
|
4660
|
+
[35689 /* FLOAT_MAT4x2 */]: "mat4x2<f32>",
|
|
4661
|
+
[35690 /* FLOAT_MAT4x3 */]: "mat4x3<f32>",
|
|
4662
|
+
[35676 /* FLOAT_MAT4 */]: "mat4x4<f32>"
|
|
4663
|
+
};
|
|
4664
|
+
WEBGL_SAMPLER_TO_TEXTURE_BINDINGS = {
|
|
4665
|
+
[35678 /* SAMPLER_2D */]: { viewDimension: "2d", sampleType: "float" },
|
|
4666
|
+
[35680 /* SAMPLER_CUBE */]: { viewDimension: "cube", sampleType: "float" },
|
|
4667
|
+
[35679 /* SAMPLER_3D */]: { viewDimension: "3d", sampleType: "float" },
|
|
4668
|
+
[35682 /* SAMPLER_2D_SHADOW */]: { viewDimension: "3d", sampleType: "depth" },
|
|
4669
|
+
[36289 /* SAMPLER_2D_ARRAY */]: { viewDimension: "2d-array", sampleType: "float" },
|
|
4670
|
+
[36292 /* SAMPLER_2D_ARRAY_SHADOW */]: { viewDimension: "2d-array", sampleType: "depth" },
|
|
4671
|
+
[36293 /* SAMPLER_CUBE_SHADOW */]: { viewDimension: "cube", sampleType: "float" },
|
|
4672
|
+
[36298 /* INT_SAMPLER_2D */]: { viewDimension: "2d", sampleType: "sint" },
|
|
4673
|
+
[36299 /* INT_SAMPLER_3D */]: { viewDimension: "3d", sampleType: "sint" },
|
|
4674
|
+
[36300 /* INT_SAMPLER_CUBE */]: { viewDimension: "cube", sampleType: "sint" },
|
|
4675
|
+
[36303 /* INT_SAMPLER_2D_ARRAY */]: { viewDimension: "2d-array", sampleType: "uint" },
|
|
4676
|
+
[36306 /* UNSIGNED_INT_SAMPLER_2D */]: { viewDimension: "2d", sampleType: "uint" },
|
|
4677
|
+
[36307 /* UNSIGNED_INT_SAMPLER_3D */]: { viewDimension: "3d", sampleType: "uint" },
|
|
4678
|
+
[36308 /* UNSIGNED_INT_SAMPLER_CUBE */]: { viewDimension: "cube", sampleType: "uint" },
|
|
4679
|
+
[36311 /* UNSIGNED_INT_SAMPLER_2D_ARRAY */]: { viewDimension: "2d-array", sampleType: "uint" }
|
|
4680
|
+
};
|
|
4681
|
+
NORMALIZED_SHADER_TYPE_TO_WEBGL = {
|
|
4682
|
+
uint8: 5121 /* UNSIGNED_BYTE */,
|
|
4683
|
+
sint8: 5120 /* BYTE */,
|
|
4684
|
+
unorm8: 5121 /* UNSIGNED_BYTE */,
|
|
4685
|
+
snorm8: 5120 /* BYTE */,
|
|
4686
|
+
uint16: 5123 /* UNSIGNED_SHORT */,
|
|
4687
|
+
sint16: 5122 /* SHORT */,
|
|
4688
|
+
unorm16: 5123 /* UNSIGNED_SHORT */,
|
|
4689
|
+
snorm16: 5122 /* SHORT */,
|
|
4690
|
+
uint32: 5125 /* UNSIGNED_INT */,
|
|
4691
|
+
sint32: 5124 /* INT */,
|
|
4692
|
+
// WebGPU does not support normalized 32 bit integer attributes
|
|
4693
|
+
// 'unorm32': GL.UNSIGNED_INT,
|
|
4694
|
+
// 'snorm32': GL.INT,
|
|
4695
|
+
float16: 5131 /* HALF_FLOAT */,
|
|
4696
|
+
float32: 5126 /* FLOAT */
|
|
4697
|
+
};
|
|
4698
|
+
WEBGL_TO_NORMALIZED_DATA_TYPE = {
|
|
4699
|
+
[5120 /* BYTE */]: ["sint8", "snorm16"],
|
|
4700
|
+
[5121 /* UNSIGNED_BYTE */]: ["uint8", "unorm8"],
|
|
4701
|
+
[5122 /* SHORT */]: ["sint16", "unorm16"],
|
|
4702
|
+
[5123 /* UNSIGNED_SHORT */]: ["uint16", "unorm16"],
|
|
4703
|
+
[5124 /* INT */]: ["sint32", "sint32"],
|
|
4704
|
+
[5125 /* UNSIGNED_INT */]: ["uint32", "uint32"],
|
|
4705
|
+
[5126 /* FLOAT */]: ["float32", "float32"],
|
|
4706
|
+
[5131 /* HALF_FLOAT */]: ["float16", "float16"]
|
|
4707
|
+
};
|
|
4708
|
+
}
|
|
4709
|
+
});
|
|
4710
|
+
|
|
4711
|
+
// src/adapter/helpers/get-shader-layout-from-glsl.ts
|
|
4712
|
+
function getShaderLayoutFromGLSL(gl, program) {
|
|
4713
|
+
const shaderLayout = {
|
|
4714
|
+
attributes: [],
|
|
4715
|
+
bindings: []
|
|
4716
|
+
};
|
|
4717
|
+
shaderLayout.attributes = readAttributeDeclarations(gl, program);
|
|
4718
|
+
const uniformBlocks = readUniformBlocks(gl, program);
|
|
4719
|
+
for (const uniformBlock of uniformBlocks) {
|
|
4720
|
+
const uniforms2 = uniformBlock.uniforms.map((uniform) => ({
|
|
4721
|
+
name: uniform.name,
|
|
4722
|
+
format: uniform.format,
|
|
4723
|
+
byteOffset: uniform.byteOffset,
|
|
4724
|
+
byteStride: uniform.byteStride,
|
|
4725
|
+
arrayLength: uniform.arrayLength
|
|
4726
|
+
}));
|
|
4727
|
+
shaderLayout.bindings.push({
|
|
4728
|
+
type: "uniform",
|
|
4729
|
+
name: uniformBlock.name,
|
|
4730
|
+
group: 0,
|
|
4731
|
+
location: uniformBlock.location,
|
|
4732
|
+
visibility: (uniformBlock.vertex ? 1 : 0) & (uniformBlock.fragment ? 2 : 0),
|
|
4733
|
+
minBindingSize: uniformBlock.byteLength,
|
|
4734
|
+
uniforms: uniforms2
|
|
4735
|
+
});
|
|
4736
|
+
}
|
|
4737
|
+
const uniforms = readUniformBindings(gl, program);
|
|
4738
|
+
let textureUnit = 0;
|
|
4739
|
+
for (const uniform of uniforms) {
|
|
4740
|
+
if (isGLSamplerType(uniform.type)) {
|
|
4741
|
+
const { viewDimension, sampleType } = getTextureBindingFromGLSamplerType(uniform.type);
|
|
4742
|
+
shaderLayout.bindings.push({
|
|
4743
|
+
type: "texture",
|
|
4744
|
+
name: uniform.name,
|
|
4745
|
+
group: 0,
|
|
4746
|
+
location: textureUnit,
|
|
4747
|
+
viewDimension,
|
|
4748
|
+
sampleType
|
|
4749
|
+
});
|
|
4750
|
+
uniform.textureUnit = textureUnit;
|
|
4751
|
+
textureUnit += 1;
|
|
4752
|
+
}
|
|
4753
|
+
}
|
|
4754
|
+
if (uniforms.length) {
|
|
4755
|
+
shaderLayout.uniforms = uniforms;
|
|
4756
|
+
}
|
|
4757
|
+
const varyings = readVaryings(gl, program);
|
|
4758
|
+
if (varyings?.length) {
|
|
4759
|
+
shaderLayout.varyings = varyings;
|
|
4760
|
+
}
|
|
4761
|
+
return shaderLayout;
|
|
4762
|
+
}
|
|
4763
|
+
function readAttributeDeclarations(gl, program) {
|
|
4764
|
+
const attributes = [];
|
|
4765
|
+
const count = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES);
|
|
4766
|
+
for (let index = 0; index < count; index++) {
|
|
4767
|
+
const activeInfo = gl.getActiveAttrib(program, index);
|
|
4768
|
+
if (!activeInfo) {
|
|
4769
|
+
throw new Error("activeInfo");
|
|
4770
|
+
}
|
|
4771
|
+
const {
|
|
4772
|
+
name,
|
|
4773
|
+
type: compositeType
|
|
4774
|
+
/* , size*/
|
|
4775
|
+
} = activeInfo;
|
|
4776
|
+
const location = gl.getAttribLocation(program, name);
|
|
4777
|
+
if (location >= 0) {
|
|
4778
|
+
const attributeType = convertGLUniformTypeToShaderVariableType(compositeType);
|
|
4779
|
+
const stepMode = /instance/i.test(name) ? "instance" : "vertex";
|
|
4780
|
+
attributes.push({
|
|
4781
|
+
name,
|
|
4782
|
+
location,
|
|
4783
|
+
stepMode,
|
|
4784
|
+
type: attributeType
|
|
4785
|
+
// size - for arrays, size is the number of elements in the array
|
|
4786
|
+
});
|
|
4787
|
+
}
|
|
4788
|
+
}
|
|
4789
|
+
attributes.sort((a, b) => a.location - b.location);
|
|
4790
|
+
return attributes;
|
|
4791
|
+
}
|
|
4792
|
+
function readVaryings(gl, program) {
|
|
4793
|
+
const varyings = [];
|
|
4794
|
+
const count = gl.getProgramParameter(program, 35971 /* TRANSFORM_FEEDBACK_VARYINGS */);
|
|
4795
|
+
for (let location = 0; location < count; location++) {
|
|
4796
|
+
const activeInfo = gl.getTransformFeedbackVarying(program, location);
|
|
4797
|
+
if (!activeInfo) {
|
|
4798
|
+
throw new Error("activeInfo");
|
|
4799
|
+
}
|
|
4800
|
+
const { name, type: glUniformType, size } = activeInfo;
|
|
4801
|
+
const uniformType = convertGLUniformTypeToShaderVariableType(glUniformType);
|
|
4802
|
+
const { type, components } = (0, import_core17.getVariableShaderTypeInfo)(uniformType);
|
|
4803
|
+
varyings.push({ location, name, type, size: size * components });
|
|
4804
|
+
}
|
|
4805
|
+
varyings.sort((a, b) => a.location - b.location);
|
|
4806
|
+
return varyings;
|
|
4807
|
+
}
|
|
4808
|
+
function readUniformBindings(gl, program) {
|
|
4809
|
+
const uniforms = [];
|
|
4810
|
+
const uniformCount = gl.getProgramParameter(program, 35718 /* ACTIVE_UNIFORMS */);
|
|
4811
|
+
for (let i = 0; i < uniformCount; i++) {
|
|
4812
|
+
const activeInfo = gl.getActiveUniform(program, i);
|
|
4813
|
+
if (!activeInfo) {
|
|
4814
|
+
throw new Error("activeInfo");
|
|
4815
|
+
}
|
|
4816
|
+
const { name: rawName, size, type } = activeInfo;
|
|
4817
|
+
const { name, isArray: isArray3 } = parseUniformName(rawName);
|
|
4818
|
+
let webglLocation = gl.getUniformLocation(program, name);
|
|
4819
|
+
const uniformInfo = {
|
|
4820
|
+
// WebGL locations are uniquely typed but just numbers
|
|
4821
|
+
location: webglLocation,
|
|
4822
|
+
name,
|
|
4823
|
+
size,
|
|
4824
|
+
type,
|
|
4825
|
+
isArray: isArray3
|
|
4826
|
+
};
|
|
4827
|
+
uniforms.push(uniformInfo);
|
|
4828
|
+
if (uniformInfo.size > 1) {
|
|
4829
|
+
for (let j = 0; j < uniformInfo.size; j++) {
|
|
4830
|
+
const elementName = `${name}[${j}]`;
|
|
4831
|
+
webglLocation = gl.getUniformLocation(program, elementName);
|
|
4832
|
+
const arrayElementUniformInfo = {
|
|
4833
|
+
...uniformInfo,
|
|
4834
|
+
name: elementName,
|
|
4835
|
+
location: webglLocation
|
|
4836
|
+
};
|
|
4837
|
+
uniforms.push(arrayElementUniformInfo);
|
|
4838
|
+
}
|
|
4839
|
+
}
|
|
4840
|
+
}
|
|
4841
|
+
return uniforms;
|
|
4842
|
+
}
|
|
4843
|
+
function readUniformBlocks(gl, program) {
|
|
4844
|
+
const getBlockParameter = (blockIndex, pname) => gl.getActiveUniformBlockParameter(program, blockIndex, pname);
|
|
4845
|
+
const uniformBlocks = [];
|
|
4846
|
+
const blockCount = gl.getProgramParameter(program, 35382 /* ACTIVE_UNIFORM_BLOCKS */);
|
|
4847
|
+
for (let blockIndex = 0; blockIndex < blockCount; blockIndex++) {
|
|
4848
|
+
const blockInfo = {
|
|
4849
|
+
name: gl.getActiveUniformBlockName(program, blockIndex) || "",
|
|
4850
|
+
location: getBlockParameter(blockIndex, 35391 /* UNIFORM_BLOCK_BINDING */),
|
|
4851
|
+
byteLength: getBlockParameter(blockIndex, 35392 /* UNIFORM_BLOCK_DATA_SIZE */),
|
|
4852
|
+
vertex: getBlockParameter(blockIndex, 35396 /* UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER */),
|
|
4853
|
+
fragment: getBlockParameter(blockIndex, 35398 /* UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER */),
|
|
4854
|
+
uniformCount: getBlockParameter(blockIndex, 35394 /* UNIFORM_BLOCK_ACTIVE_UNIFORMS */),
|
|
4855
|
+
uniforms: []
|
|
4856
|
+
};
|
|
4857
|
+
const uniformIndices = getBlockParameter(blockIndex, 35395 /* UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES */) || [];
|
|
4858
|
+
const uniformType = gl.getActiveUniforms(program, uniformIndices, 35383 /* UNIFORM_TYPE */);
|
|
4859
|
+
const uniformArrayLength = gl.getActiveUniforms(program, uniformIndices, 35384 /* UNIFORM_SIZE */);
|
|
4860
|
+
const uniformOffset = gl.getActiveUniforms(program, uniformIndices, 35387 /* UNIFORM_OFFSET */);
|
|
4861
|
+
const uniformStride = gl.getActiveUniforms(program, uniformIndices, 35388 /* UNIFORM_ARRAY_STRIDE */);
|
|
4862
|
+
for (let i = 0; i < blockInfo.uniformCount; ++i) {
|
|
4863
|
+
const uniformIndex = uniformIndices[i];
|
|
4864
|
+
if (uniformIndex !== void 0) {
|
|
4865
|
+
const activeInfo = gl.getActiveUniform(program, uniformIndex);
|
|
4866
|
+
if (!activeInfo) {
|
|
4867
|
+
throw new Error("activeInfo");
|
|
4868
|
+
}
|
|
4869
|
+
const format = convertGLUniformTypeToShaderVariableType(uniformType[i]);
|
|
4870
|
+
blockInfo.uniforms.push({
|
|
4871
|
+
name: activeInfo.name,
|
|
4872
|
+
format,
|
|
4873
|
+
type: uniformType[i],
|
|
4874
|
+
arrayLength: uniformArrayLength[i],
|
|
4875
|
+
byteOffset: uniformOffset[i],
|
|
4876
|
+
byteStride: uniformStride[i]
|
|
4877
|
+
// matrixStride: uniformStride[i],
|
|
4878
|
+
// rowMajor: uniformRowMajor[i]
|
|
4879
|
+
});
|
|
4880
|
+
}
|
|
4881
|
+
}
|
|
4882
|
+
uniformBlocks.push(blockInfo);
|
|
4883
|
+
}
|
|
4884
|
+
uniformBlocks.sort((a, b) => a.location - b.location);
|
|
4885
|
+
return uniformBlocks;
|
|
4886
|
+
}
|
|
4887
|
+
function parseUniformName(name) {
|
|
4888
|
+
if (name[name.length - 1] !== "]") {
|
|
4889
|
+
return {
|
|
4890
|
+
name,
|
|
4891
|
+
length: 1,
|
|
4892
|
+
isArray: false
|
|
4893
|
+
};
|
|
4894
|
+
}
|
|
4895
|
+
const UNIFORM_NAME_REGEXP = /([^[]*)(\[[0-9]+\])?/;
|
|
4896
|
+
const matches = UNIFORM_NAME_REGEXP.exec(name);
|
|
4897
|
+
const uniformName = (0, import_core17.assertDefined)(matches?.[1], `Failed to parse GLSL uniform name ${name}`);
|
|
4898
|
+
return {
|
|
4899
|
+
name: uniformName,
|
|
4900
|
+
// TODO - is this a bug, shouldn't we return the value?
|
|
4901
|
+
length: matches?.[2] ? 1 : 0,
|
|
4902
|
+
isArray: Boolean(matches?.[2])
|
|
4903
|
+
};
|
|
4904
|
+
}
|
|
4905
|
+
var import_core17;
|
|
4906
|
+
var init_get_shader_layout_from_glsl = __esm({
|
|
4907
|
+
"src/adapter/helpers/get-shader-layout-from-glsl.ts"() {
|
|
4908
|
+
"use strict";
|
|
4909
|
+
import_core17 = __toESM(require_core(), 1);
|
|
4910
|
+
init_webgl_shadertypes();
|
|
4911
|
+
}
|
|
4912
|
+
});
|
|
4913
|
+
|
|
4914
|
+
// src/adapter/resources/webgl-shared-render-pipeline.ts
|
|
4915
|
+
var import_core18, LOG_PROGRAM_PERF_PRIORITY, WEBGLSharedRenderPipeline;
|
|
4916
|
+
var init_webgl_shared_render_pipeline = __esm({
|
|
4917
|
+
"src/adapter/resources/webgl-shared-render-pipeline.ts"() {
|
|
4918
|
+
"use strict";
|
|
4919
|
+
import_core18 = __toESM(require_core(), 1);
|
|
4920
|
+
init_get_shader_layout_from_glsl();
|
|
4921
|
+
init_webgl_shadertypes();
|
|
4922
|
+
LOG_PROGRAM_PERF_PRIORITY = 4;
|
|
4923
|
+
WEBGLSharedRenderPipeline = class extends import_core18.SharedRenderPipeline {
|
|
4924
|
+
device;
|
|
4925
|
+
handle;
|
|
4926
|
+
vs;
|
|
4927
|
+
fs;
|
|
4928
|
+
introspectedLayout = { attributes: [], bindings: [], uniforms: [] };
|
|
4929
|
+
linkStatus = "pending";
|
|
4930
|
+
constructor(device, props) {
|
|
4931
|
+
super(device, props);
|
|
4932
|
+
this.device = device;
|
|
4933
|
+
this.handle = props.handle || this.device.gl.createProgram();
|
|
4934
|
+
this.vs = props.vs;
|
|
4935
|
+
this.fs = props.fs;
|
|
4936
|
+
if (props.varyings && props.varyings.length > 0) {
|
|
4937
|
+
this.device.gl.transformFeedbackVaryings(
|
|
4938
|
+
this.handle,
|
|
4939
|
+
props.varyings,
|
|
4940
|
+
props.bufferMode || 35981 /* SEPARATE_ATTRIBS */
|
|
4941
|
+
);
|
|
4942
|
+
}
|
|
4943
|
+
this._linkShaders();
|
|
4944
|
+
import_core18.log.time(3, `RenderPipeline ${this.id} - shaderLayout introspection`)();
|
|
4945
|
+
this.introspectedLayout = getShaderLayoutFromGLSL(this.device.gl, this.handle);
|
|
4946
|
+
import_core18.log.timeEnd(3, `RenderPipeline ${this.id} - shaderLayout introspection`)();
|
|
4947
|
+
}
|
|
4948
|
+
destroy() {
|
|
4949
|
+
if (this.destroyed) {
|
|
4950
|
+
return;
|
|
4449
4951
|
}
|
|
4450
|
-
this.
|
|
4451
|
-
this.
|
|
4452
|
-
|
|
4453
|
-
|
|
4454
|
-
if (isIndexed && isInstanced) {
|
|
4455
|
-
this.device.gl.drawElementsInstanced(
|
|
4456
|
-
glDrawMode,
|
|
4457
|
-
vertexCount || 0,
|
|
4458
|
-
// indexCount?
|
|
4459
|
-
glIndexType,
|
|
4460
|
-
firstVertex,
|
|
4461
|
-
instanceCount || 0
|
|
4462
|
-
);
|
|
4463
|
-
} else if (isIndexed) {
|
|
4464
|
-
this.device.gl.drawElements(glDrawMode, vertexCount || 0, glIndexType, firstVertex);
|
|
4465
|
-
} else if (isInstanced) {
|
|
4466
|
-
this.device.gl.drawArraysInstanced(
|
|
4467
|
-
glDrawMode,
|
|
4468
|
-
firstVertex,
|
|
4469
|
-
vertexCount || 0,
|
|
4470
|
-
instanceCount || 0
|
|
4471
|
-
);
|
|
4472
|
-
} else {
|
|
4473
|
-
this.device.gl.drawArrays(glDrawMode, firstVertex, vertexCount || 0);
|
|
4474
|
-
}
|
|
4475
|
-
if (transformFeedback) {
|
|
4476
|
-
transformFeedback.end();
|
|
4477
|
-
}
|
|
4478
|
-
});
|
|
4479
|
-
vertexArray.unbindAfterRender(renderPass);
|
|
4480
|
-
return true;
|
|
4952
|
+
this.device.gl.useProgram(null);
|
|
4953
|
+
this.device.gl.deleteProgram(this.handle);
|
|
4954
|
+
this.handle.destroyed = true;
|
|
4955
|
+
this.destroyResource();
|
|
4481
4956
|
}
|
|
4482
|
-
// PRIVATE METHODS
|
|
4483
|
-
// setAttributes(attributes: Record<string, Buffer>): void {}
|
|
4484
|
-
// setBindings(bindings: Record<string, Binding>): void {}
|
|
4485
4957
|
async _linkShaders() {
|
|
4486
4958
|
const { gl } = this.device;
|
|
4487
4959
|
gl.attachShader(this.handle, this.vs.handle);
|
|
4488
4960
|
gl.attachShader(this.handle, this.fs.handle);
|
|
4489
|
-
|
|
4961
|
+
import_core18.log.time(LOG_PROGRAM_PERF_PRIORITY, `linkProgram for ${this.id}`)();
|
|
4490
4962
|
gl.linkProgram(this.handle);
|
|
4491
|
-
|
|
4492
|
-
if (import_core16.log.level === 0) {
|
|
4493
|
-
}
|
|
4963
|
+
import_core18.log.timeEnd(LOG_PROGRAM_PERF_PRIORITY, `linkProgram for ${this.id}`)();
|
|
4494
4964
|
if (!this.device.features.has("compilation-status-async-webgl")) {
|
|
4495
4965
|
const status2 = this._getLinkStatus();
|
|
4496
4966
|
this._reportLinkStatus(status2);
|
|
4497
4967
|
return;
|
|
4498
4968
|
}
|
|
4499
|
-
|
|
4969
|
+
import_core18.log.once(1, "RenderPipeline linking is asynchronous")();
|
|
4500
4970
|
await this._waitForLinkComplete();
|
|
4501
|
-
|
|
4971
|
+
import_core18.log.info(2, `RenderPipeline ${this.id} - async linking complete: ${this.linkStatus}`)();
|
|
4502
4972
|
const status = this._getLinkStatus();
|
|
4503
4973
|
this._reportLinkStatus(status);
|
|
4504
4974
|
}
|
|
4505
|
-
/** Report link status. First, check for shader compilation failures if linking fails */
|
|
4506
4975
|
async _reportLinkStatus(status) {
|
|
4507
4976
|
switch (status) {
|
|
4508
4977
|
case "success":
|
|
@@ -4539,11 +5008,6 @@ ${source}`;
|
|
|
4539
5008
|
this.device.debug();
|
|
4540
5009
|
}
|
|
4541
5010
|
}
|
|
4542
|
-
/**
|
|
4543
|
-
* Get the shader compilation status
|
|
4544
|
-
* TODO - Load log even when no error reported, to catch warnings?
|
|
4545
|
-
* https://gamedev.stackexchange.com/questions/30429/how-to-detect-glsl-warnings
|
|
4546
|
-
*/
|
|
4547
5011
|
_getLinkStatus() {
|
|
4548
5012
|
const { gl } = this.device;
|
|
4549
5013
|
const linked = gl.getProgramParameter(this.handle, 35714 /* LINK_STATUS */);
|
|
@@ -4551,6 +5015,7 @@ ${source}`;
|
|
|
4551
5015
|
this.linkStatus = "error";
|
|
4552
5016
|
return "link-error";
|
|
4553
5017
|
}
|
|
5018
|
+
this._initializeSamplerUniforms();
|
|
4554
5019
|
gl.validateProgram(this.handle);
|
|
4555
5020
|
const validated = gl.getProgramParameter(this.handle, 35715 /* VALIDATE_STATUS */);
|
|
4556
5021
|
if (!validated) {
|
|
@@ -4560,7 +5025,36 @@ ${source}`;
|
|
|
4560
5025
|
this.linkStatus = "success";
|
|
4561
5026
|
return "success";
|
|
4562
5027
|
}
|
|
4563
|
-
|
|
5028
|
+
_initializeSamplerUniforms() {
|
|
5029
|
+
const { gl } = this.device;
|
|
5030
|
+
gl.useProgram(this.handle);
|
|
5031
|
+
let textureUnit = 0;
|
|
5032
|
+
const uniformCount = gl.getProgramParameter(this.handle, 35718 /* ACTIVE_UNIFORMS */);
|
|
5033
|
+
for (let uniformIndex = 0; uniformIndex < uniformCount; uniformIndex++) {
|
|
5034
|
+
const activeInfo = gl.getActiveUniform(this.handle, uniformIndex);
|
|
5035
|
+
if (activeInfo && isGLSamplerType(activeInfo.type)) {
|
|
5036
|
+
const isArray3 = activeInfo.name.endsWith("[0]");
|
|
5037
|
+
const uniformName = isArray3 ? activeInfo.name.slice(0, -3) : activeInfo.name;
|
|
5038
|
+
const location = gl.getUniformLocation(this.handle, uniformName);
|
|
5039
|
+
if (location !== null) {
|
|
5040
|
+
textureUnit = this._assignSamplerUniform(location, activeInfo, isArray3, textureUnit);
|
|
5041
|
+
}
|
|
5042
|
+
}
|
|
5043
|
+
}
|
|
5044
|
+
}
|
|
5045
|
+
_assignSamplerUniform(location, activeInfo, isArray3, textureUnit) {
|
|
5046
|
+
const { gl } = this.device;
|
|
5047
|
+
if (isArray3 && activeInfo.size > 1) {
|
|
5048
|
+
const textureUnits = Int32Array.from(
|
|
5049
|
+
{ length: activeInfo.size },
|
|
5050
|
+
(_, arrayIndex) => textureUnit + arrayIndex
|
|
5051
|
+
);
|
|
5052
|
+
gl.uniform1iv(location, textureUnits);
|
|
5053
|
+
return textureUnit + activeInfo.size;
|
|
5054
|
+
}
|
|
5055
|
+
gl.uniform1i(location, textureUnit);
|
|
5056
|
+
return textureUnit + 1;
|
|
5057
|
+
}
|
|
4564
5058
|
async _waitForLinkComplete() {
|
|
4565
5059
|
const waitMs = async (ms) => await new Promise((resolve) => setTimeout(resolve, ms));
|
|
4566
5060
|
const DELAY_MS = 10;
|
|
@@ -4577,101 +5071,6 @@ ${source}`;
|
|
|
4577
5071
|
await waitMs(DELAY_MS);
|
|
4578
5072
|
}
|
|
4579
5073
|
}
|
|
4580
|
-
/**
|
|
4581
|
-
* Checks if all texture-values uniforms are renderable (i.e. loaded)
|
|
4582
|
-
* Update a texture if needed (e.g. from video)
|
|
4583
|
-
* Note: This is currently done before every draw call
|
|
4584
|
-
*/
|
|
4585
|
-
_areTexturesRenderable() {
|
|
4586
|
-
let texturesRenderable = true;
|
|
4587
|
-
for (const bindingInfo of this.shaderLayout.bindings) {
|
|
4588
|
-
if (!this.bindings[bindingInfo.name] && !this.bindings[bindingInfo.name.replace(/Uniforms$/, "")]) {
|
|
4589
|
-
import_core16.log.warn(`Binding ${bindingInfo.name} not found in ${this.id}`)();
|
|
4590
|
-
texturesRenderable = false;
|
|
4591
|
-
}
|
|
4592
|
-
}
|
|
4593
|
-
return texturesRenderable;
|
|
4594
|
-
}
|
|
4595
|
-
/** Apply any bindings (before each draw call) */
|
|
4596
|
-
_applyBindings() {
|
|
4597
|
-
if (this.linkStatus !== "success") {
|
|
4598
|
-
return;
|
|
4599
|
-
}
|
|
4600
|
-
const { gl } = this.device;
|
|
4601
|
-
gl.useProgram(this.handle);
|
|
4602
|
-
let textureUnit = 0;
|
|
4603
|
-
let uniformBufferIndex = 0;
|
|
4604
|
-
for (const binding of this.shaderLayout.bindings) {
|
|
4605
|
-
const value = this.bindings[binding.name] || this.bindings[binding.name.replace(/Uniforms$/, "")];
|
|
4606
|
-
if (!value) {
|
|
4607
|
-
throw new Error(`No value for binding ${binding.name} in ${this.id}`);
|
|
4608
|
-
}
|
|
4609
|
-
switch (binding.type) {
|
|
4610
|
-
case "uniform":
|
|
4611
|
-
const { name } = binding;
|
|
4612
|
-
const location = gl.getUniformBlockIndex(this.handle, name);
|
|
4613
|
-
if (location === 4294967295 /* INVALID_INDEX */) {
|
|
4614
|
-
throw new Error(`Invalid uniform block name ${name}`);
|
|
4615
|
-
}
|
|
4616
|
-
gl.uniformBlockBinding(this.handle, location, uniformBufferIndex);
|
|
4617
|
-
if (value instanceof WEBGLBuffer) {
|
|
4618
|
-
gl.bindBufferBase(35345 /* UNIFORM_BUFFER */, uniformBufferIndex, value.handle);
|
|
4619
|
-
} else {
|
|
4620
|
-
gl.bindBufferRange(
|
|
4621
|
-
35345 /* UNIFORM_BUFFER */,
|
|
4622
|
-
uniformBufferIndex,
|
|
4623
|
-
// @ts-expect-error
|
|
4624
|
-
value.buffer.handle,
|
|
4625
|
-
// @ts-expect-error
|
|
4626
|
-
value.offset || 0,
|
|
4627
|
-
// @ts-expect-error
|
|
4628
|
-
value.size || value.buffer.byteLength - value.offset
|
|
4629
|
-
);
|
|
4630
|
-
}
|
|
4631
|
-
uniformBufferIndex += 1;
|
|
4632
|
-
break;
|
|
4633
|
-
case "texture":
|
|
4634
|
-
if (!(value instanceof WEBGLTextureView || value instanceof WEBGLTexture || value instanceof WEBGLFramebuffer)) {
|
|
4635
|
-
throw new Error("texture");
|
|
4636
|
-
}
|
|
4637
|
-
let texture;
|
|
4638
|
-
if (value instanceof WEBGLTextureView) {
|
|
4639
|
-
texture = value.texture;
|
|
4640
|
-
} else if (value instanceof WEBGLTexture) {
|
|
4641
|
-
texture = value;
|
|
4642
|
-
} else if (value instanceof WEBGLFramebuffer && value.colorAttachments[0] instanceof WEBGLTextureView) {
|
|
4643
|
-
import_core16.log.warn(
|
|
4644
|
-
"Passing framebuffer in texture binding may be deprecated. Use fbo.colorAttachments[0] instead"
|
|
4645
|
-
)();
|
|
4646
|
-
texture = value.colorAttachments[0].texture;
|
|
4647
|
-
} else {
|
|
4648
|
-
throw new Error("No texture");
|
|
4649
|
-
}
|
|
4650
|
-
gl.activeTexture(33984 /* TEXTURE0 */ + textureUnit);
|
|
4651
|
-
gl.bindTexture(texture.glTarget, texture.handle);
|
|
4652
|
-
textureUnit += 1;
|
|
4653
|
-
break;
|
|
4654
|
-
case "sampler":
|
|
4655
|
-
break;
|
|
4656
|
-
case "storage":
|
|
4657
|
-
case "read-only-storage":
|
|
4658
|
-
throw new Error(`binding type '${binding.type}' not supported in WebGL`);
|
|
4659
|
-
}
|
|
4660
|
-
}
|
|
4661
|
-
}
|
|
4662
|
-
/**
|
|
4663
|
-
* Due to program sharing, uniforms need to be reset before every draw call
|
|
4664
|
-
* (though caching will avoid redundant WebGL calls)
|
|
4665
|
-
*/
|
|
4666
|
-
_applyUniforms() {
|
|
4667
|
-
for (const uniformLayout of this.shaderLayout.uniforms || []) {
|
|
4668
|
-
const { name, location, type, textureUnit } = uniformLayout;
|
|
4669
|
-
const value = this.uniforms[name] ?? textureUnit;
|
|
4670
|
-
if (value !== void 0) {
|
|
4671
|
-
setUniform(this.device.gl, location, type, value);
|
|
4672
|
-
}
|
|
4673
|
-
}
|
|
4674
|
-
}
|
|
4675
5074
|
};
|
|
4676
5075
|
}
|
|
4677
5076
|
});
|
|
@@ -4738,7 +5137,7 @@ ${source}`;
|
|
|
4738
5137
|
const webglBuffer = destinationBuffer;
|
|
4739
5138
|
const sourceWidth = width || framebuffer.width;
|
|
4740
5139
|
const sourceHeight = height || framebuffer.height;
|
|
4741
|
-
const colorAttachment0 = (0,
|
|
5140
|
+
const colorAttachment0 = (0, import_core19.assertDefined)(framebuffer.colorAttachments[0]);
|
|
4742
5141
|
const sourceParams = getTextureFormatWebGL(colorAttachment0.texture.props.format);
|
|
4743
5142
|
const sourceFormat = sourceParams.format;
|
|
4744
5143
|
const sourceType = sourceParams.type;
|
|
@@ -4846,7 +5245,7 @@ ${source}`;
|
|
|
4846
5245
|
}
|
|
4847
5246
|
}
|
|
4848
5247
|
function getFramebuffer(source) {
|
|
4849
|
-
if (source instanceof
|
|
5248
|
+
if (source instanceof import_core19.Texture) {
|
|
4850
5249
|
const { width, height, id } = source;
|
|
4851
5250
|
const framebuffer = source.device.createFramebuffer({
|
|
4852
5251
|
id: `framebuffer-for-${id}`,
|
|
@@ -4858,19 +5257,19 @@ ${source}`;
|
|
|
4858
5257
|
}
|
|
4859
5258
|
return { framebuffer: source, destroyFramebuffer: false };
|
|
4860
5259
|
}
|
|
4861
|
-
var
|
|
5260
|
+
var import_core19, WEBGLCommandBuffer;
|
|
4862
5261
|
var init_webgl_command_buffer = __esm({
|
|
4863
5262
|
"src/adapter/resources/webgl-command-buffer.ts"() {
|
|
4864
5263
|
"use strict";
|
|
4865
|
-
|
|
5264
|
+
import_core19 = __toESM(require_core(), 1);
|
|
4866
5265
|
init_webgl_texture();
|
|
4867
5266
|
init_webgl_texture_table();
|
|
4868
|
-
WEBGLCommandBuffer = class extends
|
|
5267
|
+
WEBGLCommandBuffer = class extends import_core19.CommandBuffer {
|
|
4869
5268
|
device;
|
|
4870
5269
|
handle = null;
|
|
4871
5270
|
commands = [];
|
|
4872
|
-
constructor(device) {
|
|
4873
|
-
super(device,
|
|
5271
|
+
constructor(device, props = {}) {
|
|
5272
|
+
super(device, props);
|
|
4874
5273
|
this.device = device;
|
|
4875
5274
|
}
|
|
4876
5275
|
_executeCommands(commands = this.commands) {
|
|
@@ -4898,15 +5297,15 @@ ${source}`;
|
|
|
4898
5297
|
});
|
|
4899
5298
|
|
|
4900
5299
|
// src/adapter/resources/webgl-render-pass.ts
|
|
4901
|
-
var
|
|
5300
|
+
var import_core20, COLOR_CHANNELS, WEBGLRenderPass;
|
|
4902
5301
|
var init_webgl_render_pass = __esm({
|
|
4903
5302
|
"src/adapter/resources/webgl-render-pass.ts"() {
|
|
4904
5303
|
"use strict";
|
|
4905
|
-
|
|
5304
|
+
import_core20 = __toESM(require_core(), 1);
|
|
4906
5305
|
init_with_parameters();
|
|
4907
5306
|
init_unified_parameter_api();
|
|
4908
5307
|
COLOR_CHANNELS = [1, 2, 4, 8];
|
|
4909
|
-
WEBGLRenderPass = class extends
|
|
5308
|
+
WEBGLRenderPass = class extends import_core20.RenderPass {
|
|
4910
5309
|
device;
|
|
4911
5310
|
handle = null;
|
|
4912
5311
|
/** Parameters that should be applied before each draw call */
|
|
@@ -4939,9 +5338,21 @@ ${source}`;
|
|
|
4939
5338
|
this.device.gl.drawBuffers([1029 /* BACK */]);
|
|
4940
5339
|
}
|
|
4941
5340
|
this.clear();
|
|
5341
|
+
if (this.props.timestampQuerySet && this.props.beginTimestampIndex !== void 0) {
|
|
5342
|
+
const webglQuerySet = this.props.timestampQuerySet;
|
|
5343
|
+
webglQuerySet.writeTimestamp(this.props.beginTimestampIndex);
|
|
5344
|
+
}
|
|
4942
5345
|
}
|
|
4943
5346
|
end() {
|
|
5347
|
+
if (this.destroyed) {
|
|
5348
|
+
return;
|
|
5349
|
+
}
|
|
5350
|
+
if (this.props.timestampQuerySet && this.props.endTimestampIndex !== void 0) {
|
|
5351
|
+
const webglQuerySet = this.props.timestampQuerySet;
|
|
5352
|
+
webglQuerySet.writeTimestamp(this.props.endTimestampIndex);
|
|
5353
|
+
}
|
|
4944
5354
|
this.device.popState();
|
|
5355
|
+
this.destroy();
|
|
4945
5356
|
}
|
|
4946
5357
|
pushDebugGroup(groupLabel) {
|
|
4947
5358
|
}
|
|
@@ -5083,31 +5494,39 @@ ${source}`;
|
|
|
5083
5494
|
});
|
|
5084
5495
|
|
|
5085
5496
|
// src/adapter/resources/webgl-command-encoder.ts
|
|
5086
|
-
var
|
|
5497
|
+
var import_core21, WEBGLCommandEncoder;
|
|
5087
5498
|
var init_webgl_command_encoder = __esm({
|
|
5088
5499
|
"src/adapter/resources/webgl-command-encoder.ts"() {
|
|
5089
5500
|
"use strict";
|
|
5090
|
-
|
|
5501
|
+
import_core21 = __toESM(require_core(), 1);
|
|
5091
5502
|
init_webgl_command_buffer();
|
|
5092
5503
|
init_webgl_render_pass();
|
|
5093
|
-
WEBGLCommandEncoder = class extends
|
|
5504
|
+
WEBGLCommandEncoder = class extends import_core21.CommandEncoder {
|
|
5094
5505
|
device;
|
|
5095
5506
|
handle = null;
|
|
5096
5507
|
commandBuffer;
|
|
5097
5508
|
constructor(device, props) {
|
|
5098
5509
|
super(device, props);
|
|
5099
5510
|
this.device = device;
|
|
5100
|
-
this.commandBuffer = new WEBGLCommandBuffer(device
|
|
5511
|
+
this.commandBuffer = new WEBGLCommandBuffer(device, {
|
|
5512
|
+
id: `${this.props.id}-command-buffer`
|
|
5513
|
+
});
|
|
5101
5514
|
}
|
|
5102
5515
|
destroy() {
|
|
5516
|
+
this.destroyResource();
|
|
5103
5517
|
}
|
|
5104
|
-
finish() {
|
|
5518
|
+
finish(props) {
|
|
5519
|
+
if (props?.id && this.commandBuffer.id !== props.id) {
|
|
5520
|
+
this.commandBuffer.id = props.id;
|
|
5521
|
+
this.commandBuffer.props.id = props.id;
|
|
5522
|
+
}
|
|
5523
|
+
this.destroy();
|
|
5105
5524
|
return this.commandBuffer;
|
|
5106
5525
|
}
|
|
5107
|
-
beginRenderPass(props) {
|
|
5108
|
-
return new WEBGLRenderPass(this.device, props);
|
|
5526
|
+
beginRenderPass(props = {}) {
|
|
5527
|
+
return new WEBGLRenderPass(this.device, this._applyTimeProfilingToPassProps(props));
|
|
5109
5528
|
}
|
|
5110
|
-
beginComputePass(props) {
|
|
5529
|
+
beginComputePass(props = {}) {
|
|
5111
5530
|
throw new Error("ComputePass not supported in WebGL");
|
|
5112
5531
|
}
|
|
5113
5532
|
copyBufferToBuffer(options) {
|
|
@@ -5133,6 +5552,10 @@ ${source}`;
|
|
|
5133
5552
|
}
|
|
5134
5553
|
resolveQuerySet(querySet, destination, options) {
|
|
5135
5554
|
}
|
|
5555
|
+
writeTimestamp(querySet, queryIndex) {
|
|
5556
|
+
const webglQuerySet = querySet;
|
|
5557
|
+
webglQuerySet.writeTimestamp(queryIndex);
|
|
5558
|
+
}
|
|
5136
5559
|
};
|
|
5137
5560
|
}
|
|
5138
5561
|
});
|
|
@@ -5181,15 +5604,15 @@ ${source}`;
|
|
|
5181
5604
|
}
|
|
5182
5605
|
return true;
|
|
5183
5606
|
}
|
|
5184
|
-
var
|
|
5607
|
+
var import_core22, WEBGLVertexArray;
|
|
5185
5608
|
var init_webgl_vertex_array = __esm({
|
|
5186
5609
|
"src/adapter/resources/webgl-vertex-array.ts"() {
|
|
5187
5610
|
"use strict";
|
|
5188
|
-
|
|
5611
|
+
import_core22 = __toESM(require_core(), 1);
|
|
5189
5612
|
init_dist();
|
|
5190
5613
|
init_webgl_vertex_formats();
|
|
5191
5614
|
init_fill_array();
|
|
5192
|
-
WEBGLVertexArray = class extends
|
|
5615
|
+
WEBGLVertexArray = class extends import_core22.VertexArray {
|
|
5193
5616
|
get [Symbol.toStringTag]() {
|
|
5194
5617
|
return "VertexArray";
|
|
5195
5618
|
}
|
|
@@ -5357,7 +5780,7 @@ ${source}`;
|
|
|
5357
5780
|
this.buffer = this.buffer || this.device.createBuffer({ byteLength });
|
|
5358
5781
|
updateNeeded ||= !compareConstantArrayValues(constantValue, this.bufferValue);
|
|
5359
5782
|
if (updateNeeded) {
|
|
5360
|
-
const typedArray = (0,
|
|
5783
|
+
const typedArray = (0, import_core22.getScratchArray)(value.constructor, length);
|
|
5361
5784
|
fillArray({ target: typedArray, source: constantValue, start: 0, count: length });
|
|
5362
5785
|
this.buffer.write(typedArray);
|
|
5363
5786
|
this.bufferValue = value;
|
|
@@ -5375,14 +5798,14 @@ ${source}`;
|
|
|
5375
5798
|
}
|
|
5376
5799
|
return /^\d+$/.test(value);
|
|
5377
5800
|
}
|
|
5378
|
-
var
|
|
5801
|
+
var import_core23, WEBGLTransformFeedback;
|
|
5379
5802
|
var init_webgl_transform_feedback = __esm({
|
|
5380
5803
|
"src/adapter/resources/webgl-transform-feedback.ts"() {
|
|
5381
5804
|
"use strict";
|
|
5382
|
-
|
|
5805
|
+
import_core23 = __toESM(require_core(), 1);
|
|
5383
5806
|
init_src2();
|
|
5384
5807
|
init_webgl_topology_utils();
|
|
5385
|
-
WEBGLTransformFeedback = class extends
|
|
5808
|
+
WEBGLTransformFeedback = class extends import_core23.TransformFeedback {
|
|
5386
5809
|
device;
|
|
5387
5810
|
gl;
|
|
5388
5811
|
handle;
|
|
@@ -5445,7 +5868,7 @@ ${source}`;
|
|
|
5445
5868
|
const { buffer, byteLength, byteOffset } = this._getBufferRange(bufferOrRange);
|
|
5446
5869
|
if (location < 0) {
|
|
5447
5870
|
this.unusedBuffers[locationOrName] = buffer;
|
|
5448
|
-
|
|
5871
|
+
import_core23.log.warn(`${this.id} unusedBuffers varying buffer ${locationOrName}`)();
|
|
5449
5872
|
return;
|
|
5450
5873
|
}
|
|
5451
5874
|
this.buffers[location] = { buffer, byteLength, byteOffset };
|
|
@@ -5528,156 +5951,249 @@ ${source}`;
|
|
|
5528
5951
|
});
|
|
5529
5952
|
|
|
5530
5953
|
// src/adapter/resources/webgl-query-set.ts
|
|
5531
|
-
var
|
|
5954
|
+
var import_core24, WEBGLQuerySet;
|
|
5532
5955
|
var init_webgl_query_set = __esm({
|
|
5533
5956
|
"src/adapter/resources/webgl-query-set.ts"() {
|
|
5534
5957
|
"use strict";
|
|
5535
|
-
|
|
5536
|
-
WEBGLQuerySet = class extends
|
|
5958
|
+
import_core24 = __toESM(require_core(), 1);
|
|
5959
|
+
WEBGLQuerySet = class extends import_core24.QuerySet {
|
|
5537
5960
|
device;
|
|
5538
5961
|
handle;
|
|
5539
|
-
|
|
5540
|
-
|
|
5541
|
-
|
|
5962
|
+
_timestampPairs = [];
|
|
5963
|
+
_occlusionQuery = null;
|
|
5964
|
+
_occlusionActive = false;
|
|
5542
5965
|
get [Symbol.toStringTag]() {
|
|
5543
|
-
return "
|
|
5966
|
+
return "QuerySet";
|
|
5544
5967
|
}
|
|
5545
|
-
// Create a query class
|
|
5546
5968
|
constructor(device, props) {
|
|
5547
5969
|
super(device, props);
|
|
5548
5970
|
this.device = device;
|
|
5549
|
-
if (props.
|
|
5550
|
-
|
|
5551
|
-
|
|
5552
|
-
|
|
5553
|
-
|
|
5554
|
-
|
|
5971
|
+
if (props.type === "timestamp") {
|
|
5972
|
+
if (props.count < 2) {
|
|
5973
|
+
throw new Error("Timestamp QuerySet requires at least two query slots");
|
|
5974
|
+
}
|
|
5975
|
+
this._timestampPairs = new Array(Math.ceil(props.count / 2)).fill(null).map(() => ({ activeQuery: null, completedQueries: [] }));
|
|
5976
|
+
this.handle = null;
|
|
5977
|
+
} else {
|
|
5978
|
+
if (props.count > 1) {
|
|
5979
|
+
throw new Error("WebGL occlusion QuerySet can only have one value");
|
|
5980
|
+
}
|
|
5981
|
+
const handle = this.device.gl.createQuery();
|
|
5982
|
+
if (!handle) {
|
|
5983
|
+
throw new Error("WebGL query not supported");
|
|
5984
|
+
}
|
|
5985
|
+
this.handle = handle;
|
|
5555
5986
|
}
|
|
5556
|
-
this.handle = handle;
|
|
5557
5987
|
Object.seal(this);
|
|
5558
5988
|
}
|
|
5559
5989
|
destroy() {
|
|
5560
|
-
|
|
5990
|
+
if (this.destroyed) {
|
|
5991
|
+
return;
|
|
5992
|
+
}
|
|
5993
|
+
if (this.handle) {
|
|
5994
|
+
this.device.gl.deleteQuery(this.handle);
|
|
5995
|
+
}
|
|
5996
|
+
for (const pair of this._timestampPairs) {
|
|
5997
|
+
if (pair.activeQuery) {
|
|
5998
|
+
this.device.gl.deleteQuery(pair.activeQuery.handle);
|
|
5999
|
+
}
|
|
6000
|
+
for (const query of pair.completedQueries) {
|
|
6001
|
+
this.device.gl.deleteQuery(query.handle);
|
|
6002
|
+
}
|
|
6003
|
+
}
|
|
6004
|
+
if (this._occlusionQuery) {
|
|
6005
|
+
this.device.gl.deleteQuery(this._occlusionQuery.handle);
|
|
6006
|
+
}
|
|
6007
|
+
this.destroyResource();
|
|
5561
6008
|
}
|
|
5562
|
-
|
|
5563
|
-
|
|
5564
|
-
|
|
5565
|
-
|
|
5566
|
-
|
|
5567
|
-
|
|
5568
|
-
|
|
5569
|
-
|
|
6009
|
+
isResultAvailable(queryIndex) {
|
|
6010
|
+
if (this.props.type === "timestamp") {
|
|
6011
|
+
if (queryIndex === void 0) {
|
|
6012
|
+
return this._timestampPairs.some(
|
|
6013
|
+
(_, pairIndex) => this._isTimestampPairAvailable(pairIndex)
|
|
6014
|
+
);
|
|
6015
|
+
}
|
|
6016
|
+
return this._isTimestampPairAvailable(this._getTimestampPairIndex(queryIndex));
|
|
6017
|
+
}
|
|
6018
|
+
if (!this._occlusionQuery) {
|
|
6019
|
+
return false;
|
|
6020
|
+
}
|
|
6021
|
+
return this._pollQueryAvailability(this._occlusionQuery);
|
|
6022
|
+
}
|
|
6023
|
+
async readResults(options) {
|
|
6024
|
+
const firstQuery = options?.firstQuery || 0;
|
|
6025
|
+
const queryCount = options?.queryCount || this.props.count - firstQuery;
|
|
6026
|
+
this._validateRange(firstQuery, queryCount);
|
|
6027
|
+
if (this.props.type === "timestamp") {
|
|
6028
|
+
const results = new Array(queryCount).fill(0n);
|
|
6029
|
+
const startPairIndex = Math.floor(firstQuery / 2);
|
|
6030
|
+
const endPairIndex = Math.floor((firstQuery + queryCount - 1) / 2);
|
|
6031
|
+
for (let pairIndex = startPairIndex; pairIndex <= endPairIndex; pairIndex++) {
|
|
6032
|
+
const duration = await this._consumeTimestampPairResult(pairIndex);
|
|
6033
|
+
const beginSlot = pairIndex * 2;
|
|
6034
|
+
const endSlot = beginSlot + 1;
|
|
6035
|
+
if (beginSlot >= firstQuery && beginSlot < firstQuery + queryCount) {
|
|
6036
|
+
results[beginSlot - firstQuery] = 0n;
|
|
6037
|
+
}
|
|
6038
|
+
if (endSlot >= firstQuery && endSlot < firstQuery + queryCount) {
|
|
6039
|
+
results[endSlot - firstQuery] = duration;
|
|
6040
|
+
}
|
|
6041
|
+
}
|
|
6042
|
+
return results;
|
|
6043
|
+
}
|
|
6044
|
+
if (!this._occlusionQuery) {
|
|
6045
|
+
throw new Error("Occlusion query has not been started");
|
|
6046
|
+
}
|
|
6047
|
+
return [await this._consumeQueryResult(this._occlusionQuery)];
|
|
5570
6048
|
}
|
|
5571
|
-
|
|
5572
|
-
this.
|
|
6049
|
+
async readTimestampDuration(beginIndex, endIndex) {
|
|
6050
|
+
if (this.props.type !== "timestamp") {
|
|
6051
|
+
throw new Error("Timestamp durations require a timestamp QuerySet");
|
|
6052
|
+
}
|
|
6053
|
+
if (beginIndex < 0 || endIndex >= this.props.count || endIndex <= beginIndex) {
|
|
6054
|
+
throw new Error("Timestamp duration range is out of bounds");
|
|
6055
|
+
}
|
|
6056
|
+
if (beginIndex % 2 !== 0 || endIndex !== beginIndex + 1) {
|
|
6057
|
+
throw new Error("WebGL timestamp durations require adjacent even/odd query indices");
|
|
6058
|
+
}
|
|
6059
|
+
const result = await this._consumeTimestampPairResult(this._getTimestampPairIndex(beginIndex));
|
|
6060
|
+
return Number(result) / 1e6;
|
|
5573
6061
|
}
|
|
5574
|
-
|
|
5575
|
-
|
|
5576
|
-
|
|
5577
|
-
|
|
5578
|
-
)
|
|
6062
|
+
beginOcclusionQuery() {
|
|
6063
|
+
if (this.props.type !== "occlusion") {
|
|
6064
|
+
throw new Error("Occlusion queries require an occlusion QuerySet");
|
|
6065
|
+
}
|
|
6066
|
+
if (!this.handle) {
|
|
6067
|
+
throw new Error("WebGL occlusion query is not available");
|
|
6068
|
+
}
|
|
6069
|
+
if (this._occlusionActive) {
|
|
6070
|
+
throw new Error("Occlusion query is already active");
|
|
6071
|
+
}
|
|
6072
|
+
this.device.gl.beginQuery(35887 /* ANY_SAMPLES_PASSED */, this.handle);
|
|
6073
|
+
this._occlusionQuery = {
|
|
6074
|
+
handle: this.handle,
|
|
6075
|
+
promise: null,
|
|
6076
|
+
result: null,
|
|
6077
|
+
disjoint: false
|
|
6078
|
+
};
|
|
6079
|
+
this._occlusionActive = true;
|
|
5579
6080
|
}
|
|
5580
6081
|
endOcclusionQuery() {
|
|
5581
|
-
this.
|
|
5582
|
-
|
|
5583
|
-
|
|
5584
|
-
|
|
5585
|
-
|
|
5586
|
-
}
|
|
5587
|
-
endTransformFeedbackQuery() {
|
|
5588
|
-
this._end();
|
|
5589
|
-
}
|
|
5590
|
-
async resolveQuery() {
|
|
5591
|
-
const value = await this.pollQuery();
|
|
5592
|
-
return [value];
|
|
6082
|
+
if (!this._occlusionActive) {
|
|
6083
|
+
throw new Error("Occlusion query is not active");
|
|
6084
|
+
}
|
|
6085
|
+
this.device.gl.endQuery(35887 /* ANY_SAMPLES_PASSED */);
|
|
6086
|
+
this._occlusionActive = false;
|
|
5593
6087
|
}
|
|
5594
|
-
|
|
5595
|
-
|
|
5596
|
-
|
|
5597
|
-
|
|
5598
|
-
|
|
5599
|
-
|
|
5600
|
-
|
|
5601
|
-
|
|
5602
|
-
|
|
5603
|
-
|
|
6088
|
+
writeTimestamp(queryIndex) {
|
|
6089
|
+
if (this.props.type !== "timestamp") {
|
|
6090
|
+
throw new Error("Timestamp writes require a timestamp QuerySet");
|
|
6091
|
+
}
|
|
6092
|
+
const pairIndex = this._getTimestampPairIndex(queryIndex);
|
|
6093
|
+
const pair = this._timestampPairs[pairIndex];
|
|
6094
|
+
if (queryIndex % 2 === 0) {
|
|
6095
|
+
if (pair.activeQuery) {
|
|
6096
|
+
throw new Error("Timestamp query pair is already active");
|
|
6097
|
+
}
|
|
6098
|
+
const handle = this.device.gl.createQuery();
|
|
6099
|
+
if (!handle) {
|
|
6100
|
+
throw new Error("WebGL query not supported");
|
|
6101
|
+
}
|
|
6102
|
+
const query = {
|
|
6103
|
+
handle,
|
|
6104
|
+
promise: null,
|
|
6105
|
+
result: null,
|
|
6106
|
+
disjoint: false
|
|
6107
|
+
};
|
|
6108
|
+
this.device.gl.beginQuery(35007 /* TIME_ELAPSED_EXT */, handle);
|
|
6109
|
+
pair.activeQuery = query;
|
|
5604
6110
|
return;
|
|
5605
6111
|
}
|
|
5606
|
-
|
|
5607
|
-
|
|
5608
|
-
|
|
6112
|
+
if (!pair.activeQuery) {
|
|
6113
|
+
throw new Error("Timestamp query pair was ended before it was started");
|
|
6114
|
+
}
|
|
6115
|
+
this.device.gl.endQuery(35007 /* TIME_ELAPSED_EXT */);
|
|
6116
|
+
pair.completedQueries.push(pair.activeQuery);
|
|
6117
|
+
pair.activeQuery = null;
|
|
5609
6118
|
}
|
|
5610
|
-
|
|
5611
|
-
|
|
5612
|
-
|
|
5613
|
-
return;
|
|
6119
|
+
_validateRange(firstQuery, queryCount) {
|
|
6120
|
+
if (firstQuery < 0 || queryCount < 0 || firstQuery + queryCount > this.props.count) {
|
|
6121
|
+
throw new Error("Query read range is out of bounds");
|
|
5614
6122
|
}
|
|
5615
|
-
|
|
5616
|
-
|
|
5617
|
-
|
|
5618
|
-
|
|
6123
|
+
}
|
|
6124
|
+
_getTimestampPairIndex(queryIndex) {
|
|
6125
|
+
if (queryIndex < 0 || queryIndex >= this.props.count) {
|
|
6126
|
+
throw new Error("Query index is out of bounds");
|
|
5619
6127
|
}
|
|
5620
|
-
return;
|
|
6128
|
+
return Math.floor(queryIndex / 2);
|
|
5621
6129
|
}
|
|
5622
|
-
|
|
5623
|
-
|
|
5624
|
-
if (!
|
|
6130
|
+
_isTimestampPairAvailable(pairIndex) {
|
|
6131
|
+
const pair = this._timestampPairs[pairIndex];
|
|
6132
|
+
if (!pair || pair.completedQueries.length === 0) {
|
|
5625
6133
|
return false;
|
|
5626
6134
|
}
|
|
6135
|
+
return this._pollQueryAvailability(pair.completedQueries[0]);
|
|
6136
|
+
}
|
|
6137
|
+
_pollQueryAvailability(query) {
|
|
6138
|
+
if (query.result !== null || query.disjoint) {
|
|
6139
|
+
return true;
|
|
6140
|
+
}
|
|
5627
6141
|
const resultAvailable = this.device.gl.getQueryParameter(
|
|
5628
|
-
|
|
6142
|
+
query.handle,
|
|
5629
6143
|
34919 /* QUERY_RESULT_AVAILABLE */
|
|
5630
6144
|
);
|
|
5631
|
-
if (resultAvailable) {
|
|
5632
|
-
|
|
6145
|
+
if (!resultAvailable) {
|
|
6146
|
+
return false;
|
|
5633
6147
|
}
|
|
5634
|
-
|
|
5635
|
-
|
|
5636
|
-
|
|
5637
|
-
|
|
5638
|
-
return this.device.gl.getParameter(36795 /* GPU_DISJOINT_EXT */);
|
|
5639
|
-
}
|
|
5640
|
-
// Returns query result.
|
|
5641
|
-
getResult() {
|
|
5642
|
-
return this.device.gl.getQueryParameter(this.handle, 34918 /* QUERY_RESULT */);
|
|
6148
|
+
const isDisjoint = Boolean(this.device.gl.getParameter(36795 /* GPU_DISJOINT_EXT */));
|
|
6149
|
+
query.disjoint = isDisjoint;
|
|
6150
|
+
query.result = isDisjoint ? 0n : BigInt(this.device.gl.getQueryParameter(query.handle, 34918 /* QUERY_RESULT */));
|
|
6151
|
+
return true;
|
|
5643
6152
|
}
|
|
5644
|
-
|
|
5645
|
-
|
|
5646
|
-
|
|
6153
|
+
async _consumeTimestampPairResult(pairIndex) {
|
|
6154
|
+
const pair = this._timestampPairs[pairIndex];
|
|
6155
|
+
if (!pair || pair.completedQueries.length === 0) {
|
|
6156
|
+
throw new Error("Timestamp query pair has no completed result");
|
|
6157
|
+
}
|
|
6158
|
+
const query = pair.completedQueries.shift();
|
|
6159
|
+
try {
|
|
6160
|
+
return await this._consumeQueryResult(query);
|
|
6161
|
+
} finally {
|
|
6162
|
+
this.device.gl.deleteQuery(query.handle);
|
|
6163
|
+
}
|
|
5647
6164
|
}
|
|
5648
|
-
|
|
5649
|
-
|
|
5650
|
-
|
|
5651
|
-
return this._pollingPromise;
|
|
6165
|
+
_consumeQueryResult(query) {
|
|
6166
|
+
if (query.promise) {
|
|
6167
|
+
return query.promise;
|
|
5652
6168
|
}
|
|
5653
|
-
|
|
5654
|
-
this._pollingPromise = new Promise((resolve, reject) => {
|
|
6169
|
+
query.promise = new Promise((resolve, reject) => {
|
|
5655
6170
|
const poll = () => {
|
|
5656
|
-
if (this.
|
|
5657
|
-
resolve(this.getResult());
|
|
5658
|
-
this._pollingPromise = null;
|
|
5659
|
-
} else if (counter++ > limit) {
|
|
5660
|
-
reject("Timed out");
|
|
5661
|
-
this._pollingPromise = null;
|
|
5662
|
-
} else {
|
|
6171
|
+
if (!this._pollQueryAvailability(query)) {
|
|
5663
6172
|
requestAnimationFrame(poll);
|
|
6173
|
+
return;
|
|
6174
|
+
}
|
|
6175
|
+
query.promise = null;
|
|
6176
|
+
if (query.disjoint) {
|
|
6177
|
+
reject(new Error("GPU timestamp query was invalidated by a disjoint event"));
|
|
6178
|
+
} else {
|
|
6179
|
+
resolve(query.result || 0n);
|
|
5664
6180
|
}
|
|
5665
6181
|
};
|
|
5666
|
-
|
|
6182
|
+
poll();
|
|
5667
6183
|
});
|
|
5668
|
-
return
|
|
6184
|
+
return query.promise;
|
|
5669
6185
|
}
|
|
5670
6186
|
};
|
|
5671
6187
|
}
|
|
5672
6188
|
});
|
|
5673
6189
|
|
|
5674
6190
|
// src/adapter/resources/webgl-fence.ts
|
|
5675
|
-
var
|
|
6191
|
+
var import_core25, WEBGLFence;
|
|
5676
6192
|
var init_webgl_fence = __esm({
|
|
5677
6193
|
"src/adapter/resources/webgl-fence.ts"() {
|
|
5678
6194
|
"use strict";
|
|
5679
|
-
|
|
5680
|
-
WEBGLFence = class extends
|
|
6195
|
+
import_core25 = __toESM(require_core(), 1);
|
|
6196
|
+
WEBGLFence = class extends import_core25.Fence {
|
|
5681
6197
|
device;
|
|
5682
6198
|
gl;
|
|
5683
6199
|
handle;
|
|
@@ -5797,7 +6313,7 @@ ${source}`;
|
|
|
5797
6313
|
sourceFormat ||= texture?.glFormat || 6408 /* RGBA */;
|
|
5798
6314
|
sourceType ||= texture?.glType || 5121 /* UNSIGNED_BYTE */;
|
|
5799
6315
|
target2 = getPixelArray(target2, sourceType, sourceFormat, sourceWidth, sourceHeight, sourceDepth);
|
|
5800
|
-
const signedType = (0,
|
|
6316
|
+
const signedType = (0, import_core26.getDataType)(target2);
|
|
5801
6317
|
sourceType = sourceType || convertDataTypeToGLDataType(signedType);
|
|
5802
6318
|
const prevHandle = gl.bindFramebuffer(
|
|
5803
6319
|
36160 /* FRAMEBUFFER */,
|
|
@@ -5849,7 +6365,7 @@ ${source}`;
|
|
|
5849
6365
|
return webglBufferTarget;
|
|
5850
6366
|
}
|
|
5851
6367
|
function getFramebuffer2(source) {
|
|
5852
|
-
if (!(source instanceof
|
|
6368
|
+
if (!(source instanceof import_core26.Framebuffer)) {
|
|
5853
6369
|
return { framebuffer: toFramebuffer(source), deleteFramebuffer: true };
|
|
5854
6370
|
}
|
|
5855
6371
|
return { framebuffer: source, deleteFramebuffer: false };
|
|
@@ -5871,15 +6387,15 @@ ${source}`;
|
|
|
5871
6387
|
}
|
|
5872
6388
|
glType ||= 5121 /* UNSIGNED_BYTE */;
|
|
5873
6389
|
const shaderType = convertGLDataTypeToDataType(glType);
|
|
5874
|
-
const ArrayType = (0,
|
|
6390
|
+
const ArrayType = (0, import_core26.getTypedArrayConstructor)(shaderType);
|
|
5875
6391
|
const components = glFormatToComponents(glFormat);
|
|
5876
6392
|
return new ArrayType(width * height * components);
|
|
5877
6393
|
}
|
|
5878
|
-
var
|
|
6394
|
+
var import_core26;
|
|
5879
6395
|
var init_webgl_texture_utils = __esm({
|
|
5880
6396
|
"src/adapter/helpers/webgl-texture-utils.ts"() {
|
|
5881
6397
|
"use strict";
|
|
5882
|
-
|
|
6398
|
+
import_core26 = __toESM(require_core(), 1);
|
|
5883
6399
|
init_webgl_shadertypes();
|
|
5884
6400
|
init_format_utils();
|
|
5885
6401
|
init_shader_formats();
|
|
@@ -5925,11 +6441,11 @@ ${source}`;
|
|
|
5925
6441
|
}
|
|
5926
6442
|
return true;
|
|
5927
6443
|
}
|
|
5928
|
-
var
|
|
6444
|
+
var import_core27, WebGLDevice;
|
|
5929
6445
|
var init_webgl_device = __esm({
|
|
5930
6446
|
"src/adapter/webgl-device.ts"() {
|
|
5931
6447
|
"use strict";
|
|
5932
|
-
|
|
6448
|
+
import_core27 = __toESM(require_core(), 1);
|
|
5933
6449
|
init_webgl_state_tracker();
|
|
5934
6450
|
init_create_browser_context();
|
|
5935
6451
|
init_webgl_context_data();
|
|
@@ -5937,6 +6453,7 @@ ${source}`;
|
|
|
5937
6453
|
init_webgl_device_features();
|
|
5938
6454
|
init_webgl_device_limits();
|
|
5939
6455
|
init_webgl_canvas_context();
|
|
6456
|
+
init_webgl_presentation_context();
|
|
5940
6457
|
init_spector();
|
|
5941
6458
|
init_webgl_developer_tools();
|
|
5942
6459
|
init_webgl_texture_table();
|
|
@@ -5947,6 +6464,7 @@ ${source}`;
|
|
|
5947
6464
|
init_webgl_texture();
|
|
5948
6465
|
init_webgl_framebuffer();
|
|
5949
6466
|
init_webgl_render_pipeline();
|
|
6467
|
+
init_webgl_shared_render_pipeline();
|
|
5950
6468
|
init_webgl_command_encoder();
|
|
5951
6469
|
init_webgl_vertex_array();
|
|
5952
6470
|
init_webgl_transform_feedback();
|
|
@@ -5956,7 +6474,7 @@ ${source}`;
|
|
|
5956
6474
|
init_unified_parameter_api();
|
|
5957
6475
|
init_with_parameters();
|
|
5958
6476
|
init_webgl_extensions();
|
|
5959
|
-
WebGLDevice = class extends
|
|
6477
|
+
WebGLDevice = class extends import_core27.Device {
|
|
5960
6478
|
static getDeviceFromContext(gl) {
|
|
5961
6479
|
if (!gl) {
|
|
5962
6480
|
return null;
|
|
@@ -6007,7 +6525,7 @@ ${source}`;
|
|
|
6007
6525
|
}
|
|
6008
6526
|
constructor(props) {
|
|
6009
6527
|
super({ ...props, id: props.id || uid("webgl-device") });
|
|
6010
|
-
const canvasContextProps =
|
|
6528
|
+
const canvasContextProps = import_core27.Device._getCanvasContextProps(props);
|
|
6011
6529
|
if (!canvasContextProps) {
|
|
6012
6530
|
throw new Error("WebGLDevice requires props.createCanvasContext to be set");
|
|
6013
6531
|
}
|
|
@@ -6049,7 +6567,7 @@ ${source}`;
|
|
|
6049
6567
|
device = WebGLDevice.getDeviceFromContext(gl);
|
|
6050
6568
|
if (device) {
|
|
6051
6569
|
if (props._reuseDevices) {
|
|
6052
|
-
|
|
6570
|
+
import_core27.log.log(
|
|
6053
6571
|
1,
|
|
6054
6572
|
`Not creating a new Device, instead returning a reference to Device ${device.id} already attached to WebGL context`,
|
|
6055
6573
|
device
|
|
@@ -6073,17 +6591,18 @@ ${source}`;
|
|
|
6073
6591
|
this.features.initializeFeatures();
|
|
6074
6592
|
}
|
|
6075
6593
|
const glState = new WebGLStateTracker(this.gl, {
|
|
6076
|
-
log: (...args) =>
|
|
6594
|
+
log: (...args) => import_core27.log.log(1, ...args)()
|
|
6077
6595
|
});
|
|
6078
6596
|
glState.trackState(this.gl, { copyState: false });
|
|
6079
6597
|
if (props.debug || props.debugWebGL) {
|
|
6080
6598
|
this.gl = makeDebugContext(this.gl, { debugWebGL: true, traceWebGL: props.debugWebGL });
|
|
6081
|
-
|
|
6599
|
+
import_core27.log.warn("WebGL debug mode activated. Performance reduced.")();
|
|
6082
6600
|
}
|
|
6083
6601
|
if (props.debugWebGL) {
|
|
6084
|
-
|
|
6602
|
+
import_core27.log.level = Math.max(import_core27.log.level, 1);
|
|
6085
6603
|
}
|
|
6086
6604
|
this.commandEncoder = new WEBGLCommandEncoder(this, { id: `${this}-command-encoder` });
|
|
6605
|
+
this.canvasContext._startObservers();
|
|
6087
6606
|
}
|
|
6088
6607
|
/**
|
|
6089
6608
|
* Destroys the device
|
|
@@ -6096,6 +6615,7 @@ ${source}`;
|
|
|
6096
6615
|
* browser API for destroying WebGL contexts.
|
|
6097
6616
|
*/
|
|
6098
6617
|
destroy() {
|
|
6618
|
+
this.commandEncoder?.destroy();
|
|
6099
6619
|
if (!this.props._reuseDevices && !this._reused) {
|
|
6100
6620
|
const contextData = getWebGLContextData(this.handle);
|
|
6101
6621
|
contextData.device = null;
|
|
@@ -6108,6 +6628,9 @@ ${source}`;
|
|
|
6108
6628
|
createCanvasContext(props) {
|
|
6109
6629
|
throw new Error("WebGL only supports a single canvas");
|
|
6110
6630
|
}
|
|
6631
|
+
createPresentationContext(props) {
|
|
6632
|
+
return new WebGLPresentationContext(this, props || {});
|
|
6633
|
+
}
|
|
6111
6634
|
createBuffer(props) {
|
|
6112
6635
|
const newProps = this._normalizeBufferProps(props);
|
|
6113
6636
|
return new WEBGLBuffer(this, newProps);
|
|
@@ -6142,6 +6665,12 @@ ${source}`;
|
|
|
6142
6665
|
createRenderPipeline(props) {
|
|
6143
6666
|
return new WEBGLRenderPipeline(this, props);
|
|
6144
6667
|
}
|
|
6668
|
+
_createSharedRenderPipelineWebGL(props) {
|
|
6669
|
+
return new WEBGLSharedRenderPipeline(
|
|
6670
|
+
this,
|
|
6671
|
+
props
|
|
6672
|
+
);
|
|
6673
|
+
}
|
|
6145
6674
|
createComputePipeline(props) {
|
|
6146
6675
|
throw new Error("ComputePipeline not supported in WebGL");
|
|
6147
6676
|
}
|
|
@@ -6154,12 +6683,27 @@ ${source}`;
|
|
|
6154
6683
|
* Chrome's offscreen canvas does not require gl.commit
|
|
6155
6684
|
*/
|
|
6156
6685
|
submit(commandBuffer) {
|
|
6686
|
+
let submittedCommandEncoder = null;
|
|
6157
6687
|
if (!commandBuffer) {
|
|
6158
|
-
|
|
6688
|
+
submittedCommandEncoder = this.commandEncoder;
|
|
6689
|
+
commandBuffer = submittedCommandEncoder.finish();
|
|
6159
6690
|
this.commandEncoder.destroy();
|
|
6160
|
-
this.commandEncoder = this.createCommandEncoder({
|
|
6691
|
+
this.commandEncoder = this.createCommandEncoder({
|
|
6692
|
+
id: submittedCommandEncoder.props.id,
|
|
6693
|
+
timeProfilingQuerySet: submittedCommandEncoder.getTimeProfilingQuerySet()
|
|
6694
|
+
});
|
|
6695
|
+
}
|
|
6696
|
+
try {
|
|
6697
|
+
commandBuffer._executeCommands();
|
|
6698
|
+
if (submittedCommandEncoder) {
|
|
6699
|
+
submittedCommandEncoder.resolveTimeProfilingQuerySet().then(() => {
|
|
6700
|
+
this.commandEncoder._gpuTimeMs = submittedCommandEncoder._gpuTimeMs;
|
|
6701
|
+
}).catch(() => {
|
|
6702
|
+
});
|
|
6703
|
+
}
|
|
6704
|
+
} finally {
|
|
6705
|
+
commandBuffer.destroy();
|
|
6161
6706
|
}
|
|
6162
|
-
commandBuffer._executeCommands();
|
|
6163
6707
|
}
|
|
6164
6708
|
//
|
|
6165
6709
|
// TEMPORARY HACKS - will be removed in v9.1
|
|
@@ -6182,7 +6726,7 @@ ${source}`;
|
|
|
6182
6726
|
return withGLParameters(this.gl, parameters, func);
|
|
6183
6727
|
}
|
|
6184
6728
|
resetWebGL() {
|
|
6185
|
-
|
|
6729
|
+
import_core27.log.warn("WebGLDevice.resetWebGL is deprecated, use only for debugging")();
|
|
6186
6730
|
resetGLParameters(this.gl);
|
|
6187
6731
|
}
|
|
6188
6732
|
_getDeviceSpecificTextureFormatCapabilities(capabilities) {
|
|
@@ -6254,7 +6798,7 @@ ${source}`;
|
|
|
6254
6798
|
this._constants = this._constants || new Array(maxVertexAttributes).fill(null);
|
|
6255
6799
|
const currentConstant = this._constants[location];
|
|
6256
6800
|
if (currentConstant && compareConstantArrayValues2(currentConstant, constant)) {
|
|
6257
|
-
|
|
6801
|
+
import_core27.log.info(
|
|
6258
6802
|
1,
|
|
6259
6803
|
`setConstantAttributeWebGL(${location}) could have been skipped, value unchanged`
|
|
6260
6804
|
)();
|
|
@@ -6300,21 +6844,21 @@ ${source}`;
|
|
|
6300
6844
|
}
|
|
6301
6845
|
return Boolean(gl && typeof gl.createVertexArray === "function");
|
|
6302
6846
|
}
|
|
6303
|
-
var
|
|
6847
|
+
var import_core28, LOG_LEVEL2, WebGLAdapter, webgl2Adapter;
|
|
6304
6848
|
var init_webgl_adapter = __esm({
|
|
6305
6849
|
"src/adapter/webgl-adapter.ts"() {
|
|
6306
6850
|
"use strict";
|
|
6307
|
-
|
|
6851
|
+
import_core28 = __toESM(require_core(), 1);
|
|
6308
6852
|
init_polyfill_webgl1_extensions();
|
|
6309
6853
|
init_spector();
|
|
6310
6854
|
init_webgl_developer_tools();
|
|
6311
6855
|
LOG_LEVEL2 = 1;
|
|
6312
|
-
WebGLAdapter = class extends
|
|
6856
|
+
WebGLAdapter = class extends import_core28.Adapter {
|
|
6313
6857
|
/** type of device's created by this adapter */
|
|
6314
6858
|
type = "webgl";
|
|
6315
6859
|
constructor() {
|
|
6316
6860
|
super();
|
|
6317
|
-
|
|
6861
|
+
import_core28.Device.defaultProps = { ...import_core28.Device.defaultProps, ...DEFAULT_SPECTOR_PROPS };
|
|
6318
6862
|
}
|
|
6319
6863
|
/** Force any created WebGL contexts to be WebGL2 contexts, polyfilled with WebGL1 extensions */
|
|
6320
6864
|
enforceWebGL2(enable2) {
|
|
@@ -6329,7 +6873,7 @@ ${source}`;
|
|
|
6329
6873
|
return true;
|
|
6330
6874
|
}
|
|
6331
6875
|
if (typeof WebGLRenderingContext !== "undefined" && handle instanceof WebGLRenderingContext) {
|
|
6332
|
-
|
|
6876
|
+
import_core28.log.warn("WebGL1 is not supported", handle)();
|
|
6333
6877
|
}
|
|
6334
6878
|
return false;
|
|
6335
6879
|
}
|
|
@@ -6371,19 +6915,19 @@ ${source}`;
|
|
|
6371
6915
|
const results = await Promise.allSettled(promises);
|
|
6372
6916
|
for (const result of results) {
|
|
6373
6917
|
if (result.status === "rejected") {
|
|
6374
|
-
|
|
6918
|
+
import_core28.log.error(`Failed to initialize debug libraries ${result.reason}`)();
|
|
6375
6919
|
}
|
|
6376
6920
|
}
|
|
6377
6921
|
try {
|
|
6378
6922
|
const device = new WebGLDevice2(props);
|
|
6379
|
-
|
|
6923
|
+
import_core28.log.groupCollapsed(LOG_LEVEL2, `WebGLDevice ${device.id} created`)();
|
|
6380
6924
|
const message2 = `${device._reused ? "Reusing" : "Created"} device with WebGL2 ${device.props.debug ? "debug " : ""}context: ${device.info.vendor}, ${device.info.renderer} for canvas: ${device.canvasContext.id}`;
|
|
6381
|
-
|
|
6382
|
-
|
|
6925
|
+
import_core28.log.probe(LOG_LEVEL2, message2)();
|
|
6926
|
+
import_core28.log.table(LOG_LEVEL2, device.info)();
|
|
6383
6927
|
return device;
|
|
6384
6928
|
} finally {
|
|
6385
|
-
|
|
6386
|
-
|
|
6929
|
+
import_core28.log.groupEnd(LOG_LEVEL2)();
|
|
6930
|
+
import_core28.log.info(
|
|
6387
6931
|
LOG_LEVEL2,
|
|
6388
6932
|
`%cWebGL call tracing: luma.log.set('debug-webgl') `,
|
|
6389
6933
|
"color: white; background: blue; padding: 2px 6px; border-radius: 3px;"
|