Skip to content

Commit

Permalink
feat(shader-ast): add optimizers for built-in fns
Browse files Browse the repository at this point in the history
  • Loading branch information
postspectacular committed Aug 13, 2021
1 parent e2af71b commit b0124d7
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 14 deletions.
6 changes: 4 additions & 2 deletions packages/shader-ast/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ yarn add @thi.ng/shader-ast
<script src="https://unpkg.com/@thi.ng/shader-ast/lib/index.umd.js" crossorigin></script>
```

Package sizes (gzipped, pre-treeshake): ESM: 5.21 KB / CJS: 5.78 KB / UMD: 5.13 KB
Package sizes (gzipped, pre-treeshake): ESM: 5.46 KB / CJS: 6.00 KB / UMD: 5.36 KB

## Dependencies

Expand All @@ -195,6 +195,7 @@ Package sizes (gzipped, pre-treeshake): ESM: 5.21 KB / CJS: 5.78 KB / UMD: 5.13
- [@thi.ng/defmulti](https://github.com/thi-ng/umbrella/tree/develop/packages/defmulti)
- [@thi.ng/dgraph](https://github.com/thi-ng/umbrella/tree/develop/packages/dgraph)
- [@thi.ng/errors](https://github.com/thi-ng/umbrella/tree/develop/packages/errors)
- [@thi.ng/math](https://github.com/thi-ng/umbrella/tree/develop/packages/math)

## Usage examples

Expand Down Expand Up @@ -569,7 +570,8 @@ execute shader-ast trees/programs:

Currently, only the following operations are supported / considered:

- scalar math ops
- scalar math operators
- scalar math built-in functions
- single component vector swizzling
- literal hoisting

Expand Down
3 changes: 2 additions & 1 deletion packages/shader-ast/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@
"@thi.ng/checks": "^2.9.10",
"@thi.ng/defmulti": "^1.3.16",
"@thi.ng/dgraph": "^1.3.30",
"@thi.ng/errors": "^1.3.4"
"@thi.ng/errors": "^1.3.4",
"@thi.ng/math": "^4.0.5"
},
"files": [
"*.js",
Expand Down
66 changes: 56 additions & 10 deletions packages/shader-ast/src/optimize.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { LogLevel } from "@thi.ng/api";
import { Fn, IObjectOf, LogLevel } from "@thi.ng/api";
import { DEFAULT, defmulti } from "@thi.ng/defmulti";
import type { Lit, Op1, Op2, Swizzle, Term } from "./api/nodes";
import { clamp, deg, fract, mix, mod, rad } from "@thi.ng/math";
import type { FnCall, Lit, Op1, Op2, Swizzle, Term } from "./api/nodes";
import type { Operator } from "./api/ops";
import type { Swizzle4_1 } from "./api/swizzles";
import {
Expand Down Expand Up @@ -36,8 +37,14 @@ const replaceNode = (node: any, next: any) => {
return true;
};

const replaceNumericNode = (node: any, res: number) => {
node.type === "int" && (res |= 0);
node.type === "uint" && (res >>>= 0);
return replaceNode(node, lit(node.type, res));
};

/** @internal */
const maybeFoldMath = (op: Operator, l: any, r: any) =>
const maybeFoldMath = (op: Operator, l: number, r: number) =>
op === "+"
? l + r
: op === "-"
Expand All @@ -51,6 +58,33 @@ const maybeFoldMath = (op: Operator, l: any, r: any) =>
/** @internal */
const COMPS: Record<Swizzle4_1, number> = { x: 0, y: 1, z: 2, w: 3 };

const BUILTINS: IObjectOf<Fn<number[], number>> = {
abs: ([a]) => Math.abs(a),
acos: ([a]) => Math.acos(a),
asin: ([a]) => Math.asin(a),
ceil: ([a]) => Math.ceil(a),
clamp: ([a, b, c]) => clamp(a, b, c),
cos: ([a]) => Math.cos(a),
degrees: ([a]) => deg(a),
exp: ([a]) => Math.exp(a),
exp2: ([a]) => Math.pow(2, a),
floor: ([a]) => Math.floor(a),
fract: ([a]) => fract(a),
inversesqrt: ([a]) => 1 / Math.sqrt(a),
log: ([a]) => Math.log(a),
log2: ([a]) => Math.log2(a),
max: ([a, b]) => Math.max(a, b),
min: ([a, b]) => Math.min(a, b),
mix: ([a, b, c]) => mix(a, b, c),
mod: ([a, b]) => mod(a, b),
pow: ([a, b]) => Math.pow(a, b),
radians: ([a]) => rad(a),
sign: ([a]) => Math.sign(a),
sin: ([a]) => Math.sin(a),
tan: ([a]) => Math.tan(a),
sqrt: ([a]) => Math.sqrt(a),
};

/** @internal */
export const foldNode = defmulti<Term<any>, boolean | undefined>((t) => t.tag);
foldNode.add(DEFAULT, () => false);
Expand All @@ -67,13 +101,24 @@ foldNode.addAll({
op2: (node) => {
const $node = <Op2<any>>node;
if (isLitNumericConst($node.l) && isLitNumericConst($node.r)) {
const vl = (<Lit<"float">>$node.l).val;
const vr = (<Lit<"float">>$node.r).val;
let res = maybeFoldMath($node.op, vl, vr);
const l: number = $node.l.val;
const r: number = $node.r.val;
let res = maybeFoldMath($node.op, l, r);
if (res !== undefined) {
$node.type === "int" && (res |= 0);
$node.type === "uint" && (res >>>= 0);
return replaceNode(node, lit($node.type, res));
return replaceNumericNode(node, res);
}
}
},

call_i: (node) => {
const $node = <FnCall<any>>node;
if ($node.args.every((x) => isLitNumericConst(x))) {
const op = BUILTINS[$node.id];
if (op !== undefined) {
return replaceNumericNode(
node,
op($node.args.map((x) => (<Lit<any>>x).val))
);
}
}
},
Expand Down Expand Up @@ -115,7 +160,8 @@ foldNode.addAll({
* @remarks
* Currently, only the following operations are supported / considered:
*
* - scalar math ops
* - scalar math operators
* - scalar math built-in functions
* - single component vector swizzling
* - literal hoisting
*
Expand Down
3 changes: 2 additions & 1 deletion packages/shader-ast/tpl.readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,8 @@ execute shader-ast trees/programs:

Currently, only the following operations are supported / considered:

- scalar math ops
- scalar math operators
- scalar math built-in functions
- single component vector swizzling
- literal hoisting

Expand Down

0 comments on commit b0124d7

Please sign in to comment.