Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
initLayout,
maskLayout,
type MaskTexture,
paramsAccessor,
paramsAccess,
pingPongLayout,
SampleResult,
VisualizationParams,
Expand Down Expand Up @@ -284,7 +284,7 @@ const createDistanceField = root['~unstable'].createGuardedComputePipeline(
);

const distancePipeline = root['~unstable']
.with(paramsAccessor, paramsUniform)
.with(paramsAccess, paramsUniform)
.withVertex(fullScreenTriangle)
.withFragment(distanceFrag, { format: presentationFormat })
.createPipeline();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const SampleResult = d.struct({
outside: d.vec2f,
});

export const paramsAccessor = tgpu['~unstable'].accessor(VisualizationParams);
export const paramsAccess = tgpu['~unstable'].accessor(VisualizationParams);

export const distSampleLayout = tgpu.bindGroupLayout({
distTexture: { texture: d.texture2d() },
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import tgpu from 'typegpu';
import * as d from 'typegpu/data';
import * as std from 'typegpu/std';
import { distSampleLayout, paramsAccessor } from './types.ts';
import { distSampleLayout, paramsAccess } from './types.ts';

const outsideGradient = tgpu.const(d.arrayOf(d.vec3f, 5), [
d.vec3f(0.05, 0.05, 0.15),
Expand Down Expand Up @@ -31,10 +31,10 @@ export const distanceFrag = tgpu['~unstable'].fragmentFn({
uv,
).x;

if (paramsAccessor.$.showInside === 0 && dist < 0) {
if (paramsAccess.$.showInside === 0 && dist < 0) {
dist = 0;
}
if (paramsAccessor.$.showOutside === 0 && dist > 0) {
if (paramsAccess.$.showOutside === 0 && dist > 0) {
dist = 0;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ import {
blockDim,
blurLayout,
drawWithMaskLayout,
flipSlot,
flipAccess,
generateMaskLayout,
Params,
paramsAccessor,
paramsAccess,
prepareModelInputLayout,
} from './schemas.ts';
import {
Expand Down Expand Up @@ -126,7 +126,7 @@ let blurBindGroups: TgpuBindGroup<typeof blurLayout.entries>[];
// pipelines

const prepareModelInputPipeline = root['~unstable']
.with(paramsAccessor, paramsUniform)
.with(paramsAccess, paramsUniform)
.createGuardedComputePipeline(
prepareModelInput,
);
Expand Down Expand Up @@ -161,13 +161,13 @@ const generateMaskFromOutputPipeline = root['~unstable']

const blurPipelines = [false, true].map((flip) =>
root['~unstable']
.with(flipSlot, flip)
.with(flipAccess, flip)
.withCompute(computeFn)
.createPipeline()
);

const drawWithMaskPipeline = root['~unstable']
.with(paramsAccessor, paramsUniform)
.with(paramsAccess, paramsUniform)
.withVertex(fullScreenTriangle, {})
.withFragment(drawWithMaskFragment, { format: presentationFormat })
.createPipeline();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ export const Params = d.struct({
sampleBias: d.f32,
});

export const paramsAccessor = tgpu['~unstable'].accessor(Params);
export const flipSlot = tgpu['~unstable'].accessor(d.bool);
export const paramsAccess = tgpu['~unstable'].accessor(Params);
export const flipAccess = tgpu['~unstable'].accessor(d.bool);

export interface ModelConfig {
name: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,18 @@ import {
blurLayout,
drawWithMaskLayout,
filterDim,
flipSlot,
flipAccess,
generateMaskLayout,
paramsAccessor,
paramsAccess,
prepareModelInputLayout,
} from './schemas.ts';
import { MODEL_HEIGHT, MODEL_WIDTH } from './model.ts';

export const prepareModelInput = (x: number, y: number) => {
'use gpu';
const modelUV = d.vec2f(d.f32(x), d.f32(y)).div(
d.vec2f(MODEL_WIDTH, MODEL_HEIGHT),
);
const modelUV = d.vec2f(x, y).div(d.vec2f(MODEL_WIDTH, MODEL_HEIGHT));

const cropBounds = paramsAccessor.$.cropBounds;
const cropBounds = paramsAccess.$.cropBounds;
const uvMin = cropBounds.xy;
const uvMax = cropBounds.zw;
const videoUV = std.mix(uvMin, uvMax, modelUV);
Expand Down Expand Up @@ -63,7 +61,7 @@ export const computeFn = tgpu['~unstable'].computeFn({
for (let r = 0; r < 4; r++) {
for (let c = 0; c < 4; c++) {
let loadIndex = baseIndex.add(d.vec2i(c, r));
if (flipSlot.$) {
if (flipAccess.$) {
loadIndex = loadIndex.yx;
}

Expand All @@ -82,7 +80,7 @@ export const computeFn = tgpu['~unstable'].computeFn({
for (let r = 0; r < 4; r++) {
for (let c = 0; c < 4; c++) {
let writeIndex = baseIndex.add(d.vec2i(c, r));
if (flipSlot.$) {
if (flipAccess.$) {
writeIndex = writeIndex.yx;
}

Expand Down Expand Up @@ -114,7 +112,7 @@ export const drawWithMaskFragment = tgpu['~unstable'].fragmentFn({
);

let blurredColor = d.vec4f();
if (paramsAccessor.$.useGaussian === 1) {
if (paramsAccess.$.useGaussian === 1) {
blurredColor = std.textureSampleBaseClampToEdge(
drawWithMaskLayout.$.inputBlurredTexture,
drawWithMaskLayout.$.sampler,
Expand All @@ -125,11 +123,11 @@ export const drawWithMaskFragment = tgpu['~unstable'].fragmentFn({
drawWithMaskLayout.$.inputBlurredTexture,
drawWithMaskLayout.$.sampler,
input.uv,
paramsAccessor.$.sampleBias,
paramsAccess.$.sampleBias,
);
}

const cropBounds = paramsAccessor.$.cropBounds;
const cropBounds = paramsAccess.$.cropBounds;
const uvMin = cropBounds.xy;
const uvMax = cropBounds.zw;
const maskUV = d.vec2f(input.uv).sub(uvMin).div(uvMax.sub(uvMin));
Expand Down
15 changes: 8 additions & 7 deletions packages/typegpu/src/core/constant/tgpuConstant.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import type { AnyData } from '../../data/dataTypes.ts';
import { type ResolvedSnippet, snip } from '../../data/snippet.ts';
import {
type AnyWgslData,
isNaturallyEphemeral,
} from '../../data/wgslTypes.ts';
import { isNaturallyEphemeral } from '../../data/wgslTypes.ts';
import { inCodegenMode } from '../../execMode.ts';
import type { TgpuNamable } from '../../shared/meta.ts';
import { getName, setName } from '../../shared/meta.ts';
Expand All @@ -26,8 +24,9 @@ type DeepReadonly<T> = T extends { [$internal]: unknown } ? T
? { readonly [K in keyof T]: DeepReadonly<T[K]> }
: T;

export interface TgpuConst<TDataType extends AnyWgslData = AnyWgslData>
export interface TgpuConst<TDataType extends AnyData = AnyData>
extends TgpuNamable {
readonly resourceType: 'const';
readonly [$gpuValueOf]: DeepReadonly<InferGPU<TDataType>>;
readonly value: DeepReadonly<InferGPU<TDataType>>;
readonly $: DeepReadonly<InferGPU<TDataType>>;
Expand All @@ -41,7 +40,7 @@ export interface TgpuConst<TDataType extends AnyWgslData = AnyWgslData>
/**
* Creates a module constant with specified value.
*/
export function constant<TDataType extends AnyWgslData>(
export function constant<TDataType extends AnyData>(
dataType: TDataType,
value: InferGPU<TDataType>,
): TgpuConst<TDataType> {
Expand Down Expand Up @@ -69,15 +68,17 @@ function deepFreeze<T extends object>(object: T): T {
return Object.freeze(object);
}

class TgpuConstImpl<TDataType extends AnyWgslData>
class TgpuConstImpl<TDataType extends AnyData>
implements TgpuConst<TDataType>, SelfResolvable {
readonly [$internal] = {};
readonly resourceType: 'const';
readonly #value: DeepReadonly<InferGPU<TDataType>>;

constructor(
public readonly dataType: TDataType,
value: InferGPU<TDataType>,
) {
this.resourceType = 'const';
this.#value = value && typeof value === 'object'
? deepFreeze(value) as DeepReadonly<InferGPU<TDataType>>
: value as DeepReadonly<InferGPU<TDataType>>;
Expand Down
11 changes: 9 additions & 2 deletions packages/typegpu/src/core/function/comptime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,16 @@ import { $getNameForward, $internal } from '../../shared/symbols.ts';
import { coerceToSnippet } from '../../tgsl/generationHelpers.ts';
import { isKnownAtComptime, NormalState } from '../../types.ts';

export type TgpuComptime<T extends (...args: never[]) => unknown> =
export type TgpuComptime<
T extends (...args: never[]) => unknown = (...args: never[]) => unknown,
> =
& DualFn<T>
& TgpuNamable
& { [$getNameForward]: unknown };
& { [$getNameForward]: unknown; [$internal]: { isComptime: true } };

export function isComptimeFn(value: unknown): value is TgpuComptime {
return !!(value as TgpuComptime)?.[$internal]?.isComptime;
}

/**
* Creates a version of `func` that can called safely in a TypeGPU function to
Expand Down Expand Up @@ -72,6 +78,7 @@ export function comptime<T extends (...args: never[]) => unknown>(
};
Object.defineProperty(impl, $internal, {
value: {
isComptime: true,
jsImpl: func,
gpuImpl,
argConversionHint: 'keep',
Expand Down
19 changes: 13 additions & 6 deletions packages/typegpu/src/core/function/tgpuFn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,21 @@ import {
} from '../../shared/symbols.ts';
import type { Prettify } from '../../shared/utilityTypes.ts';
import type { ResolutionCtx, SelfResolvable } from '../../types.ts';
import type { TgpuBufferUsage } from '../buffer/bufferUsage.ts';
import {
addArgTypesToExternals,
addReturnTypeToExternals,
} from '../resolve/externals.ts';
import { stitch } from '../resolve/stitch.ts';
import {
type AccessorIn,
type Eventual,
isAccessor,
isMutableAccessor,
type MutableAccessorIn,
type Providing,
type SlotValuePair,
type TgpuAccessor,
type TgpuMutableAccessor,
type TgpuSlot,
} from '../slot/slotTypes.ts';
import { dualImpl } from './dualImpl.ts';
Expand Down Expand Up @@ -92,7 +95,11 @@ interface TgpuFnBase<ImplSchema extends AnyFn> extends TgpuNamable {
with<T>(slot: TgpuSlot<T>, value: Eventual<T>): TgpuFn<ImplSchema>;
with<T extends AnyData>(
accessor: TgpuAccessor<T>,
value: TgpuFn<() => T> | TgpuBufferUsage<T> | Infer<T>,
value: AccessorIn<NoInfer<T>>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any particular reason we use NoInfer here and not in the other .with signatures (on root for example)?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nevermind, they are there in the public APIs

): TgpuFn<ImplSchema>;
with<T extends AnyData>(
accessor: TgpuMutableAccessor<T>,
value: MutableAccessorIn<NoInfer<T>>,
): TgpuFn<ImplSchema>;
}

Expand Down Expand Up @@ -184,11 +191,11 @@ function createFn<ImplSchema extends AnyFn>(
},

with(
slot: TgpuSlot<unknown> | TgpuAccessor,
slot: TgpuSlot<unknown> | TgpuAccessor | TgpuMutableAccessor,
value: unknown,
): TgpuFn<ImplSchema> {
return createBoundFunction(fn, [
[isAccessor(slot) ? slot.slot : slot, value],
[isAccessor(slot) || isMutableAccessor(slot) ? slot.slot : slot, value],
]);
},

Expand Down Expand Up @@ -288,12 +295,12 @@ function createBoundFunction<ImplSchema extends AnyFn>(
},

with(
slot: TgpuSlot<unknown> | TgpuAccessor,
slot: TgpuSlot<unknown> | TgpuAccessor | TgpuMutableAccessor,
value: unknown,
): TgpuFn<ImplSchema> {
return createBoundFunction(fn, [
...pairs,
[isAccessor(slot) ? slot.slot : slot, value],
[isAccessor(slot) || isMutableAccessor(slot) ? slot.slot : slot, value],
]);
},
};
Expand Down
25 changes: 10 additions & 15 deletions packages/typegpu/src/core/root/configurableImpl.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,31 @@
import type { AnyData } from '../../data/dataTypes.ts';
import type { Infer } from '../../shared/repr.ts';
import type { AnyWgslData } from '../../data/wgslTypes.ts';
import type { TgpuBufferUsage } from '../buffer/bufferUsage.ts';
import type { TgpuFn } from '../function/tgpuFn.ts';
import {
type AccessorIn,
isAccessor,
isMutableAccessor,
type MutableAccessorIn,
type TgpuAccessor,
type TgpuMutableAccessor,
type TgpuSlot,
} from '../slot/slotTypes.ts';
import type { Configurable } from './rootTypes.ts';
import type { TgpuTextureView } from '../texture/texture.ts';
import type { WgslStorageTexture, WgslTexture } from '../../data/texture.ts';

export class ConfigurableImpl implements Configurable {
constructor(readonly bindings: [TgpuSlot<unknown>, unknown][]) {}

with<T extends AnyWgslData>(
slot: TgpuSlot<T> | TgpuAccessor<T>,
value: T extends WgslTexture | WgslStorageTexture
? TgpuTextureView<T> | TgpuFn<() => T> | Infer<T>
: T | TgpuFn<() => T> | TgpuBufferUsage<T> | Infer<T>,
with<T extends AnyData>(
slot: TgpuSlot<T> | TgpuAccessor<T> | TgpuMutableAccessor<T>,
value: AccessorIn<T> | MutableAccessorIn<T> | Infer<T>,
): Configurable {
return new ConfigurableImpl([
...this.bindings,
[isAccessor(slot) ? slot.slot : slot, value],
[isAccessor(slot) || isMutableAccessor(slot) ? slot.slot : slot, value],
]);
}

pipe(transform: (cfg: Configurable) => Configurable): Configurable {
const newCfg = transform(this);
return new ConfigurableImpl([
...this.bindings,
...newCfg.bindings,
]);
return new ConfigurableImpl([...this.bindings, ...newCfg.bindings]);
}
}
Loading
Loading