Skip to content

Commit 15daabb

Browse files
authored
Merge branch 'main' into feat/destruct-entry-args
2 parents d521dbf + 51354a8 commit 15daabb

27 files changed

+1462
-793
lines changed

apps/typegpu-docs/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
"react": "^19.0.0",
4242
"react-dom": "^19.0.0",
4343
"remeda": "^2.21.2",
44-
"sharp": "^0.32.5",
44+
"sharp": "^0.34.2",
4545
"starlight-blog": "^0.23.2",
4646
"starlight-typedoc": "^0.19.0",
4747
"tinybench": "^3.1.0",
@@ -60,7 +60,7 @@
6060
"@webgpu/types": "catalog:",
6161
"astro-vtbot": "^2.0.6",
6262
"autoprefixer": "^10.4.16",
63-
"tailwindcss": "^4.1.6",
63+
"tailwindcss": "^4.1.7",
6464
"tailwindcss-motion": "^1.0.1",
6565
"yaml": "^2.7.0"
6666
}

apps/typegpu-docs/src/content/docs/reference/data-schema-cheatsheet.mdx

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,47 @@
22
title: Data Schema Cheatsheet
33
---
44

5-
## Numeric data types
5+
## Scalar data types
66

77
import { Code } from '@astrojs/starlight/components';
88

99
| Schema | JavaScript | WGSL |
1010
| --- | --- | --- |
1111
| <Code code="import { f32 } from 'typegpu/data';" lang="js" /> | `number` | `f32` |
12+
| <Code code="import { f16 } from 'typegpu/data';" lang="js" /> | `number` | `f16` |
1213
| <Code code="import { i32 } from 'typegpu/data';" lang="js" /> | `number` | `i32` |
1314
| <Code code="import { u32 } from 'typegpu/data';" lang="js" /> | `number` | `u32` |
1415
| <Code code="import { bool } from 'typegpu/data';" lang="js" /> | `boolean` | `bool` |
1516

1617
## Vector and matrix types
1718

