From db9c603d8ab6daf3ba0135b3e9449901b75d4194 Mon Sep 17 00:00:00 2001 From: Felix Palmer Date: Mon, 18 Dec 2023 15:10:40 +0100 Subject: [PATCH 1/5] Support all vertex formats in GPUGeometry --- .../type-utils/decode-attribute-type.ts | 48 ++++++++++++++++++- modules/core/src/index.ts | 2 +- modules/engine/src/geometry/gpu-geometry.ts | 4 +- 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/modules/core/src/adapter/type-utils/decode-attribute-type.ts b/modules/core/src/adapter/type-utils/decode-attribute-type.ts index 36ccf10e17..86deb26ad0 100644 --- a/modules/core/src/adapter/type-utils/decode-attribute-type.ts +++ b/modules/core/src/adapter/type-utils/decode-attribute-type.ts @@ -1,6 +1,7 @@ // luma.gl, MIT licese +import {TypedArray} from '../..'; import {ShaderDataType, ShaderAttributeType} from '../types/shader-types'; -import {VertexFormat, VertexType} from '../types/vertex-formats'; +import {DataType, VertexFormat, VertexType} from '../types/vertex-formats'; /** Information extracted from a ShaderAttributeInfo constant */ export type ShaderAttributeTypeInfo = { @@ -53,6 +54,51 @@ function getCompatibleVertexFormat(dataType: ShaderDataType, components: 1 | 2 | return `${vertexType}x${components}`; } +export function getVertexFormatFromAttribute({value, size}: {value: TypedArray, size?: number}): VertexFormat { + if(!size || size > 4) { + throw new Error(`Invalid attribute size ${size}`); + } + + const components = size as 1 | 2 | 3 | 4; + let dataType: DataType; + if (value instanceof Uint8Array || value instanceof Uint8ClampedArray) { + dataType = 'uint8'; + } else if (value instanceof Int8Array) { + dataType = 'sint8'; + } else if (value instanceof Uint16Array) { + dataType = 'uint16'; + } else if (value instanceof Int16Array) { + dataType = 'sint16'; + } else if (value instanceof Uint32Array) { + dataType = 'uint32'; + } else if (value instanceof Int32Array) { + dataType = 'sint32'; + } else if (value instanceof Float32Array) { + dataType = 'float32'; + } else { + throw new Error(`Unknown attribute format ${value.constructor.name}`); + } + + if (dataType === 'uint8' || dataType === 'sint8') { + if (components === 1 || components === 3) { + throw new Error('WebGPU only supports 16 bit aligned formats'); + } + return `${dataType}x${components}`; + } + if (dataType === 'uint16' || dataType === 'sint16') { + if (components === 1 || components === 3) { + throw new Error('WebGPU only supports 32 bit aligned formats'); + } + return `${dataType}x${components}`; + } + + if (components === 1) { + return dataType; + } + + return `${dataType}x${components}`; +} + /** All valid shader attribute types. A table guarantees exhaustive list and fast execution */ const TYPE_INFO: Record = { f32: ['f32', 1], diff --git a/modules/core/src/index.ts b/modules/core/src/index.ts index e20e378cb8..a9b04f6597 100644 --- a/modules/core/src/index.ts +++ b/modules/core/src/index.ts @@ -116,7 +116,7 @@ export {decodeTextureFormat} from './adapter/type-utils/decode-texture-format'; // SHADER TYPE UTILS export {decodeShaderUniformType} from './adapter/type-utils/decode-shader-types'; -export {decodeShaderAttributeType} from './adapter/type-utils/decode-attribute-type'; +export {decodeShaderAttributeType, getVertexFormatFromAttribute} from './adapter/type-utils/decode-attribute-type'; // COMPILER LOG export type {CompilerMessage} from './lib/compiler-log/compiler-message'; diff --git a/modules/engine/src/geometry/gpu-geometry.ts b/modules/engine/src/geometry/gpu-geometry.ts index 55c1ce5330..4384bd25a3 100644 --- a/modules/engine/src/geometry/gpu-geometry.ts +++ b/modules/engine/src/geometry/gpu-geometry.ts @@ -1,5 +1,5 @@ import type {PrimitiveTopology, BufferLayout} from '@luma.gl/core'; -import {Device, Buffer, uid, assert} from '@luma.gl/core'; +import {Device, Buffer, uid, assert, getVertexFormatFromAttribute} from '@luma.gl/core'; import type {Geometry} from '../geometry/geometry'; export type GPUGeometryProps = { @@ -114,7 +114,7 @@ export function getAttributeBuffersFromGeometry( case 'TEXCOORD_0': name = 'texCoords'; break; } attributes[name] = device.createBuffer({data: attribute.value, id: `${attributeName}-buffer`}); - bufferLayout.push({name, format: `float32x${attribute.size as 2 | 3 | 4}`}); + bufferLayout.push({name, format: getVertexFormatFromAttribute(attribute)}); } const vertexCount = geometry._calculateVertexCount(geometry.attributes, geometry.indices) From 9fad0814dbb6e69e54026e5984eb9fe509538e35 Mon Sep 17 00:00:00 2001 From: Felix Palmer Date: Mon, 18 Dec 2023 15:37:18 +0100 Subject: [PATCH 2/5] Tests --- .../type-utils/decode-attribute-type.ts | 48 +----------------- .../vertex-format-from-attribute.ts | 50 +++++++++++++++++++ modules/core/src/index.ts | 3 +- .../vertex-format-from-attribute.spec.ts | 28 +++++++++++ modules/core/test/index.ts | 1 + 5 files changed, 82 insertions(+), 48 deletions(-) create mode 100644 modules/core/src/adapter/type-utils/vertex-format-from-attribute.ts create mode 100644 modules/core/test/adapter/type-utils/vertex-format-from-attribute.spec.ts diff --git a/modules/core/src/adapter/type-utils/decode-attribute-type.ts b/modules/core/src/adapter/type-utils/decode-attribute-type.ts index 86deb26ad0..36ccf10e17 100644 --- a/modules/core/src/adapter/type-utils/decode-attribute-type.ts +++ b/modules/core/src/adapter/type-utils/decode-attribute-type.ts @@ -1,7 +1,6 @@ // luma.gl, MIT licese -import {TypedArray} from '../..'; import {ShaderDataType, ShaderAttributeType} from '../types/shader-types'; -import {DataType, VertexFormat, VertexType} from '../types/vertex-formats'; +import {VertexFormat, VertexType} from '../types/vertex-formats'; /** Information extracted from a ShaderAttributeInfo constant */ export type ShaderAttributeTypeInfo = { @@ -54,51 +53,6 @@ function getCompatibleVertexFormat(dataType: ShaderDataType, components: 1 | 2 | return `${vertexType}x${components}`; } -export function getVertexFormatFromAttribute({value, size}: {value: TypedArray, size?: number}): VertexFormat { - if(!size || size > 4) { - throw new Error(`Invalid attribute size ${size}`); - } - - const components = size as 1 | 2 | 3 | 4; - let dataType: DataType; - if (value instanceof Uint8Array || value instanceof Uint8ClampedArray) { - dataType = 'uint8'; - } else if (value instanceof Int8Array) { - dataType = 'sint8'; - } else if (value instanceof Uint16Array) { - dataType = 'uint16'; - } else if (value instanceof Int16Array) { - dataType = 'sint16'; - } else if (value instanceof Uint32Array) { - dataType = 'uint32'; - } else if (value instanceof Int32Array) { - dataType = 'sint32'; - } else if (value instanceof Float32Array) { - dataType = 'float32'; - } else { - throw new Error(`Unknown attribute format ${value.constructor.name}`); - } - - if (dataType === 'uint8' || dataType === 'sint8') { - if (components === 1 || components === 3) { - throw new Error('WebGPU only supports 16 bit aligned formats'); - } - return `${dataType}x${components}`; - } - if (dataType === 'uint16' || dataType === 'sint16') { - if (components === 1 || components === 3) { - throw new Error('WebGPU only supports 32 bit aligned formats'); - } - return `${dataType}x${components}`; - } - - if (components === 1) { - return dataType; - } - - return `${dataType}x${components}`; -} - /** All valid shader attribute types. A table guarantees exhaustive list and fast execution */ const TYPE_INFO: Record = { f32: ['f32', 1], diff --git a/modules/core/src/adapter/type-utils/vertex-format-from-attribute.ts b/modules/core/src/adapter/type-utils/vertex-format-from-attribute.ts new file mode 100644 index 0000000000..9f38cd2f8a --- /dev/null +++ b/modules/core/src/adapter/type-utils/vertex-format-from-attribute.ts @@ -0,0 +1,50 @@ +// luma.gl, MIT licese +import {TypedArray} from '../..'; +import {DataType, VertexFormat} from '../types/vertex-formats'; + +/** Get the vertex format for an attribute with TypedArray value and size*/ +export function getVertexFormatFromAttribute({value, size}: {value: TypedArray, size?: number}): VertexFormat { + if(!size || size > 4) { + throw new Error(`Invalid attribute size ${size}`); + } + + const components = size as 1 | 2 | 3 | 4; + let dataType: DataType; + if (value instanceof Uint8Array || value instanceof Uint8ClampedArray) { + dataType = 'uint8'; + } else if (value instanceof Int8Array) { + dataType = 'sint8'; + } else if (value instanceof Uint16Array) { + dataType = 'uint16'; + } else if (value instanceof Int16Array) { + dataType = 'sint16'; + } else if (value instanceof Uint32Array) { + dataType = 'uint32'; + } else if (value instanceof Int32Array) { + dataType = 'sint32'; + } else if (value instanceof Float32Array) { + dataType = 'float32'; + } else { + throw new Error(`Unknown attribute format ${value.constructor.name}`); + } + + if (dataType === 'uint8' || dataType === 'sint8') { + if (components === 1 || components === 3) { + throw new Error('WebGPU only supports 16 bit aligned formats'); + } + return `${dataType}x${components}`; + } + if (dataType === 'uint16' || dataType === 'sint16') { + if (components === 1 || components === 3) { + throw new Error('WebGPU only supports 32 bit aligned formats'); + } + return `${dataType}x${components}`; + } + + if (components === 1) { + return dataType; + } + + return `${dataType}x${components}`; +} + diff --git a/modules/core/src/index.ts b/modules/core/src/index.ts index a9b04f6597..10856d7c16 100644 --- a/modules/core/src/index.ts +++ b/modules/core/src/index.ts @@ -113,10 +113,11 @@ export {UniformStore} from './lib/uniforms/uniform-store'; // TYPE UTILS export {decodeVertexFormat} from './adapter/type-utils/decode-vertex-format'; export {decodeTextureFormat} from './adapter/type-utils/decode-texture-format'; +export {getVertexFormatFromAttribute} from './adapter/type-utils/vertex-format-from-attribute'; // SHADER TYPE UTILS export {decodeShaderUniformType} from './adapter/type-utils/decode-shader-types'; -export {decodeShaderAttributeType, getVertexFormatFromAttribute} from './adapter/type-utils/decode-attribute-type'; +export {decodeShaderAttributeType} from './adapter/type-utils/decode-attribute-type'; // COMPILER LOG export type {CompilerMessage} from './lib/compiler-log/compiler-message'; diff --git a/modules/core/test/adapter/type-utils/vertex-format-from-attribute.spec.ts b/modules/core/test/adapter/type-utils/vertex-format-from-attribute.spec.ts new file mode 100644 index 0000000000..28277e6de6 --- /dev/null +++ b/modules/core/test/adapter/type-utils/vertex-format-from-attribute.spec.ts @@ -0,0 +1,28 @@ +// luma.gl, MIT license +import test from 'tape-promise/tape'; +import {TypedArray, VertexFormat, getVertexFormatFromAttribute} from '@luma.gl/core'; + +const TEST_CASES: {value: TypedArray, size?: number, result: VertexFormat}[] = [ + {value: new Uint8Array(), size: 4, result: 'uint8x4'}, + {value: new Uint8ClampedArray(), size: 2, result: 'uint8x2'}, + {value: new Int8Array(), size: 4, result: 'sint8x4'}, + {value: new Uint16Array(), size: 4, result: 'uint16x4'}, + {value: new Int16Array(), size: 2, result: 'sint16x2'}, + {value: new Uint32Array(), size: 3, result: 'uint32x3'}, + {value: new Int32Array(), size: 1, result: 'sint32'}, + {value: new Float32Array(), size: 2, result: 'float32x2'}, + {value: new Float32Array(), size: 3, result: 'float32x3'}, + {value: new Float32Array(), size: 4, result: 'float32x4'} +]; + +test.only('api#getVertexFormatFromAttribute', t => { + for (const {value, size, result} of TEST_CASES) { + const vertexFormat = getVertexFormatFromAttribute({value, size}); + t.deepEqual( + vertexFormat, + result, + `Attribute value '${value.constructor.name}, size: ${size}' => ${result}` + ); + } + t.end(); +}); diff --git a/modules/core/test/index.ts b/modules/core/test/index.ts index 323f2fdfe1..f2aea3fb00 100644 --- a/modules/core/test/index.ts +++ b/modules/core/test/index.ts @@ -12,6 +12,7 @@ import './adapter/type-utils/decode-attribute-type.spec'; import './adapter/type-utils/decode-vertex-format.spec'; import './adapter/type-utils/decode-texture-format.spec'; +import './adapter/type-utils/vertex-format-from-attribute.spec'; // adapter import './adapter/canvas-context.spec'; From ef476b5de767fde7a4a7dc40e604f8f8d6618890 Mon Sep 17 00:00:00 2001 From: Felix Palmer Date: Mon, 18 Dec 2023 15:45:38 +0100 Subject: [PATCH 3/5] Failure cases --- .../vertex-format-from-attribute.spec.ts | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/modules/core/test/adapter/type-utils/vertex-format-from-attribute.spec.ts b/modules/core/test/adapter/type-utils/vertex-format-from-attribute.spec.ts index 28277e6de6..64ed987b64 100644 --- a/modules/core/test/adapter/type-utils/vertex-format-from-attribute.spec.ts +++ b/modules/core/test/adapter/type-utils/vertex-format-from-attribute.spec.ts @@ -2,7 +2,7 @@ import test from 'tape-promise/tape'; import {TypedArray, VertexFormat, getVertexFormatFromAttribute} from '@luma.gl/core'; -const TEST_CASES: {value: TypedArray, size?: number, result: VertexFormat}[] = [ +const TEST_CASES: {value: TypedArray, size?: number, result?: VertexFormat, error?: string}[] = [ {value: new Uint8Array(), size: 4, result: 'uint8x4'}, {value: new Uint8ClampedArray(), size: 2, result: 'uint8x2'}, {value: new Int8Array(), size: 4, result: 'sint8x4'}, @@ -12,17 +12,29 @@ const TEST_CASES: {value: TypedArray, size?: number, result: VertexFormat}[] = [ {value: new Int32Array(), size: 1, result: 'sint32'}, {value: new Float32Array(), size: 2, result: 'float32x2'}, {value: new Float32Array(), size: 3, result: 'float32x3'}, - {value: new Float32Array(), size: 4, result: 'float32x4'} + {value: new Float32Array(), size: 4, result: 'float32x4'}, + + {value: new Float32Array(), size: 5, error: 'Invalid attribute size 5'}, + {value: new Int32Array(), error: 'Missing attribute size'}, + {value: new Uint8Array(), size: 1, error: 'Bad 16 bit alignment'}, + {value: new Int16Array(), size: 3, error: 'Bad 32 bit alignment'}, + {value: new Float64Array(), size: 2, error: 'Unknown array format'}, ]; -test.only('api#getVertexFormatFromAttribute', t => { - for (const {value, size, result} of TEST_CASES) { - const vertexFormat = getVertexFormatFromAttribute({value, size}); - t.deepEqual( - vertexFormat, - result, - `Attribute value '${value.constructor.name}, size: ${size}' => ${result}` - ); +test('api#getVertexFormatFromAttribute', t => { + for (const {value, size, result, error} of TEST_CASES) { + if (result) { + const vertexFormat = getVertexFormatFromAttribute({value, size}); + t.deepEqual( + vertexFormat, + result, + `Attribute value '${value.constructor.name}, size: ${size}' => ${result}` + ); + } else { + t.throws(() => { + getVertexFormatFromAttribute({value, size}); + }, error); + } } t.end(); }); From 515a2ffc125ecea08336273327f6872c030c3b3e Mon Sep 17 00:00:00 2001 From: Felix Palmer Date: Tue, 19 Dec 2023 11:13:14 +0100 Subject: [PATCH 4/5] Review comments --- .../vertex-format-from-attribute.ts | 85 +++++++++++++------ modules/core/src/index.ts | 2 +- .../vertex-format-from-attribute.spec.ts | 66 +++++++++----- modules/engine/src/geometry/gpu-geometry.ts | 3 +- 4 files changed, 108 insertions(+), 48 deletions(-) diff --git a/modules/core/src/adapter/type-utils/vertex-format-from-attribute.ts b/modules/core/src/adapter/type-utils/vertex-format-from-attribute.ts index 9f38cd2f8a..1ff39eaf00 100644 --- a/modules/core/src/adapter/type-utils/vertex-format-from-attribute.ts +++ b/modules/core/src/adapter/type-utils/vertex-format-from-attribute.ts @@ -1,42 +1,77 @@ // luma.gl, MIT licese -import {TypedArray} from '../..'; -import {DataType, VertexFormat} from '../types/vertex-formats'; +import {TypedArray, TypedArrayConstructor} from '../..'; +import {VertexFormat} from '../types/vertex-formats'; -/** Get the vertex format for an attribute with TypedArray value and size*/ -export function getVertexFormatFromAttribute({value, size}: {value: TypedArray, size?: number}): VertexFormat { +// import {DataType} from '../types/vertex-formats'; +// type Omit unfortunately breaks Typescript inferance +type DataType = 'uint8' | 'sint8' | 'uint16' | 'sint16' | 'uint32' | 'sint32' | 'float32'; + +export function getDataTypeFromTypedArray(arrayOrType: TypedArray | TypedArrayConstructor): DataType { + const type = ArrayBuffer.isView(arrayOrType) ? arrayOrType.constructor : arrayOrType; + switch (type) { + case Float32Array: + return 'float32'; + case Uint16Array: + return 'uint16'; + case Uint32Array: + return 'uint32'; + case Uint8Array: + case Uint8ClampedArray: + return 'uint8'; + case Int8Array: + return 'sint8'; + case Int16Array: + return 'sint16'; + case Int32Array: + return 'sint32'; + default: + // Failed to deduce data type from typed array + throw new Error(type.constructor.name); + } +} + +export function getTypedArrayFromDataType(dataType: DataType): TypedArrayConstructor { + switch (dataType) { + case 'float32': + return Float32Array; + case 'uint16': + return Uint16Array; + case 'uint32': + return Uint32Array; + case 'uint8': + return Uint8Array; + case 'sint8': + return Int8Array; + case 'sint16': + return Int16Array; + case 'sint32': + return Int32Array; + default: + // Failed to deduce typed array from data type + throw new Error(dataType); + } +} + +/** Get the vertex format for an attribute with TypedArray and size */ +export function getVertexFormatFromAttribute(typedArray: TypedArray, size?: number): VertexFormat { if(!size || size > 4) { - throw new Error(`Invalid attribute size ${size}`); + throw new Error(`size ${size}`); } const components = size as 1 | 2 | 3 | 4; - let dataType: DataType; - if (value instanceof Uint8Array || value instanceof Uint8ClampedArray) { - dataType = 'uint8'; - } else if (value instanceof Int8Array) { - dataType = 'sint8'; - } else if (value instanceof Uint16Array) { - dataType = 'uint16'; - } else if (value instanceof Int16Array) { - dataType = 'sint16'; - } else if (value instanceof Uint32Array) { - dataType = 'uint32'; - } else if (value instanceof Int32Array) { - dataType = 'sint32'; - } else if (value instanceof Float32Array) { - dataType = 'float32'; - } else { - throw new Error(`Unknown attribute format ${value.constructor.name}`); - } + const dataType: DataType = getDataTypeFromTypedArray(typedArray); if (dataType === 'uint8' || dataType === 'sint8') { if (components === 1 || components === 3) { - throw new Error('WebGPU only supports 16 bit aligned formats'); + // WebGPU 8 bit formats must be aligned to 16 bit boundaries'); + throw new Error(`size: ${size}`); } return `${dataType}x${components}`; } if (dataType === 'uint16' || dataType === 'sint16') { if (components === 1 || components === 3) { - throw new Error('WebGPU only supports 32 bit aligned formats'); + // WebGPU 16 bit formats must be aligned to 32 bit boundaries + throw new Error(`size: ${size}`); } return `${dataType}x${components}`; } diff --git a/modules/core/src/index.ts b/modules/core/src/index.ts index 10856d7c16..99b4132fc6 100644 --- a/modules/core/src/index.ts +++ b/modules/core/src/index.ts @@ -113,7 +113,7 @@ export {UniformStore} from './lib/uniforms/uniform-store'; // TYPE UTILS export {decodeVertexFormat} from './adapter/type-utils/decode-vertex-format'; export {decodeTextureFormat} from './adapter/type-utils/decode-texture-format'; -export {getVertexFormatFromAttribute} from './adapter/type-utils/vertex-format-from-attribute'; +export {getDataTypeFromTypedArray, getTypedArrayFromDataType, getVertexFormatFromAttribute} from './adapter/type-utils/vertex-format-from-attribute'; // SHADER TYPE UTILS export {decodeShaderUniformType} from './adapter/type-utils/decode-shader-types'; diff --git a/modules/core/test/adapter/type-utils/vertex-format-from-attribute.spec.ts b/modules/core/test/adapter/type-utils/vertex-format-from-attribute.spec.ts index 64ed987b64..86e507533d 100644 --- a/modules/core/test/adapter/type-utils/vertex-format-from-attribute.spec.ts +++ b/modules/core/test/adapter/type-utils/vertex-format-from-attribute.spec.ts @@ -1,40 +1,64 @@ // luma.gl, MIT license import test from 'tape-promise/tape'; -import {TypedArray, VertexFormat, getVertexFormatFromAttribute} from '@luma.gl/core'; +import {VertexFormat, getDataTypeFromTypedArray, getTypedArrayFromDataType, getVertexFormatFromAttribute} from '@luma.gl/core'; +import type {TypedArray, TypedArrayConstructor} from '@luma.gl/core'; -const TEST_CASES: {value: TypedArray, size?: number, result?: VertexFormat, error?: string}[] = [ - {value: new Uint8Array(), size: 4, result: 'uint8x4'}, - {value: new Uint8ClampedArray(), size: 2, result: 'uint8x2'}, - {value: new Int8Array(), size: 4, result: 'sint8x4'}, - {value: new Uint16Array(), size: 4, result: 'uint16x4'}, - {value: new Int16Array(), size: 2, result: 'sint16x2'}, - {value: new Uint32Array(), size: 3, result: 'uint32x3'}, - {value: new Int32Array(), size: 1, result: 'sint32'}, - {value: new Float32Array(), size: 2, result: 'float32x2'}, - {value: new Float32Array(), size: 3, result: 'float32x3'}, - {value: new Float32Array(), size: 4, result: 'float32x4'}, +const TEST_CASES: {typedArray: TypedArray, size?: number, result?: VertexFormat, error?: string}[] = [ + {typedArray: new Uint8Array(), size: 4, result: 'uint8x4'}, + {typedArray: new Uint8ClampedArray(), size: 2, result: 'uint8x2'}, + {typedArray: new Int8Array(), size: 4, result: 'sint8x4'}, + {typedArray: new Uint16Array(), size: 4, result: 'uint16x4'}, + {typedArray: new Int16Array(), size: 2, result: 'sint16x2'}, + {typedArray: new Uint32Array(), size: 3, result: 'uint32x3'}, + {typedArray: new Int32Array(), size: 1, result: 'sint32'}, + {typedArray: new Float32Array(), size: 2, result: 'float32x2'}, + {typedArray: new Float32Array(), size: 3, result: 'float32x3'}, + {typedArray: new Float32Array(), size: 4, result: 'float32x4'}, - {value: new Float32Array(), size: 5, error: 'Invalid attribute size 5'}, - {value: new Int32Array(), error: 'Missing attribute size'}, - {value: new Uint8Array(), size: 1, error: 'Bad 16 bit alignment'}, - {value: new Int16Array(), size: 3, error: 'Bad 32 bit alignment'}, - {value: new Float64Array(), size: 2, error: 'Unknown array format'}, + {typedArray: new Float32Array(), size: 5, error: 'Invalid attribute size 5'}, + {typedArray: new Int32Array(), error: 'Missing attribute size'}, + {typedArray: new Uint8Array(), size: 1, error: 'Bad 16 bit alignment'}, + {typedArray: new Int16Array(), size: 3, error: 'Bad 32 bit alignment'}, + {typedArray: new Float64Array(), size: 2, error: 'Unknown array format'}, ]; test('api#getVertexFormatFromAttribute', t => { - for (const {value, size, result, error} of TEST_CASES) { + for (const {typedArray, size, result, error} of TEST_CASES) { if (result) { - const vertexFormat = getVertexFormatFromAttribute({value, size}); + const vertexFormat = getVertexFormatFromAttribute(typedArray, size); t.deepEqual( vertexFormat, result, - `Attribute value '${value.constructor.name}, size: ${size}' => ${result}` + `Typed array: '${typedArray.constructor.name}, size: ${size}' => ${result}` ); } else { t.throws(() => { - getVertexFormatFromAttribute({value, size}); + getVertexFormatFromAttribute(typedArray, size); }, error); } } t.end(); }); + +const ARRAY_TEST_CASES: {typedArray: TypedArrayConstructor}[] = [ + {typedArray: Uint8Array}, + {typedArray: Int8Array}, + {typedArray: Uint16Array}, + {typedArray: Int16Array}, + {typedArray: Uint32Array}, + {typedArray: Int32Array}, + {typedArray: Float32Array} +] + +test('api#getDataTypeFromTypedArray', t => { + for (const {typedArray} of ARRAY_TEST_CASES) { + const dataType = getDataTypeFromTypedArray(typedArray); + const result = getTypedArrayFromDataType(dataType); + t.deepEqual( + typedArray, + result, + `TypedArray '${typedArray.name}, => ${dataType} => ${result.name}` + ); + } + t.end(); +}); diff --git a/modules/engine/src/geometry/gpu-geometry.ts b/modules/engine/src/geometry/gpu-geometry.ts index 4384bd25a3..cd7ffa27b1 100644 --- a/modules/engine/src/geometry/gpu-geometry.ts +++ b/modules/engine/src/geometry/gpu-geometry.ts @@ -114,7 +114,8 @@ export function getAttributeBuffersFromGeometry( case 'TEXCOORD_0': name = 'texCoords'; break; } attributes[name] = device.createBuffer({data: attribute.value, id: `${attributeName}-buffer`}); - bufferLayout.push({name, format: getVertexFormatFromAttribute(attribute)}); + const {value, size} = attribute; + bufferLayout.push({name, format: getVertexFormatFromAttribute(value, size)}); } const vertexCount = geometry._calculateVertexCount(geometry.attributes, geometry.indices) From 84d5ae2ea96e577f1791ca7bf90405bdcbbc313c Mon Sep 17 00:00:00 2001 From: Felix Palmer Date: Tue, 19 Dec 2023 11:17:23 +0100 Subject: [PATCH 5/5] Add deprecation notices --- modules/webgl/src/classic/typed-array-utils.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/webgl/src/classic/typed-array-utils.ts b/modules/webgl/src/classic/typed-array-utils.ts index e2ba0d9fde..1e03cc9eff 100644 --- a/modules/webgl/src/classic/typed-array-utils.ts +++ b/modules/webgl/src/classic/typed-array-utils.ts @@ -9,6 +9,7 @@ const ERR_TYPE_DEDUCTION = 'Failed to deduce GL constant from typed array'; /** * Converts TYPED ARRAYS to corresponding GL constant * Used to auto deduce gl parameter types + * @deprecated Use getDataTypeFromTypedArray * @param arrayOrType * @returns */ @@ -40,6 +41,7 @@ export function getGLTypeFromTypedArray(arrayOrType: TypedArray): GLDataType { /** * Converts GL constant to corresponding TYPED ARRAY * Used to auto deduce gl parameter types + * @deprecated Use getTypedArrayFromDataType * @param glType * @param param1 * @returns