Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -182,11 +182,11 @@ describe('oklab example', () => {
let g2 = (((-1.2684380046f * ldt2) + (2.6097574011f * mdt2)) - (0.3413193965f * sdt2));
let u_g = (g1 / ((g1 * g1) - ((0.5f * g) * g2)));
var t_g = (-(g) * u_g);
let b_1 = ((((-0.0041960863f * l) - (0.7034186147f * m)) + (1.707614701f * s)) - 1f);
let b2 = ((((-0.0041960863f * l) - (0.7034186147f * m)) + (1.707614701f * s)) - 1f);
let b1 = (((-0.0041960863f * ldt) - (0.7034186147f * mdt)) + (1.707614701f * sdt));
let b2 = (((-0.0041960863f * ldt2) - (0.7034186147f * mdt2)) + (1.707614701f * sdt2));
let u_b = (b1 / ((b1 * b1) - ((0.5f * b_1) * b2)));
var t_b = (-(b_1) * u_b);
let b22 = (((-0.0041960863f * ldt2) - (0.7034186147f * mdt2)) + (1.707614701f * sdt2));
let u_b = (b1 / ((b1 * b1) - ((0.5f * b2) * b22)));
var t_b = (-(b2) * u_b);
t_r = select(FLT_MAX, t_r, (u_r >= 0f));
t_g = select(FLT_MAX, t_g, (u_g >= 0f));
t_b = select(FLT_MAX, t_b, (u_b >= 0f));
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"dev": "DEV=true pnpm run --filter typegpu-docs dev",
"dev:host": "DEV=true pnpm run --filter typegpu-docs dev --host --mode https",
"fix": "oxlint -c oxlint.config.ts --fix && oxfmt",
"test": "pnpm run test:types && pnpm run test:style && pnpm run test:unit-and-attest && pnpm run test:circular-deps",
"test": "pnpm -r run build && pnpm run test:types && pnpm run test:style && TEST_BUILT_CODE=true pnpm run test:unit-and-attest && pnpm run test:circular-deps",
"test:circular-deps": "pnpm dpdm -T --exit-code circular:1 packages/**/src/index.ts packages/**/src/index.js !packages/**/node_modules",
"test:types": "pnpm run --filter typegpu-docs transform-overloads && pnpm run -r --parallel test:types",
"test:style": "oxlint -c oxlint.config.ts --max-warnings=0 --type-aware --report-unused-disable-directives && oxfmt --check",
Expand Down
1 change: 1 addition & 0 deletions packages/typegpu/src/tgsl/shaderGenerator_members.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export { UnknownData } from '../data/dataTypes.ts';

// types
export type { ResolutionCtx } from '../types.ts';
export type { Snippet, Origin } from '../data/snippet.ts';
136 changes: 70 additions & 66 deletions packages/typegpu/src/tgsl/wgslGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -910,6 +910,75 @@ ${this.ctx.pre}}`;
return snip(stitch`${this.ctx.resolve(schema).value}(${args})`, schema, 'runtime');
}

public _return(statement: tinyest.Return): string {
const returnNode = statement[1];

if (returnNode !== undefined) {
const expectedReturnType = this.ctx.topFunctionReturnType;
let returnSnippet = expectedReturnType
? this._typedExpression(returnNode, expectedReturnType)
: this._expression(returnNode);

if (returnSnippet.value instanceof RefOperator) {
throw new WgslTypeError(
stitch`Cannot return references, returning '${returnSnippet.value.snippet}'`,
);
}

// Arguments cannot be returned from functions without copying. A simple example why is:
// const identity = (x) => {
// 'use gpu';
// return x;
// };
//
// const foo = (arg: d.v3f) => {
// 'use gpu';
// const marg = identity(arg);
// marg.x = 1; // 'marg's origin would be 'runtime', so we wouldn't be able to track this misuse.
// };
if (
returnSnippet.origin === 'argument' &&
!wgsl.isNaturallyEphemeral(returnSnippet.dataType) &&
// Only restricting this use in non-entry functions, as the function
// is giving up ownership of all references anyway.
this.ctx.topFunctionScope?.functionType === 'normal'
) {
throw new WgslTypeError(
stitch`Cannot return references to arguments, returning '${returnSnippet}'. Copy the argument before returning it.`,
);
}

if (
!expectedReturnType &&
!isEphemeralSnippet(returnSnippet) &&
returnSnippet.origin !== 'this-function'
) {
const str = this.ctx.resolve(returnSnippet.value, returnSnippet.dataType).value;
const typeStr = this.ctx.resolve(unptr(returnSnippet.dataType)).value;
throw new WgslTypeError(
`'return ${str};' is invalid, cannot return references.
-----
Try 'return ${typeStr}(${str});' instead.
-----`,
);
}

returnSnippet = tryConvertSnippet(
this.ctx,
returnSnippet,
unptr(returnSnippet.dataType) as wgsl.AnyWgslData,
false,
);

invariant(returnSnippet.dataType !== UnknownData, 'Return type should be known');

this.ctx.reportReturnType(returnSnippet.dataType);
return stitch`${this.ctx.pre}return ${returnSnippet};`;
}

return `${this.ctx.pre}return;`;
}

public _statement(statement: tinyest.Statement): string {
if (typeof statement === 'string') {
const id = this._identifier(statement);
Expand All @@ -923,72 +992,7 @@ ${this.ctx.pre}}`;
}