18-
| Schema | Value constructors | WGSL equivalents |
19+
| <div style="width:5em">Schema</div> | Value constructors | <div style="width:5em">WGSL equivalents</div> |
1920
| --- | --- | --- |
2021
| `vec2u` | <ul><li>`vec2u(x: number, y: number)`</li> <li>`vec2u(xy: number)`</li> <li>`vec2u()`</li></ul> | vec2u, vec2\<u32\> |
2122
| `vec2f` | <ul><li>`vec2f(x: number, y: number)`</li> <li>`vec2f(xy: number)`</li> <li>`vec2f()`</li></ul> | vec2f, vec2\<f32\> |
2223
| `vec2i` | <ul><li>`vec2i(x: number, y: number)`</li> <li>`vec2i(xy: number)`</li> <li>`vec2i()`</li></ul> | vec2i, vec2\<i32\> |
2324
| `vec2h` | <ul><li>`vec2h(x: number, y: number)`</li> <li>`vec2h(xy: number)`</li> <li>`vec2h()`</li></ul> | vec2h, vec2\<f16\> |
25+
| `vec2b` | <ul><li>`vec2b(x: boolean, y: boolean)`</li> <li>`vec2b(xy: boolean)`</li> <li>`vec2b()`</li></ul> | vec2\<bool\> |
2426
| `vec3u` | <ul><li>`vec3u(x: number, y: number, z: number)`</li> <li>`vec3u(xyz: number)`</li> <li>`vec3u()`</li></ul> | vec3u, vec3\<u32\> |
2527
| `vec3f` | <ul><li>`vec3f(x: number, y: number, z: number)`</li> <li>`vec3f(xyz: number)`</li> <li>`vec3f()`</li></ul> | vec3f, vec3\<f32\> |
2628
| `vec3i` | <ul><li>`vec3i(x: number, y: number, z: number)`</li> <li>`vec3i(xyz: number)`</li> <li>`vec3i()`</li></ul> | vec3i, vec3\<i32\> |
2729
| `vec3h` | <ul><li>`vec3h(x: number, y: number, z: number)`</li> <li>`vec3h(xyz: number)`</li> <li>`vec3h()`</li></ul> | vec3h, vec3\<f16\> |
30+
| `vec3b` | <ul><li>`vec3b(x: boolean, y: boolean, z: boolean)`</li> <li>`vec3b(xyz: boolean)`</li> <li>`vec3b()`</li></ul> | vec3\<bool\> |
2831
| `vec4u` | <ul><li>`vec4u(x: number, y: number, z: number, w: number)`</li> <li>`vec4u(xyzw: number)`</li> <li>`vec4u()`</li></ul> | vec4u, vec4\<u32\> |
2932
| `vec4f` | <ul><li>`vec4f(x: number, y: number, z: number, w: number)`</li> <li>`vec4f(xyzw: number)`</li> <li>`vec4f()`</li></ul> | vec4f, vec4\<f32\> |
3033
| `vec4i` | <ul><li>`vec4i(x: number, y: number, z: number, w: number)`</li> <li>`vec4i(xyzw: number)`</li> <li>`vec4i()`</li></ul> | vec4i, vec4\<i32\> |
3134
| `vec4h` | <ul><li>`vec4h(x: number, y: number, z: number, w: number)`</li> <li>`vec4h(xyzw: number)`</li> <li>`vec4h()`</li></ul> | vec4h, vec4\<f16\> |
32-
| `mat2x2f` | <ul><li>`mat2x2f(...elements: number[])`</li> <li>`mat2x2f(...columns: vec2f[])`</li> <li>`mat2x2f()`</li></ul> | mat2x2f, mat2x2\<f32\> |
33-
| `mat3x3f` | <ul><li>`mat3x3f(...elements: number[])`</li> <li>`mat3x3f(...columns: vec3f[])`</li> <li>`mat3x3f()`</li></ul> | mat3x3f, mat3x3\<f32\> |
34-
| `mat4x4f` | <ul><li>`mat4x4f(...elements: number[])`</li> <li>`mat4x4f(...columns: vec4f[])`</li> <li>`mat4x4f()`</li></ul> | mat4x4f, mat4x4\<f32\> |
35+
| `vec4b` | <ul><li>`vec4b(x: boolean, y: boolean, z: boolean, w: boolean)`</li> <li>`vec4b(xyzw: boolean)`</li> <li>`vec4b()`</li></ul> | vec4\<bool\> |
36+
| `mat2x2f` | <ul><li>`mat2x2f(...elements: [number, number, number, number])`</li> <li>`mat2x2f(...columns: [v2f, v2f])`</li> <li>`mat2x2f()`</li></ul> | mat2x2f, mat2x2\<f32\> |
37+
| `mat3x3f` | <ul><li>`mat3x3f(...elements: [number, number, number, number, number, number, number, number, number])`</li> <li>`mat3x3f(...columns: [v3f, v3f, v3f])`</li> <li>`mat3x3f()`</li></ul> | mat3x3f, mat3x3\<f32\> |
38+
| `mat4x4f` | <ul><li>`mat4x4f(...elements: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number])`</li> <li>`mat4x4f(...columns: [v4f, v4f, v4f, v4f])`</li> <li>`mat4x4f()`</li></ul> | mat4x4f, mat4x4\<f32\> |
39+
40+
Apart from the listed constructors, all vectors can be created from any mix of other vectors and numbers, like this:
41+
42+
<Code code="
43+
import { vec2f, vec3f, vec4f } from 'typegpu/data';
44+
45+
const a = vec2f(1, 2); // 1, 2
46+
const b = vec3f(0, a); // 0, 1, 2
47+
const c = vec4f(b.xz, a.xx); // 0, 2, 1, 1
48+
" lang="js" />

packages/typegpu/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@
7676
"tsup": "catalog:",
7777
"typescript": "catalog:",
7878
"unplugin-typegpu": "workspace:*",
79-
"wesl": "0.6.0-rc4",
79+
"wesl": "0.6.7",
8080
"wgpu-matrix": "^3.4.0"
8181
},
8282
"packageManager": "[email protected]+sha512.c753b6c3ad7afa13af388fa6d808035a008e30ea9993f58c6663e2bc5ff21679aa834db094987129aa4d488b86df57f7b634981b2f827cdcacc698cc0cfb88af",

packages/typegpu/src/core/function/fnTypes.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type * as tinyest from 'tinyest';
2+
import type { BuiltinClipDistances } from '../../builtin.ts';
23
import type { AnyAttribute } from '../../data/attributes.ts';
34
import type {
45
Decorated,
@@ -80,7 +81,10 @@ export type BaseIOData =
8081
| Vec3u
8182
| Vec4u;
8283

83-
export type IOData = BaseIOData | Decorated<BaseIOData, AnyAttribute[]>;
84+
export type IOData =
85+
| BaseIOData
86+
| Decorated<BaseIOData, AnyAttribute[]>
87+
| BuiltinClipDistances;
8488

8589
export type IORecord<TElementType extends IOData = IOData> = Record<
8690
string,

packages/typegpu/src/core/function/ioOutputType.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import type { IOData, IOLayout, IORecord } from './fnTypes.ts';
1818
export type WithLocations<T extends IORecord> = {
1919
[Key in keyof T]: IsBuiltin<T[Key]> extends true ? T[Key]
2020
: HasCustomLocation<T[Key]> extends true ? T[Key]
21-
: Decorate<T[Key], Location<number>>;
21+
: Decorate<T[Key], Location>;
2222
};
2323

2424
export type IOLayoutToSchema<T extends IOLayout> = T extends BaseData
@@ -52,7 +52,10 @@ export function withLocations<T extends IOData>(
5252
);
5353
}
5454

