Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: various type fixes addressing deck.gl integration #1685

Merged
merged 2 commits into from Nov 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 1 addition & 3 deletions modules/api/src/adapter/resources/texture.ts
@@ -1,6 +1,6 @@
// luma.gl, MIT license
import type Device from '../device';
import type {TypedArray} from '../../types';
import type {TypedArray, PartialBy} from '../../types';
import type {TextureFormat} from '../types/texture-formats';
import Resource, {ResourceProps, DEFAULT_RESOURCE_PROPS} from './resource';
import Sampler, {SamplerProps} from './sampler';
Expand Down Expand Up @@ -80,8 +80,6 @@ export type TextureViewProps = {
baseMipLevel?: number;
};

type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;

const DEFAULT_TEXTURE_PROPS: PartialBy<Required<TextureProps>, 'width' | 'height' | 'type' | 'samples' | 'mipLevels' | 'textureUnit' | 'target' | 'dataFormat'> = {
...DEFAULT_RESOURCE_PROPS,
data: null,
Expand Down
15 changes: 11 additions & 4 deletions modules/api/src/index.ts
Expand Up @@ -10,7 +10,6 @@ export {default as Device} from './adapter/device';
export type {CanvasContextProps} from './adapter/canvas-context';
export {default as CanvasContext} from './adapter/canvas-context';


// GPU RESOURCES
export type {ResourceProps} from './adapter/resources/resource';
export {default as Resource} from './adapter/resources/resource';
Expand Down Expand Up @@ -64,7 +63,7 @@ export type {UniformFormat} from './adapter/types/uniform-formats';
export type {
TextureFormat,
ColorTextureFormat,
DepthStencilTextureFormat,
DepthStencilTextureFormat
} from './adapter/types/texture-formats';
export type {ColorAttachment, DepthStencilAttachment} from './adapter/types/types';

Expand All @@ -90,9 +89,17 @@ export {default as UniformBlock} from './lib/uniform-block';
export {decodeVertexFormat} from './adapter/utils/decode-vertex-format';
export {decodeTextureFormat} from './adapter/utils/decode-texture-format';


// GENERAL TYPES
export type {TypedArray, TypedArrayConstructor, NumberArray} from './types';
export type {
TypedArray,
TypedArrayConstructor,
NumberArray,
NumericArray,
BigIntOrNumberArray,
BigIntOrNumericArray,
ConstructorOf,
PartialBy
} from './types';

// GENERAL UTILS

Expand Down
20 changes: 18 additions & 2 deletions modules/api/src/types.ts
Expand Up @@ -10,7 +10,8 @@ export type TypedArray =
| Float32Array
| Float64Array;

export type TypedArrayConstructor =
/** TypeScript type covering constructors of any of the typed arrays */
export type TypedArrayConstructor =
| Int8ArrayConstructor
| Uint8ArrayConstructor
| Int16ArrayConstructor
Expand All @@ -21,9 +22,24 @@ export type TypedArray =
| Float32ArrayConstructor
| Float64ArrayConstructor;

export type BigIntTypedArray = BigInt64Array | BigUint64Array;
/** Keep big int arrays separate as they are still problematic, can't be indexed and don't work well on Safari */
export type BigIntTypedArray = BigInt64Array | BigUint64Array;

/** type covering all typed arrays and classic arrays consisting of numbers */
export type NumberArray = number[] | TypedArray;
export type NumericArray = number[] | TypedArray;

export type BigIntOrNumberArray = NumberArray | BigIntTypedArray;
export type BigIntOrNumericArray = NumberArray | BigIntTypedArray;

/** Get the constructor type of a type */
export interface ConstructorOf<T> {
new (...args: unknown[]): T;
}

/**
* Make specific fields in a type optional. Granular version of `Partial<T>`
* @example
* type PartialProps = PartialBy<Required<DeviceProps>, 'device' | 'canvas'>
*/
export type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
9 changes: 4 additions & 5 deletions modules/engine/src/lib/model.ts
@@ -1,6 +1,6 @@
// luma.gl, MIT license

import type {Device, Buffer, RenderPipelineProps, RenderPass, Binding} from '@luma.gl/api';
import type {Device, Buffer, RenderPipelineProps, RenderPass, Binding, PrimitiveTopology} from '@luma.gl/api';
import {RenderPipeline, Shader, cast} from '@luma.gl/api';
import type { ShaderModule } from '@luma.gl/shadertools';
import type Geometry from '../geometry/geometry';
Expand Down Expand Up @@ -35,7 +35,7 @@ export default class Model {
readonly id: string;
readonly vs: string;
readonly fs: string | undefined;
readonly topology: string;
readonly topology: PrimitiveTopology;
readonly vertexCount;
props: Required<ModelProps>;

Expand All @@ -61,14 +61,13 @@ export default class Model {
this.topology = this.props.geometry.topology;
}

const {pipeline, getUniforms} = PipelineFactory.getDefaultPipelineFactory(this.device).createRenderPipeline({
const pipelineFactory = PipelineFactory.getDefaultPipelineFactory(this.device);
const {pipeline, getUniforms} = pipelineFactory.createRenderPipeline({
...this.props,
vs: this.vs,
fs: this.fs,
topology: this.topology,
parameters: props.parameters,
// Geometry in the vertex shader!
// @ts-expect-error
layout: props.layout
});

Expand Down
28 changes: 15 additions & 13 deletions modules/engine/src/lib/pipeline-factory.ts
@@ -1,34 +1,35 @@
import type {RenderPipelineProps, RenderPipelineParameters} from '@luma.gl/api';
import type {RenderPipelineProps, RenderPipelineParameters, PrimitiveTopology, ShaderLayout} from '@luma.gl/api';
import {Device, RenderPipeline, ComputePipeline} from '@luma.gl/api/';
import type { ShaderModule } from '@luma.gl/shadertools';
import {assembleShaders} from '@luma.gl/shadertools';

export type GetRenderPipelineOptions = {
vs: string,
fs: string,
topology;
vs: string;
fs: string;
topology: PrimitiveTopology;
layout?: ShaderLayout;
parameters?: RenderPipelineParameters;

modules?: ShaderModule[];
defines?: Record<string, string | number | boolean>,
inject?: Record<string, string>,
defines?: Record<string, string | number | boolean>;
inject?: Record<string, string>;
transpileToGLSL100?: boolean;

varyings?: string[],
varyings?: string[];
bufferMode?: number,
};

export type GetComputePipelineOptions = {
cs: string,
parameters?: RenderPipelineParameters;
cs: string;
parameters?: RenderPipelineParameters;

modules?: ShaderModule[];
defines?: Record<string, string>,
inject?: Record<string, string>,
defines?: Record<string, string>;
inject?: Record<string, string>;
transpileToGLSL100?: boolean;

varyings?: string[],
bufferMode?: number,
varyings?: string[];
bufferMode?: number;
};

const DEFAULT_RENDER_PIPELINE_OPTIONS: Required<GetRenderPipelineOptions> = {
Expand All @@ -38,6 +39,7 @@ const DEFAULT_RENDER_PIPELINE_OPTIONS: Required<GetRenderPipelineOptions> = {
defines: {},
inject: {},
transpileToGLSL100: false,
layout: null,

varyings: [],
bufferMode: 0x8c8d, // // varyings/bufferMode for xform feedback, 0x8c8d: SEPARATE_ATTRIBS
Expand Down
56 changes: 28 additions & 28 deletions modules/engine/test/lib/pipeline-factory.spec.ts
Expand Up @@ -66,18 +66,18 @@ test('PipelineFactory#getDefaultPipelineFactory', (t) => {
test('PipelineFactory#basic', (t) => {
const pipelineFactory = new PipelineFactory(webgl1TestDevice);

const {pipeline: program1} = pipelineFactory.createRenderPipeline({vs, fs, topology: 'triangles'});
const {pipeline: program1} = pipelineFactory.createRenderPipeline({vs, fs, topology: 'triangle-list'});

t.ok(program1, 'Got a pipeline');

const {pipeline: pipeline2} = pipelineFactory.createRenderPipeline({vs, fs, topology: 'triangles'});
const {pipeline: pipeline2} = pipelineFactory.createRenderPipeline({vs, fs, topology: 'triangle-list'});

t.ok(program1 === pipeline2, 'Got cached pipeline');

const {pipeline: definePipeline1} = pipelineFactory.createRenderPipeline({
vs,
fs,
topology: 'triangles',
topology: 'triangle-list',
defines: {
MY_DEFINE: true
}
Expand All @@ -88,7 +88,7 @@ test('PipelineFactory#basic', (t) => {
const {pipeline: definePipeline2} = pipelineFactory.createRenderPipeline({
vs,
fs,
topology: 'triangles',
topology: 'triangle-list',
defines: {
MY_DEFINE: true
}
Expand All @@ -99,7 +99,7 @@ test('PipelineFactory#basic', (t) => {
const {pipeline: modulePipeline1} = pipelineFactory.createRenderPipeline({
vs,
fs,
topology: 'triangles',
topology: 'triangle-list',
modules: [picking]
});

Expand All @@ -109,7 +109,7 @@ test('PipelineFactory#basic', (t) => {
const {pipeline: modulePipeline2} = pipelineFactory.createRenderPipeline({
vs,
fs,
topology: 'triangles',
topology: 'triangle-list',
modules: [picking]
});

Expand All @@ -118,7 +118,7 @@ test('PipelineFactory#basic', (t) => {
const {pipeline: defineModulePipeline1} = pipelineFactory.createRenderPipeline({
vs,
fs,
topology: 'triangles',
topology: 'triangle-list',
modules: [picking],
defines: {
MY_DEFINE: true
Expand All @@ -132,7 +132,7 @@ test('PipelineFactory#basic', (t) => {
const {pipeline: defineModulePipeline2} = pipelineFactory.createRenderPipeline({
vs,
fs,
topology: 'triangles',
topology: 'triangle-list',
modules: [picking],
defines: {
MY_DEFINE: true
Expand All @@ -150,15 +150,15 @@ test('PipelineFactory#basic', (t) => {
test('PipelineFactory#hooks', (t) => {
const pipelineFactory = new PipelineFactory(webgl1TestDevice);

const {pipeline: preHookPipeline} = pipelineFactory.createRenderPipeline({vs, fs, topology: 'triangles'});
const {pipeline: preHookPipeline} = pipelineFactory.createRenderPipeline({vs, fs, topology: 'triangle-list'});

pipelineFactory.addShaderHook('vs:LUMAGL_pickColor(inout vec4 color)');
pipelineFactory.addShaderHook('fs:LUMAGL_fragmentColor(inout vec4 color)', {
header: 'if (color.a == 0.0) discard;\n',
footer: 'color.a *= 1.2;\n'
});

const {pipeline: postHookPipeline} = pipelineFactory.createRenderPipeline({vs, fs, topology: 'triangles'});
const {pipeline: postHookPipeline} = pipelineFactory.createRenderPipeline({vs, fs, topology: 'triangle-list'});

t.ok(preHookPipeline !== postHookPipeline, 'Adding hooks changes hash');

Expand All @@ -175,7 +175,7 @@ test('PipelineFactory#hooks', (t) => {
picking
);

const {pipeline: noModulePipeline} = pipelineFactory.createRenderPipeline({vs, fs, topology: 'triangles'});
const {pipeline: noModulePipeline} = pipelineFactory.createRenderPipeline({vs, fs, topology: 'triangle-list'});

t.ok(preHookPipeline !== noModulePipeline, 'Adding hooks changes hash');

Expand All @@ -200,7 +200,7 @@ test('PipelineFactory#hooks', (t) => {
const {pipeline: modulesPipeline} = pipelineFactory.createRenderPipeline({
vs,
fs,
topology: 'triangles',
topology: 'triangle-list',
modules: [pickingInjection]
});
const modulesVs = modulesPipeline.vs.source;
Expand Down Expand Up @@ -232,7 +232,7 @@ test('PipelineFactory#hooks', (t) => {
const {pipeline: injectPipeline} = pipelineFactory.createRenderPipeline({
vs,
fs,
topology: 'triangles',
topology: 'triangle-list',
inject: {
'vs:LUMAGL_pickColor': 'color *= 0.1;',
'fs:LUMAGL_fragmentColor': 'color += 0.1;'
Expand All @@ -247,7 +247,7 @@ test('PipelineFactory#hooks', (t) => {
const {pipeline: injectDefinePipeline1} = pipelineFactory.createRenderPipeline({
vs,
fs,
topology: 'triangles',
topology: 'triangle-list',
inject: {
'vs:LUMAGL_pickColor': 'color *= 0.1;'
}
Expand All @@ -256,7 +256,7 @@ test('PipelineFactory#hooks', (t) => {
const {pipeline: injectDefinePipeline2} = pipelineFactory.createRenderPipeline({
vs,
fs,
topology: 'triangles',
topology: 'triangle-list',
defines: {
'vs:LUMAGL_pickColor': 'color *= 0.1;'
}
Expand All @@ -270,24 +270,24 @@ test('PipelineFactory#hooks', (t) => {
test('PipelineFactory#defaultModules', (t) => {
const pipelineFactory = new PipelineFactory(webgl1TestDevice);

const {pipeline} = pipelineFactory.createRenderPipeline({vs, fs, topology: 'triangles'});
const {pipeline} = pipelineFactory.createRenderPipeline({vs, fs, topology: 'triangle-list'});

const {pipeline: preDefaultModulePipeline} = pipelineFactory.createRenderPipeline({
vs,
fs,
topology: 'triangles',
topology: 'triangle-list',
modules: [dirlight]
});

const preDefaultModuleSource = preDefaultModulePipeline.fs.source;

pipelineFactory.addDefaultModule(dirlight);

const {pipeline: defaultModulePipeline} = pipelineFactory.createRenderPipeline({vs, fs, topology: 'triangles'});
const {pipeline: defaultModulePipeline} = pipelineFactory.createRenderPipeline({vs, fs, topology: 'triangle-list'});
const {pipeline: modulePipeline} = pipelineFactory.createRenderPipeline({
vs,
fs,
topology: 'triangles',
topology: 'triangle-list',
modules: [dirlight]
});

Expand All @@ -307,7 +307,7 @@ test('PipelineFactory#defaultModules', (t) => {

pipelineFactory.removeDefaultModule(dirlight);

const {pipeline: noDefaultModulePipeline} = pipelineFactory.createRenderPipeline({vs, fs, topology: 'triangles'});
const {pipeline: noDefaultModulePipeline} = pipelineFactory.createRenderPipeline({vs, fs, topology: 'triangle-list'});

t.ok(pipeline.fs.source === noDefaultModulePipeline.fs.source, 'Default module was removed');
t.ok(modulePipeline.fs.source !== noDefaultModulePipeline.fs.source, 'Default module was removed');
Expand All @@ -319,7 +319,7 @@ test('PipelineFactory#defaultModules', (t) => {
pipelineFactory.release(noDefaultModulePipeline);

pipelineFactory.addDefaultModule(dirlight);
const {pipeline: uncachedPipeline} = pipelineFactory.createRenderPipeline({vs, fs, topology: 'triangles'});
const {pipeline: uncachedPipeline} = pipelineFactory.createRenderPipeline({vs, fs, topology: 'triangle-list'});
const defaultModuleSource = uncachedPipeline.fs.source;

t.ok(defaultModulePipeline !== uncachedPipeline, 'Pipeline is not cached');
Expand All @@ -331,8 +331,8 @@ test('PipelineFactory#defaultModules', (t) => {
test('PipelineFactory#release', (t) => {
const pipelineFactory = new PipelineFactory(webgl1TestDevice);

const {pipeline: pipeline1} = pipelineFactory.createRenderPipeline({vs, fs, topology: 'triangles'});
const {pipeline: pipeline2} = pipelineFactory.createRenderPipeline({vs, fs, topology: 'triangles'});
const {pipeline: pipeline1} = pipelineFactory.createRenderPipeline({vs, fs, topology: 'triangle-list'});
const {pipeline: pipeline2} = pipelineFactory.createRenderPipeline({vs, fs, topology: 'triangle-list'});

pipelineFactory.release(pipeline1);
t.ok(!pipeline1.destroyed, 'Pipeline not deleted when still referenced.');
Expand All @@ -350,22 +350,22 @@ test('PipelineFactory#transpileToGLSL100', (t) => {
pipelineFactory.createRenderPipeline({
vs: VS_300,
fs: FS_300,
topology: 'triangles'
topology: 'triangle-list'
});
}, "Can't compile 300 shader with WebGL 1");

t.doesNotThrow(() => {
pipelineFactory.createRenderPipeline({
vs: VS_300,
fs: FS_300,
topology: 'triangles',
topology: 'triangle-list',
transpileToGLSL100: true
});
}, 'Can compile transpiled 300 shader with WebGL 1');

const {pipeline: programTranspiled} = pipelineFactory.createRenderPipeline({vs, fs, topology: 'triangles', transpileToGLSL100: true});
const {pipeline: programUntranspiled} = pipelineFactory.createRenderPipeline({vs, fs, topology: 'triangles'});
const {pipeline: programTranspiled2} = pipelineFactory.createRenderPipeline({vs, fs, topology: 'triangles', transpileToGLSL100: true});
const {pipeline: programTranspiled} = pipelineFactory.createRenderPipeline({vs, fs, topology: 'triangle-list', transpileToGLSL100: true});
const {pipeline: programUntranspiled} = pipelineFactory.createRenderPipeline({vs, fs, topology: 'triangle-list'});
const {pipeline: programTranspiled2} = pipelineFactory.createRenderPipeline({vs, fs, topology: 'triangle-list', transpileToGLSL100: true});

t.equals(programTranspiled, programTranspiled2, 'Transpiled programs match');
t.notEquals(
Expand Down