chore: Restore texture tests (#2123)

This commit is contained in:
Ib Green 2024-07-03 12:03:13 -04:00 committed by GitHub
parent cc973d8032
commit 4e28a224d0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 178 additions and 154 deletions

View File

@ -43,7 +43,6 @@ Each device has a `device.features` field that holds a `DeviceFeatures` object w
| `shader-conservative-depth-webgl` | <F f="shader-conservative-depth-webgl"/> | GLSL enable early depth test optimizations | `EXT_conservative_depth` |
| `shader-clip-cull-distance-webgl` | <F f="shader-clip-cull-distance-webgl"/> | GLSL `gl_ClipDistance[]/gl_CullDistance[]` | `WEBGL_clip_cull_distance` |
| **Texture Extensions** |
| `depth24unorm-stencil8` | <F f="depth24unorm-stencil8"/> | | `GL.UNSIGNED_INT_24_8_WEBGL` |
| `depth32float-stencil8` | <F f="depth32float-stencil8"/> | | N/A |
| `rg11b10ufloat-renderable` | <F f="rg11b10ufloat-renderable"/> | rg11b10ufloat textures renderable | N/A |
| `float32-renderable-webgl` | <F f="float32-renderable-webgl"/> | float32 textures renderable | `EXT_color_buffer_float` |

View File

@ -22,7 +22,7 @@ const framebuffer = device.createFramebuffer({
width: window.innerWidth,
height: window.innerHeight,
colorAttachments: [{format: 'rgb8unorm'}],
depthStencilAttachment: {format: 'depth24unorm-stencil8'}
depthStencilAttachment: {format: 'depth24plus-stencil8'}
});
```
@ -36,7 +36,7 @@ const size = {
const framebuffer = device.createFramebuffer({
...size,
colorAttachments: [device.createTexture({format: 'rgb8unorm', ...size})],
depthStencilAttachment: device.createTexture({format: 'depth24unorm-stencil8', ...size})
depthStencilAttachment: device.createTexture({format: 'depth24plus-stencil8', ...size})
});
```

View File

@ -81,7 +81,6 @@ Note that even though a GPU supports creating and sampling textures of a certain
| `depth24plus` | <Ft f="depth24plus" /> | <L f="depth24plus" /> | <R f="depth24plus" /> | Platform dependent: Maps to "`depth24unorm`" or `depth32float`. |
| `depth24plus-stencil81` | <Ft f="depth24plus-stencil8" /> | <L f="depth24plus-stencil8" /> | <R f="depth24plus-stencil8" /> | Platform dependent: Maps to "`depth24unorm`" or `depth32float`. |
| `depth32float` | <Ft f="depth32float" /> | <L f="depth32float" /> | <R f="depth32float" /> | Higher precision than `depth24unorm` in representable range (0.0 to 1.0) |
| `depth24unorm-stencil8` | <Ft f="depth24unorm-stencil8" /> | <L f="depth24unorm-stencil8" /> | <R f="depth24unorm-stencil8" /> | Platform dependent: Check via `depth24unorm-stencil8` feature. |
| `depth32float-stencil8` | <Ft f="depth32float-stencil8" /> | <L f="depth32float-stencil8" /> | <R f="depth32float-stencil8" /> | Platform dependent: Check via `depth32float-stencil8` feature. |
| **`texture-compression-bc(5)`** | | | | _[S3 Texture Compression][s3tc_wiki], aka BC (Block Compression) using FourCC DXTn file identifiers. 4-6x compression._ |
| `bc1-rgb-unorm-webgl` | <Ft f="bc1-rgb-unorm-webgl" /> | <L f="bc1-rgb-unorm-webgl" /> | <R f="bc1-rgb-unorm-webgl" /> | BC1 / DXT1: 16 input pixels in 64 bits. |

View File

@ -16,24 +16,29 @@ Some deprectations and minor breaking changes are necessary as WebGPU support is
**@luma.gl/core**
| Updated API | Status | Replacement |
| ------------------------------ | ---------- | -------------------------------------------------------------------------------------------- |
| `luma.registerDevices()` | Deprecated | Use [`luma.registerAdapters()`](/docs/api-reference/core/luma#lumaregisteradapters) instead. |
| `Texture.props.data` (Promise) | Changed | Textures no longer accept promises, use `AsyncTexture` class instead. |
| `triangle-fan-webgl` | Removed | Rebuild your geometries using `triangle-strip`. |
| `line-loop-webgl` | Removed | Rebuild your geometries`line-list`. |
| `glsl` template string | Removed | Enable syntax highlighting in vscode using `/* glsl */` comment instead |
| `Parameters.blend` | New | Explicit control over color blending |
| Updated API | Status | Replacement | Comment |
| ------------------------------ | ---------- | -------------------------------------- | --------------------------------------------------------------- |
| `Parameters.blend` | New | | Explicit activation of color blending |
| `luma.registerDevices()` | Deprecated | [`luma.registerAdapters()`][adapters]. | Adapters provide a cleaner way to work with GPU backends. |
| `Texture.props.data` (Promise) | Changed | `AsyncTexture` class | Textures no longer accept promises. |
| `triangle-fan-webgl` | Removed | `triangle-strip`. | Reorganize your geometries |
| `line-loop-webgl` | Removed | `line-list`. | Reorganize your geometries |
| `glsl` shader template string | Removed | `/* glsl */` comment | Enable syntax highlighting in vscode using before shader string |
| `depth24unorm-stencil8` | Removed | `depth24plus-stencil8` | The `TextureFormat` was removed from the WebGPU spec |
| `rgb8unorm-unsized` | Removed | `rgb8unorm` | No longer support unsized WebGL1 `TextureFormat` |
| `rgba8unorm-unsized` | Removed | `rgb8aunorm` | No longer support unsized WebGL1 `TextureFormat` |
[adapters]: /docs/api-reference/core/luma#lumaregisteradapters
**@luma.gl/shadertools**
| Updated API | Status | Replacement |
| ------------------------------------ | ------- | ----------------------------------------------------------------------- |
| `ShaderModuleInstance` | Removed | Type has been removed. Use `ShaderModule` instead. |
| `initializeShaderModule()` | Changed | Stores initialized information on the original shader module object. |
| `ShaderModuleInstance.getUniforms()` | Removed | Use `getShaderModuleUniforms(module, ...)` instead. |
| `getDependencyGraph()` | Removed | Use `getShaderModuleDependencies(module)` instead. |
| `glsl` template string | Removed | Enable syntax highlighting in vscode using `/* glsl */` comment instead |
| Updated API | Status | Replacement | Comment |
| ------------------------------------ | ------- | --------------------------------------- | -------------------------------------------------- |
| `ShaderModuleInstance` | Removed | Use `ShaderModule` instead. | Type has been removed. |
| `initializeShaderModule()` | Changed | | Initializes the original shader module object |
| `ShaderModuleInstance.getUniforms()` | Removed | `getShaderModuleUniforms(module, ...)`. | Interact directly with the shader module |
| `getDependencyGraph()` | Removed | `getShaderModuleDependencies(module)` . | Interact directly with the shader module |
| `glsl` template string | Removed | `/* glsl */` comment | Enable syntax highlighting in vscode using comment |
## Upgrading to v9.0

View File

@ -145,7 +145,6 @@ export type WebGPUDeviceFeature =
| 'indirect-first-instance'
| 'timestamp-query'
| 'shader-f16'
| 'depth24unorm-stencil8'
| 'depth32float-stencil8'
| 'rg11b10ufloat-renderable' // Is the rg11b10ufloat texture format renderable?
| 'float32-filterable' // Is the float32 format filterable?

View File

@ -11,19 +11,37 @@ const COMPRESSED_TEXTURE_FORMAT_PREFIXES = [
'bc1', 'bc2', 'bc3', 'bc4', 'bc5', 'bc6', 'bc7', 'etc1', 'etc2', 'eac', 'atc', 'astc', 'pvrtc'
];
const REGEX = /^(rg?b?a?)([0-9]*)([a-z]*)(-srgb)?(-webgl|-unsized)?$/;
const REGEX = /^(r|rg|rgb|rgba|bgra)([0-9]*)([a-z]*)(-srgb)?(-webgl)?$/;
export type DecodedTextureFormat = {
format: 'r' | 'rg' | 'rgb' | 'rgba';
/** String describing which channels this texture has */
channels: 'r' | 'rg' | 'rgb' | 'rgba' | 'bgra';
/** Number of components (corresponds to channels string) */
components: 1 | 2 | 3 | 4;
/** What is the data type of each component */
dataType?: VertexType;
srgb: boolean;
webgl: boolean;
unsized: boolean;
/** Number of bytes per pixel */
bpp?: number;
/** Depth stencil formats */
a?: 'depth' | 'stencil' | 'depth-stencil';
/** SRGB texture format? */
srgb?: boolean;
/** WebGL specific texture format? */
webgl?: boolean;
/** byteLength */
byteLength: number;
/** Is this an integer or floating point format? */
integer: boolean;
/** Is this a signed or unsigned format? */
signed: boolean;
/** Is this a normalized integer format? */
normalized: boolean;
/** Is this a compressed texture format */
compressed?: boolean;
/** Block size for ASTC formats (texture must be a multiple) */
blockWidth?: number;
/** Block size for ASTC formats (texture must be a multiple) */
blockHeight?: number;
};
/**
@ -39,19 +57,23 @@ export function isTextureFormatCompressed(textureFormat: TextureFormat): boolean
export function decodeTextureFormat(format: TextureFormat): DecodedTextureFormat {
const matches = REGEX.exec(format as string);
if (matches) {
const [, format, length, type, srgb, suffix] = matches;
const [, channels, length, type, srgb, suffix] = matches;
if (format) {
const dataType = `${type}${length}` as VertexType;
const decodedType = decodeVertexType(dataType);
return {
format: format as 'r' | 'rg' | 'rgb' | 'rgba',
components: format.length as 1 | 2 | 3 | 4,
// dataType - overwritten by decodedType
srgb: srgb === '-srgb',
unsized: suffix === '-unsized',
webgl: suffix === '-webgl',
const info: DecodedTextureFormat = {
channels: channels as 'r' | 'rg' | 'rgb' | 'rgba',
components: channels.length as 1 | 2 | 3 | 4,
...decodedType
};
if (suffix === '-webgl') {
info.webgl = true;
}
// dataType - overwritten by decodedType
if (srgb === '-srgb') {
info.srgb = true;
}
return info;
}
}
@ -60,42 +82,67 @@ export function decodeTextureFormat(format: TextureFormat): DecodedTextureFormat
// https://www.w3.org/TR/webgpu/#texture-format-caps
const EXCEPTIONS: Partial<Record<TextureFormat, any>> = {
const EXCEPTIONS: Partial<Record<TextureFormat, Partial<DecodedTextureFormat>>> = {
// Packed 16 bit formats
'rgba4unorm-webgl': {format: 'rgba', bpp: 2},
'rgb565unorm-webgl': {format: 'rgb', bpp: 2},
'rgb5a1unorm-webgl': {format: 'rgba', bbp: 2},
'rgba4unorm-webgl': {channels: 'rgba', bpp: 2},
'rgb565unorm-webgl': {channels: 'rgb', bpp: 2},
'rgb5a1unorm-webgl': {channels: 'rgba', bpp: 2},
// Packed 32 bit formats
rgb9e5ufloat: {format: 'rgb', bbp: 4},
rg11b10ufloat: {format: 'rgb', bbp: 4},
rgb10a2unorm: {format: 'rgba', bbp: 4},
'rgb10a2uint-webgl': {format: 'rgba', bbp: 4},
rgb9e5ufloat: {channels: 'rgb', bpp: 4},
rg11b10ufloat: {channels: 'rgb', bpp: 4},
rgb10a2unorm: {channels: 'rgba', bpp: 4},
'rgb10a2uint-webgl': {channels: 'rgba', bpp: 4},
// Depth/stencil
stencil8: {components: 1, bpp: 1, a: 'stencil'},
depth16unorm: {components: 1, bpp: 2, a: 'depth'},
depth24plus: {components: 1, bpp: 3, a: 'depth'},
depth32float: {components: 1, bpp: 4, a: 'depth'},
'depth24plus-stencil8': {components: 2, bpp: 4, a: 'depth-stencil'},
// "depth24unorm-stencil8" feature
'depth24unorm-stencil8': {components: 2, bpp: 4, a: 'depth-stencil'},
// "depth32float-stencil8" feature
'depth32float-stencil8': {components: 2, bpp: 4, a: 'depth-stencil'}
};
function decodeNonStandardFormat(format: TextureFormat): DecodedTextureFormat {
if (isTextureFormatCompressed(format)) {
const info: DecodedTextureFormat = {
channels: 'rgb',
components: 3,
byteLength: 1,
srgb: false,
compressed: true
} as DecodedTextureFormat;
const blockSize = getCompressedTextureBlockSize(format);
if (blockSize) {
info.blockWidth = blockSize.blockWidth;
info.blockHeight = blockSize.blockHeight;
}
return info;
}
const data = EXCEPTIONS[format];
if (!data) {
throw new Error(`Unknown format ${format}`);
}
return {
format: data.format || '',
components: data.components || data.format?.length || 1,
channels: data.channels || '',
components: data.components || data.channels?.length || 1,
byteLength: data.bpp || 1,
srgb: false,
unsized: false
srgb: false
} as DecodedTextureFormat;
}
/** Parses ASTC block widths from format string */
function getCompressedTextureBlockSize(
format: string
): {blockWidth: number; blockHeight: number} | null {
const REGEX = /.*-(\d+)x(\d+)-.*/;
const matches = REGEX.exec(format);
if (matches) {
const [, blockWidth, blockHeight] = matches;
return {blockWidth: Number(blockWidth), blockHeight: Number(blockHeight)};
}
return null;
}
/*
'r8unorm': {s: "float"}, // ✓ ✓ ✓ },
'r8snorm': {s: "float"}, // ✓ },

View File

@ -12,16 +12,11 @@ export type DepthStencilTextureFormat =
| 'depth24plus'
| 'depth24plus-stencil8'
| 'depth32float'
// device.features.has('depth24unorm-stencil8')
| 'depth24unorm-stencil8'
// device.features.has('depth32float-stencil8')
| 'depth32float-stencil8';
/** Texture formats for color attachments */
export type ColorTextureFormat =
| WebGPUColorTextureFormat
| WebGL2ColorTextureFormat
| UnsizedColorTextureFormat;
export type ColorTextureFormat = WebGPUColorTextureFormat | WebGL2ColorTextureFormat;
export type WebGPUColorTextureFormat =
// 8-bit formats
@ -103,6 +98,7 @@ export type WebGPUColorTextureFormat =
// ASTC compressed formats usable if "texture-compression-astc" is both
// supported by the device/user agent and enabled in requestDevice.
// Textures must be multiple of block size (encoded in format string).
| 'astc-4x4-unorm'
| 'astc-4x4-unorm-srgb'
| 'astc-5x4-unorm'
@ -132,13 +128,6 @@ export type WebGPUColorTextureFormat =
| 'astc-12x12-unorm'
| 'astc-12x12-unorm-srgb';
/** Unsized texture formats (the only formats supported by WebGL1) */
export type UnsizedColorTextureFormat = 'rgb8unorm-unsized' | 'rgba8unorm-unsized';
// 'r8unorm-unsized' |
// 'ra8unorm-unsized' |
// 'rgb8unorm-srgb-unsized' |
// 'rgba8unorm-srgb-unsized'
/** Sized formats in WebGL 2 that are not (yet?) supported by WebGPU */
export type WebGL2ColorTextureFormat =
| 'r16unorm-webgl'

View File

@ -200,8 +200,6 @@ type WebGLTextureInfo = {
};
const WEBGL_TEXTURE_FORMATS: Record<TextureFormat, WebGLTextureInfo> = {
// Unsized texture format - more performance
'rgb8unorm-unsized': {dataFormat: GL.RGB, types: [GL.UNSIGNED_BYTE, GL.UNSIGNED_SHORT_5_6_5]},
// TODO: format: GL.RGBA type: GL.FLOAT is supported in WebGL1 when 'OES_texure_float' is suported
// we need to update this table structure to specify extensions (gl1ext: 'OES_texure_float', gl2ext: false) for each type.
rgba8unorm: {

View File

@ -5,11 +5,14 @@
import test from 'tape-promise/tape';
import {webglDevice, getTestDevices} from '@luma.gl/test-utils';
import {Device, Texture, TextureFormat} from '@luma.gl/core';
import {Device, Texture, TextureFormat, decodeTextureFormat} from '@luma.gl/core';
import {GL} from '@luma.gl/constants';
// TODO(v9): Avoid import from `@luma.gl/webgl` in core tests.
import {TEXTURE_FORMATS} from '@luma.gl/webgl/adapter/converters/texture-formats';
import {
TEXTURE_FORMATS,
getTextureFormatWebGL
} from '../../../../webgl/src/adapter/converters/texture-formats';
import {SAMPLER_PARAMETERS} from './sampler.spec';
import {WEBGLTexture} from '@luma.gl/webgl/adapter/resources/webgl-texture';
@ -63,13 +66,6 @@ test('Texture#depth/stencil formats', async t => {
t.end();
});
test.skip('Texture#format deduction', async t => {
for (const device of await getTestDevices()) {
testFormatDeduction(t, device);
}
t.end();
});
const DEFAULT_TEXTURE_DATA = new Uint8Array([
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
]);
@ -93,6 +89,49 @@ const TEXTURE_DATA = {
// [GL.UNSIGNED_SHORT_5_6_5]: v => [v >> 11 / 32, v >> 6 % 64 / 64, v % 32 * 32]
// };
test('Texture#format simple creation', async t => {
for (const device of await getTestDevices()) {
for (const [formatName, formatInfo] of Object.entries(TEXTURE_FORMATS)) {
if (['stencil8'].includes(formatName)) {
continue;
}
if (device.isTextureFormatSupported(formatName)) {
// For compressed textures there may be a block size that we need to be a multiple of
const decodedFormat = decodeTextureFormat(formatName);
const width = decodedFormat.blockWidth ?? 4;
const height = decodedFormat.blockHeight ?? 4;
let texture: Texture;
t.doesNotThrow(() => {
texture = device.createTexture({
format: formatName,
height,
width
});
}, `Texture(${device.type},${formatName}) creation OK`);
t.equals(texture.format, formatName, `Texture(${device.type},${formatName}).format OK`);
if (device.type === 'webgl') {
// const formatInfo = getTextureFormatWebGL(forma)
const expectedInternalFormat = formatInfo.gl;
t.equals(
texture.glInternalFormat,
expectedInternalFormat,
`Texture(${device.type},${formatName}).glInternal OK`
);
// const expectedType = formatInfo.types?.[0];
// const expectedDataFormat = formatInfo.dataFormat;
// t.equals(texture.glType, expectedType, `Texture(${formatName}).type OK`);
// t.equals(texture.glFormat, expectedDataFormat, `Texture(${formatName}).glFormat OK`);
}
texture.destroy();
}
}
}
t.end();
});
function testFormatCreation(t, device: Device, withData: boolean = false) {
for (const [textureFormat, formatInfo] of Object.entries(TEXTURE_FORMATS)) {
const format = textureFormat as TextureFormat;
@ -134,33 +173,6 @@ function testFormatCreation(t, device: Device, withData: boolean = false) {
}
}
function testFormatDeduction(t, device: Device) {
for (const [formatName, formatInfo] of Object.entries(TEXTURE_FORMATS)) {
const expectedType = formatInfo.types[0];
const expectedDataFormat = formatInfo.dataFormat;
const options = {
format: Number(format),
height: 1,
width: 1
};
if (device.isTextureFormatSupported({format})) {
const texture = device.createTexture(options);
const msg = `Texture({format: ${device.getGLKey(format)}}) created`;
t.equals(texture.format, Number(format), msg);
t.equals(texture.type, expectedType, msg);
t.equals(texture.dataFormat, expectedDataFormat, msg);
texture.destroy();
}
}
}
test.skip('Texture#format deduction', async t => {
for (const device of await getTestDevices()) {
testFormatDeduction(t, device);
}
t.end();
});
test.skip('Texture#format creation', async t => {
for (const device of await getTestDevices()) {
testFormatCreation(t, device);
@ -175,21 +187,6 @@ test.skip('Texture#format creation with data', async t => {
t.end();
});
/*
test.skip('Texture#WebGL2 format creation', t => {
for (const format in TEXTURE_FORMATS) {
}
let texture = webglDevice.createTexture({});
t.ok(texture instanceof Texture, 'Texture construction successful');
texture = texture.destroy();
t.ok(texture instanceof Texture, 'Texture delete successful');
t.end();
});
*/
test.skip('Texture#setParameters', t => {
const texture = webglDevice.createTexture({});
t.ok(texture instanceof Texture, 'Texture construction successful');

View File

@ -8,15 +8,15 @@ import {decodeTextureFormat, TextureFormat} from '@luma.gl/core';
// prettier-ignore
const TEST_CASES: {format: TextureFormat, result: any}[] = [
// 8-bit formats
{format: 'r8unorm', result: { format: 'r', components: 1, dataType: 'uint8', byteLength: 1, integer: false, signed: false, normalized: true, srgb: false, webgl: false, unsized: false }},
{format: 'r8snorm', result: { format: 'r', components: 1, dataType: 'sint8', byteLength: 1, integer: false, signed: true, normalized: true, srgb: false, webgl: false, unsized: false }},
{format: 'r8uint', result: { format: 'r', components: 1, dataType: 'uint8', byteLength: 1, integer: true, signed: false, normalized: false, srgb: false, webgl: false, unsized: false }},
{format: 'r8sint', result: { format: 'r', components: 1, dataType: 'sint8', byteLength: 1, integer: true, signed: true, normalized: false, srgb: false, webgl: false, unsized: false }},
{format: 'r8unorm', result: {channels: 'r', components: 1, dataType: 'uint8', byteLength: 1, integer: false, signed: false, normalized: true}},
{format: 'r8snorm', result: {channels: 'r', components: 1, dataType: 'sint8', byteLength: 1, integer: false, signed: true, normalized: true}},
{format: 'r8uint', result: {channels: 'r', components: 1, dataType: 'uint8', byteLength: 1, integer: true, signed: false, normalized: false}},
{format: 'r8sint', result: {channels: 'r', components: 1, dataType: 'sint8', byteLength: 1, integer: true, signed: true, normalized: false}},
// 16-bit formats
{format: 'r16uint', result: { format: 'r', components: 1, dataType: 'uint16', byteLength: 2, integer: true, signed: false, normalized: false, srgb: false, webgl: false, unsized: false }},
{format: 'r16sint', result: { format: 'r', components: 1, dataType: 'sint16', byteLength: 2, integer: true, signed: true, normalized: false, srgb: false, webgl: false, unsized: false }},
{format: 'r16float', result: { format: 'r', components: 1, dataType: 'float16', byteLength: 2, integer: false, signed: false, normalized: false, srgb: false, webgl: false, unsized: false }}
{format: 'r16uint', result: {channels: 'r', components: 1, dataType: 'uint16', byteLength: 2, integer: true, signed: false, normalized: false}},
{format: 'r16sint', result: {channels: 'r', components: 1, dataType: 'sint16', byteLength: 2, integer: true, signed: true, normalized: false}},
{format: 'r16float', result: {channels: 'r', components: 1, dataType: 'float16', byteLength: 2, integer: false, signed: false, normalized: false }}
];
test('api#decodeTextureFormat', t => {

View File

@ -141,15 +141,6 @@ type Format = {
*/
// prettier-ignore
export const TEXTURE_FORMATS: Record<TextureFormat, Format> = {
// Unsized formats that leave the precision up to the driver. TODO - Fix bpp constants
'rgb8unorm-unsized': {gl: GL.RGB, b: 4, c: 2, bpp: 4,
dataFormat: GL.RGB, types: [GL.UNSIGNED_BYTE, GL.UNSIGNED_SHORT_5_6_5]},
'rgba8unorm-unsized': {gl: GL.RGBA, b: 4, c: 2, bpp: 4,
dataFormat: GL.RGBA, types: [GL.UNSIGNED_BYTE, GL.UNSIGNED_SHORT_4_4_4_4, GL.UNSIGNED_SHORT_5_5_5_1]},
// 'r8unorm-unsized': {gl: GL.LUMINANCE, b: 4, c: 2, bpp: 4},
// 'rgb8unorm-srgb-unsized': {gl: GL.SRGB_EXT, b: 4, c: 2, bpp: 4, gl1Ext: SRGB},
// 'rgba8unorm-srgb-unsized': {gl: GL.SRGB_ALPHA_EXT, b: 4, c: 2, bpp: 4, gl1Ext: SRGB},
// 8-bit formats
'r8unorm': {gl: GL.R8, b: 1, c: 1, rb: true},
'r8snorm': {gl: GL.R8_SNORM, b: 1, c: 1, render: snorm8_renderable},
@ -239,9 +230,6 @@ export const TEXTURE_FORMATS: Record<TextureFormat, Format> = {
// The depth component of the "depth24plus" and "depth24plus-stencil8" formats may be implemented as either a 24-bit depth value or a "depth32float" value.
'depth24plus-stencil8': {gl: GL.DEPTH24_STENCIL8, b: 4, c: 2, p: 1, attachment: GL.DEPTH_STENCIL_ATTACHMENT, rb: true, depthTexture: true,
dataFormat: GL.DEPTH_STENCIL, types: [GL.UNSIGNED_INT_24_8]},
// "depth24unorm-stencil8" feature
'depth24unorm-stencil8': {gl: GL.DEPTH24_STENCIL8, b: 4, c: 2, p: 1, attachment: GL.DEPTH_STENCIL_ATTACHMENT,
dataFormat: GL.DEPTH_STENCIL, types: [GL.UNSIGNED_INT_24_8], rb: true},
// "depth32float-stencil8" feature - TODO below is render buffer only?
'depth32float-stencil8': {gl: GL.DEPTH32F_STENCIL8, b: 5, c: 2, p: 1, attachment: GL.DEPTH_STENCIL_ATTACHMENT,
dataFormat: GL.DEPTH_STENCIL, types: [GL.FLOAT_32_UNSIGNED_INT_24_8_REV], rb: true},
@ -469,6 +457,10 @@ export function isTextureFormatSupported(
if (info.gl === undefined) {
return false;
}
const feature = info.f;
if (feature) {
return checkTextureFeature(gl, feature, extensions);
}
// Check extensions
const extension = info.x || info.gl2ext;
if (extension) {
@ -586,13 +578,12 @@ export function getTextureFormatWebGL(format: TextureFormat): {
internalFormat: webglFormat,
format:
formatData?.dataFormat ||
getWebGLPixelDataFormat(decoded.format, decoded.integer, decoded.normalized, webglFormat),
getWebGLPixelDataFormat(decoded.channels, decoded.integer, decoded.normalized, webglFormat),
// depth formats don't have a type
type: decoded.dataType
? getGLFromVertexType(decoded.dataType)
: formatData?.types?.[0] || GL.UNSIGNED_BYTE,
// @ts-expect-error
compressed: decoded.compressed
compressed: decoded.compressed || false
};
}
@ -619,7 +610,7 @@ export function getTextureFormatBytesPerPixel(format: TextureFormat): number {
// DATA TYPE HELPERS
export function getWebGLPixelDataFormat(
dataFormat: string,
channels: 'r' | 'rg' | 'rgb' | 'rgba' | 'bgra',
integer: boolean,
normalized: boolean,
format: GL
@ -629,11 +620,12 @@ export function getWebGLPixelDataFormat(
return format;
}
// prettier-ignore
switch (dataFormat) {
switch (channels) {
case 'r': return integer && !normalized ? GL.RED_INTEGER : GL.RED;
case 'rg': return integer && !normalized ? GL.RG_INTEGER : GL.RG;
case 'rgb': return integer && !normalized ? GL.RGB_INTEGER : GL.RGB;
case 'rgba': return integer && !normalized ? GL.RGBA_INTEGER : GL.RGBA;
case 'bgra': throw new Error('bgra pixels not supported by WebGL');
default: return GL.RGBA;
}
}

View File

@ -21,7 +21,6 @@ const WEBGL_FEATURES: Partial<Record<DeviceFeature, boolean | string>> = {
// 'timestamp-query' // GPUQueryType "timestamp-query"
// "indirect-first-instance"
// Textures are handled by getTextureFeatures()
// 'depth24unorm-stencil8' // GPUTextureFormat 'depth24unorm-stencil8'
// 'depth32float-stencil8' // GPUTextureFormat 'depth32float-stencil8'
// optional WebGL features

View File

@ -149,22 +149,22 @@ export function polyfillWebGL1Extensions(gl: WebGL2RenderingContext): void {
// Update unsized WebGL1 formats to sized WebGL2 formats
// todo move to texture format file
export function getInternalFormat(gl: WebGL2RenderingContext, format: GL, type: GL): GL {
// webgl2 texture formats
// https://webgl2fundamentals.org/webgl/lessons/webgl-data-textures.html
switch (format) {
case GL.DEPTH_COMPONENT:
return GL.DEPTH_COMPONENT24;
case GL.DEPTH_STENCIL:
return GL.DEPTH24_STENCIL8;
case GL.RGBA:
return type === GL.HALF_FLOAT ? GL.RGBA16F : GL.RGBA32F;
case GL.RGB:
return type === GL.HALF_FLOAT ? GL.RGB16F : GL.RGB32F;
default:
return format;
}
}
// export function getInternalFormat(gl: WebGL2RenderingContext, format: GL, type: GL): GL {
// // webgl2 texture formats
// // https://webgl2fundamentals.org/webgl/lessons/webgl-data-textures.html
// switch (format) {
// case GL.DEPTH_COMPONENT:
// return GL.DEPTH_COMPONENT24;
// case GL.DEPTH_STENCIL:
// return GL.DEPTH24_STENCIL8;
// case GL.RGBA:
// return type === GL.HALF_FLOAT ? GL.RGBA16F : GL.RGBA32F;
// case GL.RGB:
// return type === GL.HALF_FLOAT ? GL.RGB16F : GL.RGB32F;
// default:
// return format;
// }
// }
/*
// texture type to update on the fly