55-
export function createOutputType<T extends IOData>(returnType: IOLayout<T>) {
55+
export function createIoSchema<
56+
T extends IOData,
57+
Layout extends IORecord<T> | IOLayout<T>,
58+
>(returnType: Layout) {
5659
return (
5760
isData(returnType)
5861
? isVoid(returnType)
@@ -61,9 +64,5 @@ export function createOutputType<T extends IOData>(returnType: IOLayout<T>) {
6164
? returnType
6265
: location(0, returnType)
6366
: struct(withLocations(returnType) as Record<string, T>)
64-
) as IOLayoutToSchema<IOLayout<T>>;
65-
}
66-
67-
export function createStructFromIO<T extends IOData>(members: IORecord<T>) {
68-
return struct(withLocations(members) as Record<string, T>);
67+
) as IOLayoutToSchema<Layout>;
6968
}

packages/typegpu/src/core/function/tgpuComputeFn.ts

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import type { AnyComputeBuiltin } from '../../builtin.ts';
2-
import { type AnyWgslStruct, Void } from '../../data/wgslTypes.ts';
2+
import { Void } from '../../data/wgslTypes.ts';
33
import { getName, isNamable, setName, type TgpuNamable } from '../../name.ts';
44
import { $getNameForward } from '../../shared/symbols.ts';
55
import type { ResolutionCtx, SelfResolvable } from '../../types.ts';
66
import { createFnCore, type FnCore } from './fnCore.ts';
7-
import type { Implementation, InferIO } from './fnTypes.ts';
8-
import { createStructFromIO } from './ioOutputType.ts';
7+
import type { Implementation, InferIO, IORecord } from './fnTypes.ts';
8+
import { createIoSchema, type IOLayoutToSchema } from './ioOutputType.ts';
99
import { stripTemplate } from './templateUtils.ts';
1010

1111
// ----------
@@ -16,9 +16,9 @@ import { stripTemplate } from './templateUtils.ts';
1616
* Describes a compute entry function signature (its arguments, return type and workgroup size)
1717
*/
1818
type TgpuComputeFnShellHeader<
19-
ComputeIn extends Record<string, AnyComputeBuiltin>,
19+
ComputeIn extends IORecord<AnyComputeBuiltin>,
2020
> = {
21-
readonly argTypes: [AnyWgslStruct] | [];
21+
readonly argTypes: [IOLayoutToSchema<ComputeIn>] | [];
2222
readonly returnType: Void;
2323
readonly workgroupSize: [number, number, number];
2424
readonly isEntry: true;
@@ -30,7 +30,7 @@ type TgpuComputeFnShellHeader<
3030
* and passing the implementation (as WGSL string or JS function) as the argument.
3131
*/
3232
export type TgpuComputeFnShell<
33-
ComputeIn extends Record<string, AnyComputeBuiltin>,
33+
ComputeIn extends IORecord<AnyComputeBuiltin>,
3434
> =
3535
& TgpuComputeFnShellHeader<ComputeIn>
3636
/**
@@ -66,12 +66,10 @@ export type TgpuComputeFnShell<
6666
};
6767

6868
export interface TgpuComputeFn<
69-
ComputeIn extends Record<string, AnyComputeBuiltin> = Record<
70-
string,
71-
AnyComputeBuiltin
72-
>,
69+
// biome-ignore lint/suspicious/noExplicitAny: to allow assigning any compute fn to TgpuComputeFn (non-generic) type
70+
ComputeIn extends IORecord<AnyComputeBuiltin> = any,
7371
> extends TgpuNamable {
74-
readonly shell: TgpuComputeFnShell<ComputeIn>;
72+
readonly shell: TgpuComputeFnShellHeader<ComputeIn>;
7573

7674
$uses(dependencyMap: Record<string, unknown>): this;
7775
}
@@ -86,7 +84,7 @@ export function computeFn(options: {
8684
}): TgpuComputeFnShell<{}>;
8785

8886
export function computeFn<
89-
ComputeIn extends Record<string, AnyComputeBuiltin>,
87+
ComputeIn extends IORecord<AnyComputeBuiltin>,
9088
>(options: {
9189
in: ComputeIn;
9290
workgroupSize: number[];
@@ -102,14 +100,14 @@ export function computeFn<
102100
* Size of blocks that the thread grid will be divided into (up to 3 dimensions).
103101
*/
104102
export function computeFn<
105-
ComputeIn extends Record<string, AnyComputeBuiltin>,
103+
ComputeIn extends IORecord<AnyComputeBuiltin>,
106104
>(options: {
107105
in?: ComputeIn;
108106
workgroupSize: number[];
109107
}): TgpuComputeFnShell<ComputeIn> {
110108
const shell: TgpuComputeFnShellHeader<ComputeIn> = {
111109
argTypes: options.in && Object.keys(options.in).length !== 0
112-
? [createStructFromIO(options.in)]
110+
? [createIoSchema(options.in)]
113111
: [],
114112
returnType: Void,
115113
workgroupSize: [
@@ -139,7 +137,7 @@ export function computeFn<
139137
// Implementation
140138
// --------------
141139

142-
function createComputeFn<ComputeIn extends Record<string, AnyComputeBuiltin>>(
140+
function createComputeFn<ComputeIn extends IORecord<AnyComputeBuiltin>>(
143141
shell: TgpuComputeFnShellHeader<ComputeIn>,
144142
workgroupSize: number[],
145143
implementation: Implementation,

packages/typegpu/src/core/function/tgpuFragmentFn.ts

Lines changed: 15 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,11 @@ import type {
33
AnyFragmentOutputBuiltin,
44
OmitBuiltins,
55
} from '../../builtin.ts';
6-
import type { AnyAttribute } from '../../data/attributes.ts';
76
import type {
8-
AnyWgslStruct,
97
Decorated,
8+
Interpolate,
109
Location,
1110
Vec4f,
12-
Void,
1311
} from '../../data/wgslTypes.ts';
1412
import { getName, isNamable, setName, type TgpuNamable } from '../../name.ts';
1513
import { $getNameForward } from '../../shared/symbols.ts';
@@ -21,44 +19,38 @@ import type {
2119
BaseIOData,
2220
Implementation,
2321
InferIO,
22+
IOLayout,
2423
IORecord,
2524
} from './fnTypes.ts';
26-
import {
27-
createOutputType,
28-
createStructFromIO,
29-
type IOLayoutToSchema,
30-
} from './ioOutputType.ts';
25+
import { createIoSchema, type IOLayoutToSchema } from './ioOutputType.ts';
3126
import { stripTemplate } from './templateUtils.ts';
3227

3328
// ----------
3429
// Public API
3530
// ----------
3631

37-
export type FragmentOutConstrained =
38-
| Void
39-
| Vec4f
40-
| Decorated<Vec4f, [Location<number>]>
41-
| AnyFragmentOutputBuiltin
42-
| IORecord<
43-
Vec4f | Decorated<Vec4f, [Location<number>]> | AnyFragmentOutputBuiltin
44-
>;
45-
4632
export type FragmentInConstrained = IORecord<
4733
| BaseIOData
48-
| Decorated<BaseIOData, AnyAttribute<never>[]>
34+
| Decorated<BaseIOData, (Location | Interpolate)[]>
4935
| AnyFragmentInputBuiltin
5036
>;
5137

38+
export type FragmentOutConstrained = IOLayout<
39+
| Vec4f
40+
| Decorated<Vec4f, (Location | Interpolate)[]>
41+
| AnyFragmentOutputBuiltin
42+
>;
43+
5244
/**
5345
* Describes a fragment entry function signature (its arguments, return type and targets)
5446
*/
5547
type TgpuFragmentFnShellHeader<
5648
FragmentIn extends FragmentInConstrained,
5749
FragmentOut extends FragmentOutConstrained,
5850
> = {
59-
readonly argTypes: [AnyWgslStruct] | [];
51+
readonly argTypes: [IOLayoutToSchema<FragmentIn>] | [];
6052
readonly targets: FragmentOut;
61-
readonly returnType: FragmentOut;
53+
readonly returnType: IOLayoutToSchema<FragmentOut>;
6254
readonly isEntry: true;
6355
};
6456

@@ -154,10 +146,10 @@ export function fragmentFn<
154146
}): TgpuFragmentFnShell<FragmentIn, FragmentOut> {
155147
const shell: TgpuFragmentFnShellHeader<FragmentIn, FragmentOut> = {
156148
argTypes: options.in && Object.keys(options.in).length !== 0
157-
? [createStructFromIO(options.in)]
149+
? [createIoSchema(options.in)]
158150
: [],
159151
targets: options.out,
160-
returnType: createOutputType(options.out) as FragmentOut,
152+
returnType: createIoSchema(options.out),
161153
isEntry: true,
162154
};
163155

@@ -185,9 +177,7 @@ function createFragmentFn(
185177
type This = TgpuFragmentFn & SelfResolvable & { [$getNameForward]: FnCore };
186178

187179
const core = createFnCore(shell, implementation);
188-
const outputType = shell.returnType as IOLayoutToSchema<
189-
typeof shell.returnType
190-
>;
180+
const outputType = shell.returnType;
191181
const inputType = shell.argTypes[0];
192182
if (typeof implementation === 'string') {
193183
addReturnTypeToExternals(

0 commit comments

Comments
 (0)