mirror of
https://github.com/visgl/luma.gl.git
synced 2026-02-01 14:33:49 +00:00
chore: Restore texture tests (#2123)
This commit is contained in:
parent
cc973d8032
commit
4e28a224d0
@ -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` |
|
||||
|
||||
@ -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})
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
@ -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. |
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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?
|
||||
|
||||
@ -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"}, // ✓ },
|
||||
|
||||
@ -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'
|
||||
|
||||
@ -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: {
|
||||
|
||||
@ -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');
|
||||
|
||||
@ -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 => {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user