Skip to content

Commit a658909

Browse files
authored
feat: A type alias for no-custom auto inputs (#2344)
1 parent 5d462bf commit a658909

File tree

5 files changed

+79
-7
lines changed

5 files changed

+79
-7
lines changed

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import type { BaseData, v4f } from '../../data/wgslTypes.ts';
77
import { getName, setName } from '../../shared/meta.ts';
88
import type { InferGPU, InferGPURecord, InferRecord } from '../../shared/repr.ts';
99
import { $internal, $resolve } from '../../shared/symbols.ts';
10-
import type { Assume } from '../../shared/utilityTypes.ts';
10+
import type { Assume, RemoveIndexSignature } from '../../shared/utilityTypes.ts';
1111
import type { TgpuVertexAttrib } from '../../shared/vertexFormat.ts';
1212
import type { ResolutionCtx, SelfResolvable } from '../../types.ts';
1313
import { shaderStageSlot } from '../slot/internalSlots.ts';
@@ -21,7 +21,8 @@ const builtinVertexIn = {
2121
$instanceIndex: builtin.instanceIndex,
2222
} as const;
2323

24-
export type AutoVertexIn<T extends AnyAutoCustoms> = T & InferRecord<typeof builtinVertexIn>;
24+
export type AutoVertexIn<T extends AnyAutoCustoms> = RemoveIndexSignature<T> &
25+
InferRecord<typeof builtinVertexIn>;
2526

2627
export type _AutoVertexIn<T> = AutoVertexIn<{
2728
[Key in keyof T]: T[Key] extends TgpuVertexAttrib
@@ -47,7 +48,8 @@ const builtinFragmentIn = {
4748
$subgroupSize: builtin.subgroupSize,
4849
} as const;
4950

50-
export type AutoFragmentIn<T extends AnyAutoCustoms> = T & InferRecord<typeof builtinFragmentIn>;
51+
export type AutoFragmentIn<T extends AnyAutoCustoms> = RemoveIndexSignature<T> &
52+
InferRecord<typeof builtinFragmentIn>;
5153

5254
const builtinFragmentOut = {
5355
$fragDepth: builtin.fragDepth,

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ export declare namespace TgpuFragmentFn {
121121
type Out = Record<string, BaseData> | BaseData;
122122
type AutoIn<T extends AnyAutoCustoms> = AutoFragmentIn<T>;
123123
type AutoOut<T extends AnyAutoCustoms = AnyAutoCustoms> = AutoFragmentOut<T>;
124+
125+
type AutoInEmpty = AutoFragmentIn<Record<string, never>>;
124126
}
125127

126128
export function fragmentFn<FragmentOut extends FragmentOutConstrained>(options: {

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ export declare namespace TgpuVertexFn {
8686
type Out = Record<string, BaseData>;
8787
type AutoIn<T> = _AutoVertexIn<T>;
8888
type AutoOut<T extends AnyAutoCustoms = AnyAutoCustoms> = AutoVertexOut<T>;
89+
90+
type AutoInEmpty = _AutoVertexIn<Record<string, never>>;
8991
}
9092

9193
export function vertexFn<VertexOut extends VertexOutConstrained>(options: {

packages/typegpu/src/shared/utilityTypes.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export type Mutable<T> = {
5656
};
5757

5858
/**
59-
* Source: https://code.lol/post/programming/higher-kinded-types/
59+
* Source: https://code.lol/post/programming/higher-kinded-types
6060
*/
6161
export type Assume<T, U> = T extends U ? T : U;
6262

@@ -74,3 +74,16 @@ export type TypedArray =
7474
export function assertExhaustive(x: never, location: string): never {
7575
throw new Error(`Failed to handle ${x} at ${location}`);
7676
}
77+
78+
/**
79+
* Source: https://futurestud.io/tutorials/typescript-how-to-remove-index-signature-from-a-type
80+
*/
81+
export type RemoveIndexSignature<T> = {
82+
[K in keyof T as string extends K
83+
? never
84+
: number extends K
85+
? never
86+
: symbol extends K
87+
? never
88+
: K]: T[K];
89+
};

packages/typegpu/tests/renderPipeline.test.ts

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ import tgpu, {
66
common,
77
d,
88
MissingBindGroupsError,
9+
type TgpuFragmentFn,
910
type TgpuFragmentFnShell,
1011
type TgpuRenderPipeline,
12+
type TgpuVertexFn,
1113
type TgpuVertexFnShell,
1214
} from '../src/index.js';
1315
import { $internal } from '../src/shared/symbols.ts';
@@ -1591,7 +1593,7 @@ describe('root.createRenderPipeline', () => {
15911593
attribs: { vertexIndex: vertexLayout.attrib },
15921594
vertex: ({ vertexIndex, $vertexIndex }) => {
15931595
'use gpu';
1594-
return { $position: d.vec4f() };
1596+
return { $position: d.vec4f(vertexIndex, $vertexIndex, 0, 1) };
15951597
},
15961598
fragment: () => {
15971599
'use gpu';
@@ -1619,7 +1621,7 @@ describe('root.createRenderPipeline', () => {
16191621
},
16201622
fragment: ({ position }) => {
16211623
'use gpu';
1622-
return d.vec4f();
1624+
return position;
16231625
},
16241626
targets: { format: 'rgba8unorm' },
16251627
});
@@ -1641,7 +1643,10 @@ describe('root.createRenderPipeline', () => {
16411643
},
16421644
fragment: ({ $frontFacing, frontFacing }) => {
16431645
'use gpu';
1644-
return d.vec4f();
1646+
if ($frontFacing && frontFacing === 1) {
1647+
return d.vec4f(0, 1, 0, 1);
1648+
}
1649+
return d.vec4f(1, 0, 0, 1);
16451650
},
16461651
targets: { format: 'rgba8unorm' },
16471652
});
@@ -1774,6 +1779,54 @@ describe('root.createRenderPipeline', () => {
17741779
]
17751780
`);
17761781
});
1782+
1783+
it('accepts entry functions with no attributes or varyings', ({ root }) => {
1784+
const positions = tgpu.const(d.arrayOf(d.vec2f, 3), [
1785+
d.vec2f(0, 0),
1786+
d.vec2f(1, 0),
1787+
d.vec2f(0, 1),
1788+
]);
1789+
const vertex = ({ $vertexIndex }: TgpuVertexFn.AutoInEmpty) => {
1790+
'use gpu';
1791+
return {
1792+
$position: d.vec4f(positions.$[$vertexIndex]!, 0, 1),
1793+
} satisfies TgpuVertexFn.AutoOut;
1794+
};
1795+
1796+
const fragment = ({ $position }: TgpuFragmentFn.AutoInEmpty) => {
1797+
'use gpu';
1798+
return $position;
1799+
};
1800+
1801+
const pipeline = root.createRenderPipeline({
1802+
vertex,
1803+
fragment,
1804+
});
1805+
1806+
expect(tgpu.resolve([pipeline])).toMatchInlineSnapshot(`
1807+
"const positions: array<vec2f, 3> = array<vec2f, 3>(vec2f(), vec2f(1, 0), vec2f(0, 1));
1808+
1809+
struct VertexOut {
1810+
@builtin(position) position: vec4f,
1811+
}
1812+
1813+
struct VertexIn {
1814+
@builtin(vertex_index) vertexIndex: u32,
1815+
}
1816+
1817+
@vertex fn vertex(_arg_0: VertexIn) -> VertexOut {
1818+
return VertexOut(vec4f(positions[_arg_0.vertexIndex], 0f, 1f));
1819+
}
1820+
1821+
struct FragmentIn {
1822+
@builtin(position) position: vec4f,
1823+
}
1824+
1825+
@fragment fn fragment(_arg_0: FragmentIn) -> @location(0) vec4f {
1826+
return _arg_0.position;
1827+
}"
1828+
`);
1829+
});
17771830
});
17781831

17791832
describe('matchUpVaryingLocations', () => {

0 commit comments

Comments
 (0)