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
32 changes: 16 additions & 16 deletions packages/typegpu/src/core/buffer/buffer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,14 @@ import { isWgslData } from '../../data/wgslTypes.ts';
import type { StorageFlag } from '../../extension.ts';
import type { TgpuNamable } from '../../shared/meta.ts';
import { getName, setName } from '../../shared/meta.ts';
import type {
Infer,
InferPartial,
IsValidIndexSchema,
IsValidStorageSchema,
IsValidUniformSchema,
IsValidVertexSchema,
MemIdentity,
} from '../../shared/repr.ts';
import { $internal } from '../../shared/symbols.ts';
import type { Infer, InferPartial, MemIdentity } from '../../shared/repr.ts';
import {
$internal,
type $invalidIndexSchema,
type $invalidStorageSchema,
type $invalidUniformSchema,
type $invalidVertexSchema,
} from '../../shared/symbols.ts';
import type {
Prettify,
UnionToIntersection,
Expand Down Expand Up @@ -84,15 +82,17 @@ const usageToUsageConstructor = { uniform, mutable, readonly };
/**
* Done as an object to later Prettify it
*/
type InnerValidUsagesFor<T> = {
type InnerValidUsagesFor<T extends BaseData> = {
usage:
| (IsValidStorageSchema<T> extends true ? 'storage' : never)
| (IsValidUniformSchema<T> extends true ? 'uniform' : never)
| (IsValidVertexSchema<T> extends true ? 'vertex' : never)
| (IsValidIndexSchema<T> extends true ? 'index' : never);
| (T[typeof $invalidStorageSchema] extends string ? never : 'storage')
| (T[typeof $invalidUniformSchema] extends string ? never : 'uniform')
| (T[typeof $invalidVertexSchema] extends string ? never : 'vertex')
| (T[typeof $invalidIndexSchema] extends string ? never : 'index');
};

export type ValidUsagesFor<T> = InnerValidUsagesFor<T>['usage'];
export type ValidUsagesFor<T extends BaseData> = InnerValidUsagesFor<
T
>['usage'];

export interface TgpuBuffer<TData extends BaseData> extends TgpuNamable {
readonly [$internal]: true;
Expand Down
76 changes: 43 additions & 33 deletions packages/typegpu/src/core/root/rootTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import type {
WgslSamplerProps,
} from '../../data/sampler.ts';
import type {
AnyWgslData,
BaseData,
U16,
U32,
Expand All @@ -19,15 +18,14 @@ import type {
Void,
WgslArray,
} from '../../data/wgslTypes.ts';
import type {
ExtractInvalidSchemaError,
Infer,
InferGPURecord,
IsValidBufferSchema,
IsValidStorageSchema,
IsValidUniformSchema,
} from '../../shared/repr.ts';
import { $internal } from '../../shared/symbols.ts';
import type { ExtractInvalidSchemaError, Infer } from '../../shared/repr.ts';
import {
$internal,
$invalidIndexSchema,
$invalidStorageSchema,
$invalidUniformSchema,
$invalidVertexSchema,
} from '../../shared/symbols.ts';
import type {
Assume,
Mutable,
Expand Down Expand Up @@ -80,6 +78,7 @@ import type {
import type { TgpuVertexLayout } from '../vertexLayout/vertexLayout.ts';
import type { TgpuComputeFn } from './../function/tgpuComputeFn.ts';
import type { TgpuNamable } from '../../shared/meta.ts';
import { Illegal } from '../../errors.ts';
import type {
AnyAutoCustoms,
AutoFragmentIn,
Expand Down Expand Up @@ -751,20 +750,21 @@ export interface RenderPass {
): undefined;
}

export type ValidateBufferSchema<TData extends BaseData> =
IsValidBufferSchema<TData> extends false
? ExtractInvalidSchemaError<TData, '(Error) '>
: TData;

export type ValidateStorageSchema<TData extends BaseData> =
IsValidStorageSchema<TData> extends false
? ExtractInvalidSchemaError<TData, '(Error) '>
: TData;

export type ValidateUniformSchema<TData extends BaseData> =
IsValidUniformSchema<TData> extends false
? ExtractInvalidSchemaError<TData, '(Error) '>
: TData;
/** @deprecated Not useful anymore, it's now an identity type */
export type ValidateBufferSchema<TData extends BaseData> = TData;
/** @deprecated Not useful anymore, it's now an identity type */
export type ValidateStorageSchema<TData extends BaseData> = TData;
/** @deprecated Not useful anymore, it's now an identity type */
export type ValidateUniformSchema<TData extends BaseData> = TData;

type InvalidBufferData =
& BaseData
& ({
readonly [$invalidStorageSchema]: string;
readonly [$invalidUniformSchema]: string;
readonly [$invalidVertexSchema]: string;
readonly [$invalidIndexSchema]: string;
});

export type ConfigureContextOptions = {
/**
Expand Down Expand Up @@ -795,6 +795,16 @@ export interface TgpuRoot extends Unwrapper {
*/
configureContext(options: ConfigureContextOptions): GPUCanvasContext;

/**
* **The provided schema is not host-shareable**
* @deprecated
*/
createBuffer<TData extends InvalidBufferData>(
typeSchema: TData,
// NoInfer is there to infer the schema type just based on the first parameter
initial?: Infer<NoInfer<TData>> | undefined,
): Illegal<ExtractInvalidSchemaError<TData>>;

/**
* Allocates memory on the GPU, allows passing data between host and shader.
*
Expand All @@ -804,8 +814,8 @@ export interface TgpuRoot extends Unwrapper {
* @param typeSchema The type of data that this buffer will hold.
* @param initial The initial value of the buffer. (optional)
*/
createBuffer<TData extends AnyData>(
typeSchema: ValidateBufferSchema<TData>,
createBuffer<TData extends BaseData>(
typeSchema: TData,
// NoInfer is there to infer the schema type just based on the first parameter
initial?: Infer<NoInfer<TData>> | undefined,
): TgpuBuffer<TData>;
Expand All @@ -819,7 +829,7 @@ export interface TgpuRoot extends Unwrapper {
* @param typeSchema The type of data that this buffer will hold.
* @param gpuBuffer A vanilla WebGPU buffer.
*/
createBuffer<TData extends AnyData>(
createBuffer<TData extends BaseData>(
typeSchema: ValidateBufferSchema<TData>,
gpuBuffer: GPUBuffer,
): TgpuBuffer<TData>;
Expand All @@ -832,7 +842,7 @@ export interface TgpuRoot extends Unwrapper {
* @param typeSchema The type of data that this buffer will hold.
* @param initial The initial value of the buffer. (optional)
*/
createUniform<TData extends AnyWgslData>(
createUniform<TData extends BaseData>(
typeSchema: ValidateUniformSchema<TData>,
// NoInfer is there to infer the schema type just based on the first parameter
initial?: Infer<NoInfer<TData>>,
Expand All @@ -846,7 +856,7 @@ export interface TgpuRoot extends Unwrapper {
* @param typeSchema The type of data that this buffer will hold.
* @param gpuBuffer A vanilla WebGPU buffer.
*/
createUniform<TData extends AnyWgslData>(
createUniform<TData extends BaseData>(
typeSchema: ValidateUniformSchema<TData>,
gpuBuffer: GPUBuffer,
): TgpuUniform<TData>;
Expand All @@ -859,7 +869,7 @@ export interface TgpuRoot extends Unwrapper {
* @param typeSchema The type of data that this buffer will hold.
* @param initial The initial value of the buffer. (optional)
*/
createMutable<TData extends AnyWgslData>(
createMutable<TData extends BaseData>(
typeSchema: ValidateStorageSchema<TData>,
// NoInfer is there to infer the schema type just based on the first parameter
initial?: Infer<NoInfer<TData>>,
Expand All @@ -873,7 +883,7 @@ export interface TgpuRoot extends Unwrapper {
* @param typeSchema The type of data that this buffer will hold.
* @param gpuBuffer A vanilla WebGPU buffer.
*/
createMutable<TData extends AnyWgslData>(
createMutable<TData extends BaseData>(
typeSchema: ValidateStorageSchema<TData>,
gpuBuffer: GPUBuffer,
): TgpuMutable<TData>;
Expand All @@ -886,7 +896,7 @@ export interface TgpuRoot extends Unwrapper {
* @param typeSchema The type of data that this buffer will hold.
* @param initial The initial value of the buffer. (optional)
*/
createReadonly<TData extends AnyWgslData>(
createReadonly<TData extends BaseData>(
typeSchema: ValidateStorageSchema<TData>,
// NoInfer is there to infer the schema type just based on the first parameter
initial?: Infer<NoInfer<TData>>,
Expand All @@ -900,7 +910,7 @@ export interface TgpuRoot extends Unwrapper {
* @param typeSchema The type of data that this buffer will hold.
* @param gpuBuffer A vanilla WebGPU buffer.
*/
createReadonly<TData extends AnyWgslData>(
createReadonly<TData extends BaseData>(
typeSchema: ValidateStorageSchema<TData>,
gpuBuffer: GPUBuffer,
): TgpuReadonly<TData>;
Expand Down
16 changes: 11 additions & 5 deletions packages/typegpu/src/data/atomic.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Infer, MemIdentity } from '../shared/repr.ts';
import { $internal } from '../shared/symbols.ts';
import { $internal, $validIndexSchema } from '../shared/symbols.ts';
import {
$gpuRepr,
$memIdent,
Expand Down Expand Up @@ -36,15 +36,21 @@ export function atomic<TSchema extends U32 | I32>(
class AtomicImpl<TSchema extends U32 | I32> implements Atomic<TSchema> {
public readonly [$internal] = {};
public readonly type = 'atomic';
public readonly [$validStorageSchema]: true;
public readonly [$validUniformSchema]: true;
public readonly [$validVertexSchema]: true;
public readonly [$validIndexSchema]: false;

// Type-tokens, not available at runtime
declare readonly [$repr]: Infer<TSchema>;
declare readonly [$memIdent]: MemIdentity<TSchema>;
declare readonly [$gpuRepr]: TSchema extends U32 ? atomicU32 : atomicI32;
declare readonly [$validStorageSchema]: true;
declare readonly [$validUniformSchema]: true;
declare readonly [$validVertexSchema]: true;
// ---

constructor(public readonly inner: TSchema) {}
constructor(public readonly inner: TSchema) {
this[$validStorageSchema] = true;
this[$validUniformSchema] = true;
this[$validVertexSchema] = true;
this[$validIndexSchema] = false;
}
}
43 changes: 29 additions & 14 deletions packages/typegpu/src/data/attributes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,16 @@ import type {
Infer,
InferGPU,
InferPartial,
IsValidStorageSchema,
IsValidUniformSchema,
IsValidVertexSchema,
MemIdentity,
} from '../shared/repr.ts';
import { $internal } from '../shared/symbols.ts';
import {
$gpuRepr,
$internal,
$invalidSchemaReason,
$memIdent,
$repr,
$reprPartial,
$validIndexSchema,
$validStorageSchema,
$validUniformSchema,
$validVertexSchema,
Expand Down Expand Up @@ -360,6 +358,11 @@ export function getAttributesString<T extends BaseData>(field: T): string {

class BaseDecoratedImpl<TInner extends BaseData, TAttribs extends unknown[]> {
public readonly [$internal] = {};
public readonly [$validStorageSchema]: boolean;
public readonly [$validUniformSchema]: boolean;
public readonly [$validVertexSchema]: boolean;
public readonly [$validIndexSchema]: boolean;
public [$invalidSchemaReason]?: string | undefined;

// Type-tokens, not available at runtime
declare readonly [$repr]: Infer<TInner>;
Expand All @@ -371,6 +374,12 @@ class BaseDecoratedImpl<TInner extends BaseData, TAttribs extends unknown[]> {
public readonly inner: TInner,
public readonly attribs: TAttribs,
) {
this[$validStorageSchema] = inner[$validStorageSchema];
this[$validUniformSchema] = inner[$validUniformSchema];
this[$validVertexSchema] = inner[$validVertexSchema];
this[$validIndexSchema] = inner[$validIndexSchema];
this[$invalidSchemaReason] = inner[$invalidSchemaReason];

const alignAttrib = attribs.find(isAlignAttrib)?.params[0];
const sizeAttrib = attribs.find(isSizeAttrib)?.params[0];

Expand Down Expand Up @@ -421,16 +430,15 @@ class DecoratedImpl<TInner extends BaseData, TAttribs extends unknown[]>
implements Decorated<TInner, TAttribs> {
public readonly [$internal] = {};
public readonly type = 'decorated';
declare readonly [$validStorageSchema]: TInner[typeof $validStorageSchema];
declare readonly [$validUniformSchema]: TInner[typeof $validUniformSchema];
declare readonly [$validVertexSchema]: TInner[typeof $validVertexSchema];
declare readonly [$validIndexSchema]: false;

// Type-tokens, not available at runtime
declare readonly [$memIdent]: TAttribs extends Location[]
? MemIdentity<TInner> | Decorated<MemIdentity<TInner>, TAttribs>
: Decorated<MemIdentity<TInner>, TAttribs>;
declare readonly [$invalidSchemaReason]:
Decorated[typeof $invalidSchemaReason];
declare readonly [$validStorageSchema]: IsValidStorageSchema<TInner>;
declare readonly [$validUniformSchema]: IsValidUniformSchema<TInner>;
declare readonly [$validVertexSchema]: IsValidVertexSchema<TInner>;
// ---
}

Expand All @@ -439,10 +447,17 @@ class LooseDecoratedImpl<TInner extends BaseData, TAttribs extends unknown[]>
implements LooseDecorated<TInner, TAttribs> {
public readonly [$internal] = {};
public readonly type = 'loose-decorated';
declare readonly [$validStorageSchema]: false;
declare readonly [$validUniformSchema]: false;
declare readonly [$validVertexSchema]: TInner[typeof $validVertexSchema];
declare readonly [$validIndexSchema]: false;

// Type-tokens, not available at runtime
declare readonly [$invalidSchemaReason]:
LooseDecorated[typeof $invalidSchemaReason];
declare readonly [$validVertexSchema]: IsValidVertexSchema<TInner>;
// ---
constructor(
public readonly inner: TInner,
public readonly attribs: TAttribs,
) {
super(inner, attribs);
this[$invalidSchemaReason] =
'Loosely decorated schemas are not host-shareable';
}
}
Loading
Loading