if (statement[0] === NODE.return) {
const returnNode = statement[1];

if (returnNode !== undefined) {
const expectedReturnType = this.ctx.topFunctionReturnType;
let returnSnippet = expectedReturnType
? this._typedExpression(returnNode, expectedReturnType)
: this._expression(returnNode);

if (returnSnippet.value instanceof RefOperator) {
throw new WgslTypeError(
stitch`Cannot return references, returning '${returnSnippet.value.snippet}'`,
);
}

// Arguments cannot be returned from functions without copying. A simple example why is:
// const identity = (x) => {
// 'use gpu';
// return x;
// };
//
// const foo = (arg: d.v3f) => {
// 'use gpu';
// const marg = identity(arg);
// marg.x = 1; // 'marg's origin would be 'runtime', so we wouldn't be able to track this misuse.
// };
if (
returnSnippet.origin === 'argument' &&
!wgsl.isNaturallyEphemeral(returnSnippet.dataType) &&
// Only restricting this use in non-entry functions, as the function
// is giving up ownership of all references anyway.
this.ctx.topFunctionScope?.functionType === 'normal'
) {
throw new WgslTypeError(
stitch`Cannot return references to arguments, returning '${returnSnippet}'. Copy the argument before returning it.`,
);
}

if (
!expectedReturnType &&
!isEphemeralSnippet(returnSnippet) &&
returnSnippet.origin !== 'this-function'
) {
const str = this.ctx.resolve(returnSnippet.value, returnSnippet.dataType).value;
const typeStr = this.ctx.resolve(unptr(returnSnippet.dataType)).value;
throw new WgslTypeError(
`'return ${str};' is invalid, cannot return references.
-----
Try 'return ${typeStr}(${str});' instead.
-----`,
);
}

returnSnippet = tryConvertSnippet(
this.ctx,
returnSnippet,
unptr(returnSnippet.dataType) as wgsl.AnyWgslData,
false,
);

invariant(returnSnippet.dataType !== UnknownData, 'Return type should be known');

this.ctx.reportReturnType(returnSnippet.dataType);
return stitch`${this.ctx.pre}return ${returnSnippet};`;
}

return `${this.ctx.pre}return;`;
return this._return(statement);
}

if (statement[0] === NODE.if) {
Expand Down
2 changes: 1 addition & 1 deletion packages/typegpu/tests/accessor.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, expect, expectTypeOf } from 'vitest';
import tgpu, { d, std, type TgpuAccessor } from '../src/index.js';
import tgpu, { d, std, type TgpuAccessor } from 'typegpu';
import { it } from 'typegpu-testing-utility';

const RED = d.vec3f(1, 0, 0);
Expand Down
2 changes: 1 addition & 1 deletion packages/typegpu/tests/align.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, expect, expectTypeOf, it } from 'vitest';
import { d, tgpu } from '../src/index.js';
import { d, tgpu } from 'typegpu';

describe('d.align', () => {
it('adds @align attribute for custom aligned struct members', () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/typegpu/tests/array.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { attest } from '@ark/attest';
import { BufferReader, BufferWriter } from 'typed-binary';
import { describe, expect, expectTypeOf, it } from 'vitest';
import { readData, writeData } from '../src/data/dataIO.ts';
import { d, tgpu } from '../src/index.js';
import { d, tgpu } from 'typegpu';
import { namespace } from '../src/core/resolve/namespace.ts';
import { resolve } from '../src/resolutionCtx.ts';
import type { Infer } from '../src/shared/repr.ts';
Expand Down
2 changes: 1 addition & 1 deletion packages/typegpu/tests/attributes.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, expect, expectTypeOf, it } from 'vitest';
import { d, tgpu } from '../src/index.js';
import { d, tgpu } from 'typegpu';

describe('attributes', () => {
it('adds attributes in the correct order', () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/typegpu/tests/bindGroupLayout.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
type TgpuBuffer,
type TgpuTextureView,
type UniformFlag,
} from '../src/index.js';
} from 'typegpu';
import {
type ExtractBindGroupInputFromLayout,
MissingBindingError,
Expand Down
2 changes: 1 addition & 1 deletion packages/typegpu/tests/buffer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { describe, expect, expectTypeOf, vi } from 'vitest';
import * as common from '../src/common/index.ts';
import * as d from '../src/data/index.ts';
import { sizeOf } from '../src/data/sizeOf.ts';
import type { ValidateBufferSchema, ValidUsagesFor } from '../src/index.js';
import type { ValidateBufferSchema, ValidUsagesFor } from 'typegpu';
import { getName } from '../src/shared/meta.ts';
import type { InferPatch, IsValidBufferSchema, IsValidUniformSchema } from '../src/shared/repr.ts';
import type { TypedArray } from '../src/shared/utilityTypes.ts';
Expand Down
2 changes: 1 addition & 1 deletion packages/typegpu/tests/bufferShorthands.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import type {
TgpuReadonly,
TgpuUniform,
UniformFlag,
} from '../src/index.js';
} from 'typegpu';
import { attest } from '@ark/attest';

describe('root.createMutable', () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/typegpu/tests/bufferUsage.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { describe, expect, expectTypeOf } from 'vitest';

import { d, tgpu } from '../src/index.js';
import { d, tgpu } from 'typegpu';
import type { Infer } from '../src/shared/repr.ts';
import { it } from 'typegpu-testing-utility';

Expand Down
2 changes: 1 addition & 1 deletion packages/typegpu/tests/computePipeline.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { describe, expect, expectTypeOf, vi } from 'vitest';
import type { TgpuQuerySet } from '../src/core/querySet/querySet.ts';
import { d, MissingBindGroupsError, tgpu, type TgpuComputePipeline } from '../src/index.js';
import { d, MissingBindGroupsError, tgpu, type TgpuComputePipeline } from 'typegpu';
import { $internal } from '../src/shared/symbols.ts';
import { it } from 'typegpu-testing-utility';
import { extensionEnabled } from '../src/std/extensions.ts';
Expand Down
2 changes: 1 addition & 1 deletion packages/typegpu/tests/constant.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, expect, it } from 'vitest';
import { d, tgpu } from '../src/index.js';
import { d, tgpu } from 'typegpu';

const Boid = d.struct({
pos: d.vec3f,
Expand Down
2 changes: 1 addition & 1 deletion packages/typegpu/tests/data/atomic.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, expect, expectTypeOf, it } from 'vitest';
import * as d from '../../src/data/index.ts';
import { d } from 'typegpu';

describe('d.atomic', () => {
it('creates a u32 atomic schema', () => {
Expand Down
6 changes: 4 additions & 2 deletions packages/typegpu/tests/data/deepEqual.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ import {
vec2f,
vec2u,
vec3f,
} from '../../src/data/index.ts';
import { ptrPrivate, ptrStorage, ptrWorkgroup } from '../../src/data/ptr.ts';
ptrPrivate,
ptrStorage,
ptrWorkgroup,
} from 'typegpu/data';

describe('deepEqual', () => {
it('compares simple types', () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/typegpu/tests/data/ptr.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, expect, expectTypeOf, it } from 'vitest';
import { d, tgpu } from '../../src/index.js';
import { d, tgpu } from 'typegpu';

describe('d.ptrFn', () => {
it('wraps a schema and infers type properly', () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/typegpu/tests/data/schemaCallWrapper.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, expect, it } from 'vitest';
import * as d from '../../src/data/index.ts';
import { d } from 'typegpu';
import { schemaCallWrapper } from '../../src/data/schemaCallWrapper.ts';

describe('schemaCallWrapper', () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/typegpu/tests/declare.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, expect, it } from 'vitest';
import { d, tgpu } from '../src/index.js';
import { d, tgpu } from 'typegpu';

describe('tgpu.declare', () => {
it('should inject provided declaration when resolving a function', () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/typegpu/tests/entryFnBuiltinArgs.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { describe, it } from 'vitest';
import * as d from '../src/data/index.ts';
import tgpu, { type TgpuComputeFn, type TgpuFragmentFn, type TgpuVertexFn } from '../src/index.js';
import tgpu, { type TgpuComputeFn, type TgpuFragmentFn, type TgpuVertexFn } from 'typegpu';
import { attest } from '@ark/attest';

describe('entry functions accepting only the allowed subset of builtins', () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/typegpu/tests/entryFnHeaderGen.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest';
import * as d from '../src/data/index.ts';
import tgpu from '../src/index.js';
import tgpu from 'typegpu';

describe('autogenerating wgsl headers for tgpu entry functions with raw string WGSL implementations', () => {
it('works for fragment entry function with non-decorated non-struct output', () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/typegpu/tests/function.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { describe, expect, expectTypeOf, it } from 'vitest';
import type { InferIO, InheritArgNames, IOLayout } from '../src/core/function/fnTypes.ts';
import * as d from '../src/data/index.ts';
import { Void } from '../src/data/wgslTypes.ts';
import tgpu, { type TgpuFn, type TgpuFnShell } from '../src/index.js';
import tgpu, { type TgpuFn, type TgpuFnShell } from 'typegpu';
import type { Prettify } from '../src/shared/utilityTypes.ts';

const empty = tgpu.fn([])`() {
Expand Down
2 changes: 1 addition & 1 deletion packages/typegpu/tests/functionTagged.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest';
import * as d from '../src/data/index.ts';
import tgpu from '../src/index.js';
import tgpu from 'typegpu';

describe('tagged syntax', () => {
describe('function', () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/typegpu/tests/gpuValueOf.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { describe, expectTypeOf } from 'vitest';
import * as d from '../src/data/index.ts';
import tgpu from '../src/index.js';
import tgpu from 'typegpu';
import type { GPUValueOf } from '../src/shared/repr.ts';
import { it } from 'typegpu-testing-utility';

Expand Down
2 changes: 1 addition & 1 deletion packages/typegpu/tests/indent.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, expect, it } from 'vitest';
import tgpu, { d, std } from '../src/index.js';
import tgpu, { d, std } from 'typegpu';

describe('indents', () => {
it('should indent sanely', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { afterAll, beforeAll, describe, expect } from 'vitest';
// Importing directly from source, since we're testing internals
import { abstractFloat, abstractInt } from '../../src/data/numeric.ts';
import * as d from '../../src/data/index.ts';
import { snip, type Snippet } from '../../src/data/snippet.ts';
Expand Down
Loading
Loading