New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

typegpu

Package Overview
Dependencies
Maintainers
3
Versions
58
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

typegpu - npm Package Compare versions

Comparing version
0.10.0
to
0.10.1
+818
builtin-DdtWpk2t.js
import { An as isAlignAttrib, At as stitch, B as vec2h, Bn as isNaturallyEphemeral, Cn as isDisarray, Dn as undecorate, En as isUnstruct, G as vec3h, H as vec2u, Hn as isSizeAttrib, J as vec4b, Jn as isWgslData, K as vec3i, Kn as isVoid, L as isValidProp, Ln as isMat, M as INTERNAL_createStruct, Mn as isBuiltinAttrib, Nn as isDecorated, O as coerceToSnippet, Q as vec4u, R as vec2b, Sn as isData, Tn as isLooseDecorated, U as vec3b, Un as isVec, V as vec2i, Vn as isPtr, W as vec3f, Wt as isKnownAtComptime, X as vec4h, Y as vec4f, Yn as isWgslStruct, Z as vec4i, _n as MatrixColumnsAccess, _t as schemaCallWrapperGPU, at as i32, bn as getCustomLocation, bt as derefSnippet, cr as $internal, dn as isEphemeralSnippet, er as getName, fr as $resolve, gn as InfixDispatch, gt as schemaCallWrapper, ht as safeStringify, i as mul, ir as $cast, it as f32, mn as snip, n as div, nt as bool, o as sub, or as $gpuCallable, pr as isMarkedInternal, q as vec3u, qn as isWgslArray, r as mod, rr as setName, rt as f16, st as u32, t as add, tt as abstractInt, vn as UnknownData, w as comptime, wn as isLooseData, xn as getCustomSize, yn as getCustomAlignment, z as vec2f } from "./operators-d-PMVTo7.js";
//#region src/data/vertexFormatData.ts
var TgpuVertexFormatDataImpl = class {
[$internal] = {};
[$gpuCallable];
constructor(type) {
this.type = type;
this[$gpuCallable] = { call: (ctx, [v]) => {
return schemaCallWrapperGPU(ctx, formatToWGSLType[this.type], v);
} };
}
[$cast](v) {
return schemaCallWrapper(formatToWGSLType[this.type], v);
}
};
const formatToWGSLType = {
uint8: u32,
uint8x2: vec2u,
uint8x4: vec4u,
sint8: i32,
sint8x2: vec2i,
sint8x4: vec4i,
unorm8: f32,
unorm8x2: vec2f,
unorm8x4: vec4f,
snorm8: f32,
snorm8x2: vec2f,
snorm8x4: vec4f,
uint16: u32,
uint16x2: vec2u,
uint16x4: vec4u,
sint16: i32,
sint16x2: vec2i,
sint16x4: vec4i,
unorm16: f32,
unorm16x2: vec2f,
unorm16x4: vec4f,
snorm16: f32,
snorm16x2: vec2f,
snorm16x4: vec4f,
float16: f32,
float16x2: vec2f,
float16x4: vec4f,
float32: f32,
float32x2: vec2f,
float32x3: vec3f,
float32x4: vec4f,
uint32: u32,
uint32x2: vec2u,
uint32x3: vec3u,
uint32x4: vec4u,
sint32: i32,
sint32x2: vec2i,
sint32x3: vec3i,
sint32x4: vec4i,
"unorm10-10-10-2": vec4f,
"unorm8x4-bgra": vec4f
};
const packedFormats = new Set(Object.keys(formatToWGSLType));
const uint8 = new TgpuVertexFormatDataImpl("uint8");
const uint8x2 = new TgpuVertexFormatDataImpl("uint8x2");
const uint8x4 = new TgpuVertexFormatDataImpl("uint8x4");
const sint8 = new TgpuVertexFormatDataImpl("sint8");
const sint8x2 = new TgpuVertexFormatDataImpl("sint8x2");
const sint8x4 = new TgpuVertexFormatDataImpl("sint8x4");
const unorm8 = new TgpuVertexFormatDataImpl("unorm8");
const unorm8x2 = new TgpuVertexFormatDataImpl("unorm8x2");
const unorm8x4 = new TgpuVertexFormatDataImpl("unorm8x4");
const snorm8 = new TgpuVertexFormatDataImpl("snorm8");
const snorm8x2 = new TgpuVertexFormatDataImpl("snorm8x2");
const snorm8x4 = new TgpuVertexFormatDataImpl("snorm8x4");
const uint16 = new TgpuVertexFormatDataImpl("uint16");
const uint16x2 = new TgpuVertexFormatDataImpl("uint16x2");
const uint16x4 = new TgpuVertexFormatDataImpl("uint16x4");
const sint16 = new TgpuVertexFormatDataImpl("sint16");
const sint16x2 = new TgpuVertexFormatDataImpl("sint16x2");
const sint16x4 = new TgpuVertexFormatDataImpl("sint16x4");
const unorm16 = new TgpuVertexFormatDataImpl("unorm16");
const unorm16x2 = new TgpuVertexFormatDataImpl("unorm16x2");
const unorm16x4 = new TgpuVertexFormatDataImpl("unorm16x4");
const snorm16 = new TgpuVertexFormatDataImpl("snorm16");
const snorm16x2 = new TgpuVertexFormatDataImpl("snorm16x2");
const snorm16x4 = new TgpuVertexFormatDataImpl("snorm16x4");
const float16 = new TgpuVertexFormatDataImpl("float16");
const float16x2 = new TgpuVertexFormatDataImpl("float16x2");
const float16x4 = new TgpuVertexFormatDataImpl("float16x4");
const float32 = new TgpuVertexFormatDataImpl("float32");
const float32x2 = new TgpuVertexFormatDataImpl("float32x2");
const float32x3 = new TgpuVertexFormatDataImpl("float32x3");
const float32x4 = new TgpuVertexFormatDataImpl("float32x4");
const uint32 = new TgpuVertexFormatDataImpl("uint32");
const uint32x2 = new TgpuVertexFormatDataImpl("uint32x2");
const uint32x3 = new TgpuVertexFormatDataImpl("uint32x3");
const uint32x4 = new TgpuVertexFormatDataImpl("uint32x4");
const sint32 = new TgpuVertexFormatDataImpl("sint32");
const sint32x2 = new TgpuVertexFormatDataImpl("sint32x2");
const sint32x3 = new TgpuVertexFormatDataImpl("sint32x3");
const sint32x4 = new TgpuVertexFormatDataImpl("sint32x4");
const unorm10_10_10_2 = new TgpuVertexFormatDataImpl("unorm10-10-10-2");
const unorm8x4_bgra = new TgpuVertexFormatDataImpl("unorm8x4-bgra");
function isPackedData(value) {
return isMarkedInternal(value) && packedFormats.has(value?.type);
}
//#endregion
//#region src/data/alignmentOf.ts
const knownAlignmentMap = {
f32: 4,
f16: 2,
i32: 4,
u32: 4,
bool: 4,
u16: 2,
vec2f: 8,
vec2h: 4,
vec2i: 8,
vec2u: 8,
"vec2<bool>": 8,
vec3f: 16,
vec3h: 8,
vec3i: 16,
vec3u: 16,
"vec3<bool>": 16,
vec4f: 16,
vec4h: 8,
vec4i: 16,
vec4u: 16,
"vec4<bool>": 16,
mat2x2f: 8,
mat3x3f: 16,
mat4x4f: 16,
atomic: 4
};
function computeAlignment(data) {
const dataType = data?.type;
const knownAlignment = knownAlignmentMap[dataType];
if (knownAlignment !== void 0) return knownAlignment;
if (isWgslStruct(data)) return Object.values(data.propTypes).map(alignmentOf).reduce((a, b) => a > b ? a : b);
if (isWgslArray(data)) return alignmentOf(data.elementType);
if (isUnstruct(data)) {
const firstProp = Object.values(data.propTypes)[0];
return firstProp ? getCustomAlignment(firstProp) ?? 1 : 1;
}
if (isDisarray(data)) return getCustomAlignment(data.elementType) ?? 1;
if (isDecorated(data) || isLooseDecorated(data)) return getCustomAlignment(data) ?? alignmentOf(data.inner);
if (packedFormats.has(dataType)) return 1;
throw new Error(`Cannot determine alignment of data: ${safeStringify(data)}`);
}
function computeCustomAlignment(data) {
if (isUnstruct(data)) {
const firstProp = Object.values(data.propTypes)[0];
return firstProp ? customAlignmentOf(firstProp) : 1;
}
if (isDisarray(data)) return customAlignmentOf(data.elementType);
if (isLooseDecorated(data)) return getCustomAlignment(data) ?? customAlignmentOf(data.inner);
return getCustomAlignment(data) ?? 1;
}
/**
* Since alignments can be inferred from data types, they are not stored on them.
* Instead, this weak map acts as an extended property of those data types.
*/
const cachedAlignments = /* @__PURE__ */ new WeakMap();
const cachedCustomAlignments = /* @__PURE__ */ new WeakMap();
function alignmentOf(data) {
let alignment = cachedAlignments.get(data);
if (alignment === void 0) {
alignment = computeAlignment(data);
cachedAlignments.set(data, alignment);
}
return alignment;
}
function customAlignmentOf(data) {
let alignment = cachedCustomAlignments.get(data);
if (alignment === void 0) {
alignment = computeCustomAlignment(data);
cachedCustomAlignments.set(data, alignment);
}
return alignment;
}
/**
* Returns the alignment (in bytes) of data represented by the `schema`.
*/
function PUBLIC_alignmentOf(schema) {
return alignmentOf(schema);
}
//#endregion
//#region src/mathUtils.ts
/**
* @param value
* @param modulo has to be power of 2
*/
const roundUp = (value, modulo) => {
const bitMask = modulo - 1;
const invBitMask = ~bitMask;
return (value & bitMask) === 0 ? value : (value & invBitMask) + modulo;
};
//#endregion
//#region src/data/schemaMemoryLayout.ts
const knownSizesMap = {
bool: 4,
f32: 4,
f16: 2,
i32: 4,
u32: 4,
u16: 2,
vec2f: 8,
vec2h: 4,
vec2i: 8,
vec2u: 8,
"vec2<bool>": 8,
vec3f: 12,
vec3h: 6,
vec3i: 12,
vec3u: 12,
"vec3<bool>": 12,
vec4f: 16,
vec4h: 8,
vec4i: 16,
vec4u: 16,
"vec4<bool>": 16,
mat2x2f: 16,
mat3x3f: 48,
mat4x4f: 64,
uint8: 1,
uint8x2: 2,
uint8x4: 4,
sint8: 1,
sint8x2: 2,
sint8x4: 4,
unorm8: 1,
unorm8x2: 2,
unorm8x4: 4,
snorm8: 1,
snorm8x2: 2,
snorm8x4: 4,
uint16: 2,
uint16x2: 4,
uint16x4: 8,
sint16: 2,
sint16x2: 4,
sint16x4: 8,
unorm16: 2,
unorm16x2: 4,
unorm16x4: 8,
snorm16: 2,
snorm16x2: 4,
snorm16x4: 8,
float16: 2,
float16x2: 4,
float16x4: 8,
float32: 4,
float32x2: 8,
float32x3: 12,
float32x4: 16,
uint32: 4,
uint32x2: 8,
uint32x3: 12,
uint32x4: 16,
sint32: 4,
sint32x2: 8,
sint32x3: 12,
sint32x4: 16,
"unorm10-10-10-2": 4,
"unorm8x4-bgra": 4,
atomic: 4
};
function computeMLOfStruct(struct) {
let size = 0;
let longestContiguousPrefix = 0;
let isContiguous = true;
let prefixEnd = false;
for (const property of Object.values(struct.propTypes)) {
if (Number.isNaN(size)) throw new Error("Only the last property of a struct can be unbounded");
const prevSize = size;
size = roundUp(size, alignmentOf(property));
const hasPadding = prevSize !== size;
const propLayout = computeMemoryLayout(property);
size += propLayout.size;
if (Number.isNaN(size) && property.type !== "array") throw new Error("Cannot nest unbounded struct within another struct");
if (prefixEnd) continue;
if (!hasPadding && propLayout.isContiguous) longestContiguousPrefix += propLayout.size;
else {
prefixEnd = true;
isContiguous = false;
if (!hasPadding) longestContiguousPrefix += propLayout.longestContiguousPrefix;
}
}
const trueSize = roundUp(size, alignmentOf(struct));
return {
isContiguous: size === trueSize && isContiguous,
size: trueSize,
longestContiguousPrefix
};
}
function computeMLOfUnstruct(data) {
let size = 0;
let longestContiguousPrefix = 0;
let isContiguous = true;
let prefixEnd = false;
for (const property of Object.values(data.propTypes)) {
const alignment = customAlignmentOf(property);
const prevSize = size;
size = roundUp(size, alignment);
const hasPadding = prevSize !== size;
if (hasPadding) isContiguous = false;
const propLayout = computeMemoryLayout(property);
size += propLayout.size;
if (prefixEnd) continue;
if (!hasPadding && propLayout.isContiguous) longestContiguousPrefix += propLayout.size;
else {
prefixEnd = true;
isContiguous = false;
if (!hasPadding) longestContiguousPrefix += propLayout.longestContiguousPrefix;
}
}
return {
isContiguous,
size,
longestContiguousPrefix
};
}
function computeMLOfWgslArray(data) {
const elementType = data.elementType;
const elementMemoryLayout = computeMemoryLayout(elementType);
const elementSize = elementMemoryLayout.size;
const stride = roundUp(elementSize, alignmentOf(elementType));
const isContiguous = !(stride > elementSize) && elementMemoryLayout.isContiguous;
const size = data.elementCount === 0 ? NaN : data.elementCount * stride;
let longestContiguousPrefix;
if (isContiguous) longestContiguousPrefix = size;
else longestContiguousPrefix = elementMemoryLayout.longestContiguousPrefix;
return {
size,
isContiguous,
longestContiguousPrefix
};
}
function computeMLOfDisarray(data) {
const elementType = data.elementType;
const elementMemoryLayout = computeMemoryLayout(elementType);
const elementSize = elementMemoryLayout.size;
const stride = roundUp(elementSize, customAlignmentOf(elementType));
const isContiguous = !(stride > elementSize) && elementMemoryLayout.isContiguous;
const size = data.elementCount * stride;
let longestContiguousPrefix;
if (isContiguous) longestContiguousPrefix = size;
else longestContiguousPrefix = elementMemoryLayout.longestContiguousPrefix;
return {
size,
isContiguous,
longestContiguousPrefix
};
}
function computeMemoryLayout(data) {
const knownSize = knownSizesMap[data.type];
if (knownSize !== void 0) return {
isContiguous: data.type !== "mat3x3f",
size: knownSize,
longestContiguousPrefix: data.type === "mat3x3f" ? 12 : knownSize
};
if (isWgslStruct(data)) return computeMLOfStruct(data);
if (isUnstruct(data)) return computeMLOfUnstruct(data);
if (isWgslArray(data)) return computeMLOfWgslArray(data);
if (isDisarray(data)) return computeMLOfDisarray(data);
if (isDecorated(data) || isLooseDecorated(data)) {
const size = getCustomSize(data);
const undecoratedLayout = computeMemoryLayout(undecorate(data));
if (size) return {
isContiguous: size === undecoratedLayout.size && undecoratedLayout.isContiguous,
size,
longestContiguousPrefix: undecoratedLayout.longestContiguousPrefix
};
return computeMemoryLayout(data.inner);
}
throw new Error(`Cannot determine memory layout of data: ${data}`);
}
/**
* Since memory layout can be inferred from data types, they are not stored on them.
* Instead, this weak map acts as an extended property of those data types.
*/
const cachedLayouts = /* @__PURE__ */ new WeakMap();
function getLayoutInfo(schema, key) {
let layout = cachedLayouts.get(schema);
if (layout === void 0) {
layout = computeMemoryLayout(schema);
cachedLayouts.set(schema, layout);
}
return layout[key];
}
//#endregion
//#region src/data/sizeOf.ts
function sizeOf(schema) {
return getLayoutInfo(schema, "size");
}
/**
* Returns the size (in bytes) of data represented by the `schema`.
*/
function PUBLIC_sizeOf(schema) {
return sizeOf(schema);
}
//#endregion
//#region src/data/attributes.ts
function attribute(data, attrib) {
if (isDecorated(data)) return new DecoratedImpl(data.inner, [attrib, ...data.attribs]);
if (isLooseDecorated(data)) return new LooseDecoratedImpl(data.inner, [attrib, ...data.attribs]);
if (isLooseData(data)) return new LooseDecoratedImpl(data, [attrib]);
return new DecoratedImpl(data, [attrib]);
}
/**
* Gives the wrapped data-type a custom byte alignment. Useful in order to
* fulfill uniform alignment requirements.
*
* @example
* const Data = d.struct({
* a: u32, // takes up 4 bytes
* // 12 bytes of padding, because `b` is custom aligned to multiples of 16 bytes
* b: d.align(16, u32),
* });
*
* @param alignment The multiple of bytes this data should align itself to.
* @param data The data-type to align.
*/
function align(alignment, data) {
return attribute(data, {
[$internal]: true,
type: "@align",
params: [alignment]
});
}
/**
* Adds padding bytes after the wrapped data-type, until the whole value takes up `size` bytes.
*
* @example
* const Data = d.struct({
* a: d.size(16, u32), // takes up 16 bytes, instead of 4
* b: u32, // starts at byte 16, because `a` has a custom size
* });
*
* @param size The amount of bytes that should be reserved for this data-type.
* @param data The data-type to wrap.
*/
function size(size, data) {
return attribute(data, {
[$internal]: true,
type: "@size",
params: [size]
});
}
/**
* Assigns an explicit numeric location to a struct member or a parameter that has this type.
*
* @example
* const VertexOutput = {
* a: d.u32, // has implicit location 0
* b: d.location(5, d.u32),
* c: d.u32, // has implicit location 6
* };
*
* @param location The explicit numeric location.
* @param data The data-type to wrap.
*/
function location(location, data) {
return attribute(data, {
[$internal]: true,
type: "@location",
params: [location]
});
}
function interpolate(interpolationType, data) {
return attribute(data, {
[$internal]: true,
type: "@interpolate",
params: [interpolationType]
});
}
/**
* Marks a position built-in output value as invariant in vertex shaders.
* If the data and control flow match for two position outputs in different
* entry points, then the result values are guaranteed to be the same.
*
* Must only be applied to the position built-in value.
*
* @example
* const VertexOutput = {
* pos: d.invariant(d.builtin.position),
* };
*
* @param data The position built-in data-type to mark as invariant.
*/
function invariant(data) {
if (!isBuiltin(data)) throw new Error("The @invariant attribute must only be applied to the position built-in value.");
const builtinAttrib = isDecorated(data) || isLooseDecorated(data) ? data.attribs.find(isBuiltinAttrib) : void 0;
if (!builtinAttrib || builtinAttrib.params[0] !== "position") throw new Error("The @invariant attribute must only be applied to the position built-in value.");
return attribute(data, {
[$internal]: true,
type: "@invariant",
params: []
});
}
function isBuiltin(value) {
return (isDecorated(value) || isLooseDecorated(value)) && value.attribs.find(isBuiltinAttrib) !== void 0;
}
function getAttributesString(field) {
if (!isDecorated(field) && !isLooseDecorated(field)) return "";
return field.attribs.map((attrib) => {
if (attrib.params.length === 0) return `${attrib.type} `;
return `${attrib.type}(${attrib.params.join(", ")}) `;
}).join("");
}
var BaseDecoratedImpl = class {
[$internal] = {};
constructor(inner, attribs) {
this.inner = inner;
this.attribs = attribs;
const alignAttrib = attribs.find(isAlignAttrib)?.params[0];
const sizeAttrib = attribs.find(isSizeAttrib)?.params[0];
if (alignAttrib !== void 0) {
if (alignAttrib <= 0) throw new Error(`Custom data alignment must be a positive number, got: ${alignAttrib}.`);
if (Math.log2(alignAttrib) % 1 !== 0) throw new Error(`Alignment has to be a power of 2, got: ${alignAttrib}.`);
if (isWgslData(this.inner)) {
if (alignAttrib % alignmentOf(this.inner) !== 0) throw new Error(`Custom alignment has to be a multiple of the standard data alignment. Got: ${alignAttrib}, expected multiple of: ${alignmentOf(this.inner)}.`);
}
}
if (sizeAttrib !== void 0) {
if (sizeAttrib < sizeOf(this.inner)) throw new Error(`Custom data size cannot be smaller then the standard data size. Got: ${sizeAttrib}, expected at least: ${sizeOf(this.inner)}.`);
if (sizeAttrib <= 0) throw new Error(`Custom data size must be a positive number. Got: ${sizeAttrib}.`);
}
}
};
var DecoratedImpl = class extends BaseDecoratedImpl {
[$internal] = {};
type = "decorated";
};
var LooseDecoratedImpl = class extends BaseDecoratedImpl {
[$internal] = {};
type = "loose-decorated";
};
//#endregion
//#region src/core/function/ioSchema.ts
function withLocations(members, locations = {}) {
let nextLocation = 0;
const usedCustomLocations = /* @__PURE__ */ new Set();
return Object.fromEntries(Object.entries(members ?? {}).map(([key, member]) => {
const customLocation = getCustomLocation(member);
if (customLocation !== void 0) {
if (usedCustomLocations.has(customLocation)) throw new Error("Duplicate custom location attributes found");
usedCustomLocations.add(customLocation);
}
return [key, member];
}).map(([key, member]) => {
if (isBuiltin(member)) return [key, member];
if (getCustomLocation(member) !== void 0) return [key, member];
if (locations[key]) return [key, location(locations[key], member)];
while (usedCustomLocations.has(nextLocation)) nextLocation++;
return [key, location(nextLocation++, member)];
}));
}
function createIoSchema(layout, locations = {}) {
return isData(layout) ? isVoid(layout) ? layout : isBuiltin(layout) ? layout : getCustomLocation(layout) !== void 0 ? layout : location(0, layout) : INTERNAL_createStruct(withLocations(layout, locations), false);
}
//#endregion
//#region src/data/autoStruct.ts
/**
* A requirement for the generated struct is that non-builtin properties need to
* have the same name in WGSL as they do in JS. This allows locations to be properly
* matched between the Vertex output and Fragment input.
*/
var AutoStruct = class {
/**
* js key -> data type
*/
#validProps;
/**
* js key -> { prop: 'wgsl key', type: ... }
* @example '$position' -> { prop: 'position', type: ... }
*/
#allocated;
#usedWgslKeys;
#locations;
#cachedStruct;
#typeForExtraProps;
constructor(validProps, typeForExtraProps, locations) {
this.#validProps = validProps;
this.#typeForExtraProps = typeForExtraProps;
this.#allocated = {};
this.#locations = locations;
this.#usedWgslKeys = /* @__PURE__ */ new Set();
}
/**
* Used for accessing builtins, varying and attributes in code.
*/
accessProp(key) {
const dataType = this.#validProps[key] ?? this.#typeForExtraProps;
if (!dataType) return;
return this.provideProp(key, dataType);
}
/**
* Used for providing new varyings.
*
* @privateRemarks
* Internally used by `accessProp`.
*/
provideProp(key, dataType) {
let alloc = this.#allocated[key];
if (!alloc) {
const wgslKey = key.replaceAll("$", "");
if (this.#usedWgslKeys.has(wgslKey)) throw new Error(`Property name '${wgslKey}' causes naming clashes. Choose a different name.`);
if (!isValidProp(wgslKey)) throw new Error(`Property key '${key}' is a reserved WGSL word. Choose a different name.`);
this.#usedWgslKeys.add(wgslKey);
alloc = {
prop: wgslKey,
type: dataType
};
this.#allocated[key] = alloc;
}
return alloc;
}
get completeStruct() {
if (!this.#cachedStruct) {
this.#cachedStruct = createIoSchema(Object.fromEntries(Object.values(this.#allocated).map((alloc) => {
return [alloc.prop, alloc.type];
})), this.#locations);
const ownName = getName(this);
if (ownName) setName(this.#cachedStruct, ownName);
}
return this.#cachedStruct;
}
[$resolve](ctx) {
return ctx.resolve(this.completeStruct);
}
toString() {
return `auto-struct:${getName(this) ?? "<unnamed>"}`;
}
};
AutoStruct.prototype[$internal] = {};
AutoStruct.prototype.type = "auto-struct";
//#endregion
//#region src/tgsl/accessProp.ts
const infixKinds = [
"vec2f",
"vec3f",
"vec4f",
"vec2h",
"vec3h",
"vec4h",
"vec2i",
"vec3i",
"vec4i",
"vec2u",
"vec3u",
"vec4u",
"mat2x2f",
"mat3x3f",
"mat4x4f"
];
const infixOperators = {
add,
sub,
mul,
div,
mod
};
const swizzleLenToType = {
f: {
1: f32,
2: vec2f,
3: vec3f,
4: vec4f
},
h: {
1: f16,
2: vec2h,
3: vec3h,
4: vec4h
},
i: {
1: i32,
2: vec2i,
3: vec3i,
4: vec4i
},
u: {
1: u32,
2: vec2u,
3: vec3u,
4: vec4u
},
b: {
1: bool,
2: vec2b,
3: vec3b,
4: vec4b
}
};
function accessProp(target, propName) {
if (infixKinds.includes(target.dataType.type) && propName in infixOperators) {
const operator = infixOperators[propName];
return snip(new InfixDispatch(propName, target, operator[$gpuCallable].call.bind(operator)), UnknownData, target.origin);
}
if (isWgslArray(target.dataType) && propName === "length") {
if (target.dataType.elementCount === 0) return snip(stitch`arrayLength(&${target})`, u32, "runtime");
return snip(target.dataType.elementCount, abstractInt, "constant");
}
if (isMat(target.dataType) && propName === "columns") return snip(new MatrixColumnsAccess(target), UnknownData, target.origin);
if (isWgslStruct(target.dataType) || isUnstruct(target.dataType)) {
let propType = target.dataType.propTypes[propName];
if (!propType) return;
propType = undecorate(propType);
return snip(stitch`${target}.${propName}`, propType, target.origin === "argument" ? "argument" : !isEphemeralSnippet(target) && !isNaturallyEphemeral(propType) ? target.origin : target.origin === "constant" || target.origin === "constant-tgpu-const-ref" ? "constant" : "runtime");
}
if (target.dataType instanceof AutoStruct) {
const result = target.dataType.accessProp(propName);
if (!result) return;
return snip(stitch`${target}.${result.prop}`, result.type, "argument");
}
if (isPtr(target.dataType)) {
const derefed = derefSnippet(target);
if (propName === "$") return derefed;
return accessProp(derefed, propName);
}
if (isVec(target.dataType)) {
if (propName === "kind") return snip(target.dataType.type, UnknownData, "constant");
}
const propLength = propName.length;
if (isVec(target.dataType) && propLength >= 1 && propLength <= 4) {
const isXYZW = /^[xyzw]+$/.test(propName);
const isRGBA = /^[rgba]+$/.test(propName);
if (!isXYZW && !isRGBA) return;
const swizzleType = swizzleLenToType[target.dataType.type.includes("bool") ? "b" : target.dataType.type[4]][propLength];
if (!swizzleType) return;
return snip(isKnownAtComptime(target) ? target.value[propName] : stitch`${target}.${propName}`, swizzleType, target.origin === "argument" && propLength === 1 ? "argument" : target.origin === "constant" || target.origin === "constant-tgpu-const-ref" ? "constant" : "runtime");
}
if (isKnownAtComptime(target) || target.dataType === UnknownData) return coerceToSnippet(target.value[propName]);
}
//#endregion
//#region src/data/array.ts
/**
* Creates an array schema that can be used to construct gpu buffers.
* Describes arrays with fixed-size length, storing elements of the same type.
*
* @example
* const LENGTH = 3;
* const array = d.arrayOf(d.u32, LENGTH);
*
* If `elementCount` is not specified, a partially applied function is returned.
* @example
* const array = d.arrayOf(d.vec3f);
* // ^? (n: number) => WgslArray<d.Vec3f>
*
* @param elementType The type of elements in the array.
* @param elementCount The number of elements in the array.
*/
const arrayOf = comptime(((elementType, elementCount) => {
if (elementCount === void 0) return comptime((count) => cpu_arrayOf(elementType, count));
return cpu_arrayOf(elementType, elementCount);
})).$name("arrayOf");
function cpu_arrayOf(elementType, elementCount) {
const arraySchema = (elements) => {
if (elements && elements.length !== elementCount) throw new Error(`Array schema of ${elementCount} elements of type ${elementType.type} called with ${elements.length} argument(s).`);
return Array.from({ length: elementCount }, (_, i) => schemaCallWrapper(elementType, elements?.[i]));
};
Object.setPrototypeOf(arraySchema, WgslArrayImpl);
if (Number.isNaN(sizeOf(elementType))) throw new Error("Cannot nest runtime sized arrays.");
arraySchema.elementType = elementType;
if (!Number.isInteger(elementCount) || elementCount < 0) throw new Error(`Cannot create array schema with invalid element count: ${elementCount}.`);
arraySchema.elementCount = elementCount;
return arraySchema;
}
const WgslArrayImpl = {
[$internal]: true,
type: "array",
toString() {
return `arrayOf(${this.elementType}, ${this.elementCount})`;
}
};
//#endregion
//#region src/builtin.ts
function defineBuiltin(dataType, value) {
return attribute(dataType, {
[$internal]: true,
type: "@builtin",
params: [value]
});
}
const builtin = {
vertexIndex: defineBuiltin(u32, "vertex_index"),
instanceIndex: defineBuiltin(u32, "instance_index"),
clipDistances: defineBuiltin(arrayOf(u32, 8), "clip_distances"),
position: defineBuiltin(vec4f, "position"),
frontFacing: defineBuiltin(bool, "front_facing"),
fragDepth: defineBuiltin(f32, "frag_depth"),
primitiveIndex: defineBuiltin(u32, "primitive_index"),
sampleIndex: defineBuiltin(u32, "sample_index"),
sampleMask: defineBuiltin(u32, "sample_mask"),
localInvocationId: defineBuiltin(vec3u, "local_invocation_id"),
localInvocationIndex: defineBuiltin(u32, "local_invocation_index"),
globalInvocationId: defineBuiltin(vec3u, "global_invocation_id"),
workgroupId: defineBuiltin(vec3u, "workgroup_id"),
numWorkgroups: defineBuiltin(vec3u, "num_workgroups"),
subgroupInvocationId: defineBuiltin(u32, "subgroup_invocation_id"),
subgroupSize: defineBuiltin(u32, "subgroup_size"),
subgroupId: defineBuiltin(u32, "subgroup_id"),
numSubgroups: defineBuiltin(u32, "num_subgroups")
};
//#endregion
export { uint32x4 as $, packedFormats as A, sint8x4 as B, float16x4 as C, float32x4 as D, float32x3 as E, sint32x2 as F, snorm8x2 as G, snorm16x2 as H, sint32x3 as I, uint16x2 as J, snorm8x4 as K, sint32x4 as L, sint16x2 as M, sint16x4 as N, formatToWGSLType as O, sint32 as P, uint32x3 as Q, sint8 as R, float16x2 as S, float32x2 as T, snorm16x4 as U, snorm16 as V, snorm8 as W, uint32 as X, uint16x4 as Y, uint32x2 as Z, roundUp as _, AutoStruct as a, unorm16x2 as at, customAlignmentOf as b, getAttributesString as c, unorm8x2 as ct, isBuiltin as d, uint8 as et, location as f, getLayoutInfo as g, sizeOf as h, infixOperators as i, unorm16 as it, sint16 as j, isPackedData as k, interpolate as l, unorm8x4 as lt, PUBLIC_sizeOf as m, arrayOf as n, uint8x4 as nt, createIoSchema as o, unorm16x4 as ot, size as p, uint16 as q, accessProp as r, unorm10_10_10_2 as rt, align as s, unorm8 as st, builtin as t, uint8x2 as tt, invariant as u, unorm8x4_bgra as ut, PUBLIC_alignmentOf as v, float32 as w, float16 as x, alignmentOf as y, sint8x2 as z };
//# sourceMappingURL=builtin-DdtWpk2t.js.map

Sorry, the diff of this file is too big to display

import { Cn as isDisarray, Dn as undecorate, En as isUnstruct, Nn as isDecorated, Tn as isLooseDecorated, Un as isVec, Vn as isPtr, Yn as isWgslStruct, cr as $internal, dr as $repr, er as getName, gt as schemaCallWrapper, jn as isAtomic, qn as isWgslArray, rr as setName, w as comptime } from "./operators-d-PMVTo7.js";
import { _ as roundUp, b as customAlignmentOf, g as getLayoutInfo, h as sizeOf, y as alignmentOf } from "./builtin-DdtWpk2t.js";
import { Measurer } from "typed-binary";
//#region src/data/sampler.ts
function sampler() {
return {
[$internal]: {},
type: "sampler",
[$repr]: void 0
};
}
function comparisonSampler() {
return {
[$internal]: {},
type: "sampler_comparison",
[$repr]: void 0
};
}
function isWgslSampler(value) {
return !!value[$internal] && value.type === "sampler";
}
function isWgslComparisonSampler(value) {
return !!value[$internal] && value.type === "sampler_comparison";
}
//#endregion
//#region src/data/alignIO.ts
/**
* @param io the IO to align
* @param baseAlignment must be power of 2
*/
function alignIO(io, baseAlignment) {
const currentPos = "size" in io ? io.size : io.currentByteOffset;
const bitMask = baseAlignment - 1;
const offset = currentPos & bitMask;
if ("skipBytes" in io) io.skipBytes(baseAlignment - offset & bitMask);
else io.add(baseAlignment - offset & bitMask);
}
//#endregion
//#region src/data/offsets.ts
const cachedOffsets = /* @__PURE__ */ new WeakMap();
function offsetsForProps(struct) {
const cached = cachedOffsets.get(struct);
if (cached) return cached;
const measurer = new Measurer();
const offsets = {};
let lastEntry;
for (const key in struct.propTypes) {
const prop = struct.propTypes[key];
if (prop === void 0) throw new Error(`Property ${key} is undefined in struct`);
const beforeAlignment = measurer.size;
alignIO(measurer, isUnstruct(struct) ? customAlignmentOf(prop) : alignmentOf(prop));
if (lastEntry) lastEntry.padding = measurer.size - beforeAlignment;
const propSize = sizeOf(prop);
offsets[key] = {
offset: measurer.size,
size: propSize
};
lastEntry = offsets[key];
measurer.add(propSize);
}
if (lastEntry) lastEntry.padding = roundUp(sizeOf(struct), alignmentOf(struct)) - measurer.size;
cachedOffsets.set(struct, offsets);
return offsets;
}
//#endregion
//#region src/data/atomic.ts
/**
* Marks a concrete integer scalar type schema (u32 or i32) as a WGSL atomic.
*
* @example
* const atomicU32 = d.atomic(d.u32);
* const atomicI32 = d.atomic(d.i32);
*
* @param data Underlying type schema.
*/
function atomic(data) {
return new AtomicImpl(data);
}
var AtomicImpl = class {
[$internal] = {};
type = "atomic";
constructor(inner) {
this.inner = inner;
}
};
//#endregion
//#region src/data/isContiguous.ts
function isContiguous(schema) {
return getLayoutInfo(schema, "isContiguous");
}
/**
* Returns `true` if data represented by the `schema` doesn't have padding.
*/
function PUBLIC_isContiguous(schema) {
return isContiguous(schema);
}
//#endregion
//#region src/data/getLongestContiguousPrefix.ts
function getLongestContiguousPrefix(schema) {
return getLayoutInfo(schema, "longestContiguousPrefix");
}
/**
* Returns the size (in bytes) of the longest contiguous memory prefix of data represented by the `schema`.
*/
function PUBLIC_getLongestContiguousPrefix(schema) {
return getLongestContiguousPrefix(schema);
}
//#endregion
//#region src/data/offsetUtils.ts
const OFFSET_MARKER = Symbol("indirectOffset");
const CONTIGUOUS_MARKER = Symbol("indirectContiguous");
function isOffsetProxy(value) {
return typeof value === "object" && value !== null && OFFSET_MARKER in value && CONTIGUOUS_MARKER in value;
}
function scalarNode(offset, contiguous) {
return {
[OFFSET_MARKER]: offset,
[CONTIGUOUS_MARKER]: contiguous
};
}
function getMarker(target, prop) {
if (prop === OFFSET_MARKER) return target[OFFSET_MARKER];
if (prop === CONTIGUOUS_MARKER) return target[CONTIGUOUS_MARKER];
}
function makeProxy(schema, baseOffset, contiguous = sizeOf(schema)) {
const unwrapped = undecorate(schema);
const vecComponentCount = isVec(unwrapped) ? unwrapped.componentCount : void 0;
if (vecComponentCount !== void 0) {
const componentSize = sizeOf(unwrapped.primitive);
return makeVecProxy(scalarNode(baseOffset, contiguous), componentSize, vecComponentCount);
}
if (isWgslStruct(unwrapped)) return makeStructProxy(unwrapped, scalarNode(baseOffset, contiguous));
if (isWgslArray(unwrapped)) return makeArrayProxy(unwrapped, scalarNode(baseOffset, contiguous));
return scalarNode(baseOffset, contiguous);
}
function createOffsetProxy(schema, baseOffset = 0) {
return makeProxy(schema, baseOffset, sizeOf(schema));
}
function makeVecProxy(target, componentSize, componentCount) {
const baseOffset = target[OFFSET_MARKER];
return new Proxy(target, { get(t, prop) {
const marker = getMarker(t, prop);
if (marker !== void 0) return marker;
const idx = prop === "x" || prop === "0" ? 0 : prop === "y" || prop === "1" ? 1 : prop === "z" || prop === "2" ? 2 : prop === "w" || prop === "3" ? 3 : -1;
if (idx < 0 || idx >= componentCount) return;
const byteOffset = idx * componentSize;
const contiguous = Math.max(0, t[CONTIGUOUS_MARKER] - byteOffset);
return scalarNode(baseOffset + byteOffset, contiguous);
} });
}
function makeArrayProxy(array, target) {
const elementType = array.elementType;
const elementSize = sizeOf(elementType);
const stride = roundUp(elementSize, alignmentOf(elementType));
const hasPadding = stride > elementSize;
return new Proxy(target, { get(t, prop) {
const marker = getMarker(t, prop);
if (marker !== void 0) return marker;
if (prop === "length") return array.elementCount;
if (typeof prop !== "string") return;
const index = Number(prop);
if (!Number.isInteger(index) || index < 0 || index >= array.elementCount) return;
const elementOffset = index * stride;
const remainingFromHere = !isContiguous(elementType) ? elementSize + getLongestContiguousPrefix(elementType) : Math.max(0, t[CONTIGUOUS_MARKER] - elementOffset);
const childContiguous = hasPadding ? Math.min(remainingFromHere, elementSize) : remainingFromHere;
return makeProxy(elementType, t[OFFSET_MARKER] + elementOffset, childContiguous);
} });
}
function makeStructProxy(struct, target) {
const offsets = offsetsForProps(struct);
const propTypes = struct.propTypes;
const propNames = Object.keys(propTypes);
const meta = /* @__PURE__ */ new Map();
let runStart = 0;
for (let i = 0; i < propNames.length; i++) {
const name = propNames[i];
if (!name) continue;
const type = propTypes[name];
if (!type) continue;
const info = offsets[name];
const padding = info.padding ?? 0;
const typeContiguous = isContiguous(type);
if (!(i === propNames.length - 1 || padding > 0 || !typeContiguous)) continue;
const runEnd = info.offset + (typeContiguous ? info.size : getLongestContiguousPrefix(type));
for (let j = runStart; j <= i; j++) {
const runName = propNames[j];
if (!runName) continue;
const runInfo = offsets[runName];
meta.set(runName, {
offset: runInfo.offset,
runEnd
});
}
runStart = i + 1;
}
return new Proxy(target, { get(t, prop) {
const marker = getMarker(t, prop);
if (marker !== void 0) return marker;
if (typeof prop !== "string") return;
const m = meta.get(prop);
if (!m) return;
const remainingFromHere = Math.max(0, t[CONTIGUOUS_MARKER] - m.offset);
const localLimit = Math.max(0, m.runEnd - m.offset);
const propSchema = propTypes[prop];
if (!propSchema) return;
return makeProxy(propSchema, t[OFFSET_MARKER] + m.offset, sizeOf(struct) === m.runEnd ? remainingFromHere : localLimit);
} });
}
function getRootContiguous(schema) {
const unwrapped = undecorate(schema);
if (isWgslStruct(unwrapped)) {
const offsets = offsetsForProps(unwrapped);
const propTypes = unwrapped.propTypes;
const propNames = Object.keys(propTypes);
for (let i = 0; i < propNames.length; i++) {
const name = propNames[i];
if (!name) continue;
const info = offsets[name];
const padding = info.padding ?? 0;
const runEnd = info.offset + info.size;
if (i === propNames.length - 1 || padding > 0) return runEnd;
}
return 0;
}
if (isWgslArray(unwrapped)) {
const elementType = unwrapped.elementType;
const elementSize = sizeOf(elementType);
const stride = roundUp(elementSize, alignmentOf(elementType));
const totalSize = sizeOf(schema);
if (!Number.isFinite(totalSize)) return elementSize;
return stride > elementSize ? elementSize : totalSize;
}
return sizeOf(schema);
}
/**
* A function that retrieves offset and information for a specific primitive within a data schema.
* Example usage:
* ```ts
* const Boid = d.struct({
* position: d.vec3f,
* velocity: d.vec3f,
* });
* const memLayout = d.memoryLayoutOf(Boid, (b) => b.velocity.y);
* console.log(memLayout.offset); // Byte offset of velocity.y within Boid (here 20 bytes)
* console.log(memLayout.contiguous); // Contiguous bytes available from that offset (here 8 bytes)
* ```
*
* @param schema - The data schema to analyze.
* @param accessor - Optional function that accesses a specific primitive within the schema. If omitted, uses the root offset (0).
* @returns An object containing the offset and contiguous byte information.
*/
function memoryLayoutOf(schema, accessor) {
if (!accessor) return {
offset: 0,
contiguous: getRootContiguous(schema)
};
const result = accessor(createOffsetProxy(schema));
if (isOffsetProxy(result)) return {
offset: result[OFFSET_MARKER],
contiguous: result[CONTIGUOUS_MARKER]
};
throw new Error("Invalid accessor result. Expected an offset proxy with markers.");
}
//#endregion
//#region src/data/disarray.ts
/**
* Creates an array schema that can be used to construct vertex buffers.
* Describes arrays with fixed-size length, storing elements of the same type.
*
* Elements in the schema are not aligned in respect to their `byteAlignment`,
* unless they are explicitly decorated with the custom align attribute
* via `d.align` function.
*
* @example
* const disarray = d.disarrayOf(d.vec3f, 3); // packed array of vec3f
*
* @example
* const disarray = d.disarrayOf(d.align(16, d.vec3f), 3);
*
* If `elementCount` is not specified, a partially applied function is returned.
* @example
* const disarray = d.disarrayOf(d.vec3f);
* // ^? (n: number) => Disarray<d.Vec3f>
*
* @param elementType The type of elements in the array.
* @param elementCount The number of elements in the array.
*/
const disarrayOf = comptime(((elementType, elementCount) => {
if (elementCount === void 0) return (count) => cpu_disarrayOf(elementType, count);
return cpu_disarrayOf(elementType, elementCount);
})).$name("disarrayOf");
function cpu_disarrayOf(elementType, elementCount) {
const disarraySchema = (elements) => {
if (elements && elements.length !== elementCount) throw new Error(`Disarray schema of ${elementCount} elements of type ${elementType.type} called with ${elements.length} argument(s).`);
return Array.from({ length: elementCount }, (_, i) => schemaCallWrapper(elementType, elements?.[i]));
};
Object.setPrototypeOf(disarraySchema, DisarrayImpl);
disarraySchema.elementType = elementType;
if (!Number.isInteger(elementCount) || elementCount < 0) throw new Error(`Cannot create disarray schema with invalid element count: ${elementCount}.`);
disarraySchema.elementCount = elementCount;
return disarraySchema;
}
const DisarrayImpl = {
[$internal]: true,
type: "disarray",
toString() {
return `disarrayOf(${this.elementType}, ${this.elementCount})`;
}
};
//#endregion
//#region src/data/unstruct.ts
/**
* Creates a loose struct schema that can be used to construct vertex buffers.
* Describes structs with members of both loose and non-loose types.
*
* The order of members matches the passed in properties object.
* Members are not aligned in respect to their `byteAlignment`,
* unless they are explicitly decorated with the custom align attribute
* via `d.align` function.
*
* @example
* const CircleStruct = d.unstruct({ radius: d.f32, pos: d.vec3f }); // packed struct with no padding
*
* @example
* const CircleStruct = d.unstruct({ radius: d.f32, pos: d.align(16, d.vec3f) });
*
* @param properties Record with `string` keys and `TgpuData` or `TgpuLooseData` values,
* each entry describing one struct member.
*/
function unstruct(properties) {
const unstructSchema = (instanceProps) => Object.fromEntries(Object.entries(properties).map(([key, schema]) => [key, schemaCallWrapper(schema, instanceProps?.[key])]));
Object.setPrototypeOf(unstructSchema, UnstructImpl);
unstructSchema.propTypes = properties;
return unstructSchema;
}
const UnstructImpl = {
[$internal]: true,
type: "unstruct",
$name(label) {
setName(this, label);
return this;
},
toString() {
return `unstruct:${getName(this) ?? "<unnamed>"}`;
}
};
//#endregion
//#region src/data/deepEqual.ts
/**
* Performs a deep comparison of two TypeGPU data schemas.
*
* @param a The first data schema to compare.
* @param b The second data schema to compare.
* @returns `true` if the schemas are deeply equal, `false` otherwise.
*
* @example
* ```ts
* import { vec3f, struct, deepEqual } from 'typegpu/data';
*
* const schema1 = struct({ a: vec3f });
* const schema2 = struct({ a: vec3f });
* const schema3 = struct({ b: vec3f });
*
* console.log(deepEqual(schema1, schema2)); // true
* console.log(deepEqual(schema1, schema3)); // false
* ```
*/
function deepEqual(a, b) {
if (a === b) return true;
if (a.type !== b.type) return false;
if (isWgslStruct(a) && isWgslStruct(b) || isUnstruct(a) && isUnstruct(b)) {
const aProps = a.propTypes;
const bProps = b.propTypes;
const aKeys = Object.keys(aProps);
const bKeys = Object.keys(bProps);
if (aKeys.length !== bKeys.length) return false;
for (let i = 0; i < aKeys.length; i++) {
const keyA = aKeys[i];
const keyB = bKeys[i];
if (keyA !== keyB || !keyA || !keyB || !deepEqual(aProps[keyA], bProps[keyB])) return false;
}
return true;
}
if (isWgslArray(a) && isWgslArray(b) || isDisarray(a) && isDisarray(b)) return a.elementCount === b.elementCount && deepEqual(a.elementType, b.elementType);
if (isPtr(a) && isPtr(b)) return a.addressSpace === b.addressSpace && a.access === b.access && deepEqual(a.inner, b.inner);
if (isAtomic(a) && isAtomic(b)) return deepEqual(a.inner, b.inner);
if (isDecorated(a) && isDecorated(b) || isLooseDecorated(a) && isLooseDecorated(b)) {
if (!deepEqual(a.inner, b.inner)) return false;
if (a.attribs.length !== b.attribs.length) return false;
const getAttrKey = (attr) => {
const anyAttr = attr;
return `${anyAttr.type}(${(anyAttr.params ?? []).join(",")})`;
};
const attrsA = a.attribs.map(getAttrKey);
const attrsB = b.attribs.map(getAttrKey);
for (let i = 0; i < attrsA.length; i++) if (attrsA[i] !== attrsB[i]) return false;
}
return true;
}
//#endregion
export { PUBLIC_getLongestContiguousPrefix as a, offsetsForProps as c, isWgslComparisonSampler as d, isWgslSampler as f, memoryLayoutOf as i, alignIO as l, unstruct as n, PUBLIC_isContiguous as o, sampler as p, disarrayOf as r, atomic as s, deepEqual as t, comparisonSampler as u };
//# sourceMappingURL=deepEqual-DQxK4vdp.js.map
{"version":3,"file":"deepEqual-DQxK4vdp.js","names":[],"sources":["../src/data/sampler.ts","../src/data/alignIO.ts","../src/data/offsets.ts","../src/data/atomic.ts","../src/data/isContiguous.ts","../src/data/getLongestContiguousPrefix.ts","../src/data/offsetUtils.ts","../src/data/disarray.ts","../src/data/unstruct.ts","../src/data/deepEqual.ts"],"sourcesContent":["import { $internal, $repr } from '../shared/symbols.ts';\nimport type { BaseData } from './wgslTypes.ts';\n\nexport interface WgslSamplerProps {\n addressModeU?: GPUAddressMode;\n addressModeV?: GPUAddressMode;\n /**\n * Specifies the address modes for the texture width, height, and depth\n * coordinates, respectively.\n */\n addressModeW?: GPUAddressMode;\n /**\n * Specifies the sampling behavior when the sample footprint is smaller than or equal to one\n * texel.\n */\n magFilter?: GPUFilterMode;\n /**\n * Specifies the sampling behavior when the sample footprint is larger than one texel.\n */\n minFilter?: GPUFilterMode;\n /**\n * Specifies behavior for sampling between mipmap levels.\n */\n mipmapFilter?: GPUMipmapFilterMode;\n lodMinClamp?: number;\n /**\n * Specifies the minimum and maximum levels of detail, respectively, used internally when\n * sampling a texture.\n */\n lodMaxClamp?: number;\n /**\n * Specifies the maximum anisotropy value clamp used by the sampler. Anisotropic filtering is\n * enabled when {@link GPUSamplerDescriptor.maxAnisotropy} is > 1 and the implementation supports it.\n * Anisotropic filtering improves the image quality of textures sampled at oblique viewing\n * angles. Higher {@link GPUSamplerDescriptor.maxAnisotropy} values indicate the maximum ratio of\n * anisotropy supported when filtering.\n *\n * Most implementations support {@link GPUSamplerDescriptor.maxAnisotropy} values in range\n * between 1 and 16, inclusive. The used value of {@link GPUSamplerDescriptor.maxAnisotropy}\n * will be clamped to the maximum value that the platform supports.\n * The precise filtering behavior is implementation-dependent.\n */\n maxAnisotropy?: number;\n}\n\nexport interface WgslComparisonSamplerProps {\n compare: GPUCompareFunction;\n addressModeU?: GPUAddressMode;\n addressModeV?: GPUAddressMode;\n /**\n * Specifies the address modes for the texture width, height, and depth\n * coordinates, respectively.\n */\n addressModeW?: GPUAddressMode;\n /**\n * Specifies the sampling behavior when the sample footprint is smaller than or equal to one\n * texel.\n */\n magFilter?: GPUFilterMode;\n /**\n * Specifies the sampling behavior when the sample footprint is larger than one texel.\n */\n minFilter?: GPUFilterMode;\n /**\n * Specifies behavior for sampling between mipmap levels.\n */\n mipmapFilter?: GPUMipmapFilterMode;\n lodMinClamp?: number;\n /**\n * Specifies the minimum and maximum levels of detail, respectively, used internally when\n * sampling a texture.\n */\n lodMaxClamp?: number;\n /**\n * Specifies the maximum anisotropy value clamp used by the sampler. Anisotropic filtering is\n * enabled when {@link GPUSamplerDescriptor.maxAnisotropy} is > 1 and the implementation supports it.\n * Anisotropic filtering improves the image quality of textures sampled at oblique viewing\n * angles. Higher {@link GPUSamplerDescriptor.maxAnisotropy} values indicate the maximum ratio of\n * anisotropy supported when filtering.\n *\n * Most implementations support {@link GPUSamplerDescriptor.maxAnisotropy} values in range\n * between 1 and 16, inclusive. The used value of {@link GPUSamplerDescriptor.maxAnisotropy}\n * will be clamped to the maximum value that the platform supports.\n * The precise filtering behavior is implementation-dependent.\n */\n maxAnisotropy?: number;\n}\n\nexport interface sampler {\n [$internal]: true;\n type: 'sampler';\n}\n\nexport function sampler(): WgslSampler {\n return {\n [$internal]: {},\n type: 'sampler',\n [$repr]: undefined as unknown as sampler,\n };\n}\n\nexport interface comparisonSampler {\n [$internal]: Record<string, never>;\n type: 'sampler_comparison';\n}\n\nexport function comparisonSampler(): WgslComparisonSampler {\n return {\n [$internal]: {},\n type: 'sampler_comparison',\n [$repr]: undefined as unknown as comparisonSampler,\n };\n}\n\nexport interface WgslSampler extends BaseData {\n readonly [$repr]: sampler;\n readonly type: 'sampler';\n}\n\nexport interface WgslComparisonSampler extends BaseData {\n readonly [$repr]: comparisonSampler;\n readonly type: 'sampler_comparison';\n}\n\nexport function isWgslSampler(value: unknown): value is WgslSampler {\n return (\n !!(value as WgslSampler)[$internal] &&\n (value as WgslSampler).type === 'sampler'\n );\n}\n\nexport function isWgslComparisonSampler(\n value: unknown,\n): value is WgslComparisonSampler {\n return (\n !!(value as WgslComparisonSampler)[$internal] &&\n (value as WgslComparisonSampler).type === 'sampler_comparison'\n );\n}\n","import type { IMeasurer, ISerialInput, ISerialOutput } from 'typed-binary';\n\n/**\n * @param io the IO to align\n * @param baseAlignment must be power of 2\n */\nfunction alignIO(\n io: ISerialInput | ISerialOutput | IMeasurer,\n baseAlignment: number,\n) {\n const currentPos = 'size' in io ? io.size : io.currentByteOffset;\n\n const bitMask = baseAlignment - 1;\n const offset = currentPos & bitMask;\n\n if ('skipBytes' in io) {\n io.skipBytes((baseAlignment - offset) & bitMask);\n } else {\n io.add((baseAlignment - offset) & bitMask);\n }\n}\n\nexport default alignIO;\n","import { Measurer } from 'typed-binary';\nimport { roundUp } from '../mathUtils.ts';\nimport alignIO from './alignIO.ts';\nimport { alignmentOf, customAlignmentOf } from './alignmentOf.ts';\nimport { isUnstruct, type Unstruct } from './dataTypes.ts';\nimport { sizeOf } from './sizeOf.ts';\nimport type { WgslStruct } from './wgslTypes.ts';\n\nexport interface OffsetInfo {\n offset: number;\n size: number;\n padding?: number | undefined;\n}\n\nconst cachedOffsets = new WeakMap<\n WgslStruct | Unstruct,\n Record<string, OffsetInfo>\n>();\n\nexport function offsetsForProps<T extends WgslStruct | Unstruct>(\n struct: T,\n): Record<keyof T['propTypes'], OffsetInfo> {\n type Key = keyof T['propTypes'];\n\n const cached = cachedOffsets.get(struct);\n if (cached) {\n return cached as Record<Key, OffsetInfo>;\n }\n\n const measurer = new Measurer();\n const offsets = {} as Record<Key, OffsetInfo>;\n let lastEntry: OffsetInfo | undefined;\n\n for (const key in struct.propTypes) {\n const prop = struct.propTypes[key];\n if (prop === undefined) {\n throw new Error(`Property ${key} is undefined in struct`);\n }\n\n const beforeAlignment = measurer.size;\n\n alignIO(\n measurer,\n isUnstruct(struct) ? customAlignmentOf(prop) : alignmentOf(prop),\n );\n\n if (lastEntry) {\n lastEntry.padding = measurer.size - beforeAlignment;\n }\n\n const propSize = sizeOf(prop);\n offsets[key as Key] = { offset: measurer.size, size: propSize };\n lastEntry = offsets[key];\n measurer.add(propSize);\n }\n\n if (lastEntry) {\n lastEntry.padding = roundUp(sizeOf(struct), alignmentOf(struct)) -\n measurer.size;\n }\n\n cachedOffsets.set(struct, offsets);\n return offsets;\n}\n","import type { Infer, MemIdentity } from '../shared/repr.ts';\nimport { $internal } from '../shared/symbols.ts';\nimport {\n $gpuRepr,\n $memIdent,\n $repr,\n $validStorageSchema,\n $validUniformSchema,\n $validVertexSchema,\n} from '../shared/symbols.ts';\nimport type { Atomic, atomicI32, atomicU32, I32, U32 } from './wgslTypes.ts';\n\n// ----------\n// Public API\n// ----------\n\n/**\n * Marks a concrete integer scalar type schema (u32 or i32) as a WGSL atomic.\n *\n * @example\n * const atomicU32 = d.atomic(d.u32);\n * const atomicI32 = d.atomic(d.i32);\n *\n * @param data Underlying type schema.\n */\nexport function atomic<TSchema extends U32 | I32>(\n data: TSchema,\n): Atomic<TSchema> {\n return new AtomicImpl(data);\n}\n\n// --------------\n// Implementation\n// --------------\n\nclass AtomicImpl<TSchema extends U32 | I32> implements Atomic<TSchema> {\n public readonly [$internal] = {};\n public readonly type = 'atomic';\n\n // Type-tokens, not available at runtime\n declare readonly [$repr]: Infer<TSchema>;\n declare readonly [$memIdent]: MemIdentity<TSchema>;\n declare readonly [$gpuRepr]: TSchema extends U32 ? atomicU32 : atomicI32;\n declare readonly [$validStorageSchema]: true;\n declare readonly [$validUniformSchema]: true;\n declare readonly [$validVertexSchema]: true;\n // ---\n\n constructor(public readonly inner: TSchema) {}\n}\n","import type { AnyData } from './dataTypes.ts';\nimport type { BaseData } from './wgslTypes.ts';\nimport { getLayoutInfo } from './schemaMemoryLayout.ts';\n\nexport function isContiguous(schema: BaseData): boolean {\n return getLayoutInfo(schema, 'isContiguous');\n}\n\n/**\n * Returns `true` if data represented by the `schema` doesn't have padding.\n */\nexport function PUBLIC_isContiguous(schema: AnyData): boolean {\n return isContiguous(schema);\n}\n","import type { AnyData } from './dataTypes.ts';\nimport type { BaseData } from './wgslTypes.ts';\nimport { getLayoutInfo } from './schemaMemoryLayout.ts';\n\nexport function getLongestContiguousPrefix(schema: BaseData): number {\n return getLayoutInfo(schema, 'longestContiguousPrefix');\n}\n\n/**\n * Returns the size (in bytes) of the longest contiguous memory prefix of data represented by the `schema`.\n */\nexport function PUBLIC_getLongestContiguousPrefix(schema: AnyData): number {\n return getLongestContiguousPrefix(schema);\n}\n","import { roundUp } from '../mathUtils.ts';\nimport { alignmentOf } from './alignmentOf.ts';\nimport {\n type OffsetInfo as PropOffsetInfo,\n offsetsForProps,\n} from './offsets.ts';\nimport { sizeOf } from './sizeOf.ts';\nimport { isContiguous } from './isContiguous.ts';\nimport { getLongestContiguousPrefix } from './getLongestContiguousPrefix.ts';\nimport type {\n AnyWgslData,\n BaseData,\n VecData,\n WgslArray,\n WgslStruct,\n} from './wgslTypes.ts';\nimport { isVec, isWgslArray, isWgslStruct } from './wgslTypes.ts';\nimport { undecorate } from './dataTypes.ts';\nimport type { Infer } from '../shared/repr.ts';\n\nconst OFFSET_MARKER = Symbol('indirectOffset');\nconst CONTIGUOUS_MARKER = Symbol('indirectContiguous');\n\ninterface OffsetProxy {\n [OFFSET_MARKER]: number;\n [CONTIGUOUS_MARKER]: number;\n}\n\nfunction isOffsetProxy(value: unknown): value is OffsetProxy {\n return (\n typeof value === 'object' &&\n value !== null &&\n OFFSET_MARKER in value &&\n CONTIGUOUS_MARKER in value\n );\n}\n\nfunction scalarNode(offset: number, contiguous: number): OffsetProxy {\n return { [OFFSET_MARKER]: offset, [CONTIGUOUS_MARKER]: contiguous };\n}\n\nfunction getMarker(target: OffsetProxy, prop: PropertyKey): number | undefined {\n if (prop === OFFSET_MARKER) {\n return target[OFFSET_MARKER];\n }\n if (prop === CONTIGUOUS_MARKER) {\n return target[CONTIGUOUS_MARKER];\n }\n return undefined;\n}\n\nfunction makeProxy(\n schema: AnyWgslData,\n baseOffset: number,\n contiguous = sizeOf(schema),\n): unknown {\n const unwrapped = undecorate(schema);\n\n const vecComponentCount = isVec(unwrapped)\n ? unwrapped.componentCount\n : undefined;\n\n if (vecComponentCount !== undefined) {\n const componentSize = sizeOf((unwrapped as VecData).primitive);\n return makeVecProxy(\n scalarNode(baseOffset, contiguous),\n componentSize,\n vecComponentCount,\n );\n }\n\n if (isWgslStruct(unwrapped)) {\n return makeStructProxy(unwrapped, scalarNode(baseOffset, contiguous));\n }\n\n if (isWgslArray(unwrapped)) {\n return makeArrayProxy(unwrapped, scalarNode(baseOffset, contiguous));\n }\n\n return scalarNode(baseOffset, contiguous);\n}\n\nexport function createOffsetProxy<T extends BaseData>(\n schema: T,\n baseOffset = 0,\n): unknown {\n return makeProxy(schema as AnyWgslData, baseOffset, sizeOf(schema));\n}\n\nfunction makeVecProxy(\n target: OffsetProxy,\n componentSize: number,\n componentCount: 2 | 3 | 4,\n): unknown {\n const baseOffset = target[OFFSET_MARKER];\n\n return new Proxy(target, {\n get(t, prop) {\n const marker = getMarker(t, prop);\n if (marker !== undefined) {\n return marker;\n }\n\n const idx = prop === 'x' || prop === '0'\n ? 0\n : prop === 'y' || prop === '1'\n ? 1\n : prop === 'z' || prop === '2'\n ? 2\n : prop === 'w' || prop === '3'\n ? 3\n : -1;\n\n if (idx < 0 || idx >= componentCount) {\n return undefined;\n }\n\n const byteOffset = idx * componentSize;\n const contiguous = Math.max(0, t[CONTIGUOUS_MARKER] - byteOffset);\n\n return scalarNode(baseOffset + byteOffset, contiguous);\n },\n });\n}\n\nfunction makeArrayProxy(array: WgslArray, target: OffsetProxy): unknown {\n const elementType = array.elementType as AnyWgslData;\n const elementSize = sizeOf(elementType);\n const stride = roundUp(elementSize, alignmentOf(elementType));\n const hasPadding = stride > elementSize;\n\n return new Proxy(target, {\n get(t, prop) {\n const marker = getMarker(t, prop);\n if (marker !== undefined) {\n return marker;\n }\n\n if (prop === 'length') {\n return array.elementCount;\n }\n\n if (typeof prop !== 'string') {\n return undefined;\n }\n\n const index = Number(prop);\n if (\n !Number.isInteger(index) ||\n index < 0 || index >= array.elementCount\n ) {\n return undefined;\n }\n\n const elementOffset = index * stride;\n const remainingFromHere = !isContiguous(elementType)\n ? elementSize + getLongestContiguousPrefix(elementType) // it is too much, but we correct it later\n : Math.max(\n 0,\n t[CONTIGUOUS_MARKER] - elementOffset,\n );\n\n const childContiguous = hasPadding\n ? Math.min(remainingFromHere, elementSize)\n : remainingFromHere;\n\n return makeProxy(\n elementType,\n t[OFFSET_MARKER] + elementOffset,\n childContiguous,\n );\n },\n });\n}\n\ntype StructFieldMeta = {\n offset: number;\n runEnd: number;\n};\n\nfunction makeStructProxy(struct: WgslStruct, target: OffsetProxy): unknown {\n const offsets = offsetsForProps(struct);\n const propTypes = struct.propTypes as Record<string, AnyWgslData>;\n const propNames = Object.keys(propTypes);\n\n const meta = new Map<string, StructFieldMeta>();\n\n let runStart = 0;\n for (let i = 0; i < propNames.length; i++) {\n const name = propNames[i];\n if (!name) {\n continue;\n }\n const type = propTypes[name];\n if (!type) {\n continue;\n }\n\n const info = offsets[name] as PropOffsetInfo;\n const padding = info.padding ?? 0;\n\n const typeContiguous = isContiguous(type);\n const isRunEnd = i === propNames.length - 1 || padding > 0 ||\n !typeContiguous;\n if (!isRunEnd) {\n continue;\n }\n\n const runEnd = info.offset +\n (typeContiguous ? info.size : getLongestContiguousPrefix(type));\n for (let j = runStart; j <= i; j++) {\n const runName = propNames[j];\n if (!runName) {\n continue;\n }\n const runInfo = offsets[runName] as PropOffsetInfo;\n meta.set(runName, { offset: runInfo.offset, runEnd });\n }\n runStart = i + 1;\n }\n\n return new Proxy(target, {\n get(t, prop) {\n const marker = getMarker(t, prop);\n if (marker !== undefined) {\n return marker;\n }\n\n if (typeof prop !== 'string') {\n return undefined;\n }\n\n const m = meta.get(prop);\n if (!m) {\n return undefined;\n }\n\n const remainingFromHere = Math.max(\n 0,\n t[CONTIGUOUS_MARKER] - m.offset,\n );\n const localLimit = Math.max(0, m.runEnd - m.offset);\n const propSchema = propTypes[prop];\n if (!propSchema) {\n return undefined;\n }\n\n return makeProxy(\n propSchema,\n t[OFFSET_MARKER] + m.offset,\n sizeOf(struct) === m.runEnd ? remainingFromHere : localLimit,\n );\n },\n });\n}\n\nfunction getRootContiguous(schema: AnyWgslData): number {\n const unwrapped = undecorate(schema);\n\n if (isWgslStruct(unwrapped)) {\n const offsets = offsetsForProps(unwrapped);\n const propTypes = unwrapped.propTypes as Record<string, AnyWgslData>;\n const propNames = Object.keys(propTypes);\n\n for (let i = 0; i < propNames.length; i++) {\n const name = propNames[i];\n if (!name) {\n continue;\n }\n const info = offsets[name] as PropOffsetInfo;\n const padding = info.padding ?? 0;\n\n const runEnd = info.offset + info.size;\n const isRunEnd = i === propNames.length - 1 || padding > 0;\n if (isRunEnd) {\n return runEnd;\n }\n }\n\n return 0;\n }\n\n if (isWgslArray(unwrapped)) {\n const elementType = unwrapped.elementType as AnyWgslData;\n const elementSize = sizeOf(elementType);\n const stride = roundUp(elementSize, alignmentOf(elementType));\n const totalSize = sizeOf(schema);\n if (!Number.isFinite(totalSize)) {\n return elementSize;\n }\n return stride > elementSize ? elementSize : totalSize;\n }\n\n return sizeOf(schema);\n}\n\n/**\n * Interface containing information about the offset and the available contiguous after a selected primitive.\n */\nexport interface PrimitiveOffsetInfo {\n /** The byte offset of the primitive within the buffer. */\n offset: number;\n /** The number of contiguous bytes available from the offset. */\n contiguous: number;\n}\n\n/**\n * A function that retrieves offset and information for a specific primitive within a data schema.\n * Example usage:\n * ```ts\n * const Boid = d.struct({\n * position: d.vec3f,\n * velocity: d.vec3f,\n * });\n * const memLayout = d.memoryLayoutOf(Boid, (b) => b.velocity.y);\n * console.log(memLayout.offset); // Byte offset of velocity.y within Boid (here 20 bytes)\n * console.log(memLayout.contiguous); // Contiguous bytes available from that offset (here 8 bytes)\n * ```\n *\n * @param schema - The data schema to analyze.\n * @param accessor - Optional function that accesses a specific primitive within the schema. If omitted, uses the root offset (0).\n * @returns An object containing the offset and contiguous byte information.\n */\nexport function memoryLayoutOf<T extends BaseData>(\n schema: T,\n accessor?: (proxy: Infer<T>) => number,\n): PrimitiveOffsetInfo {\n if (!accessor) {\n return {\n offset: 0,\n contiguous: getRootContiguous(schema as AnyWgslData),\n };\n }\n\n const proxy = createOffsetProxy(schema);\n const result = accessor(proxy as Infer<T>);\n\n if (isOffsetProxy(result)) {\n return {\n offset: result[OFFSET_MARKER],\n contiguous: result[CONTIGUOUS_MARKER],\n };\n }\n\n throw new Error(\n 'Invalid accessor result. Expected an offset proxy with markers.',\n );\n}\n","import { comptime } from '../core/function/comptime.ts';\nimport { $internal } from '../shared/symbols.ts';\nimport type { AnyData, Disarray } from './dataTypes.ts';\nimport { schemaCallWrapper } from './schemaCallWrapper.ts';\n\n// ----------\n// Public API\n// ----------\n\ninterface DisarrayConstructor {\n <TElement extends AnyData>(\n elementType: TElement,\n ): (elementCount: number) => Disarray<TElement>;\n\n <TElement extends AnyData>(\n elementType: TElement,\n elementCount: number,\n ): Disarray<TElement>;\n}\n\n/**\n * Creates an array schema that can be used to construct vertex buffers.\n * Describes arrays with fixed-size length, storing elements of the same type.\n *\n * Elements in the schema are not aligned in respect to their `byteAlignment`,\n * unless they are explicitly decorated with the custom align attribute\n * via `d.align` function.\n *\n * @example\n * const disarray = d.disarrayOf(d.vec3f, 3); // packed array of vec3f\n *\n * @example\n * const disarray = d.disarrayOf(d.align(16, d.vec3f), 3);\n *\n * If `elementCount` is not specified, a partially applied function is returned.\n * @example\n * const disarray = d.disarrayOf(d.vec3f);\n * // ^? (n: number) => Disarray<d.Vec3f>\n *\n * @param elementType The type of elements in the array.\n * @param elementCount The number of elements in the array.\n */\nexport const disarrayOf = comptime(\n ((elementType, elementCount) => {\n if (elementCount === undefined) {\n return (count: number) => cpu_disarrayOf(elementType, count);\n }\n return cpu_disarrayOf(elementType, elementCount);\n }) as DisarrayConstructor,\n).$name('disarrayOf');\n\nexport function cpu_disarrayOf<TElement extends AnyData>(\n elementType: TElement,\n elementCount: number,\n): Disarray<TElement> {\n // In the schema call, create and return a deep copy\n // by wrapping all the values in `elementType` schema calls.\n const disarraySchema = (elements?: TElement[]) => {\n if (elements && elements.length !== elementCount) {\n throw new Error(\n `Disarray schema of ${elementCount} elements of type ${elementType.type} called with ${elements.length} argument(s).`,\n );\n }\n\n return Array.from(\n { length: elementCount },\n (_, i) => schemaCallWrapper(elementType, elements?.[i]),\n );\n };\n Object.setPrototypeOf(disarraySchema, DisarrayImpl);\n\n disarraySchema.elementType = elementType;\n\n if (!Number.isInteger(elementCount) || elementCount < 0) {\n throw new Error(\n `Cannot create disarray schema with invalid element count: ${elementCount}.`,\n );\n }\n disarraySchema.elementCount = elementCount;\n\n return disarraySchema as unknown as Disarray<TElement>;\n}\n\n// --------------\n// Implementation\n// --------------\n\nconst DisarrayImpl = {\n [$internal]: true,\n type: 'disarray',\n\n toString(this: Disarray): string {\n return `disarrayOf(${this.elementType}, ${this.elementCount})`;\n },\n};\n","import { getName, setName } from '../shared/meta.ts';\nimport { $internal } from '../shared/symbols.ts';\nimport type { AnyData, Unstruct } from './dataTypes.ts';\nimport { schemaCallWrapper } from './schemaCallWrapper.ts';\n\n// ----------\n// Public API\n// ----------\n\n/**\n * Creates a loose struct schema that can be used to construct vertex buffers.\n * Describes structs with members of both loose and non-loose types.\n *\n * The order of members matches the passed in properties object.\n * Members are not aligned in respect to their `byteAlignment`,\n * unless they are explicitly decorated with the custom align attribute\n * via `d.align` function.\n *\n * @example\n * const CircleStruct = d.unstruct({ radius: d.f32, pos: d.vec3f }); // packed struct with no padding\n *\n * @example\n * const CircleStruct = d.unstruct({ radius: d.f32, pos: d.align(16, d.vec3f) });\n *\n * @param properties Record with `string` keys and `TgpuData` or `TgpuLooseData` values,\n * each entry describing one struct member.\n */\nexport function unstruct<TProps extends Record<string, AnyData>>(\n properties: TProps,\n): Unstruct<TProps> {\n // In the schema call, create and return a deep copy\n // by wrapping all the values in corresponding schema calls.\n const unstructSchema = (instanceProps?: TProps) =>\n Object.fromEntries(\n Object.entries(properties).map(([key, schema]) => [\n key,\n schemaCallWrapper(schema, instanceProps?.[key]),\n ]),\n );\n Object.setPrototypeOf(unstructSchema, UnstructImpl);\n unstructSchema.propTypes = properties;\n\n return unstructSchema as unknown as Unstruct<TProps>;\n}\n\n// --------------\n// Implementation\n// --------------\n\nconst UnstructImpl = {\n [$internal]: true,\n type: 'unstruct',\n\n $name(label: string) {\n setName(this, label);\n return this;\n },\n\n toString(): string {\n return `unstruct:${getName(this) ?? '<unnamed>'}`;\n },\n};\n","import type { AnyAttribute } from './attributes.ts';\nimport { isDisarray, isLooseDecorated, isUnstruct } from './dataTypes.ts';\nimport type { AnyData } from './dataTypes.ts';\nimport {\n isAtomic,\n isDecorated,\n isPtr,\n isWgslArray,\n isWgslStruct,\n} from './wgslTypes.ts';\n\n/**\n * Performs a deep comparison of two TypeGPU data schemas.\n *\n * @param a The first data schema to compare.\n * @param b The second data schema to compare.\n * @returns `true` if the schemas are deeply equal, `false` otherwise.\n *\n * @example\n * ```ts\n * import { vec3f, struct, deepEqual } from 'typegpu/data';\n *\n * const schema1 = struct({ a: vec3f });\n * const schema2 = struct({ a: vec3f });\n * const schema3 = struct({ b: vec3f });\n *\n * console.log(deepEqual(schema1, schema2)); // true\n * console.log(deepEqual(schema1, schema3)); // false\n * ```\n */\nexport function deepEqual(a: AnyData, b: AnyData): boolean {\n if (a === b) {\n return true;\n }\n\n if (a.type !== b.type) {\n return false;\n }\n\n if (\n (isWgslStruct(a) && isWgslStruct(b)) ||\n (isUnstruct(a) && isUnstruct(b))\n ) {\n const aProps = a.propTypes;\n const bProps = b.propTypes;\n const aKeys = Object.keys(aProps);\n const bKeys = Object.keys(bProps);\n\n if (aKeys.length !== bKeys.length) {\n return false;\n }\n\n for (let i = 0; i < aKeys.length; i++) {\n const keyA = aKeys[i];\n const keyB = bKeys[i];\n if (\n keyA !== keyB || !keyA || !keyB ||\n !deepEqual(aProps[keyA] as AnyData, bProps[keyB] as AnyData)\n ) {\n return false;\n }\n }\n return true;\n }\n\n if ((isWgslArray(a) && isWgslArray(b)) || (isDisarray(a) && isDisarray(b))) {\n return (\n a.elementCount === b.elementCount &&\n deepEqual(a.elementType as AnyData, b.elementType as AnyData)\n );\n }\n\n if (isPtr(a) && isPtr(b)) {\n return (\n a.addressSpace === b.addressSpace &&\n a.access === b.access &&\n deepEqual(a.inner as AnyData, b.inner as AnyData)\n );\n }\n\n if (isAtomic(a) && isAtomic(b)) {\n return deepEqual(a.inner, b.inner);\n }\n\n if (\n (isDecorated(a) && isDecorated(b)) ||\n (isLooseDecorated(a) && isLooseDecorated(b))\n ) {\n if (!deepEqual(a.inner as AnyData, b.inner as AnyData)) {\n return false;\n }\n if (a.attribs.length !== b.attribs.length) {\n return false;\n }\n\n // Create comparable string representations for each attribute\n const getAttrKey = (attr: unknown): string => {\n const anyAttr = attr as AnyAttribute;\n return `${anyAttr.type}(${(anyAttr.params ?? []).join(',')})`;\n };\n\n const attrsA = a.attribs.map(getAttrKey);\n const attrsB = b.attribs.map(getAttrKey);\n\n for (let i = 0; i < attrsA.length; i++) {\n if (attrsA[i] !== attrsB[i]) {\n return false;\n }\n }\n }\n\n // All other types have been checked for equality at the start\n return true;\n}\n"],"mappings":"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"}

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

import { $n as getMetaData, At as stitch, Bn as isNaturallyEphemeral, Cn as isDisarray, Dn as undecorate, Jn as isWgslData, Kt as isWgsl, Mt as getResolutionCtx, O as coerceToSnippet, Un as isVec, Vn as isPtr, Vt as getOwnSnippet, W as vec3f, Wt as isKnownAtComptime, Y as vec4f, Yn as isWgslStruct, _n as MatrixColumnsAccess, ar as $getNameForward, bt as derefSnippet, cr as $internal, dn as isEphemeralSnippet, er as getName, fr as $resolve, kn as Void, lr as $ownSnippet, mn as snip, nn as MissingLinksError, nr as isNamable, qn as isWgslArray, rr as setName, sr as $gpuValueOf, tr as hasTinyestMetadata, vn as UnknownData, wn as isLooseData, z as vec2f } from "./operators-d-PMVTo7.js";
import { c as getAttributesString, o as createIoSchema, r as accessProp, t as builtin } from "./builtin-DdtWpk2t.js";
//#region src/getGPUValue.ts
function getGPUValue(object) {
return object?.[$gpuValueOf];
}
//#endregion
//#region src/tgsl/accessIndex.ts
const indexableTypeToResult = {
mat2x2f: vec2f,
mat3x3f: vec3f,
mat4x4f: vec4f
};
function accessIndex(target, indexArg) {
const index = typeof indexArg === "number" ? coerceToSnippet(indexArg) : indexArg;
if (isWgslArray(target.dataType) || isDisarray(target.dataType)) {
const elementType = target.dataType.elementType;
const isElementNatEph = isNaturallyEphemeral(elementType);
const isTargetEphemeral = isEphemeralSnippet(target);
const isIndexConstant = index.origin === "constant";
let origin;
if (target.origin === "constant-tgpu-const-ref") if (isIndexConstant) origin = isElementNatEph ? "constant" : "constant-tgpu-const-ref";
else origin = isElementNatEph ? "runtime" : "runtime-tgpu-const-ref";
else if (target.origin === "runtime-tgpu-const-ref") origin = isElementNatEph ? "runtime" : "runtime-tgpu-const-ref";
else if (!isTargetEphemeral && !isElementNatEph) origin = target.origin;
else if (isIndexConstant && target.origin === "constant") origin = "constant";
else origin = "runtime";
return snip(isKnownAtComptime(target) && isKnownAtComptime(index) ? target.value[index.value] : stitch`${target}[${index}]`, elementType, origin);
}
if (isVec(target.dataType)) return snip(isKnownAtComptime(target) && isKnownAtComptime(index) ? target.value[index.value] : stitch`${target}[${index}]`, target.dataType.primitive, target.origin === "constant" || target.origin === "constant-tgpu-const-ref" ? "constant" : "runtime");
if (isPtr(target.dataType)) return accessIndex(derefSnippet(target), index);
if (target.value instanceof MatrixColumnsAccess) {
const propType = indexableTypeToResult[target.value.matrix.dataType.type];
return snip(stitch`${target.value.matrix}[${index}]`, propType, target.origin);
}
if (target.dataType.type in indexableTypeToResult) throw new Error("The only way of accessing matrix elements in TypeGPU functions is through the 'columns' property.");
if (isKnownAtComptime(target) && isKnownAtComptime(index) || target.dataType === UnknownData) return coerceToSnippet(target.value[index.value]);
if (isWgslStruct(target.dataType) && isKnownAtComptime(index) && typeof index.value === "string") return accessProp(target, index.value);
}
//#endregion
//#region src/core/valueProxyUtils.ts
const valueProxyHandler = { get(target, prop) {
if (prop in target) return Reflect.get(target, prop);
if (prop === "toString" || prop === Symbol.toStringTag || prop === Symbol.toPrimitive) return () => target.toString();
if (typeof prop === "symbol") return;
const targetSnippet = getOwnSnippet(target);
const index = Number(prop);
if (!Number.isNaN(index)) {
const accessed = accessIndex(targetSnippet, index);
if (!accessed) return;
return new Proxy({
[$internal]: true,
[$resolve]: (ctx) => ctx.resolve(accessed.value, accessed.dataType),
[$ownSnippet]: accessed,
toString: () => `${String(target)}[${prop}]`
}, valueProxyHandler);
}
const accessed = accessProp(targetSnippet, String(prop));
if (!accessed) return;
return new Proxy({
[$internal]: true,
[$resolve]: (ctx) => ctx.resolve(accessed.value, accessed.dataType),
[$ownSnippet]: accessed,
toString: () => `${String(target)}.${prop}`
}, valueProxyHandler);
} };
function getGpuValueRecursively(value) {
let unwrapped = value;
while (true) {
const gpuValue = getGPUValue(unwrapped);
if (!gpuValue) break;
unwrapped = gpuValue;
}
return unwrapped;
}
//#endregion
//#region src/core/resolve/externals.ts
/**
* Merges two external maps into one. If a key is present in both maps, the value from the new map is used.
* If the external value is a namable object, it is given a name if it does not already have one.
* @param existing - The existing external map.
* @param newExternals - The new external map.
*/
function applyExternals(existing, newExternals) {
for (const [key, value] of Object.entries(newExternals)) {
existing[key] = value;
if (value && (typeof value === "object" || typeof value === "function") && getName(value) === void 0) setName(value, key);
}
}
function addArgTypesToExternals(implementation, argTypes, applyExternals) {
const argTypeNames = [...implementation.matchAll(/:\s*(?<arg>.*?)\s*[,)]/g)].map((found) => found ? found[1] : void 0);
applyExternals(Object.fromEntries(argTypes.flatMap((argType, i) => {
const argTypeName = argTypeNames ? argTypeNames[i] : void 0;
return isWgslStruct(argType) && argTypeName !== void 0 ? [[argTypeName, argType]] : [];
})));
}
function addReturnTypeToExternals(implementation, returnType, applyExternals) {
const matched = implementation.match(/->\s(?<output>[\w\d_]+)\s{/);
const outputName = matched ? matched[1]?.trim() : void 0;
if (isWgslStruct(returnType) && outputName && !/\s/g.test(outputName)) applyExternals({ [outputName]: returnType });
}
function identifierRegex(name) {
return new RegExp(`(?<![\\w\\$_.])${name.replaceAll(".", "\\.").replaceAll("$", "\\$")}(?![\\w\\$_])`, "g");
}
/**
* Replaces all occurrences of external names in WGSL code with their resolved values.
* It adds all necessary definitions to the resolution context.
* @param ctx - The resolution context.
* @param externalMap - The external map.
* @param wgsl - The WGSL code.
*
* @returns The WGSL code with all external names replaced with their resolved values.
*/
function replaceExternalsInWgsl(ctx, externalMap, wgsl) {
return Object.entries(externalMap).reduce((acc, [externalName, external]) => {
const externalRegex = identifierRegex(externalName);
if (wgsl && externalName !== "Out" && externalName !== "In" && !externalRegex.test(wgsl)) console.warn(`The external '${externalName}' wasn't used in the resolved template.`);
if (isWgsl(external) || isLooseData(external) || hasTinyestMetadata(external)) return acc.replaceAll(externalRegex, ctx.resolve(external).value);
if (external !== null && typeof external === "object") {
const foundProperties = [...wgsl.matchAll(new RegExp(`${externalName.replaceAll(".", "\\.").replaceAll("$", "\\$")}\\.(?<prop>.*?)(?![\\w\\$_])`, "g"))].map((found) => found[1]);
return [...new Set(foundProperties)].reduce((innerAcc, prop) => prop && prop in external ? replaceExternalsInWgsl(ctx, { [`${externalName}.${prop}`]: external[prop] }, innerAcc) : innerAcc, acc);
}
console.warn(`During resolution, the external '${externalName}' has been omitted. Only TGPU resources, 'use gpu' functions, primitives, and plain JS objects can be used as externals.`);
return acc;
}, wgsl);
}
//#endregion
//#region src/core/function/extractArgs.ts
/**
* Extracts info about arguments of a given WGSL function string.
* @example
* const code = `
* fn add(a: i32, @location(0) b: i32, c) -> i32 {
* return a + b + c;
* }`;
*
* extractArgs(code);
* // {
* // args: [
* // { identifier: 'a', attributes: [], type: 'i32' },
* // { identifier: 'b', attributes: ['@location(0)'], type: 'i32' },
* // { identifier: 'c', attributes: [], type: undefined }
* // ],
* // ret: { type: 'i32', attributes: [] },
* // range: { begin: 11, end: 51 }
* // }
*/
function extractArgs(rawCode) {
const { strippedCode, argRange: range } = strip(rawCode);
const code = new ParsableString(strippedCode);
code.consume("(");
const args = [];
while (!code.isAt(")")) {
const attributes = [];
while (code.isAt("@")) {
code.parseUntil(closingParenthesis, parentheses);
code.consume(")");
attributes.push(code.lastParsed);
}
code.parseUntil(identifierEndSymbols);
const identifier = code.lastParsed;
let maybeType;
if (code.isAt(":")) {
code.consume(":");
code.parseUntil(typeEndSymbols, angleBrackets);
maybeType = code.lastParsed;
}
args.push({
identifier,
attributes,
type: maybeType
});
if (code.isAt(",")) code.consume(",");
}
code.consume(")");
let maybeRet;
if (code.isAt("->")) {
code.consume("->");
const attributes = [];
while (code.isAt("@")) {
code.parseUntil(closingParenthesis, parentheses);
code.consume(")");
attributes.push(code.lastParsed);
}
maybeRet = {
type: code.str.slice(code.pos),
attributes
};
}
return {
args,
ret: maybeRet,
range: {
begin: range[0],
end: range[1]
}
};
}
/**
* Strips comments, whitespaces, the name and the body of the function.
* @example
* const code = `
* fn add( a, // first argument
* @location(0) b : i32 ) -> i32 {
* return a + b; // returns the sum
* }`;
*
* strip(code); // "(a,@location(0)b:i32)->i32"
*/
function strip(rawCode) {
const code = new ParsableString(rawCode);
let strippedCode = "";
let argsStart;
while (!code.isFinished()) {
if (code.isAt(blankSpaces)) {
code.advanceBy(1);
continue;
}
if (code.isAt("//")) {
code.consume("//");
code.parseUntil(lineBreaks);
code.advanceBy(1);
continue;
}
if (code.isAt("/*")) {
code.parseUntil(openingCommentBlock, commentBlocks);
code.consume("*/");
continue;
}
if (code.isAt("{")) return {
strippedCode,
argRange: [argsStart, code.pos]
};
if (code.isAt("(") && argsStart === void 0) argsStart = code.pos;
if (argsStart !== void 0) strippedCode += code.str[code.pos];
code.advanceBy(1);
}
throw new Error("Invalid wgsl code!");
}
var ParsableString = class {
#parseStartPos;
#pos;
constructor(str) {
this.str = str;
this.#pos = 0;
}
get pos() {
return this.#pos;
}
/**
* This property is equivalent to the substring of `this.str`
* from the position of the last `parseUntil` call, to the current position.
*/
get lastParsed() {
if (this.#parseStartPos === void 0) throw new Error("Parse was not called yet!");
return this.str.slice(this.#parseStartPos, this.pos);
}
isFinished() {
return this.#pos >= this.str.length;
}
isAt(substr) {
if (typeof substr === "string") {
for (let i = 0; i < substr.length; i++) if (this.str[this.#pos + i] !== substr[i]) return false;
return true;
}
for (const elem of substr) if (this.isAt(elem)) return true;
return false;
}
/**
* @param toFind a set of strings either of which satisfy the search.
* @param brackets a pair of brackets that has to be closed for result to be valid. This includes the found character(s).
* @example
* // internal state:
* // '(@attribute(0) identifier: type)'
* // ^
* this.parse(new Set(')'), ['(', ')']);
* // internal state:
* // '(@attribute(0) identifier: type)'
* // ^
*/
parseUntil(toFind, brackets) {
this.#parseStartPos = this.#pos;
let openedBrackets = 0;
while (this.#pos < this.str.length) {
if (brackets && this.isAt(brackets[0])) openedBrackets += 1;
if (brackets && this.isAt(brackets[1])) openedBrackets -= 1;
if (openedBrackets === 0) {
if (this.isAt(toFind)) return this.#pos;
}
this.#pos += 1;
}
throw new Error("Reached the end of the string without finding a match!");
}
advanceBy(steps) {
this.#pos += steps;
}
consume(str) {
if (!this.isAt(str)) throw new Error(`Expected '${str}' at position ${this.#pos}, but found '${this.str.slice(this.#pos, this.#pos + str.length)}'`);
this.advanceBy(str.length);
}
};
const lineBreaks = new Set([
"\n",
"\v",
"\f",
"\r",
"…",
"\u2028",
"\u2029"
]);
const blankSpaces = new Set([
...lineBreaks,
" ",
" ",
"‎",
"‏"
]);
const closingParenthesis = new Set([")"]);
const identifierEndSymbols = new Set([
":",
",",
")"
]);
const typeEndSymbols = new Set([",", ")"]);
const openingCommentBlock = new Set(["*/"]);
const parentheses = ["(", ")"];
const angleBrackets = ["<", ">"];
const commentBlocks = ["/*", "*/"];
//#endregion
//#region src/core/function/fnCore.ts
function createFnCore(implementation, fnAttribute = "") {
/**
* External application has to be deferred until resolution because
* some externals can reference the owner function which has not been
* initialized yet (like when accessing the Output struct of a vertex
* entry fn).
*/
const externalsToApply = [];
return {
[$getNameForward]: typeof implementation === "function" ? implementation : void 0,
applyExternals(newExternals) {
externalsToApply.push(newExternals);
},
resolve(ctx, argTypes, returnType) {
const externalMap = {};
for (const externals of externalsToApply) applyExternals(externalMap, externals);
const id = ctx.getUniqueName(this);
if (typeof implementation === "string") {
if (!returnType) throw new Error("Explicit return type is required for string implementation");
const replacedImpl = replaceExternalsInWgsl(ctx, externalMap, implementation);
let header = "";
let body = "";
if (fnAttribute !== "") {
const input = isWgslStruct(argTypes[0]) ? `(in: ${ctx.resolve(argTypes[0]).value})` : "()";
const attributes = isWgslData(returnType) ? getAttributesString(returnType) : "";
header = `${input} ${returnType !== Void ? isWgslStruct(returnType) ? `-> ${ctx.resolve(returnType).value}` : `-> ${attributes !== "" ? attributes : "@location(0)"} ${ctx.resolve(returnType).value}` : ""} `;
body = replacedImpl;
} else {
const providedArgs = extractArgs(replacedImpl);
if (providedArgs.args.length !== argTypes.length) throw new Error(`WGSL implementation has ${providedArgs.args.length} arguments, while the shell has ${argTypes.length} arguments.`);
header = `(${providedArgs.args.map((argInfo, i) => `${argInfo.identifier}: ${checkAndReturnType(ctx, `parameter ${argInfo.identifier}`, argInfo.type, argTypes[i])}`).join(", ")}) ${returnType === Void ? "" : `-> ${checkAndReturnType(ctx, "return type", providedArgs.ret?.type, returnType)}`}`;
body = replacedImpl.slice(providedArgs.range.end);
}
ctx.addDeclaration(`${fnAttribute}fn ${id}${header}${body}`);
return snip(id, returnType, "runtime");
}
const pluginData = getMetaData(implementation);
const pluginExternals = typeof pluginData?.externals === "function" ? pluginData.externals() : pluginData?.externals;
if (pluginExternals) applyExternals(externalMap, Object.fromEntries(Object.entries(pluginExternals).filter(([name]) => !(name in externalMap))));
const ast = pluginData?.ast;
if (!ast) throw new Error("Missing metadata for tgpu.fn function body (either missing 'use gpu' directive, or misconfigured `unplugin-typegpu`)");
const missingExternals = ast.externalNames.filter((name) => !(name in externalMap));
if (missingExternals.length > 0) throw new MissingLinksError(getName(this), missingExternals);
const maybeSecondArg = ast.params[1];
if (maybeSecondArg && maybeSecondArg.type === "i" && fnAttribute !== "") applyExternals(externalMap, { [maybeSecondArg.name]: undecorate(returnType) });
const { head, body, returnType: actualReturnType } = ctx.fnToWgsl({
functionType: fnAttribute.includes("@compute") ? "compute" : fnAttribute.includes("@vertex") ? "vertex" : fnAttribute.includes("@fragment") ? "fragment" : "normal",
argTypes,
params: ast.params,
returnType,
body: ast.body,
externalMap
});
ctx.addDeclaration(`${fnAttribute}fn ${id}${ctx.resolve(head).value}${ctx.resolve(body).value}`);
return snip(id, actualReturnType, "runtime");
}
};
}
function checkAndReturnType(ctx, name, wgslType, jsType) {
const resolvedJsType = ctx.resolve(jsType).value.replace(/\s/g, "");
if (!wgslType) return resolvedJsType;
const resolvedWgslType = wgslType.replace(/\s/g, "");
if (resolvedWgslType !== resolvedJsType) throw new Error(`Type mismatch between TGPU shell and WGSL code string: ${name}, JS type "${resolvedJsType}", WGSL type "${resolvedWgslType}".`);
return wgslType;
}
//#endregion
//#region src/core/function/templateUtils.ts
function stripTemplate(arg, ...values) {
return isTemplateStringsArray(arg) ? templateLiteralIdentity(arg, ...values) : arg;
}
function isTemplateStringsArray(value) {
return Array.isArray(value) && "raw" in value && Array.isArray(value.raw) && value.raw.every((item) => typeof item === "string");
}
function templateLiteralIdentity(strings, ...values) {
return strings.slice(1).reduce((acc, elem, index) => `${acc}${values[index]}${elem}`, strings[0]);
}
//#endregion
//#region src/core/slot/slot.ts
function slot(defaultValue) {
return new TgpuSlotImpl(defaultValue);
}
var TgpuSlotImpl = class {
[$internal] = true;
resourceType = "slot";
constructor(defaultValue = void 0) {
this.defaultValue = defaultValue;
}
$name(label) {
setName(this, label);
return this;
}
areEqual(a, b) {
return Object.is(a, b);
}
toString() {
return `slot:${getName(this) ?? "<unnamed>"}`;
}
get [$gpuValueOf]() {
const ctx = getResolutionCtx();
if (!ctx) throw new Error(`Cannot access tgpu.slot's value outside of resolution.`);
return getGpuValueRecursively(ctx.unwrap(this));
}
get value() {
return this[$gpuValueOf];
}
get $() {
return this.value;
}
};
//#endregion
//#region src/core/slot/internalSlots.ts
const shaderStageSlot = slot(void 0);
//#endregion
//#region src/core/function/tgpuVertexFn.ts
/**
* Creates a shell of a typed entry function for the vertex shader stage. Any function
* that implements this shell can run for each vertex, allowing the inner code to process
* attributes and determine the final position of the vertex.
*
* @param options.in
* Vertex attributes and builtins to be made available to functions that implement this shell.
* @param options.out
* A record containing the final position of the vertex, and any information
* passed onto the fragment shader stage.
*/
function vertexFn(options) {
if (Object.keys(options.out).length === 0) throw new Error(`A vertexFn output cannot be empty since it must include the 'position' builtin.`);
const shell = {
in: options.in,
out: options.out,
argTypes: options.in && Object.keys(options.in).length !== 0 ? [createIoSchema(options.in)] : [],
entryPoint: "vertex"
};
const call = (arg, ...values) => createVertexFn(shell, stripTemplate(arg, ...values));
return Object.assign(call, shell);
}
function isTgpuVertexFn(value) {
return value?.shell?.entryPoint === "vertex";
}
function createVertexFn(shell, implementation) {
const core = createFnCore(implementation, "@vertex ");
const inputType = shell.argTypes[0];
return {
shell,
$uses(newExternals) {
core.applyExternals(newExternals);
return this;
},
[$internal]: true,
[$getNameForward]: core,
$name(newLabel) {
setName(this, newLabel);
if (isNamable(inputType)) inputType.$name(`${newLabel}_Input`);
return this;
},
[$resolve](ctx) {
const outputWithLocation = createIoSchema(shell.out, ctx.varyingLocations).$name(`${getName(this) ?? ""}_Output`);
if (typeof implementation === "string") {
if (inputType) core.applyExternals({ In: inputType });
core.applyExternals({ Out: outputWithLocation });
}
return ctx.withSlots([[shaderStageSlot, "vertex"]], () => core.resolve(ctx, shell.argTypes, outputWithLocation));
},
toString() {
return `vertexFn:${getName(core) ?? "<unnamed>"}`;
}
};
}
//#endregion
//#region src/common/fullScreenTriangle.ts
/**
* A vertex function that defines a single full-screen triangle out
* of three points.
*
* @example
* ```ts
* import { common } from 'typegpu';
*
* const pipeline = root.createRenderPipeline({
* vertex: common.fullScreenTriangle,
* fragment: yourFragmentShader,
* });
*
* pipeline.draw(3);
* ```
*/
const fullScreenTriangle = vertexFn({
in: { vertexIndex: builtin.vertexIndex },
out: {
pos: builtin.position,
uv: vec2f
}
})`{
const pos = array<vec2f, 3>(vec2f(-1, -1), vec2f(3, -1), vec2f(-1, 3));
const uv = array<vec2f, 3>(vec2f(0, 1), vec2f(2, 1), vec2f(0, -1));
return Out(vec4f(pos[in.vertexIndex], 0, 1), uv[in.vertexIndex]);
}`;
//#endregion
export { slot as a, addArgTypesToExternals as c, replaceExternalsInWgsl as d, getGpuValueRecursively as f, shaderStageSlot as i, addReturnTypeToExternals as l, accessIndex as m, isTgpuVertexFn as n, stripTemplate as o, valueProxyHandler as p, vertexFn as r, createFnCore as s, fullScreenTriangle as t, applyExternals as u };
//# sourceMappingURL=fullScreenTriangle-CfFyQd_0.js.map
{"version":3,"file":"fullScreenTriangle-CfFyQd_0.js","names":["#pos","#parseStartPos"],"sources":["../src/getGPUValue.ts","../src/tgsl/accessIndex.ts","../src/core/valueProxyUtils.ts","../src/core/resolve/externals.ts","../src/core/function/extractArgs.ts","../src/core/function/fnCore.ts","../src/core/function/templateUtils.ts","../src/core/slot/slot.ts","../src/core/slot/internalSlots.ts","../src/core/function/tgpuVertexFn.ts","../src/common/fullScreenTriangle.ts"],"sourcesContent":["import { $gpuValueOf } from './shared/symbols.ts';\nimport type { WithGPUValue } from './types.ts';\n\nexport function getGPUValue(\n object: unknown,\n): unknown {\n return (object as WithGPUValue<unknown>)?.[$gpuValueOf];\n}\n","import { stitch } from '../core/resolve/stitch.ts';\nimport {\n isDisarray,\n MatrixColumnsAccess,\n UnknownData,\n} from '../data/dataTypes.ts';\nimport { derefSnippet } from '../data/ref.ts';\nimport {\n isEphemeralSnippet,\n type Origin,\n snip,\n type Snippet,\n} from '../data/snippet.ts';\nimport { vec2f, vec3f, vec4f } from '../data/vector.ts';\nimport {\n type BaseData,\n isNaturallyEphemeral,\n isPtr,\n isVec,\n isWgslArray,\n isWgslStruct,\n} from '../data/wgslTypes.ts';\nimport { isKnownAtComptime } from '../types.ts';\nimport { accessProp } from './accessProp.ts';\nimport { coerceToSnippet } from './generationHelpers.ts';\n\nconst indexableTypeToResult = {\n mat2x2f: vec2f,\n mat3x3f: vec3f,\n mat4x4f: vec4f,\n} as const;\n\nexport function accessIndex(\n target: Snippet,\n indexArg: Snippet | number,\n): Snippet | undefined {\n const index = typeof indexArg === 'number'\n ? coerceToSnippet(indexArg)\n : indexArg;\n\n // array\n if (isWgslArray(target.dataType) || isDisarray(target.dataType)) {\n const elementType = target.dataType.elementType;\n const isElementNatEph = isNaturallyEphemeral(elementType);\n const isTargetEphemeral = isEphemeralSnippet(target);\n const isIndexConstant = index.origin === 'constant';\n\n let origin: Origin;\n\n if (target.origin === 'constant-tgpu-const-ref') {\n // Constant refs stay const unless the element/index forces runtime materialization\n if (isIndexConstant) {\n origin = isElementNatEph ? 'constant' : 'constant-tgpu-const-ref';\n } else {\n origin = isElementNatEph ? 'runtime' : 'runtime-tgpu-const-ref';\n }\n } else if (target.origin === 'runtime-tgpu-const-ref') {\n // Runtime refs keep their ref semantics unless the element is ephemeral only\n origin = isElementNatEph ? 'runtime' : 'runtime-tgpu-const-ref';\n } else if (!isTargetEphemeral && !isElementNatEph) {\n // Stable containers can forward their origin information\n origin = target.origin;\n } else if (isIndexConstant && target.origin === 'constant') {\n // Plain constants indexed with constants stay constant\n origin = 'constant';\n } else {\n // Everything else must be produced at runtime\n origin = 'runtime';\n }\n\n return snip(\n isKnownAtComptime(target) && isKnownAtComptime(index)\n // oxlint-disable-next-line typescript/no-explicit-any it's fine, it's there\n ? (target.value as any)[index.value as number]\n : stitch`${target}[${index}]`,\n elementType,\n /* origin */ origin,\n );\n }\n\n // vector\n if (isVec(target.dataType)) {\n return snip(\n isKnownAtComptime(target) && isKnownAtComptime(index)\n // oxlint-disable-next-line typescript/no-explicit-any it's fine, it's there\n ? (target.value as any)[index.value as any]\n : stitch`${target}[${index}]`,\n target.dataType.primitive,\n /* origin */ target.origin === 'constant' ||\n target.origin === 'constant-tgpu-const-ref'\n ? 'constant'\n : 'runtime',\n );\n }\n\n if (isPtr(target.dataType)) {\n // Sometimes values that are typed as pointers aren't instances of `d.ref`, so we\n // allow indexing as if it wasn't a pointer.\n return accessIndex(derefSnippet(target), index);\n }\n\n // matrix.columns\n if (target.value instanceof MatrixColumnsAccess) {\n const propType = indexableTypeToResult[\n (target.value.matrix.dataType as BaseData)\n .type as keyof typeof indexableTypeToResult\n ];\n\n return snip(\n stitch`${target.value.matrix}[${index}]`,\n propType,\n /* origin */ target.origin,\n );\n }\n\n // matrix\n if ((target.dataType as BaseData).type in indexableTypeToResult) {\n throw new Error(\n \"The only way of accessing matrix elements in TypeGPU functions is through the 'columns' property.\",\n );\n }\n\n if (\n (isKnownAtComptime(target) && isKnownAtComptime(index)) ||\n target.dataType === UnknownData\n ) {\n // No idea what the type is, so we act on the snippet's value and try to guess\n return coerceToSnippet(\n // oxlint-disable-next-line typescript/no-explicit-any we're inspecting the value, and it could be any value\n (target.value as any)[index.value as number],\n );\n }\n\n if (\n isWgslStruct(target.dataType) && isKnownAtComptime(index) &&\n typeof index.value === 'string'\n ) {\n return accessProp(target, index.value);\n }\n\n return undefined;\n}\n","import type { Snippet } from '../data/snippet.ts';\nimport { getGPUValue } from '../getGPUValue.ts';\nimport { $internal, $ownSnippet, $resolve } from '../shared/symbols.ts';\nimport { accessIndex } from '../tgsl/accessIndex.ts';\nimport { accessProp } from '../tgsl/accessProp.ts';\nimport {\n getOwnSnippet,\n type SelfResolvable,\n type WithOwnSnippet,\n} from '../types.ts';\n\nexport const valueProxyHandler: ProxyHandler<\n SelfResolvable & WithOwnSnippet\n> = {\n get(target, prop) {\n if (prop in target) {\n return Reflect.get(target, prop);\n }\n\n if (\n prop === 'toString' ||\n prop === Symbol.toStringTag ||\n prop === Symbol.toPrimitive\n ) {\n return () => target.toString();\n }\n\n if (typeof prop === 'symbol') {\n return undefined;\n }\n\n const targetSnippet = getOwnSnippet(target) as Snippet;\n\n const index = Number(prop);\n if (!Number.isNaN(index)) {\n const accessed = accessIndex(targetSnippet, index);\n if (!accessed) {\n // Prop was not found, must be missing from this object\n return undefined;\n }\n\n return new Proxy({\n [$internal]: true,\n [$resolve]: (ctx) => ctx.resolve(accessed.value, accessed.dataType),\n [$ownSnippet]: accessed,\n toString: () => `${String(target)}[${prop}]`,\n }, valueProxyHandler);\n }\n\n const accessed = accessProp(targetSnippet, String(prop));\n if (!accessed) {\n // Prop was not found, must be missing from this object\n return undefined;\n }\n\n return new Proxy({\n [$internal]: true,\n [$resolve]: (ctx) => ctx.resolve(accessed.value, accessed.dataType),\n [$ownSnippet]: accessed,\n toString: () => `${String(target)}.${prop}`,\n }, valueProxyHandler);\n },\n};\n\nexport function getGpuValueRecursively<T>(value: unknown): T {\n let unwrapped = value;\n\n while (true) {\n const gpuValue = getGPUValue(unwrapped);\n if (!gpuValue) {\n break;\n }\n unwrapped = gpuValue;\n }\n\n return unwrapped as T;\n}\n","import { isLooseData } from '../../data/dataTypes.ts';\nimport { isWgslStruct } from '../../data/wgslTypes.ts';\nimport { getName, hasTinyestMetadata, setName } from '../../shared/meta.ts';\nimport { isWgsl, type ResolutionCtx } from '../../types.ts';\n\n/**\n * A key-value mapping where keys represent identifiers within shader code,\n * and values can be any type that can be resolved to a code string.\n */\nexport type ExternalMap = Record<string, unknown>;\n\n/**\n * Merges two external maps into one. If a key is present in both maps, the value from the new map is used.\n * If the external value is a namable object, it is given a name if it does not already have one.\n * @param existing - The existing external map.\n * @param newExternals - The new external map.\n */\nexport function applyExternals(\n existing: ExternalMap,\n newExternals: ExternalMap,\n) {\n for (const [key, value] of Object.entries(newExternals)) {\n existing[key] = value;\n\n // Giving name to external value, if it does not already have one.\n if (\n value && (typeof value === 'object' || typeof value === 'function') &&\n getName(value) === undefined\n ) {\n setName(value, key);\n }\n }\n}\n\nexport function addArgTypesToExternals(\n implementation: string,\n argTypes: unknown[],\n applyExternals: (externals: ExternalMap) => void,\n) {\n const argTypeNames = [\n ...implementation.matchAll(/:\\s*(?<arg>.*?)\\s*[,)]/g),\n ].map((found) => (found ? found[1] : undefined));\n\n applyExternals(\n Object.fromEntries(\n argTypes.flatMap((argType, i) => {\n const argTypeName = argTypeNames ? argTypeNames[i] : undefined;\n return isWgslStruct(argType) && argTypeName !== undefined\n ? [[argTypeName, argType]]\n : [];\n }),\n ),\n );\n}\n\nexport function addReturnTypeToExternals(\n implementation: string,\n returnType: unknown,\n applyExternals: (externals: ExternalMap) => void,\n) {\n const matched = implementation.match(/->\\s(?<output>[\\w\\d_]+)\\s{/);\n const outputName = matched ? matched[1]?.trim() : undefined;\n\n if (isWgslStruct(returnType) && outputName && !/\\s/g.test(outputName)) {\n applyExternals({ [outputName]: returnType });\n }\n}\n\nfunction identifierRegex(name: string) {\n return new RegExp(\n `(?<![\\\\w\\\\$_.])${\n name.replaceAll('.', '\\\\.').replaceAll('$', '\\\\$')\n }(?![\\\\w\\\\$_])`,\n 'g',\n );\n}\n\n/**\n * Replaces all occurrences of external names in WGSL code with their resolved values.\n * It adds all necessary definitions to the resolution context.\n * @param ctx - The resolution context.\n * @param externalMap - The external map.\n * @param wgsl - The WGSL code.\n *\n * @returns The WGSL code with all external names replaced with their resolved values.\n */\nexport function replaceExternalsInWgsl(\n ctx: ResolutionCtx,\n externalMap: ExternalMap,\n wgsl: string,\n): string {\n return Object.entries(externalMap).reduce((acc, [externalName, external]) => {\n const externalRegex = identifierRegex(externalName);\n if (\n wgsl &&\n externalName !== 'Out' &&\n externalName !== 'In' &&\n !externalRegex.test(wgsl)\n ) {\n console.warn(\n `The external '${externalName}' wasn't used in the resolved template.`,\n );\n // continue anyway, we still might need to resolve the external\n }\n\n if (\n isWgsl(external) || isLooseData(external) || hasTinyestMetadata(external)\n ) {\n return acc.replaceAll(externalRegex, ctx.resolve(external).value);\n }\n\n if (external !== null && typeof external === 'object') {\n const foundProperties = [\n ...wgsl.matchAll(\n new RegExp(\n `${\n externalName.replaceAll('.', '\\\\.').replaceAll('$', '\\\\$')\n }\\\\.(?<prop>.*?)(?![\\\\w\\\\$_])`,\n 'g',\n ),\n ),\n ].map((found) => found[1]);\n const uniqueProperties = [...new Set(foundProperties)];\n\n return uniqueProperties.reduce(\n (innerAcc: string, prop) =>\n prop && prop in external\n ? replaceExternalsInWgsl(\n ctx,\n {\n [`${externalName}.${prop}`]:\n external[prop as keyof typeof external],\n },\n innerAcc,\n )\n : innerAcc,\n acc,\n );\n }\n\n console.warn(\n `During resolution, the external '${externalName}' has been omitted. Only TGPU resources, 'use gpu' functions, primitives, and plain JS objects can be used as externals.`,\n );\n\n return acc;\n }, wgsl);\n}\n","interface FunctionArgsInfo {\n args: ArgInfo[];\n ret: ReturnInfo | undefined;\n range: {\n begin: number;\n end: number;\n };\n}\n\ninterface ArgInfo {\n identifier: string;\n attributes: string[];\n type: string | undefined;\n}\n\ninterface ReturnInfo {\n attributes: string[];\n type: string;\n}\n\n/**\n * Extracts info about arguments of a given WGSL function string.\n * @example\n * const code = `\n * fn add(a: i32, @location(0) b: i32, c) -> i32 {\n * return a + b + c;\n * }`;\n *\n * extractArgs(code);\n * // {\n * // args: [\n * // { identifier: 'a', attributes: [], type: 'i32' },\n * // { identifier: 'b', attributes: ['@location(0)'], type: 'i32' },\n * // { identifier: 'c', attributes: [], type: undefined }\n * // ],\n * // ret: { type: 'i32', attributes: [] },\n * // range: { begin: 11, end: 51 }\n * // }\n */\nexport function extractArgs(rawCode: string): FunctionArgsInfo {\n const { strippedCode, argRange: range } = strip(rawCode);\n const code = new ParsableString(strippedCode);\n code.consume('(');\n\n const args: ArgInfo[] = [];\n while (!code.isAt(')')) {\n // In each loop iteration, process all the attributes, the identifier and the potential type of a single argument.\n\n const attributes = [];\n while (code.isAt('@')) {\n code.parseUntil(closingParenthesis, parentheses);\n code.consume(')');\n attributes.push(code.lastParsed);\n }\n\n code.parseUntil(identifierEndSymbols);\n const identifier = code.lastParsed;\n\n let maybeType: string | undefined;\n if (code.isAt(':')) {\n code.consume(':');\n code.parseUntil(typeEndSymbols, angleBrackets);\n maybeType = code.lastParsed;\n }\n\n args.push({\n identifier,\n attributes,\n type: maybeType,\n });\n\n if (code.isAt(',')) {\n code.consume(',');\n }\n }\n code.consume(')');\n\n let maybeRet: ReturnInfo | undefined;\n if (code.isAt('->')) {\n code.consume('->');\n\n const attributes = [];\n while (code.isAt('@')) {\n code.parseUntil(closingParenthesis, parentheses);\n code.consume(')');\n attributes.push(code.lastParsed);\n }\n\n maybeRet = { type: code.str.slice(code.pos), attributes };\n }\n\n return {\n args,\n ret: maybeRet,\n range: { begin: range[0], end: range[1] },\n };\n}\n\n/**\n * Strips comments, whitespaces, the name and the body of the function.\n * @example\n * const code = `\n * fn add( a, // first argument\n * @location(0) b : i32 ) -> i32 {\n * return a + b; // returns the sum\n * }`;\n *\n * strip(code); // \"(a,@location(0)b:i32)->i32\"\n */\nfunction strip(\n rawCode: string,\n): { strippedCode: string; argRange: [number, number] } {\n const code = new ParsableString(rawCode);\n let strippedCode = '';\n let argsStart: number | undefined;\n\n while (!code.isFinished()) {\n // parse character by character while ignoring comments and blankspaces until you find a `{`.\n\n // skip any blankspace\n if (code.isAt(blankSpaces)) {\n code.advanceBy(1); // the blankspace character\n continue;\n }\n\n // skip line comments\n if (code.isAt('//')) {\n code.consume('//');\n code.parseUntil(lineBreaks);\n code.advanceBy(1); // the line break\n continue;\n }\n\n // skip block comments\n if (code.isAt('/*')) {\n code.parseUntil(openingCommentBlock, commentBlocks);\n code.consume('*/');\n continue;\n }\n\n if (code.isAt('{')) {\n return {\n strippedCode,\n argRange: [argsStart as number, code.pos],\n };\n }\n\n if (code.isAt('(') && argsStart === undefined) {\n argsStart = code.pos;\n }\n\n if (argsStart !== undefined) {\n strippedCode += code.str[code.pos];\n }\n code.advanceBy(1); // parsed character\n }\n throw new Error('Invalid wgsl code!');\n}\n\nclass ParsableString {\n #parseStartPos: number | undefined;\n #pos: number;\n constructor(public readonly str: string) {\n this.#pos = 0;\n }\n\n get pos(): number {\n return this.#pos;\n }\n\n /**\n * This property is equivalent to the substring of `this.str`\n * from the position of the last `parseUntil` call, to the current position.\n */\n get lastParsed(): string {\n if (this.#parseStartPos === undefined) {\n throw new Error('Parse was not called yet!');\n }\n return this.str.slice(this.#parseStartPos, this.pos);\n }\n\n isFinished() {\n return this.#pos >= this.str.length;\n }\n\n isAt(substr: string | Set<string>): boolean {\n if (typeof substr === 'string') {\n for (let i = 0; i < substr.length; i++) {\n if (this.str[this.#pos + i] !== substr[i]) {\n return false;\n }\n }\n return true;\n }\n for (const elem of substr) {\n if (this.isAt(elem)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * @param toFind a set of strings either of which satisfy the search.\n * @param brackets a pair of brackets that has to be closed for result to be valid. This includes the found character(s).\n * @example\n * // internal state:\n * // '(@attribute(0) identifier: type)'\n * // ^\n * this.parse(new Set(')'), ['(', ')']);\n * // internal state:\n * // '(@attribute(0) identifier: type)'\n * // ^\n */\n parseUntil(\n toFind: Set<string>,\n brackets?: readonly [string, string],\n ): number {\n this.#parseStartPos = this.#pos;\n let openedBrackets = 0;\n while (this.#pos < this.str.length) {\n if (brackets && this.isAt(brackets[0])) {\n openedBrackets += 1;\n }\n if (brackets && this.isAt(brackets[1])) {\n openedBrackets -= 1;\n }\n if (openedBrackets === 0) {\n if (this.isAt(toFind)) {\n return this.#pos;\n }\n }\n this.#pos += 1;\n }\n throw new Error('Reached the end of the string without finding a match!');\n }\n\n advanceBy(steps: number) {\n this.#pos += steps;\n }\n\n consume(str: string): void {\n if (!this.isAt(str)) {\n throw new Error(\n `Expected '${str}' at position ${this.#pos}, but found '${\n this.str.slice(this.#pos, this.#pos + str.length)\n }'`,\n );\n }\n this.advanceBy(str.length);\n }\n}\n\nconst lineBreaks = new Set<string>([\n '\\u000A', // line feed\n '\\u000B', // vertical tab\n '\\u000C', // form feed\n '\\u000D', // carriage return\n '\\u0085', // next line\n '\\u2028', // line separator\n '\\u2029', // paragraph separator\n]);\nconst blankSpaces = new Set<string>([\n ...lineBreaks,\n '\\u0020', // space\n '\\u0009', // horizontal tab\n '\\u200E', // left-to-right mark\n '\\u200F', // right-to-left mark\n]);\nconst closingParenthesis = new Set<string>([')']);\nconst identifierEndSymbols = new Set([':', ',', ')']);\nconst typeEndSymbols = new Set([',', ')']);\nconst openingCommentBlock = new Set(['*/']);\n\nconst parentheses = ['(', ')'] as const;\nconst angleBrackets = ['<', '>'] as const;\nconst commentBlocks = ['/*', '*/'] as const;\n","import { getAttributesString } from '../../data/attributes.ts';\nimport { undecorate } from '../../data/dataTypes.ts';\nimport { type ResolvedSnippet, snip } from '../../data/snippet.ts';\nimport {\n type BaseData,\n isWgslData,\n isWgslStruct,\n Void,\n} from '../../data/wgslTypes.ts';\nimport { MissingLinksError } from '../../errors.ts';\nimport { getMetaData, getName } from '../../shared/meta.ts';\nimport { $getNameForward } from '../../shared/symbols.ts';\nimport type { ResolutionCtx } from '../../types.ts';\nimport {\n applyExternals,\n type ExternalMap,\n replaceExternalsInWgsl,\n} from '../resolve/externals.ts';\nimport { extractArgs } from './extractArgs.ts';\nimport type { Implementation } from './fnTypes.ts';\n\nexport interface FnCore {\n applyExternals: (newExternals: ExternalMap) => void;\n resolve(\n ctx: ResolutionCtx,\n /**\n * The argument types can be AutoStruct if they're determined based on usage\n * (like in auto-entry functions).\n */\n argTypes: BaseData[],\n /**\n * The return type of the function. If undefined, the type should be inferred\n * from the implementation (relevant for shellless functions).\n */\n returnType: BaseData | undefined,\n ): ResolvedSnippet;\n}\n\nexport function createFnCore(\n implementation: Implementation,\n fnAttribute = '',\n): FnCore {\n /**\n * External application has to be deferred until resolution because\n * some externals can reference the owner function which has not been\n * initialized yet (like when accessing the Output struct of a vertex\n * entry fn).\n */\n const externalsToApply: ExternalMap[] = [];\n\n const core = {\n // Making the implementation the holder of the name, as long as it's\n // a function (and not a string implementation)\n [$getNameForward]: typeof implementation === 'function'\n ? implementation\n : undefined,\n applyExternals(newExternals: ExternalMap): void {\n externalsToApply.push(newExternals);\n },\n\n resolve(\n ctx: ResolutionCtx,\n argTypes: BaseData[],\n returnType: BaseData | undefined,\n ): ResolvedSnippet {\n const externalMap: ExternalMap = {};\n\n for (const externals of externalsToApply) {\n applyExternals(externalMap, externals);\n }\n\n const id = ctx.getUniqueName(this);\n\n if (typeof implementation === 'string') {\n if (!returnType) {\n throw new Error(\n 'Explicit return type is required for string implementation',\n );\n }\n\n const replacedImpl = replaceExternalsInWgsl(\n ctx,\n externalMap,\n implementation,\n );\n\n let header = '';\n let body = '';\n\n if (fnAttribute !== '') {\n const input = isWgslStruct(argTypes[0])\n ? `(in: ${ctx.resolve(argTypes[0]).value})`\n : '()';\n\n const attributes = isWgslData(returnType)\n ? getAttributesString(returnType)\n : '';\n const output = returnType !== Void\n ? isWgslStruct(returnType)\n ? `-> ${ctx.resolve(returnType).value}`\n : `-> ${attributes !== '' ? attributes : '@location(0)'} ${\n ctx.resolve(returnType).value\n }`\n : '';\n\n header = `${input} ${output} `;\n body = replacedImpl;\n } else {\n const providedArgs = extractArgs(replacedImpl);\n\n if (providedArgs.args.length !== argTypes.length) {\n throw new Error(\n `WGSL implementation has ${providedArgs.args.length} arguments, while the shell has ${argTypes.length} arguments.`,\n );\n }\n\n const input = providedArgs.args.map((argInfo, i) =>\n `${argInfo.identifier}: ${\n checkAndReturnType(\n ctx,\n `parameter ${argInfo.identifier}`,\n argInfo.type,\n argTypes[i],\n )\n }`\n ).join(', ');\n\n const output = returnType === Void ? '' : `-> ${\n checkAndReturnType(\n ctx,\n 'return type',\n providedArgs.ret?.type,\n returnType,\n )\n }`;\n\n header = `(${input}) ${output}`;\n\n body = replacedImpl.slice(providedArgs.range.end);\n }\n\n ctx.addDeclaration(`${fnAttribute}fn ${id}${header}${body}`);\n return snip(id, returnType, /* origin */ 'runtime');\n }\n\n // get data generated by the plugin\n const pluginData = getMetaData(implementation);\n\n // Passing a record happens prior to version 0.9.0\n // TODO: Support for this can be removed down the line\n const pluginExternals = typeof pluginData?.externals === 'function'\n ? pluginData.externals()\n : pluginData?.externals;\n\n if (pluginExternals) {\n const missing = Object.fromEntries(\n Object.entries(pluginExternals).filter(\n ([name]) => !(name in externalMap),\n ),\n );\n\n applyExternals(externalMap, missing);\n }\n\n const ast = pluginData?.ast;\n if (!ast) {\n throw new Error(\n \"Missing metadata for tgpu.fn function body (either missing 'use gpu' directive, or misconfigured `unplugin-typegpu`)\",\n );\n }\n\n // verify all required externals are present\n const missingExternals = ast.externalNames.filter(\n (name) => !(name in externalMap),\n );\n if (missingExternals.length > 0) {\n throw new MissingLinksError(getName(this), missingExternals);\n }\n\n // If an entrypoint implementation has a second argument, it represents the output schema.\n // We look at the identifier chosen by the user and add it to externals.\n const maybeSecondArg = ast.params[1];\n if (\n maybeSecondArg && maybeSecondArg.type === 'i' && fnAttribute !== ''\n ) {\n applyExternals(\n externalMap,\n {\n // oxlint-disable-next-line typescript/no-non-null-assertion entry functions cannot be shellless\n [maybeSecondArg.name]: undecorate(returnType!),\n },\n );\n }\n\n // generate wgsl string\n\n const { head, body, returnType: actualReturnType } = ctx.fnToWgsl({\n functionType: fnAttribute.includes('@compute')\n ? 'compute'\n : fnAttribute.includes('@vertex')\n ? 'vertex'\n : fnAttribute.includes('@fragment')\n ? 'fragment'\n : 'normal',\n argTypes,\n params: ast.params,\n returnType,\n body: ast.body,\n externalMap,\n });\n\n ctx.addDeclaration(\n `${fnAttribute}fn ${id}${ctx.resolve(head).value}${\n ctx.resolve(body).value\n }`,\n );\n\n return snip(id, actualReturnType, /* origin */ 'runtime');\n },\n };\n\n return core;\n}\n\nfunction checkAndReturnType(\n ctx: ResolutionCtx,\n name: string,\n wgslType: string | undefined,\n jsType: unknown,\n) {\n const resolvedJsType = ctx.resolve(jsType).value.replace(/\\s/g, '');\n\n if (!wgslType) {\n return resolvedJsType;\n }\n\n const resolvedWgslType = wgslType.replace(/\\s/g, '');\n\n if (resolvedWgslType !== resolvedJsType) {\n throw new Error(\n `Type mismatch between TGPU shell and WGSL code string: ${name}, JS type \"${resolvedJsType}\", WGSL type \"${resolvedWgslType}\".`,\n );\n }\n\n return wgslType;\n}\n","import type { Implementation } from './fnTypes.ts';\n\nexport function stripTemplate(\n arg: Implementation | TemplateStringsArray,\n ...values: unknown[]\n): Implementation {\n return isTemplateStringsArray(arg)\n ? templateLiteralIdentity(arg, ...values)\n : arg;\n}\n\nfunction isTemplateStringsArray(value: unknown): value is TemplateStringsArray {\n return (\n Array.isArray(value) &&\n 'raw' in value &&\n Array.isArray(value.raw) &&\n value.raw.every((item) => typeof item === 'string')\n );\n}\n\nfunction templateLiteralIdentity(\n strings: TemplateStringsArray,\n ...values: unknown[]\n): string {\n return strings\n .slice(1)\n .reduce(\n (acc, elem, index) => `${acc}${values[index]}${elem}`,\n strings[0] as string,\n );\n}\n","import { getResolutionCtx } from '../../execMode.ts';\nimport { getName, setName } from '../../shared/meta.ts';\nimport type { GPUValueOf } from '../../shared/repr.ts';\nimport { $gpuValueOf, $internal } from '../../shared/symbols.ts';\nimport { getGpuValueRecursively } from '../valueProxyUtils.ts';\nimport type { TgpuSlot } from './slotTypes.ts';\n\n// ----------\n// Public API\n// ----------\n\nexport function slot<T>(defaultValue?: T): TgpuSlot<T> {\n return new TgpuSlotImpl(defaultValue);\n}\n\n// --------------\n// Implementation\n// --------------\n\nclass TgpuSlotImpl<T> implements TgpuSlot<T> {\n public readonly [$internal] = true;\n public readonly resourceType = 'slot';\n\n constructor(public defaultValue: T | undefined = undefined) {}\n\n $name(label: string) {\n setName(this, label);\n return this;\n }\n\n areEqual(a: T, b: T): boolean {\n return Object.is(a, b);\n }\n\n toString(): string {\n return `slot:${getName(this) ?? '<unnamed>'}`;\n }\n\n get [$gpuValueOf](): GPUValueOf<T> {\n const ctx = getResolutionCtx();\n if (!ctx) {\n throw new Error(`Cannot access tgpu.slot's value outside of resolution.`);\n }\n\n return getGpuValueRecursively(ctx.unwrap(this));\n }\n\n get value(): GPUValueOf<T> {\n return this[$gpuValueOf];\n }\n\n get $(): GPUValueOf<T> {\n return this.value;\n }\n}\n","import type { ShaderStage } from '../../types.ts';\nimport { slot } from './slot.ts';\n\nexport const shaderStageSlot = slot<ShaderStage>(undefined);\n","import type {\n AnyVertexInputBuiltin,\n AnyVertexOutputBuiltin,\n OmitBuiltins,\n} from '../../builtin.ts';\nimport type { UndecorateRecord } from '../../data/dataTypes.ts';\nimport type { ResolvedSnippet } from '../../data/snippet.ts';\nimport type {\n BaseData,\n Decorated,\n Interpolate,\n Location,\n} from '../../data/wgslTypes.ts';\nimport {\n getName,\n isNamable,\n setName,\n type TgpuNamable,\n} from '../../shared/meta.ts';\nimport { $getNameForward, $internal, $resolve } from '../../shared/symbols.ts';\nimport type { Prettify } from '../../shared/utilityTypes.ts';\nimport type { ResolutionCtx, SelfResolvable } from '../../types.ts';\nimport { shaderStageSlot } from '../slot/internalSlots.ts';\nimport { createFnCore, type FnCore } from './fnCore.ts';\nimport type {\n BaseIOData,\n Implementation,\n InferIO,\n IORecord,\n} from './fnTypes.ts';\nimport { createIoSchema, type IOLayoutToSchema } from './ioSchema.ts';\nimport { stripTemplate } from './templateUtils.ts';\n\n// ----------\n// Public API\n// ----------\n\ntype VertexInConstrained = IORecord<\n BaseIOData | Decorated<BaseIOData, Location[]> | AnyVertexInputBuiltin\n>;\n\ntype VertexOutConstrained = IORecord<\n | BaseIOData\n | Decorated<BaseIOData, (Location | Interpolate)[]>\n | AnyVertexOutputBuiltin\n>;\n\n/**\n * Describes a vertex entry function signature (its arguments, return type and attributes)\n */\ntype TgpuVertexFnShellHeader<\n VertexIn extends TgpuVertexFn.In,\n VertexOut extends TgpuVertexFn.Out,\n> = {\n readonly in: VertexIn | undefined;\n readonly out: VertexOut;\n readonly argTypes: [IOLayoutToSchema<VertexIn>] | [];\n readonly entryPoint: 'vertex';\n};\n\ntype CleanIO<T> = T extends Record<string, BaseData>\n ? Prettify<UndecorateRecord<OmitBuiltins<T>>>\n : Prettify<UndecorateRecord<OmitBuiltins<{ a: T }>>> extends\n { a: infer Result } ? Result\n : never;\n\n/**\n * Describes a vertex entry function signature (its arguments, return type and attributes).\n * Allows creating tgpu vertex functions by calling this shell\n * and passing the implementation (as WGSL string or JS function) as the argument.\n */\nexport interface TgpuVertexFnShell<\n // We force the variance to be covariant, since shells are just containers of\n // schemas that coincidentally can be called to create a vertex function.\n // @ts-expect-error: We override the variance\n out TIn extends TgpuVertexFn.In,\n // @ts-expect-error: We override the variance\n out TOut extends TgpuVertexFn.Out,\n> extends TgpuVertexFnShellHeader<TIn, TOut> {\n (\n implementation: (\n input: InferIO<TIn>,\n out: IOLayoutToSchema<TOut>,\n ) => InferIO<TOut>,\n ): TgpuVertexFn<CleanIO<TIn>, CleanIO<TOut>>;\n (\n implementation: string,\n ): TgpuVertexFn<CleanIO<TIn>, CleanIO<TOut>>;\n (\n strings: TemplateStringsArray,\n ...values: unknown[]\n ): TgpuVertexFn<CleanIO<TIn>, CleanIO<TOut>>;\n}\n\nexport interface TgpuVertexFn<\n // @ts-expect-error: We override the variance\n in VertexIn extends TgpuVertexFn.In = Record<string, never>,\n out VertexOut extends TgpuVertexFn.Out = TgpuVertexFn.Out,\n> extends TgpuNamable {\n readonly [$internal]: true;\n readonly shell: TgpuVertexFnShellHeader<VertexIn, VertexOut>;\n $uses(dependencyMap: Record<string, unknown>): this;\n}\n\nexport declare namespace TgpuVertexFn {\n type In = BaseData | Record<string, BaseData>;\n type Out = Record<string, BaseData>;\n}\n\nexport function vertexFn<VertexOut extends VertexOutConstrained>(options: {\n out: VertexOut;\n}): TgpuVertexFnShell<{}, VertexOut>;\n\nexport function vertexFn<\n VertexIn extends VertexInConstrained,\n // Not allowing single-value output, as it is better practice\n // to properly label what the vertex shader is outputting.\n VertexOut extends VertexOutConstrained,\n>(options: {\n in: VertexIn;\n out: VertexOut;\n}): TgpuVertexFnShell<VertexIn, VertexOut>;\n\n/**\n * Creates a shell of a typed entry function for the vertex shader stage. Any function\n * that implements this shell can run for each vertex, allowing the inner code to process\n * attributes and determine the final position of the vertex.\n *\n * @param options.in\n * Vertex attributes and builtins to be made available to functions that implement this shell.\n * @param options.out\n * A record containing the final position of the vertex, and any information\n * passed onto the fragment shader stage.\n */\nexport function vertexFn<\n VertexIn extends VertexInConstrained,\n // Not allowing single-value output, as it is better practice\n // to properly label what the vertex shader is outputting.\n VertexOut extends VertexOutConstrained,\n>(options: {\n in?: VertexIn;\n out: VertexOut;\n}): TgpuVertexFnShell<VertexIn, VertexOut> {\n if (Object.keys(options.out).length === 0) {\n throw new Error(\n `A vertexFn output cannot be empty since it must include the 'position' builtin.`,\n );\n }\n const shell: TgpuVertexFnShellHeader<VertexIn, VertexOut> = {\n in: options.in,\n out: options.out,\n argTypes: options.in && Object.keys(options.in).length !== 0\n ? [createIoSchema(options.in)]\n : [],\n entryPoint: 'vertex',\n };\n\n const call = (\n arg: Implementation | TemplateStringsArray,\n ...values: unknown[]\n ) => createVertexFn(shell, stripTemplate(arg, ...values));\n\n return Object.assign(call, shell) as unknown as TgpuVertexFnShell<\n VertexIn,\n VertexOut\n >;\n}\n\nexport function isTgpuVertexFn<\n VertexIn extends VertexInConstrained,\n VertexOut extends VertexOutConstrained,\n>(\n value: unknown,\n): value is TgpuVertexFn<VertexIn, VertexOut> {\n return (value as TgpuVertexFn<VertexIn, VertexOut>)?.shell?.entryPoint ===\n 'vertex';\n}\n\n// --------------\n// Implementation\n// --------------\n\nfunction createVertexFn(\n shell: TgpuVertexFnShellHeader<VertexInConstrained, VertexOutConstrained>,\n implementation: Implementation,\n): TgpuVertexFn<VertexInConstrained, VertexOutConstrained> {\n type This =\n & TgpuVertexFn<VertexInConstrained, VertexOutConstrained>\n & SelfResolvable\n & {\n [$internal]: true;\n [$getNameForward]: FnCore;\n };\n\n const core = createFnCore(implementation, '@vertex ');\n const inputType = shell.argTypes[0];\n\n const result: This = {\n shell,\n\n $uses(newExternals) {\n core.applyExternals(newExternals);\n return this;\n },\n\n [$internal]: true,\n [$getNameForward]: core,\n $name(newLabel: string): This {\n setName(this, newLabel);\n if (isNamable(inputType)) {\n inputType.$name(`${newLabel}_Input`);\n }\n return this;\n },\n\n [$resolve](ctx: ResolutionCtx): ResolvedSnippet {\n const outputWithLocation = createIoSchema(\n shell.out,\n ctx.varyingLocations,\n ).$name(`${getName(this) ?? ''}_Output`);\n\n if (typeof implementation === 'string') {\n if (inputType) {\n core.applyExternals({ In: inputType });\n }\n core.applyExternals({ Out: outputWithLocation });\n }\n\n return ctx.withSlots([[shaderStageSlot, 'vertex']], () =>\n core.resolve(\n ctx,\n shell.argTypes,\n outputWithLocation,\n ));\n },\n\n toString() {\n return `vertexFn:${getName(core) ?? '<unnamed>'}`;\n },\n };\n return result;\n}\n","import { builtin } from '../builtin.ts';\nimport { vertexFn } from '../core/function/tgpuVertexFn.ts';\nimport { vec2f } from '../data/vector.ts';\n\n/**\n * A vertex function that defines a single full-screen triangle out\n * of three points.\n *\n * @example\n * ```ts\n * import { common } from 'typegpu';\n *\n * const pipeline = root.createRenderPipeline({\n * vertex: common.fullScreenTriangle,\n * fragment: yourFragmentShader,\n * });\n *\n * pipeline.draw(3);\n * ```\n */\nexport const fullScreenTriangle = vertexFn({\n in: { vertexIndex: builtin.vertexIndex },\n out: { pos: builtin.position, uv: vec2f },\n})`{\n const pos = array<vec2f, 3>(vec2f(-1, -1), vec2f(3, -1), vec2f(-1, 3));\n const uv = array<vec2f, 3>(vec2f(0, 1), vec2f(2, 1), vec2f(0, -1));\n\n return Out(vec4f(pos[in.vertexIndex], 0, 1), uv[in.vertexIndex]);\n}`;\n"],"mappings":"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"}

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

import { cr as $internal, dr as $repr, it as f32 } from "./operators-d-PMVTo7.js";
//#region src/data/texture.ts
function textureDescriptorToSchema(desc) {
if ("multisampled" in desc) {
if (desc.multisampled) {
if (desc.dimension === "2d") return textureMultisampled2d(desc.sampleType);
throw new Error(`Multisampled textures only support '2d' dimension, got '${desc.dimension}'`);
}
switch (desc.dimension) {
case "1d": return texture1d(desc.sampleType);
case "2d": return texture2d(desc.sampleType);
case "2d-array": return texture2dArray(desc.sampleType);
case "3d": return texture3d(desc.sampleType);
case "cube": return textureCube(desc.sampleType);
case "cube-array": return textureCubeArray(desc.sampleType);
default: throw new Error(`Unsupported texture dimension: '${desc.dimension}'`);
}
}
if (!("access" in desc)) throw new Error("Descriptor is neither a sampled nor a storage texture");
switch (desc.dimension) {
case "1d": return textureStorage1d(desc.format, desc.access);
case "2d": return textureStorage2d(desc.format, desc.access);
case "2d-array": return textureStorage2dArray(desc.format, desc.access);
case "3d": return textureStorage3d(desc.format, desc.access);
default: throw new Error(`Unsupported storage texture dimension: '${desc.dimension}'`);
}
}
function createTexture(type, props) {
const sampleTypes = type.startsWith("texture_depth") ? [
"depth",
"float",
"unfilterable-float"
] : props.sampleType.type === "i32" ? ["sint"] : props.sampleType.type === "u32" ? ["uint"] : ["float", "unfilterable-float"];
return {
[$internal]: {},
[$repr]: void 0,
type,
bindingSampleType: sampleTypes,
...props
};
}
function createStorageTexture(type, props) {
return {
[$internal]: {},
[$repr]: void 0,
type,
...props
};
}
const textureCache = /* @__PURE__ */ new Map();
const accessModeMap = {
"write-only": "write",
"read-only": "read",
"read-write": "read_write"
};
function getOrCreate(key, factory) {
let cached = textureCache.get(key);
if (!cached) {
cached = factory();
textureCache.set(key, cached);
}
return cached;
}
function texture1d(sampleType) {
const actualSampleType = sampleType || f32;
return getOrCreate(`texture_1d<${actualSampleType.type}>`, () => createTexture("texture_1d", {
dimension: "1d",
sampleType: actualSampleType,
multisampled: false
}));
}
function texture2d(sampleType) {
const actualSampleType = sampleType || f32;
return getOrCreate(`texture_2d<${actualSampleType.type}>`, () => createTexture("texture_2d", {
dimension: "2d",
sampleType: actualSampleType,
multisampled: false
}));
}
function textureMultisampled2d(sampleType) {
const actualSampleType = sampleType || f32;
return getOrCreate(`texture_multisampled_2d<${actualSampleType.type}>`, () => createTexture("texture_multisampled_2d", {
dimension: "2d",
sampleType: actualSampleType,
multisampled: true
}));
}
function texture2dArray(sampleType) {
const actualSampleType = sampleType || f32;
return getOrCreate(`texture_2d_array<${actualSampleType.type}>`, () => createTexture("texture_2d_array", {
dimension: "2d-array",
sampleType: actualSampleType,
multisampled: false
}));
}
function textureCube(sampleType) {
const actualSampleType = sampleType || f32;
return getOrCreate(`texture_cube<${actualSampleType.type}>`, () => createTexture("texture_cube", {
dimension: "cube",
sampleType: actualSampleType,
multisampled: false
}));
}
function textureCubeArray(sampleType) {
const actualSampleType = sampleType || f32;
return getOrCreate(`texture_cube_array<${actualSampleType.type}>`, () => createTexture("texture_cube_array", {
dimension: "cube-array",
sampleType: actualSampleType,
multisampled: false
}));
}
function texture3d(sampleType) {
const actualSampleType = sampleType || f32;
return getOrCreate(`texture_3d<${actualSampleType.type}>`, () => createTexture("texture_3d", {
dimension: "3d",
sampleType: actualSampleType,
multisampled: false
}));
}
function textureStorage1d(format, access) {
const actualAccess = access || "write-only";
return getOrCreate(`texture_storage_1d<${format}, ${accessModeMap[actualAccess]}>`, () => createStorageTexture("texture_storage_1d", {
dimension: "1d",
format,
access: actualAccess
}));
}
function textureStorage2d(format, access) {
const actualAccess = access || "write-only";
return getOrCreate(`texture_storage_2d<${format}, ${accessModeMap[actualAccess]}>`, () => createStorageTexture("texture_storage_2d", {
dimension: "2d",
format,
access: actualAccess
}));
}
function textureStorage2dArray(format, access) {
const actualAccess = access || "write-only";
return getOrCreate(`texture_storage_2d_array<${format}, ${accessModeMap[actualAccess]}>`, () => createStorageTexture("texture_storage_2d_array", {
dimension: "2d-array",
format,
access: actualAccess
}));
}
function textureStorage3d(format, access) {
const actualAccess = access || "write-only";
return getOrCreate(`texture_storage_3d<${format}, ${accessModeMap[actualAccess]}>`, () => createStorageTexture("texture_storage_3d", {
dimension: "3d",
format,
access: actualAccess
}));
}
function textureDepth2d() {
return getOrCreate("texture_depth_2d", () => createTexture("texture_depth_2d", {
dimension: "2d",
sampleType: f32,
multisampled: false
}));
}
function textureDepthMultisampled2d() {
return getOrCreate("texture_depth_multisampled_2d", () => createTexture("texture_depth_multisampled_2d", {
dimension: "2d",
sampleType: f32,
multisampled: true
}));
}
function textureDepth2dArray() {
return getOrCreate("texture_depth_2d_array", () => createTexture("texture_depth_2d_array", {
dimension: "2d-array",
sampleType: f32,
multisampled: false
}));
}
function textureDepthCube() {
return getOrCreate("texture_depth_cube", () => createTexture("texture_depth_cube", {
dimension: "cube",
sampleType: f32,
multisampled: false
}));
}
function textureDepthCubeArray() {
return getOrCreate("texture_depth_cube_array", () => createTexture("texture_depth_cube_array", {
dimension: "cube-array",
sampleType: f32,
multisampled: false
}));
}
function textureExternal() {
return getOrCreate("texture_external", () => ({
[$internal]: {},
[$repr]: void 0,
type: "texture_external",
dimension: "2d"
}));
}
function isWgslTexture(value) {
return !!value[$internal] && typeof value.multisampled === "boolean";
}
function isWgslStorageTexture(value) {
return !!value[$internal] && typeof value.format === "string" && typeof value.access === "string";
}
//#endregion
export { textureMultisampled2d as _, texture2d as a, textureStorage2dArray as b, textureCube as c, textureDepth2dArray as d, textureDepthCube as f, textureExternal as g, textureDescriptorToSchema as h, texture1d as i, textureCubeArray as l, textureDepthMultisampled2d as m, isWgslStorageTexture as n, texture2dArray as o, textureDepthCubeArray as p, isWgslTexture as r, texture3d as s, accessModeMap as t, textureDepth2d as u, textureStorage1d as v, textureStorage3d as x, textureStorage2d as y };
//# sourceMappingURL=texture-BagDrrks.js.map
{"version":3,"file":"texture-BagDrrks.js","names":[],"sources":["../src/data/texture.ts"],"sourcesContent":["import type { StorageTextureFormats } from '../core/texture/textureFormats.ts';\nimport { $internal, $repr } from '../shared/symbols.ts';\nimport type { Default, WithDefaults } from '../shared/utilityTypes.ts';\nimport { f32 } from './numeric.ts';\nimport type { F32 } from './wgslTypes.ts';\nimport type { BaseData, TextureSampleTypes } from './wgslTypes.ts';\n\nexport type StorageTextureDimension = '1d' | '2d' | '2d-array' | '3d';\n\nexport type WgslTextureProps = {\n dimension: GPUTextureViewDimension;\n sampleType: TextureSampleTypes;\n multisampled: boolean;\n};\n\nexport type WgslStorageTextureProps = {\n dimension: StorageTextureDimension;\n format: StorageTextureFormats;\n access: GPUStorageTextureAccess;\n};\n\ntype ResolvedTextureProps<\n TProps extends Partial<WgslTextureProps>,\n> = WithDefaults<TProps, WgslTextureProps>;\n\ntype ResolvedStorageTextureProps<\n TProps extends Partial<WgslStorageTextureProps>,\n> = WithDefaults<TProps, WgslStorageTextureProps>;\n\ntype SampledTextureLiteral = `texture_${\n | '1d'\n | '2d'\n | '2d_array'\n | '3d'\n | 'cube'\n | 'cube_array'\n | 'multisampled_2d'\n | 'depth_multisampled_2d'\n | 'depth_2d'\n | 'depth_2d_array'\n | 'depth_cube'\n | 'depth_cube_array'}`;\ntype StorageTextureLiteral = `texture_storage_${\n | '1d'\n | '2d'\n | '2d_array'\n | '3d'}`;\n\nexport interface WgslTexture<\n TProps extends Partial<WgslTextureProps> = WgslTextureProps,\n> extends BaseData {\n readonly [$repr]: unknown;\n readonly type: SampledTextureLiteral;\n\n readonly sampleType: ResolvedTextureProps<TProps>['sampleType'];\n readonly dimension: ResolvedTextureProps<TProps>['dimension'];\n readonly multisampled: ResolvedTextureProps<TProps>['multisampled'];\n readonly bindingSampleType: [GPUTextureSampleType, ...GPUTextureSampleType[]];\n}\n\nexport interface WgslStorageTexture<\n TProps extends Partial<WgslStorageTextureProps> = WgslStorageTextureProps,\n> extends BaseData {\n readonly [$repr]: unknown;\n readonly type: StorageTextureLiteral;\n\n readonly format: ResolvedStorageTextureProps<TProps>['format'];\n readonly dimension: ResolvedStorageTextureProps<TProps>['dimension'];\n readonly access: ResolvedStorageTextureProps<TProps>['access'];\n}\n\nexport interface WgslExternalTexture extends BaseData {\n readonly [$repr]: textureExternal;\n readonly type: 'texture_external';\n\n readonly dimension: '2d';\n}\n\nexport interface WgslTexture1d<\n TSample extends TextureSampleTypes = TextureSampleTypes,\n> extends\n WgslTexture<{\n dimension: '1d';\n sampleType: TSample;\n multisampled: false;\n }> {\n readonly type: 'texture_1d';\n readonly [$repr]: texture1d<TSample>;\n}\n\nexport interface WgslTexture2d<\n TSample extends TextureSampleTypes = TextureSampleTypes,\n> extends\n WgslTexture<{\n dimension: '2d';\n sampleType: TSample;\n multisampled: false;\n }> {\n readonly type: 'texture_2d';\n readonly [$repr]: texture2d<TSample>;\n}\n\nexport interface WgslTextureMultisampled2d<\n TSample extends TextureSampleTypes = TextureSampleTypes,\n> extends\n WgslTexture<{\n dimension: '2d';\n sampleType: TSample;\n multisampled: true;\n }> {\n readonly type: 'texture_multisampled_2d';\n readonly [$repr]: textureMultisampled2d<TSample>;\n}\n\nexport interface WgslTexture2dArray<\n TSample extends TextureSampleTypes = TextureSampleTypes,\n> extends\n WgslTexture<{\n dimension: '2d-array';\n sampleType: TSample;\n multisampled: false;\n }> {\n readonly type: 'texture_2d_array';\n readonly [$repr]: texture2dArray<TSample>;\n}\n\nexport interface WgslTextureCube<\n TSample extends TextureSampleTypes = TextureSampleTypes,\n> extends\n WgslTexture<{\n dimension: 'cube';\n sampleType: TSample;\n multisampled: false;\n }> {\n readonly type: 'texture_cube';\n readonly [$repr]: textureCube<TSample>;\n}\n\nexport interface WgslTextureCubeArray<\n TSample extends TextureSampleTypes = TextureSampleTypes,\n> extends\n WgslTexture<{\n dimension: 'cube-array';\n sampleType: TSample;\n multisampled: false;\n }> {\n readonly type: 'texture_cube_array';\n readonly [$repr]: textureCubeArray<TSample>;\n}\n\nexport interface WgslTexture3d<\n TSample extends TextureSampleTypes = TextureSampleTypes,\n> extends\n WgslTexture<{\n dimension: '3d';\n sampleType: TSample;\n multisampled: false;\n }> {\n readonly type: 'texture_3d';\n readonly [$repr]: texture3d<TSample>;\n}\n\n// Depth textures (sample type is always f32)\nexport interface WgslTextureDepth2d extends\n WgslTexture<{\n dimension: '2d';\n sampleType: F32;\n multisampled: false;\n }> {\n readonly type: 'texture_depth_2d';\n readonly [$repr]: textureDepth2d;\n}\n\nexport interface WgslTextureDepthMultisampled2d extends\n WgslTexture<{\n dimension: '2d';\n sampleType: F32;\n multisampled: true;\n }> {\n readonly type: 'texture_depth_multisampled_2d';\n readonly [$repr]: textureDepthMultisampled2d;\n}\n\nexport interface WgslTextureDepth2dArray extends\n WgslTexture<{\n dimension: '2d-array';\n sampleType: F32;\n multisampled: false;\n }> {\n readonly type: 'texture_depth_2d_array';\n readonly [$repr]: textureDepth2dArray;\n}\n\nexport interface WgslTextureDepthCube extends\n WgslTexture<{\n dimension: 'cube';\n sampleType: F32;\n multisampled: false;\n }> {\n readonly type: 'texture_depth_cube';\n readonly [$repr]: textureDepthCube;\n}\n\nexport interface WgslTextureDepthCubeArray extends\n WgslTexture<{\n dimension: 'cube-array';\n sampleType: F32;\n multisampled: false;\n }> {\n readonly type: 'texture_depth_cube_array';\n readonly [$repr]: textureDepthCubeArray;\n}\n\n// Storage textures\nexport interface WgslStorageTexture1d<\n TFormat extends StorageTextureFormats = StorageTextureFormats,\n TAccess extends GPUStorageTextureAccess = GPUStorageTextureAccess,\n> extends\n WgslStorageTexture<{\n dimension: '1d';\n format: TFormat;\n access: TAccess;\n }> {\n readonly type: 'texture_storage_1d';\n readonly [$repr]: textureStorage1d<TFormat, TAccess>;\n}\n\nexport interface WgslStorageTexture2d<\n TFormat extends StorageTextureFormats = StorageTextureFormats,\n TAccess extends GPUStorageTextureAccess = GPUStorageTextureAccess,\n> extends\n WgslStorageTexture<{\n dimension: '2d';\n format: TFormat;\n access: TAccess;\n }> {\n readonly type: 'texture_storage_2d';\n readonly [$repr]: textureStorage2d<TFormat, TAccess>;\n}\n\nexport interface WgslStorageTexture2dArray<\n TFormat extends StorageTextureFormats = StorageTextureFormats,\n TAccess extends GPUStorageTextureAccess = GPUStorageTextureAccess,\n> extends\n WgslStorageTexture<{\n dimension: '2d-array';\n format: TFormat;\n access: TAccess;\n }> {\n readonly type: 'texture_storage_2d_array';\n readonly [$repr]: textureStorage2dArray<TFormat, TAccess>;\n}\n\nexport interface WgslStorageTexture3d<\n TFormat extends StorageTextureFormats = StorageTextureFormats,\n TAccess extends GPUStorageTextureAccess = GPUStorageTextureAccess,\n> extends\n WgslStorageTexture<{\n dimension: '3d';\n format: TFormat;\n access: TAccess;\n }> {\n readonly type: 'texture_storage_3d';\n readonly [$repr]: textureStorage3d<TFormat, TAccess>;\n}\n\ntype SampledTextureSchemaMap<T extends WgslTextureProps> = {\n multisampled: {\n '1d': never;\n '2d': WgslTextureMultisampled2d<T['sampleType']>;\n '2d-array': never;\n '3d': never;\n cube: never;\n 'cube-array': never;\n };\n sampled: {\n '1d': WgslTexture1d<T['sampleType']>;\n '2d': WgslTexture2d<T['sampleType']>;\n '2d-array': WgslTexture2dArray<T['sampleType']>;\n '3d': WgslTexture3d<T['sampleType']>;\n cube: WgslTextureCube<T['sampleType']>;\n 'cube-array': WgslTextureCubeArray<T['sampleType']>;\n };\n};\n\ntype StorageTextureSchemaMap<T extends WgslStorageTextureProps> = {\n '1d': WgslStorageTexture1d<T['format'], T['access']>;\n '2d': WgslStorageTexture2d<T['format'], T['access']>;\n '2d-array': WgslStorageTexture2dArray<T['format'], T['access']>;\n '3d': WgslStorageTexture3d<T['format'], T['access']>;\n};\n\nexport type TextureSchemaForDescriptor<\n T extends WgslTextureProps | WgslStorageTextureProps,\n> = T extends WgslTextureProps\n ? T['multisampled'] extends true\n ? SampledTextureSchemaMap<T>['multisampled'][T['dimension']]\n : SampledTextureSchemaMap<T>['sampled'][T['dimension']]\n : T extends WgslStorageTextureProps\n ? StorageTextureSchemaMap<T>[T['dimension']]\n : never;\n\nexport function textureDescriptorToSchema<\n T extends WgslTextureProps | WgslStorageTextureProps,\n>(desc: T): TextureSchemaForDescriptor<T> {\n if ('multisampled' in desc) {\n if (desc.multisampled) {\n if (desc.dimension === '2d') {\n return textureMultisampled2d(\n desc.sampleType,\n ) as TextureSchemaForDescriptor<T>;\n }\n throw new Error(\n `Multisampled textures only support '2d' dimension, got '${desc.dimension}'`,\n );\n }\n\n switch (desc.dimension) {\n case '1d':\n return texture1d(desc.sampleType) as TextureSchemaForDescriptor<T>;\n case '2d':\n return texture2d(desc.sampleType) as TextureSchemaForDescriptor<T>;\n case '2d-array':\n return texture2dArray(\n desc.sampleType,\n ) as TextureSchemaForDescriptor<T>;\n case '3d':\n return texture3d(desc.sampleType) as TextureSchemaForDescriptor<T>;\n case 'cube':\n return textureCube(\n desc.sampleType,\n ) as TextureSchemaForDescriptor<T>;\n case 'cube-array':\n return textureCubeArray(\n desc.sampleType,\n ) as TextureSchemaForDescriptor<T>;\n default:\n throw new Error(\n // @ts-expect-error\n `Unsupported texture dimension: '${desc.dimension}'`,\n );\n }\n }\n if (!('access' in desc)) {\n throw new Error('Descriptor is neither a sampled nor a storage texture');\n }\n\n switch (desc.dimension) {\n case '1d':\n return textureStorage1d(\n desc.format,\n desc.access,\n ) as TextureSchemaForDescriptor<T>;\n case '2d':\n return textureStorage2d(\n desc.format,\n desc.access,\n ) as TextureSchemaForDescriptor<T>;\n case '2d-array':\n return textureStorage2dArray(\n desc.format,\n desc.access,\n ) as TextureSchemaForDescriptor<T>;\n case '3d':\n return textureStorage3d(\n desc.format,\n desc.access,\n ) as TextureSchemaForDescriptor<T>;\n default:\n throw new Error(\n // @ts-expect-error\n `Unsupported storage texture dimension: '${desc.dimension}'`,\n );\n }\n}\n\nfunction createTexture<TProps extends WgslTextureProps>(\n type: SampledTextureLiteral,\n props: TProps,\n): WgslTexture<TProps> {\n const isDepth = type.startsWith('texture_depth');\n const sampleTypes: [GPUTextureSampleType, ...GPUTextureSampleType[]] = isDepth\n ? ['depth', 'float', 'unfilterable-float']\n : props.sampleType.type === 'i32'\n ? ['sint']\n : props.sampleType.type === 'u32'\n ? ['uint']\n : ['float', 'unfilterable-float'];\n\n return {\n [$internal]: {},\n [$repr]: undefined as unknown as WgslTexture<TProps>,\n type,\n bindingSampleType: sampleTypes,\n ...props,\n };\n}\n\nfunction createStorageTexture<TProps extends WgslStorageTextureProps>(\n type: StorageTextureLiteral,\n props: TProps,\n): WgslStorageTexture<TProps> {\n return {\n [$internal]: {},\n [$repr]: undefined as unknown as WgslStorageTexture<TProps>,\n type,\n ...props,\n };\n}\n\nconst textureCache = new Map<\n string,\n WgslTexture | WgslStorageTexture | WgslExternalTexture\n>();\n\nexport const accessModeMap: Record<GPUStorageTextureAccess, string> = {\n 'write-only': 'write',\n 'read-only': 'read',\n 'read-write': 'read_write',\n};\n\nfunction getOrCreate<\n T extends WgslTexture | WgslStorageTexture | WgslExternalTexture,\n>(key: string, factory: () => T): T {\n let cached = textureCache.get(key) as T | undefined;\n if (!cached) {\n cached = factory();\n textureCache.set(key, cached);\n }\n return cached;\n}\n\nexport interface texture1d<T extends TextureSampleTypes = TextureSampleTypes> {\n readonly kind: `texture_1d<${T['type']}>`;\n [$internal]: T;\n}\n\nexport function texture1d<T extends TextureSampleTypes>(\n sampleType: T,\n): WgslTexture1d<T>;\nexport function texture1d(): WgslTexture1d<F32>;\nexport function texture1d<T extends TextureSampleTypes>(sampleType?: T) {\n const actualSampleType = (sampleType || f32) as Default<T, F32>;\n const key = `texture_1d<${actualSampleType.type}>`;\n return getOrCreate(key, () =>\n createTexture('texture_1d', {\n dimension: '1d',\n sampleType: actualSampleType,\n multisampled: false,\n }));\n}\n\nexport interface texture2d<T extends TextureSampleTypes = TextureSampleTypes> {\n readonly kind: `texture_2d<${T['type']}>`;\n [$internal]: T;\n}\n\nexport function texture2d<T extends TextureSampleTypes>(\n sampleType: T,\n): WgslTexture2d<T>;\nexport function texture2d(): WgslTexture2d<F32>;\nexport function texture2d<T extends TextureSampleTypes>(sampleType?: T) {\n const actualSampleType = (sampleType || f32) as Default<T, F32>;\n const key = `texture_2d<${actualSampleType.type}>`;\n return getOrCreate(key, () =>\n createTexture('texture_2d', {\n dimension: '2d',\n sampleType: actualSampleType,\n multisampled: false,\n }));\n}\n\nexport interface textureMultisampled2d<\n T extends TextureSampleTypes = TextureSampleTypes,\n> {\n readonly kind: `texture_multisampled_2d<${T['type']}>`;\n [$internal]: T;\n}\n\nexport function textureMultisampled2d<T extends TextureSampleTypes>(\n sampleType: T,\n): WgslTextureMultisampled2d<T>;\nexport function textureMultisampled2d(): WgslTextureMultisampled2d<F32>;\nexport function textureMultisampled2d<T extends TextureSampleTypes>(\n sampleType?: T,\n) {\n const actualSampleType = (sampleType || f32) as Default<T, F32>;\n const key = `texture_multisampled_2d<${actualSampleType.type}>`;\n return getOrCreate(key, () =>\n createTexture('texture_multisampled_2d', {\n dimension: '2d',\n sampleType: actualSampleType,\n multisampled: true,\n }));\n}\n\nexport interface texture2dArray<\n T extends TextureSampleTypes = TextureSampleTypes,\n> {\n readonly kind: `texture_2d_array<${T['type']}>`;\n [$internal]: T;\n}\n\nexport function texture2dArray<T extends TextureSampleTypes>(\n sampleType: T,\n): WgslTexture2dArray<T>;\nexport function texture2dArray(): WgslTexture2dArray<F32>;\nexport function texture2dArray<T extends TextureSampleTypes>(sampleType?: T) {\n const actualSampleType = (sampleType || f32) as Default<T, F32>;\n const key = `texture_2d_array<${actualSampleType.type}>`;\n return getOrCreate(key, () =>\n createTexture('texture_2d_array', {\n dimension: '2d-array',\n sampleType: actualSampleType,\n multisampled: false,\n }));\n}\n\nexport interface textureCube<\n T extends TextureSampleTypes = TextureSampleTypes,\n> {\n readonly kind: `texture_cube<${T['type']}>`;\n [$internal]: T;\n}\n\nexport function textureCube<T extends TextureSampleTypes>(\n sampleType: T,\n): WgslTextureCube<T>;\nexport function textureCube(): WgslTextureCube<F32>;\nexport function textureCube<T extends TextureSampleTypes>(sampleType?: T) {\n const actualSampleType = (sampleType || f32) as Default<T, F32>;\n const key = `texture_cube<${actualSampleType.type}>`;\n return getOrCreate(key, () =>\n createTexture('texture_cube', {\n dimension: 'cube',\n sampleType: actualSampleType,\n multisampled: false,\n }));\n}\n\nexport interface textureCubeArray<\n T extends TextureSampleTypes = TextureSampleTypes,\n> {\n readonly kind: `texture_cube_array<${T['type']}>`;\n [$internal]: T;\n}\n\nexport function textureCubeArray<T extends TextureSampleTypes>(\n sampleType: T,\n): WgslTextureCubeArray<T>;\nexport function textureCubeArray(): WgslTextureCubeArray<F32>;\nexport function textureCubeArray<T extends TextureSampleTypes>(\n sampleType?: T,\n) {\n const actualSampleType = (sampleType || f32) as Default<T, F32>;\n const key = `texture_cube_array<${actualSampleType.type}>`;\n return getOrCreate(key, () =>\n createTexture('texture_cube_array', {\n dimension: 'cube-array',\n sampleType: actualSampleType,\n multisampled: false,\n }));\n}\n\nexport interface texture3d<T extends TextureSampleTypes = TextureSampleTypes> {\n readonly kind: `texture_3d<${T['type']}>`;\n [$internal]: T;\n}\n\nexport function texture3d<T extends TextureSampleTypes>(\n sampleType: T,\n): WgslTexture3d<T>;\nexport function texture3d(): WgslTexture3d<F32>;\nexport function texture3d<T extends TextureSampleTypes>(sampleType?: T) {\n const actualSampleType = (sampleType || f32) as Default<T, F32>;\n const key = `texture_3d<${actualSampleType.type}>`;\n return getOrCreate(key, () =>\n createTexture('texture_3d', {\n dimension: '3d',\n sampleType: actualSampleType,\n multisampled: false,\n }));\n}\n\nexport interface textureStorage1d<\n TFormat extends StorageTextureFormats = StorageTextureFormats,\n TAccess extends GPUStorageTextureAccess = GPUStorageTextureAccess,\n> {\n readonly kind: `texture_storage_1d<${TFormat}, ${TAccess}>`;\n [$internal]: [TFormat, TAccess];\n}\n\nexport function textureStorage1d<\n TFormat extends StorageTextureFormats,\n TAccess extends GPUStorageTextureAccess,\n>(format: TFormat, access: TAccess): WgslStorageTexture1d<TFormat, TAccess>;\nexport function textureStorage1d<TFormat extends StorageTextureFormats>(\n format: TFormat,\n): WgslStorageTexture1d<TFormat, 'write-only'>;\nexport function textureStorage1d<\n TFormat extends StorageTextureFormats,\n TAccess extends GPUStorageTextureAccess,\n>(format: TFormat, access?: TAccess) {\n const actualAccess = (access || 'write-only') as Default<\n TAccess,\n 'write-only'\n >;\n const key = `texture_storage_1d<${format}, ${accessModeMap[actualAccess]}>`;\n return getOrCreate(key, () =>\n createStorageTexture('texture_storage_1d', {\n dimension: '1d',\n format,\n access: actualAccess,\n }));\n}\n\nexport interface textureStorage2d<\n TFormat extends StorageTextureFormats = StorageTextureFormats,\n TAccess extends GPUStorageTextureAccess = GPUStorageTextureAccess,\n> {\n readonly kind: `texture_storage_2d<${TFormat}, ${TAccess}>`;\n [$internal]: [TFormat, TAccess];\n}\n\nexport function textureStorage2d<\n TFormat extends StorageTextureFormats,\n TAccess extends GPUStorageTextureAccess,\n>(format: TFormat, access: TAccess): WgslStorageTexture2d<TFormat, TAccess>;\nexport function textureStorage2d<TFormat extends StorageTextureFormats>(\n format: TFormat,\n): WgslStorageTexture2d<TFormat, 'write-only'>;\nexport function textureStorage2d<\n TFormat extends StorageTextureFormats,\n TAccess extends GPUStorageTextureAccess,\n>(format: TFormat, access?: TAccess) {\n const actualAccess = (access || 'write-only') as Default<\n TAccess,\n 'write-only'\n >;\n const key = `texture_storage_2d<${format}, ${accessModeMap[actualAccess]}>`;\n return getOrCreate(key, () =>\n createStorageTexture('texture_storage_2d', {\n dimension: '2d',\n format,\n access: actualAccess,\n }));\n}\n\nexport interface textureStorage2dArray<\n TFormat extends StorageTextureFormats = StorageTextureFormats,\n TAccess extends GPUStorageTextureAccess = GPUStorageTextureAccess,\n> {\n readonly kind: `texture_storage_2d_array<${TFormat}, ${TAccess}>`;\n [$internal]: [TFormat, TAccess];\n}\n\nexport function textureStorage2dArray<\n TFormat extends StorageTextureFormats,\n TAccess extends GPUStorageTextureAccess,\n>(\n format: TFormat,\n access: TAccess,\n): WgslStorageTexture2dArray<TFormat, TAccess>;\nexport function textureStorage2dArray<TFormat extends StorageTextureFormats>(\n format: TFormat,\n): WgslStorageTexture2dArray<TFormat, 'write-only'>;\nexport function textureStorage2dArray<\n TFormat extends StorageTextureFormats,\n TAccess extends GPUStorageTextureAccess,\n>(format: TFormat, access?: TAccess) {\n const actualAccess = (access || 'write-only') as Default<\n TAccess,\n 'write-only'\n >;\n const key = `texture_storage_2d_array<${format}, ${\n accessModeMap[actualAccess]\n }>`;\n return getOrCreate(\n key,\n () =>\n createStorageTexture('texture_storage_2d_array', {\n dimension: '2d-array',\n format,\n access: actualAccess,\n }),\n );\n}\n\nexport interface textureStorage3d<\n TFormat extends StorageTextureFormats = StorageTextureFormats,\n TAccess extends GPUStorageTextureAccess = GPUStorageTextureAccess,\n> {\n readonly kind: `texture_storage_3d<${TFormat}, ${TAccess}>`;\n [$internal]: [TFormat, TAccess];\n}\n\nexport function textureStorage3d<\n TFormat extends StorageTextureFormats,\n TAccess extends GPUStorageTextureAccess,\n>(format: TFormat, access: TAccess): WgslStorageTexture3d<TFormat, TAccess>;\nexport function textureStorage3d<TFormat extends StorageTextureFormats>(\n format: TFormat,\n): WgslStorageTexture3d<TFormat, 'write-only'>;\nexport function textureStorage3d<\n TFormat extends StorageTextureFormats,\n TAccess extends GPUStorageTextureAccess,\n>(format: TFormat, access?: TAccess) {\n const actualAccess = (access || 'write-only') as Default<\n TAccess,\n 'write-only'\n >;\n const key = `texture_storage_3d<${format}, ${accessModeMap[actualAccess]}>`;\n return getOrCreate(key, () =>\n createStorageTexture('texture_storage_3d', {\n dimension: '3d',\n format,\n access: actualAccess,\n }));\n}\n\nexport interface textureDepth2d {\n readonly kind: 'texture_depth_2d';\n [$internal]: F32;\n}\n\nexport function textureDepth2d() {\n const key = 'texture_depth_2d';\n return getOrCreate(key, () =>\n createTexture('texture_depth_2d', {\n dimension: '2d',\n sampleType: f32,\n multisampled: false,\n })) as WgslTextureDepth2d;\n}\n\nexport interface textureDepthMultisampled2d {\n readonly kind: 'texture_depth_multisampled_2d';\n [$internal]: F32;\n}\n\nexport function textureDepthMultisampled2d() {\n const key = 'texture_depth_multisampled_2d';\n return getOrCreate(key, () =>\n createTexture('texture_depth_multisampled_2d', {\n dimension: '2d',\n sampleType: f32,\n multisampled: true,\n })) as WgslTextureDepthMultisampled2d;\n}\n\nexport interface textureDepth2dArray {\n readonly kind: 'texture_depth_2d_array';\n [$internal]: F32;\n}\n\nexport function textureDepth2dArray() {\n const key = 'texture_depth_2d_array';\n return getOrCreate(key, () =>\n createTexture('texture_depth_2d_array', {\n dimension: '2d-array',\n sampleType: f32,\n multisampled: false,\n })) as WgslTextureDepth2dArray;\n}\n\nexport interface textureDepthCube {\n readonly kind: 'texture_depth_cube';\n [$internal]: F32;\n}\n\nexport function textureDepthCube() {\n const key = 'texture_depth_cube';\n return getOrCreate(key, () =>\n createTexture('texture_depth_cube', {\n dimension: 'cube',\n sampleType: f32,\n multisampled: false,\n })) as WgslTextureDepthCube;\n}\n\nexport interface textureDepthCubeArray {\n readonly kind: 'texture_depth_cube_array';\n [$internal]: F32;\n}\n\nexport function textureDepthCubeArray() {\n const key = 'texture_depth_cube_array';\n return getOrCreate(key, () =>\n createTexture('texture_depth_cube_array', {\n dimension: 'cube-array',\n sampleType: f32,\n multisampled: false,\n })) as WgslTextureDepthCubeArray;\n}\n\nexport interface textureExternal {\n readonly kind: 'texture_external';\n [$internal]: true;\n}\n\nexport function textureExternal() {\n const key = 'texture_external';\n return getOrCreate(key, () => ({\n [$internal]: {},\n [$repr]: undefined as unknown as textureExternal,\n type: 'texture_external',\n dimension: '2d',\n })) as WgslExternalTexture;\n}\n\nexport function isWgslTexture(value: unknown): value is WgslTexture {\n return (\n !!(value as WgslTexture)[$internal] &&\n typeof (value as WgslTexture).multisampled === 'boolean'\n );\n}\n\nexport function isWgslStorageTexture(\n value: unknown,\n): value is WgslStorageTexture {\n return (\n !!(value as WgslStorageTexture)[$internal] &&\n typeof (value as WgslStorageTexture).format === 'string' &&\n typeof (value as WgslStorageTexture).access === 'string'\n );\n}\n\nexport function isWgslExternalTexture(\n value: unknown,\n): value is WgslExternalTexture {\n return (\n !!(value as WgslExternalTexture)[$internal] &&\n (value as WgslExternalTexture).type === 'texture_external'\n );\n}\n"],"mappings":";;;AA8SA,SAAgB,0BAEd,MAAwC;AACxC,KAAI,kBAAkB,MAAM;AAC1B,MAAI,KAAK,cAAc;AACrB,OAAI,KAAK,cAAc,KACrB,QAAO,sBACL,KAAK,WACN;AAEH,SAAM,IAAI,MACR,2DAA2D,KAAK,UAAU,GAC3E;;AAGH,UAAQ,KAAK,WAAb;GACE,KAAK,KACH,QAAO,UAAU,KAAK,WAAW;GACnC,KAAK,KACH,QAAO,UAAU,KAAK,WAAW;GACnC,KAAK,WACH,QAAO,eACL,KAAK,WACN;GACH,KAAK,KACH,QAAO,UAAU,KAAK,WAAW;GACnC,KAAK,OACH,QAAO,YACL,KAAK,WACN;GACH,KAAK,aACH,QAAO,iBACL,KAAK,WACN;GACH,QACE,OAAM,IAAI,MAER,mCAAmC,KAAK,UAAU,GACnD;;;AAGP,KAAI,EAAE,YAAY,MAChB,OAAM,IAAI,MAAM,wDAAwD;AAG1E,SAAQ,KAAK,WAAb;EACE,KAAK,KACH,QAAO,iBACL,KAAK,QACL,KAAK,OACN;EACH,KAAK,KACH,QAAO,iBACL,KAAK,QACL,KAAK,OACN;EACH,KAAK,WACH,QAAO,sBACL,KAAK,QACL,KAAK,OACN;EACH,KAAK,KACH,QAAO,iBACL,KAAK,QACL,KAAK,OACN;EACH,QACE,OAAM,IAAI,MAER,2CAA2C,KAAK,UAAU,GAC3D;;;AAIP,SAAS,cACP,MACA,OACqB;CAErB,MAAM,cADU,KAAK,WAAW,gBAAgB,GAE5C;EAAC;EAAS;EAAS;EAAqB,GACxC,MAAM,WAAW,SAAS,QAC1B,CAAC,OAAO,GACR,MAAM,WAAW,SAAS,QAC1B,CAAC,OAAO,GACR,CAAC,SAAS,qBAAqB;AAEnC,QAAO;GACJ,YAAY,EAAE;GACd,QAAQ;EACT;EACA,mBAAmB;EACnB,GAAG;EACJ;;AAGH,SAAS,qBACP,MACA,OAC4B;AAC5B,QAAO;GACJ,YAAY,EAAE;GACd,QAAQ;EACT;EACA,GAAG;EACJ;;AAGH,MAAM,+BAAe,IAAI,KAGtB;AAEH,MAAa,gBAAyD;CACpE,cAAc;CACd,aAAa;CACb,cAAc;CACf;AAED,SAAS,YAEP,KAAa,SAAqB;CAClC,IAAI,SAAS,aAAa,IAAI,IAAI;AAClC,KAAI,CAAC,QAAQ;AACX,WAAS,SAAS;AAClB,eAAa,IAAI,KAAK,OAAO;;AAE/B,QAAO;;AAYT,SAAgB,UAAwC,YAAgB;CACtE,MAAM,mBAAoB,cAAc;AAExC,QAAO,YADK,cAAc,iBAAiB,KAAK,UAE9C,cAAc,cAAc;EAC1B,WAAW;EACX,YAAY;EACZ,cAAc;EACf,CAAC,CAAC;;AAYP,SAAgB,UAAwC,YAAgB;CACtE,MAAM,mBAAoB,cAAc;AAExC,QAAO,YADK,cAAc,iBAAiB,KAAK,UAE9C,cAAc,cAAc;EAC1B,WAAW;EACX,YAAY;EACZ,cAAc;EACf,CAAC,CAAC;;AAcP,SAAgB,sBACd,YACA;CACA,MAAM,mBAAoB,cAAc;AAExC,QAAO,YADK,2BAA2B,iBAAiB,KAAK,UAE3D,cAAc,2BAA2B;EACvC,WAAW;EACX,YAAY;EACZ,cAAc;EACf,CAAC,CAAC;;AAcP,SAAgB,eAA6C,YAAgB;CAC3E,MAAM,mBAAoB,cAAc;AAExC,QAAO,YADK,oBAAoB,iBAAiB,KAAK,UAEpD,cAAc,oBAAoB;EAChC,WAAW;EACX,YAAY;EACZ,cAAc;EACf,CAAC,CAAC;;AAcP,SAAgB,YAA0C,YAAgB;CACxE,MAAM,mBAAoB,cAAc;AAExC,QAAO,YADK,gBAAgB,iBAAiB,KAAK,UAEhD,cAAc,gBAAgB;EAC5B,WAAW;EACX,YAAY;EACZ,cAAc;EACf,CAAC,CAAC;;AAcP,SAAgB,iBACd,YACA;CACA,MAAM,mBAAoB,cAAc;AAExC,QAAO,YADK,sBAAsB,iBAAiB,KAAK,UAEtD,cAAc,sBAAsB;EAClC,WAAW;EACX,YAAY;EACZ,cAAc;EACf,CAAC,CAAC;;AAYP,SAAgB,UAAwC,YAAgB;CACtE,MAAM,mBAAoB,cAAc;AAExC,QAAO,YADK,cAAc,iBAAiB,KAAK,UAE9C,cAAc,cAAc;EAC1B,WAAW;EACX,YAAY;EACZ,cAAc;EACf,CAAC,CAAC;;AAkBP,SAAgB,iBAGd,QAAiB,QAAkB;CACnC,MAAM,eAAgB,UAAU;AAKhC,QAAO,YADK,sBAAsB,OAAO,IAAI,cAAc,cAAc,UAEvE,qBAAqB,sBAAsB;EACzC,WAAW;EACX;EACA,QAAQ;EACT,CAAC,CAAC;;AAkBP,SAAgB,iBAGd,QAAiB,QAAkB;CACnC,MAAM,eAAgB,UAAU;AAKhC,QAAO,YADK,sBAAsB,OAAO,IAAI,cAAc,cAAc,UAEvE,qBAAqB,sBAAsB;EACzC,WAAW;EACX;EACA,QAAQ;EACT,CAAC,CAAC;;AAqBP,SAAgB,sBAGd,QAAiB,QAAkB;CACnC,MAAM,eAAgB,UAAU;AAOhC,QAAO,YAHK,4BAA4B,OAAO,IAC7C,cAAc,cACf,UAIG,qBAAqB,4BAA4B;EAC/C,WAAW;EACX;EACA,QAAQ;EACT,CAAC,CACL;;AAkBH,SAAgB,iBAGd,QAAiB,QAAkB;CACnC,MAAM,eAAgB,UAAU;AAKhC,QAAO,YADK,sBAAsB,OAAO,IAAI,cAAc,cAAc,UAEvE,qBAAqB,sBAAsB;EACzC,WAAW;EACX;EACA,QAAQ;EACT,CAAC,CAAC;;AAQP,SAAgB,iBAAiB;AAE/B,QAAO,YADK,0BAEV,cAAc,oBAAoB;EAChC,WAAW;EACX,YAAY;EACZ,cAAc;EACf,CAAC,CAAC;;AAQP,SAAgB,6BAA6B;AAE3C,QAAO,YADK,uCAEV,cAAc,iCAAiC;EAC7C,WAAW;EACX,YAAY;EACZ,cAAc;EACf,CAAC,CAAC;;AAQP,SAAgB,sBAAsB;AAEpC,QAAO,YADK,gCAEV,cAAc,0BAA0B;EACtC,WAAW;EACX,YAAY;EACZ,cAAc;EACf,CAAC,CAAC;;AAQP,SAAgB,mBAAmB;AAEjC,QAAO,YADK,4BAEV,cAAc,sBAAsB;EAClC,WAAW;EACX,YAAY;EACZ,cAAc;EACf,CAAC,CAAC;;AAQP,SAAgB,wBAAwB;AAEtC,QAAO,YADK,kCAEV,cAAc,4BAA4B;EACxC,WAAW;EACX,YAAY;EACZ,cAAc;EACf,CAAC,CAAC;;AAQP,SAAgB,kBAAkB;AAEhC,QAAO,YADK,2BACmB;GAC5B,YAAY,EAAE;GACd,QAAQ;EACT,MAAM;EACN,WAAW;EACZ,EAAE;;AAGL,SAAgB,cAAc,OAAsC;AAClE,QACE,CAAC,CAAE,MAAsB,cACzB,OAAQ,MAAsB,iBAAiB;;AAInD,SAAgB,qBACd,OAC6B;AAC7B,QACE,CAAC,CAAE,MAA6B,cAChC,OAAQ,MAA6B,WAAW,YAChD,OAAQ,MAA6B,WAAW"}
+1
-1

@@ -1,2 +0,2 @@

import { c as fullScreenTriangle } from "../indexNamedExports-Cdy7USiY.js";
import { c as fullScreenTriangle } from "../indexNamedExports-oL6tyaJ9.js";

@@ -3,0 +3,0 @@ //#region src/common/index.d.ts

import { t as __exportAll } from "../chunk-BYypO7fO.js";
import { t as fullScreenTriangle } from "../fullScreenTriangle-MdLGaAMR.js";
import { t as fullScreenTriangle } from "../fullScreenTriangle-CfFyQd_0.js";

@@ -4,0 +4,0 @@ //#region src/common/index.ts

@@ -1,2 +0,2 @@

import { $a as m3x3f, $c as align, $i as textureStorage2dArray, $n as atomic, $s as uint32x2, Aa as Vec3h, Ai as WgslTextureCube, Ar as ptrHandle, As as formatToWGSLType, Ba as WgslStruct, Bi as texture2dArray, Br as i32, Bs as sint8, Ca as Vec2b, Ci as WgslStorageTexture3d, Cl as BuiltinNumWorkgroups, Cr as vec3u, Cs as float16, Da as Vec2u, Di as WgslTexture2d, Dl as BuiltinVertexIndex, Dr as vec4i, Ds as float32x2, Ea as Vec2i, Ei as WgslTexture1d, El as BuiltinSampleMask, Er as vec4h, Es as float32, Fa as Vec4h, Fi as WgslTextureDepthCubeArray, Fl as comparisonSampler, Fr as arrayOf, Fs as sint16x4, Ga as isInterpolateAttrib, Gi as textureDepth2dArray, Gs as snorm16x4, Ha as isAtomic, Hi as textureCube, Hr as u32, Hs as sint8x4, Ia as Vec4i, Ii as WgslTextureDepthMultisampled2d, Il as sampler, Ir as struct, Is as sint32, Ja as isSizeAttrib, Ji as textureDepthMultisampled2d, Jn as deepEqual, Js as snorm8x4, Ka as isLocationAttrib, Ki as textureDepthCube, Ks as snorm8, La as Vec4u, Li as WgslTextureMultisampled2d, Lr as bool, Ls as sint32x2, Ma as Vec3u, Mi as WgslTextureDepth2d, Mr as ptrStorage, Ms as packedFormats, Na as Vec4b, Ni as WgslTextureDepth2dArray, Nl as WgslComparisonSampler, Nr as ptrUniform, Ns as sint16, Oa as Vec3b, Oi as WgslTexture2dArray, Ol as BuiltinWorkgroupId, Or as vec4u, Os as float32x3, Pa as Vec4f, Pi as WgslTextureDepthCube, Pl as WgslSampler, Pr as ptrWorkgroup, Ps as sint16x2, Qa as m2x2f, Qc as IsBuiltin, Qi as textureStorage2d, Qn as PUBLIC_sizeOf, Qs as uint32, Ra as Void, Ri as texture1d, Rr as f16, Rs as sint32x3, Sa as U32, Si as WgslStorageTexture2dArray, Sl as BuiltinLocalInvocationIndex, Sr as vec3i, Ss as TgpuVertexFormatData, Ta as Vec2h, Ti as WgslTexture, Tl as BuiltinSampleIndex, Tr as vec4f, Ts as float16x4, Ua as isBuiltinAttrib, Ui as textureCubeArray, Us as snorm16, Va as isAlignAttrib, Vi as texture3d, Vr as u16, Vs as sint8x2, Wa as isDecorated, Wi as textureDepth2d, Ws as snorm16x2, Xa as isWgslData, Xc as AnyAttribute, Xi as textureMultisampled2d, Xn as PUBLIC_getLongestContiguousPrefix, Xs as uint16x2, Ya as isWgslArray, Yi as textureExternal, Yn as PUBLIC_alignmentOf, Ys as uint16, Za as isWgslStruct, Zc as HasCustomLocation, Zi as textureStorage1d, Zn as PUBLIC_isContiguous, Zs as uint16x4, _a as Mat4x4f, _l as BuiltinFragDepth, _r as vec2i, aa as Atomic, ac as unorm10_10_10_2, ai as LooseDecorated, ao as v2u, ar as mat4x4f, ba as StorableData, bi as WgslStorageTexture1d, bl as BuiltinInstanceIndex, br as vec3f, bs as FormatToWGSLType, ca as Builtin, cc as unorm16x4, ci as isDisarray, co as v3i, da as F32, dc as unorm8x4, di as isUnstruct, do as v4f, ea as textureStorage3d, ec as uint32x3, el as interpolate, eo as m4x4f, fa as I32, fc as unorm8x4_bgra, fi as Infer, fo as v4i, fr as unstruct, ga as Mat3x3f, gl as BuiltinClipDistances, gr as vec2h, ha as Mat2x2f, hl as AnyBuiltin, ho as _ref, hr as vec2f, ia as AnyWgslStruct, ic as uint8x4, ii as Disarray, il as size, io as v2i, ir as mat3x3f, ja as Vec3i, jc as memoryLayoutOf, ji as WgslTextureCubeArray, jr as ptrPrivate, js as isPackedData, ka as Vec3f, ki as WgslTexture3d, kl as builtin, kr as ptrFn, ks as float32x4, la as Decorated, lc as unorm8, li as isLooseData, lo as v3u, ma as Location, mi as InferPartial, mo as vecBase, mr as vec2b, na as AnyVecInstance, nc as uint8, ni as AnyData, nl as isBuiltin, no as v2b, oa as BaseData, oc as unorm16, oi as Unstruct, oo as v3b, or as matToArray, pa as Interpolate, pi as InferGPU, po as v4u, pr as disarrayOf, qa as isPtr, qi as textureDepthCubeArray, qs as snorm8x2, ra as AnyWgslData, rc as uint8x2, ri as AnyLooseData, rl as location, ro as v2f, rr as mat2x2f, sa as Bool, sc as unorm16x2, si as isData, so as v3f, ta as Align, tc as uint32x4, tl as invariant, to as matBase, ua as F16, uc as unorm8x2, ui as isLooseDecorated, uo as v4b, va as Ptr, vi as WgslExternalTexture, vl as BuiltinFrontFacing, vr as vec2u, wa as Vec2f, wi as WgslStorageTextureProps, wl as BuiltinPosition, wr as vec4b, ws as float16x2, xa as U16, xi as WgslStorageTexture2d, xl as BuiltinLocalInvocationId, xr as vec3h, xs as PackedData, ya as Size, yi as WgslStorageTexture, yl as BuiltinGlobalInvocationId, yr as vec3b, ys as FormatToAcceptedData, za as WgslArray, zi as texture2d, zr as f32, zs as sint32x4 } from "../indexNamedExports-Cdy7USiY.js";
import { $a as m3x3f, $c as align, $i as textureStorage2dArray, $n as atomic, $s as uint32x2, Aa as Vec3h, Ai as WgslTextureCube, Ar as ptrHandle, As as formatToWGSLType, Ba as WgslStruct, Bi as texture2dArray, Br as i32, Bs as sint8, Ca as Vec2b, Ci as WgslStorageTexture3d, Cl as BuiltinNumWorkgroups, Cr as vec3u, Cs as float16, Da as Vec2u, Di as WgslTexture2d, Dl as BuiltinVertexIndex, Dr as vec4i, Ds as float32x2, Ea as Vec2i, Ei as WgslTexture1d, El as BuiltinSampleMask, Er as vec4h, Es as float32, Fa as Vec4h, Fi as WgslTextureDepthCubeArray, Fl as comparisonSampler, Fr as arrayOf, Fs as sint16x4, Ga as isInterpolateAttrib, Gi as textureDepth2dArray, Gs as snorm16x4, Ha as isAtomic, Hi as textureCube, Hr as u32, Hs as sint8x4, Ia as Vec4i, Ii as WgslTextureDepthMultisampled2d, Il as sampler, Ir as struct, Is as sint32, Ja as isSizeAttrib, Ji as textureDepthMultisampled2d, Jn as deepEqual, Js as snorm8x4, Ka as isLocationAttrib, Ki as textureDepthCube, Ks as snorm8, La as Vec4u, Li as WgslTextureMultisampled2d, Lr as bool, Ls as sint32x2, Ma as Vec3u, Mi as WgslTextureDepth2d, Mr as ptrStorage, Ms as packedFormats, Na as Vec4b, Ni as WgslTextureDepth2dArray, Nl as WgslComparisonSampler, Nr as ptrUniform, Ns as sint16, Oa as Vec3b, Oi as WgslTexture2dArray, Ol as BuiltinWorkgroupId, Or as vec4u, Os as float32x3, Pa as Vec4f, Pi as WgslTextureDepthCube, Pl as WgslSampler, Pr as ptrWorkgroup, Ps as sint16x2, Qa as m2x2f, Qc as IsBuiltin, Qi as textureStorage2d, Qn as PUBLIC_sizeOf, Qs as uint32, Ra as Void, Ri as texture1d, Rr as f16, Rs as sint32x3, Sa as U32, Si as WgslStorageTexture2dArray, Sl as BuiltinLocalInvocationIndex, Sr as vec3i, Ss as TgpuVertexFormatData, Ta as Vec2h, Ti as WgslTexture, Tl as BuiltinSampleIndex, Tr as vec4f, Ts as float16x4, Ua as isBuiltinAttrib, Ui as textureCubeArray, Us as snorm16, Va as isAlignAttrib, Vi as texture3d, Vr as u16, Vs as sint8x2, Wa as isDecorated, Wi as textureDepth2d, Ws as snorm16x2, Xa as isWgslData, Xc as AnyAttribute, Xi as textureMultisampled2d, Xn as PUBLIC_getLongestContiguousPrefix, Xs as uint16x2, Ya as isWgslArray, Yi as textureExternal, Yn as PUBLIC_alignmentOf, Ys as uint16, Za as isWgslStruct, Zc as HasCustomLocation, Zi as textureStorage1d, Zn as PUBLIC_isContiguous, Zs as uint16x4, _a as Mat4x4f, _l as BuiltinFragDepth, _r as vec2i, aa as Atomic, ac as unorm10_10_10_2, ai as LooseDecorated, ao as v2u, ar as mat4x4f, ba as StorableData, bi as WgslStorageTexture1d, bl as BuiltinInstanceIndex, br as vec3f, bs as FormatToWGSLType, ca as Builtin, cc as unorm16x4, ci as isDisarray, co as v3i, da as F32, dc as unorm8x4, di as isUnstruct, do as v4f, ea as textureStorage3d, ec as uint32x3, el as interpolate, eo as m4x4f, fa as I32, fc as unorm8x4_bgra, fi as Infer, fo as v4i, fr as unstruct, ga as Mat3x3f, gl as BuiltinClipDistances, gr as vec2h, ha as Mat2x2f, hl as AnyBuiltin, ho as _ref, hr as vec2f, ia as AnyWgslStruct, ic as uint8x4, ii as Disarray, il as size, io as v2i, ir as mat3x3f, ja as Vec3i, jc as memoryLayoutOf, ji as WgslTextureCubeArray, jr as ptrPrivate, js as isPackedData, ka as Vec3f, ki as WgslTexture3d, kl as builtin, kr as ptrFn, ks as float32x4, la as Decorated, lc as unorm8, li as isLooseData, lo as v3u, ma as Location, mi as InferPartial, mo as vecBase, mr as vec2b, na as AnyVecInstance, nc as uint8, ni as AnyData, nl as isBuiltin, no as v2b, oa as BaseData, oc as unorm16, oi as Unstruct, oo as v3b, or as matToArray, pa as Interpolate, pi as InferGPU, po as v4u, pr as disarrayOf, qa as isPtr, qi as textureDepthCubeArray, qs as snorm8x2, ra as AnyWgslData, rc as uint8x2, ri as AnyLooseData, rl as location, ro as v2f, rr as mat2x2f, sa as Bool, sc as unorm16x2, si as isData, so as v3f, ta as Align, tc as uint32x4, tl as invariant, to as matBase, ua as F16, uc as unorm8x2, ui as isLooseDecorated, uo as v4b, va as Ptr, vi as WgslExternalTexture, vl as BuiltinFrontFacing, vr as vec2u, wa as Vec2f, wi as WgslStorageTextureProps, wl as BuiltinPosition, wr as vec4b, ws as float16x2, xa as U16, xi as WgslStorageTexture2d, xl as BuiltinLocalInvocationId, xr as vec3h, xs as PackedData, ya as Size, yi as WgslStorageTexture, yl as BuiltinGlobalInvocationId, yr as vec3b, ys as FormatToAcceptedData, za as WgslArray, zi as texture2d, zr as f32, zs as sint32x4 } from "../indexNamedExports-oL6tyaJ9.js";

@@ -3,0 +3,0 @@ //#region src/data/index.d.ts

import { t as __exportAll } from "../chunk-BYypO7fO.js";
import { $ as VecBase, An as isAlignAttrib, B as vec2h, Cn as isDisarray, Dt as ptrStorage, En as isUnstruct, Et as ptrPrivate, Fn as isInterpolateAttrib, G as vec3h, H as vec2u, Hn as isSizeAttrib, In as isLocationAttrib, J as vec4b, Jn as isWgslData, K as vec3i, Mn as isBuiltinAttrib, Nn as isDecorated, Ot as ptrUniform, P as struct, Q as vec4u, R as vec2b, Sn as isData, Tn as isLooseDecorated, Tt as ptrHandle, U as vec3b, V as vec2i, Vn as isPtr, W as vec3f, X as vec4h, Y as vec4f, Yn as isWgslStruct, Z as vec4i, _ as mat4x4f, at as i32, d as MatBase, g as mat3x3f, h as mat2x2f, it as f32, jn as isAtomic, kn as Void, kt as ptrWorkgroup, nt as bool, ot as u16, q as vec3u, qn as isWgslArray, rt as f16, st as u32, v as matToArray, wn as isLooseData, wt as ptrFn, yt as _ref, z as vec2f } from "../operators-HTxa_0k9.js";
import { $ as uint32x4, A as packedFormats, B as sint8x4, C as float16x4, D as float32x4, E as float32x3, F as sint32x2, G as snorm8x2, H as snorm16x2, I as sint32x3, J as uint16x2, K as snorm8x4, L as sint32x4, M as sint16x2, N as sint16x4, O as formatToWGSLType, P as sint32, Q as uint32x3, R as sint8, S as float16x2, T as float32x2, U as snorm16x4, V as snorm16, W as snorm8, X as uint32, Y as uint16x4, Z as uint32x2, at as unorm16x2, ct as unorm8x2, d as isBuiltin, et as uint8, f as location, i as infixOperators, it as unorm16, j as sint16, k as isPackedData, l as interpolate, lt as unorm8x4, m as PUBLIC_sizeOf, n as arrayOf, nt as uint8x4, ot as unorm16x4, p as size, q as uint16, rt as unorm10_10_10_2, s as align, st as unorm8, t as builtin, tt as uint8x2, u as invariant, ut as unorm8x4_bgra, v as PUBLIC_alignmentOf, w as float32, x as float16, z as sint8x2 } from "../builtin-ClEnM-Ye.js";
import { a as PUBLIC_getLongestContiguousPrefix, i as memoryLayoutOf, n as unstruct, o as PUBLIC_isContiguous, p as sampler, r as disarrayOf, s as atomic, t as deepEqual, u as comparisonSampler } from "../deepEqual-yZXvaV2C.js";
import { _ as textureMultisampled2d, a as texture2d, b as textureStorage2dArray, c as textureCube, d as textureDepth2dArray, f as textureDepthCube, g as textureExternal, i as texture1d, l as textureCubeArray, m as textureDepthMultisampled2d, o as texture2dArray, p as textureDepthCubeArray, s as texture3d, u as textureDepth2d, v as textureStorage1d, x as textureStorage3d, y as textureStorage2d } from "../texture-Dg5ybJro.js";
import { $ as VecBase, An as isAlignAttrib, B as vec2h, Cn as isDisarray, Dt as ptrStorage, En as isUnstruct, Et as ptrPrivate, Fn as isInterpolateAttrib, G as vec3h, H as vec2u, Hn as isSizeAttrib, In as isLocationAttrib, J as vec4b, Jn as isWgslData, K as vec3i, Mn as isBuiltinAttrib, Nn as isDecorated, Ot as ptrUniform, P as struct, Q as vec4u, R as vec2b, Sn as isData, Tn as isLooseDecorated, Tt as ptrHandle, U as vec3b, V as vec2i, Vn as isPtr, W as vec3f, X as vec4h, Y as vec4f, Yn as isWgslStruct, Z as vec4i, _ as mat4x4f, at as i32, d as MatBase, g as mat3x3f, h as mat2x2f, it as f32, jn as isAtomic, kn as Void, kt as ptrWorkgroup, nt as bool, ot as u16, q as vec3u, qn as isWgslArray, rt as f16, st as u32, v as matToArray, wn as isLooseData, wt as ptrFn, yt as _ref, z as vec2f } from "../operators-d-PMVTo7.js";
import { $ as uint32x4, A as packedFormats, B as sint8x4, C as float16x4, D as float32x4, E as float32x3, F as sint32x2, G as snorm8x2, H as snorm16x2, I as sint32x3, J as uint16x2, K as snorm8x4, L as sint32x4, M as sint16x2, N as sint16x4, O as formatToWGSLType, P as sint32, Q as uint32x3, R as sint8, S as float16x2, T as float32x2, U as snorm16x4, V as snorm16, W as snorm8, X as uint32, Y as uint16x4, Z as uint32x2, at as unorm16x2, ct as unorm8x2, d as isBuiltin, et as uint8, f as location, i as infixOperators, it as unorm16, j as sint16, k as isPackedData, l as interpolate, lt as unorm8x4, m as PUBLIC_sizeOf, n as arrayOf, nt as uint8x4, ot as unorm16x4, p as size, q as uint16, rt as unorm10_10_10_2, s as align, st as unorm8, t as builtin, tt as uint8x2, u as invariant, ut as unorm8x4_bgra, v as PUBLIC_alignmentOf, w as float32, x as float16, z as sint8x2 } from "../builtin-DdtWpk2t.js";
import { a as PUBLIC_getLongestContiguousPrefix, i as memoryLayoutOf, n as unstruct, o as PUBLIC_isContiguous, p as sampler, r as disarrayOf, s as atomic, t as deepEqual, u as comparisonSampler } from "../deepEqual-DQxK4vdp.js";
import { _ as textureMultisampled2d, a as texture2d, b as textureStorage2dArray, c as textureCube, d as textureDepth2dArray, f as textureDepthCube, g as textureExternal, i as texture1d, l as textureCubeArray, m as textureDepthMultisampled2d, o as texture2dArray, p as textureDepthCubeArray, s as texture3d, u as textureDepth2d, v as textureStorage1d, x as textureStorage3d, y as textureStorage2d } from "../texture-BagDrrks.js";
import { Operator } from "tsover-runtime";

@@ -7,0 +7,0 @@

@@ -1,2 +0,2 @@

import { $o as TgpuLayoutComparisonSampler, $r as comptime, Ac as TgpuComputePipeline, Al as Storage, Ao as UniformFlag, Bc as isSlot, Bo as ValidateStorageSchema, Cc as TgpuFragmentFnShell, Co as fn, Dc as AutoFragmentOut, Do as IndexFlag, Ec as AutoFragmentIn, Eo as declare, Fc as TgpuMutableAccessor, Fo as isUsableAsVertex, Gc as workgroupVar, Go as WithVertex, Gr as rawCodeSnippet, Hc as VariableScope, Ho as WithBinding, Ic as TgpuSlot, Io as Configurable, Jc as computeFn, Jo as BindLayoutEntry, Jr as init, Kc as TgpuComputeFn, Ko as Withable, Kr as InitFromDeviceOptions, Lc as isAccessor, Ll as $internal, Lo as TgpuGuardedComputePipeline, Mc as Eventual, Ml as isUsableAsStorage, Mo as Vertex, Nc as TgpuAccessor, No as VertexFlag, Oc as AutoVertexIn, Oo as TgpuBuffer, Pc as TgpuLazy, Po as isBuffer, Qo as TgpuBindGroupLayout, Qr as TgpuComptime, Rc as isLazy, Rl as INTERNAL_GlobalExt, Ro as TgpuRoot, Sc as TgpuFragmentFn, So as TgpuGenericFn, Tc as isTgpuFragmentFn, To as TgpuDeclare, Uc as isVariable, Uo as WithCompute, Ur as RawCodeSnippetOrigin, Vc as TgpuVar, Vo as ValidateUniformSchema, Wc as privateVar, Wo as WithFragment, Wr as TgpuRawCodeSnippet, Xo as LayoutEntryToInput, Xr as Namespace, Yc as isTgpuComputeFn, Yo as ExtractBindGroupInputFromLayout, Yr as initFromDevice, Zo as TgpuBindGroup, Zr as namespace, _c as TextureProps, _i as isTexture, _o as ResolvableObject, _s as TgpuVertexLayout, a as MissingVertexBuffersError, al as LogResources, as as TgpuLayoutUniform, bc as isTgpuVertexFn, bo as TgpuFn, cl as TgpuUniform, cs as TgpuComparisonSampler, dl as TgpuBufferReadonly, ds as TgpuSampler, ei as TgpuConst, es as TgpuLayoutEntry, fl as TgpuBufferUniform, fs as isComparisonSampler, gc as isUsableAsSampled, gi as TgpuTextureView, go as GPUCallable, gs as TgpuRenderPipeline, hc as isUsableAsRender, hi as TgpuTexture, hs as TgpuPrimitiveState, i as MissingSlotValueError, is as TgpuLayoutTexture, jl as StorageFlag, jo as ValidUsagesFor, kc as AutoVertexOut, ko as Uniform, ll as isBufferShorthand, ls as TgpuFixedComparisonSampler, mc as SampledFlag, ml as TgpuQuerySet, ms as ColorAttachment, n as MissingBindGroupsError, ni as AnyData, ns as TgpuLayoutSampler, o as NotUniformError, oa as BaseData, ol as TgpuMutable, os as UnwrapRuntimeConstructor, pc as RenderFlag, pl as isUsableAsUniform, ps as isSampler, qc as TgpuComputeFnShell, qo as ShaderGenerator, qr as InitOptions, r as MissingLinksError, rs as TgpuLayoutStorage, s as ResolutionError, sl as TgpuReadonly, ss as bindGroupLayout, t as TgpuRenderPipelineDescriptor, ti as constant, ts as TgpuLayoutExternalTexture, ul as TgpuBufferMutable, us as TgpuFixedSampler, vc as TgpuVertexFn, vo as Wgsl, vs as vertexLayout, wc as fragmentFn, wo as isTgpuFn, xc as vertexFn, xo as TgpuFnShell, yc as TgpuVertexFnShell, yo as WgslExtension, zc as isMutableAccessor, zo as ValidateBufferSchema } from "./indexNamedExports-Cdy7USiY.js";
import { $o as TgpuLayoutComparisonSampler, $r as comptime, Ac as TgpuComputePipeline, Al as Storage, Ao as UniformFlag, Bc as isSlot, Bo as ValidateStorageSchema, Cc as TgpuFragmentFnShell, Co as fn, Dc as AutoFragmentOut, Do as IndexFlag, Ec as AutoFragmentIn, Eo as declare, Fc as TgpuMutableAccessor, Fo as isUsableAsVertex, Gc as workgroupVar, Go as WithVertex, Gr as rawCodeSnippet, Hc as VariableScope, Ho as WithBinding, Ic as TgpuSlot, Io as Configurable, Jc as computeFn, Jo as BindLayoutEntry, Jr as init, Kc as TgpuComputeFn, Ko as Withable, Kr as InitFromDeviceOptions, Lc as isAccessor, Ll as $internal, Lo as TgpuGuardedComputePipeline, Mc as Eventual, Ml as isUsableAsStorage, Mo as Vertex, Nc as TgpuAccessor, No as VertexFlag, Oc as AutoVertexIn, Oo as TgpuBuffer, Pc as TgpuLazy, Po as isBuffer, Qo as TgpuBindGroupLayout, Qr as TgpuComptime, Rc as isLazy, Rl as INTERNAL_GlobalExt, Ro as TgpuRoot, Sc as TgpuFragmentFn, So as TgpuGenericFn, Tc as isTgpuFragmentFn, To as TgpuDeclare, Uc as isVariable, Uo as WithCompute, Ur as RawCodeSnippetOrigin, Vc as TgpuVar, Vo as ValidateUniformSchema, Wc as privateVar, Wo as WithFragment, Wr as TgpuRawCodeSnippet, Xo as LayoutEntryToInput, Xr as Namespace, Yc as isTgpuComputeFn, Yo as ExtractBindGroupInputFromLayout, Yr as initFromDevice, Zo as TgpuBindGroup, Zr as namespace, _c as TextureProps, _i as isTexture, _o as ResolvableObject, _s as TgpuVertexLayout, a as MissingVertexBuffersError, al as LogResources, as as TgpuLayoutUniform, bc as isTgpuVertexFn, bo as TgpuFn, cl as TgpuUniform, cs as TgpuComparisonSampler, dl as TgpuBufferReadonly, ds as TgpuSampler, ei as TgpuConst, es as TgpuLayoutEntry, fl as TgpuBufferUniform, fs as isComparisonSampler, gc as isUsableAsSampled, gi as TgpuTextureView, go as GPUCallable, gs as TgpuRenderPipeline, hc as isUsableAsRender, hi as TgpuTexture, hs as TgpuPrimitiveState, i as MissingSlotValueError, is as TgpuLayoutTexture, jl as StorageFlag, jo as ValidUsagesFor, kc as AutoVertexOut, ko as Uniform, ll as isBufferShorthand, ls as TgpuFixedComparisonSampler, mc as SampledFlag, ml as TgpuQuerySet, ms as ColorAttachment, n as MissingBindGroupsError, ni as AnyData, ns as TgpuLayoutSampler, o as NotUniformError, oa as BaseData, ol as TgpuMutable, os as UnwrapRuntimeConstructor, pc as RenderFlag, pl as isUsableAsUniform, ps as isSampler, qc as TgpuComputeFnShell, qo as ShaderGenerator, qr as InitOptions, r as MissingLinksError, rs as TgpuLayoutStorage, s as ResolutionError, sl as TgpuReadonly, ss as bindGroupLayout, t as TgpuRenderPipelineDescriptor, ti as constant, ts as TgpuLayoutExternalTexture, ul as TgpuBufferMutable, us as TgpuFixedSampler, vc as TgpuVertexFn, vo as Wgsl, vs as vertexLayout, wc as fragmentFn, wo as isTgpuFn, xc as vertexFn, xo as TgpuFnShell, yc as TgpuVertexFnShell, yo as WgslExtension, zc as isMutableAccessor, zo as ValidateBufferSchema } from "./indexNamedExports-oL6tyaJ9.js";
import { t as index_d_exports$1 } from "./data/index.js";

@@ -3,0 +3,0 @@ import { t as index_d_exports$2 } from "./std/index.js";

{
"name": "typegpu",
"private": false,
"version": "0.10.0",
"version": "0.10.1",
"description": "A thin layer between JS and WebGPU/WGSL that improves development experience and allows for faster iteration.",

@@ -6,0 +6,0 @@ "license": "MIT",

@@ -1,2 +0,2 @@

import { $ as dpdyFine, $t as countOneBits, A as subgroupShuffleUp, An as quantizeToF16, At as rotateY4, B as textureSampleCompareLevel, Bn as smoothstep, Bt as abs, C as subgroupInclusiveMul, Cn as log2, Ct as le, D as subgroupOr, Dn as modf, Dt as or, E as subgroupMul, En as mix, Et as not, F as textureLoad, Fn as round, Ft as div, G as unpack2x16float, Gn as transpose, Gt as atan, H as textureStore, Hn as step, Ht as acosh, I as textureSample, In as saturate, It as mod, J as dpdx, Jt as ceil, K as unpack4x8unorm, Kn as trunc, Kt as atan2, L as textureSampleBaseClampToEdge, Ln as sign, Lt as mul, M as subgroupXor, Mn as reflect, Mt as scale4, N as textureDimensions, Nn as refract, Nt as translate4, O as subgroupShuffle, On as normalize, Ot as select, P as textureGather, Pn as reverseBits, Pt as add, Q as dpdyCoarse, Qt as countLeadingZeros, R as textureSampleBias, Rn as sin, Rt as neg, S as subgroupInclusiveAdd, Sn as log, St as isCloseTo, T as subgroupMin, Tn as min, Tt as ne, U as pack2x16float, Un as tan, Ut as asin, V as textureSampleLevel, Vn as sqrt, Vt as acos, W as pack4x8unorm, Wn as tanh, Wt as asinh, X as dpdxFine, Xt as cos, Y as dpdxCoarse, Yt as clamp, Z as dpdy, Zt as cosh, _ as subgroupBroadcast, _n as frexp, _t as and, an as dot, at as atomicLoad, b as subgroupExclusiveAdd, bn as ldexp, bt as ge, cn as exp, cr as rotationY4, ct as atomicOr, d as extensionEnabled, dn as faceForward, dr as translation4, dt as atomicXor, en as countTrailingZeros, er as identity2, et as fwidth, f as subgroupAdd, fn as firstLeadingBit, ft as storageBarrier, g as subgroupBallot, gn as fract, gt as allEq, h as subgroupAny, hn as fma, ht as all, in as distance, it as atomicAnd, j as subgroupShuffleXor, jn as radians, jt as rotateZ4, k as subgroupShuffleDown, kn as pow, kt as rotateX4, l as bitcastU32toF32, ln as exp2, lr as rotationZ4, lt as atomicStore, m as subgroupAnd, mn as floor, mt as workgroupBarrier, nn as degrees, nr as identity4, nt as fwidthFine, on as dot4I8Packed, ot as atomicMax, p as subgroupAll, pn as firstTrailingBit, pt as textureBarrier, q as arrayLength, qn as discard, qt as atanh, rn as determinant, rt as atomicAdd, sn as dot4U8Packed, sr as rotationX4, st as atomicMin, tn as cross, tr as identity3, tt as fwidthCoarse, u as bitcastU32toI32, un as extractBits, ur as scaling4, ut as atomicSub, v as subgroupBroadcastFirst, vn as insertBits, vt as any, w as subgroupMax, wn as max, wt as lt, x as subgroupExclusiveMul, xn as length, xt as gt, y as subgroupElect, yn as inverseSqrt, yt as eq, z as textureSampleCompare, zn as sinh, zt as sub } from "../indexNamedExports-Cdy7USiY.js";
import { $ as dpdyFine, $t as countOneBits, A as subgroupShuffleUp, An as quantizeToF16, At as rotateY4, B as textureSampleCompareLevel, Bn as smoothstep, Bt as abs, C as subgroupInclusiveMul, Cn as log2, Ct as le, D as subgroupOr, Dn as modf, Dt as or, E as subgroupMul, En as mix, Et as not, F as textureLoad, Fn as round, Ft as div, G as unpack2x16float, Gn as transpose, Gt as atan, H as textureStore, Hn as step, Ht as acosh, I as textureSample, In as saturate, It as mod, J as dpdx, Jt as ceil, K as unpack4x8unorm, Kn as trunc, Kt as atan2, L as textureSampleBaseClampToEdge, Ln as sign, Lt as mul, M as subgroupXor, Mn as reflect, Mt as scale4, N as textureDimensions, Nn as refract, Nt as translate4, O as subgroupShuffle, On as normalize, Ot as select, P as textureGather, Pn as reverseBits, Pt as add, Q as dpdyCoarse, Qt as countLeadingZeros, R as textureSampleBias, Rn as sin, Rt as neg, S as subgroupInclusiveAdd, Sn as log, St as isCloseTo, T as subgroupMin, Tn as min, Tt as ne, U as pack2x16float, Un as tan, Ut as asin, V as textureSampleLevel, Vn as sqrt, Vt as acos, W as pack4x8unorm, Wn as tanh, Wt as asinh, X as dpdxFine, Xt as cos, Y as dpdxCoarse, Yt as clamp, Z as dpdy, Zt as cosh, _ as subgroupBroadcast, _n as frexp, _t as and, an as dot, at as atomicLoad, b as subgroupExclusiveAdd, bn as ldexp, bt as ge, cn as exp, cr as rotationY4, ct as atomicOr, d as extensionEnabled, dn as faceForward, dr as translation4, dt as atomicXor, en as countTrailingZeros, er as identity2, et as fwidth, f as subgroupAdd, fn as firstLeadingBit, ft as storageBarrier, g as subgroupBallot, gn as fract, gt as allEq, h as subgroupAny, hn as fma, ht as all, in as distance, it as atomicAnd, j as subgroupShuffleXor, jn as radians, jt as rotateZ4, k as subgroupShuffleDown, kn as pow, kt as rotateX4, l as bitcastU32toF32, ln as exp2, lr as rotationZ4, lt as atomicStore, m as subgroupAnd, mn as floor, mt as workgroupBarrier, nn as degrees, nr as identity4, nt as fwidthFine, on as dot4I8Packed, ot as atomicMax, p as subgroupAll, pn as firstTrailingBit, pt as textureBarrier, q as arrayLength, qn as discard, qt as atanh, rn as determinant, rt as atomicAdd, sn as dot4U8Packed, sr as rotationX4, st as atomicMin, tn as cross, tr as identity3, tt as fwidthCoarse, u as bitcastU32toI32, un as extractBits, ur as scaling4, ut as atomicSub, v as subgroupBroadcastFirst, vn as insertBits, vt as any, w as subgroupMax, wn as max, wt as lt, x as subgroupExclusiveMul, xn as length, xt as gt, y as subgroupElect, yn as inverseSqrt, yt as eq, z as textureSampleCompare, zn as sinh, zt as sub } from "../indexNamedExports-oL6tyaJ9.js";

@@ -3,0 +3,0 @@ //#region src/std/index.d.ts

import { t as __exportAll } from "../chunk-BYypO7fO.js";
import { C as translation4, S as scaling4, a as neg, b as rotationY4, f as identity2, i as mul, m as identity4, n as div, o as sub, p as identity3, r as mod, t as add, x as rotationZ4, y as rotationX4 } from "../operators-HTxa_0k9.js";
import { $ as workgroupBarrier, $t as extractBits, A as textureSampleCompareLevel, An as sqrt, At as acos, B as fwidthCoarse, Bt as cosh, C as textureDimensions, Cn as reverseBits, Ct as pack4x8unorm, D as textureSampleBaseClampToEdge, Dn as sin, Dt as bitcastU32toI32, E as textureSample, En as sign, Et as bitcastU32toF32, F as dpdxFine, Fn as trunc, Ft as atan2, G as atomicMax, Gt as degrees, H as atomicAdd, Ht as countOneBits, I as dpdy, It as atanh, J as atomicStore, Jt as dot, K as atomicMin, Kt as determinant, L as dpdyCoarse, Lt as ceil, M as textureStore, Mn as tan, Mt as asin, N as dpdx, Nn as tanh, Nt as asinh, O as textureSampleBias, On as sinh, Ot as arrayLength, P as dpdxCoarse, Pn as transpose, Pt as atan, Q as textureBarrier, Qt as exp2, R as dpdyFine, Rt as clamp, S as subgroupXor, Sn as refract, St as pack2x16float, T as textureLoad, Tn as saturate, Tt as unpack4x8unorm, U as atomicAnd, Ut as countTrailingZeros, V as fwidthFine, Vt as countLeadingZeros, W as atomicLoad, Wt as cross, X as atomicXor, Xt as dot4U8Packed, Y as atomicSub, Yt as dot4I8Packed, Z as storageBarrier, Zt as exp, _ as subgroupOr, _n as normalize, _t as not, a as subgroupAny, an as fract, at as discard, b as subgroupShuffleUp, bn as radians, c as subgroupBroadcastFirst, cn as inverseSqrt, ct as and, d as subgroupExclusiveMul, dn as log, dt as ge, en as faceForward, et as rotateX4, f as subgroupInclusiveAdd, fn as log2, ft as gt, g as subgroupMul, gn as modf, gt as ne, h as subgroupMin, hn as mix, ht as lt, i as subgroupAnd, in as fma, it as translate4, j as textureSampleLevel, jn as step, jt as acosh, k as textureSampleCompare, kn as smoothstep, kt as abs, l as subgroupElect, ln as ldexp, lt as any, m as subgroupMax, mn as min, mt as le, n as subgroupAdd, nn as firstTrailingBit, nt as rotateZ4, o as subgroupBallot, on as frexp, ot as all, p as subgroupInclusiveMul, pn as max, pt as isCloseTo, q as atomicOr, qt as distance, r as subgroupAll, rn as floor, rt as scale4, s as subgroupBroadcast, sn as insertBits, st as allEq, t as extensionEnabled, tn as firstLeadingBit, tt as rotateY4, u as subgroupExclusiveAdd, un as length, ut as eq, v as subgroupShuffle, vn as pow, vt as or, w as textureGather, wn as round, wt as unpack2x16float, x as subgroupShuffleXor, xn as reflect, y as subgroupShuffleDown, yn as quantizeToF16, yt as select, z as fwidth, zt as cos } from "../extensions-0SFbU9FH.js";
import { C as translation4, S as scaling4, a as neg, b as rotationY4, f as identity2, i as mul, m as identity4, n as div, o as sub, p as identity3, r as mod, t as add, x as rotationZ4, y as rotationX4 } from "../operators-d-PMVTo7.js";
import { $ as workgroupBarrier, $t as extractBits, A as textureSampleCompareLevel, An as sqrt, At as acos, B as fwidthCoarse, Bt as cosh, C as textureDimensions, Cn as reverseBits, Ct as pack4x8unorm, D as textureSampleBaseClampToEdge, Dn as sin, Dt as bitcastU32toI32, E as textureSample, En as sign, Et as bitcastU32toF32, F as dpdxFine, Fn as trunc, Ft as atan2, G as atomicMax, Gt as degrees, H as atomicAdd, Ht as countOneBits, I as dpdy, It as atanh, J as atomicStore, Jt as dot, K as atomicMin, Kt as determinant, L as dpdyCoarse, Lt as ceil, M as textureStore, Mn as tan, Mt as asin, N as dpdx, Nn as tanh, Nt as asinh, O as textureSampleBias, On as sinh, Ot as arrayLength, P as dpdxCoarse, Pn as transpose, Pt as atan, Q as textureBarrier, Qt as exp2, R as dpdyFine, Rt as clamp, S as subgroupXor, Sn as refract, St as pack2x16float, T as textureLoad, Tn as saturate, Tt as unpack4x8unorm, U as atomicAnd, Ut as countTrailingZeros, V as fwidthFine, Vt as countLeadingZeros, W as atomicLoad, Wt as cross, X as atomicXor, Xt as dot4U8Packed, Y as atomicSub, Yt as dot4I8Packed, Z as storageBarrier, Zt as exp, _ as subgroupOr, _n as normalize, _t as not, a as subgroupAny, an as fract, at as discard, b as subgroupShuffleUp, bn as radians, c as subgroupBroadcastFirst, cn as inverseSqrt, ct as and, d as subgroupExclusiveMul, dn as log, dt as ge, en as faceForward, et as rotateX4, f as subgroupInclusiveAdd, fn as log2, ft as gt, g as subgroupMul, gn as modf, gt as ne, h as subgroupMin, hn as mix, ht as lt, i as subgroupAnd, in as fma, it as translate4, j as textureSampleLevel, jn as step, jt as acosh, k as textureSampleCompare, kn as smoothstep, kt as abs, l as subgroupElect, ln as ldexp, lt as any, m as subgroupMax, mn as min, mt as le, n as subgroupAdd, nn as firstTrailingBit, nt as rotateZ4, o as subgroupBallot, on as frexp, ot as all, p as subgroupInclusiveMul, pn as max, pt as isCloseTo, q as atomicOr, qt as distance, r as subgroupAll, rn as floor, rt as scale4, s as subgroupBroadcast, sn as insertBits, st as allEq, t as extensionEnabled, tn as firstLeadingBit, tt as rotateY4, u as subgroupExclusiveAdd, un as length, ut as eq, v as subgroupShuffle, vn as pow, vt as or, w as textureGather, wn as round, wt as unpack2x16float, x as subgroupShuffleXor, xn as reflect, y as subgroupShuffleDown, yn as quantizeToF16, yt as select, z as fwidth, zt as cos } from "../extensions-DIVuAfBM.js";

@@ -5,0 +5,0 @@ //#region src/std/index.ts

import { An as isAlignAttrib, At as stitch, B as vec2h, Bn as isNaturallyEphemeral, Cn as isDisarray, Dn as undecorate, En as isUnstruct, G as vec3h, H as vec2u, Hn as isSizeAttrib, J as vec4b, Jn as isWgslData, K as vec3i, Kn as isVoid, L as isValidProp, Ln as isMat, M as INTERNAL_createStruct, Mn as isBuiltinAttrib, Nn as isDecorated, O as coerceToSnippet, Q as vec4u, R as vec2b, Sn as isData, Tn as isLooseDecorated, U as vec3b, Un as isVec, V as vec2i, Vn as isPtr, W as vec3f, Wt as isKnownAtComptime, X as vec4h, Y as vec4f, Yn as isWgslStruct, Z as vec4i, _n as MatrixColumnsAccess, _t as schemaCallWrapperGPU, at as i32, bn as getCustomLocation, bt as derefSnippet, cr as $internal, dn as isEphemeralSnippet, er as getName, fr as $resolve, gn as InfixDispatch, gt as schemaCallWrapper, ht as safeStringify, i as mul, ir as $cast, it as f32, mn as snip, n as div, nt as bool, o as sub, or as $gpuCallable, pr as isMarkedInternal, q as vec3u, qn as isWgslArray, r as mod, rr as setName, rt as f16, st as u32, t as add, tt as abstractInt, vn as UnknownData, w as comptime, wn as isLooseData, xn as getCustomSize, yn as getCustomAlignment, z as vec2f } from "./operators-HTxa_0k9.js";
//#region src/data/vertexFormatData.ts
var TgpuVertexFormatDataImpl = class {
[$internal] = {};
[$gpuCallable];
constructor(type) {
this.type = type;
this[$gpuCallable] = { call: (ctx, [v]) => {
return schemaCallWrapperGPU(ctx, formatToWGSLType[this.type], v);
} };
}
[$cast](v) {
return schemaCallWrapper(formatToWGSLType[this.type], v);
}
};
const formatToWGSLType = {
uint8: u32,
uint8x2: vec2u,
uint8x4: vec4u,
sint8: i32,
sint8x2: vec2i,
sint8x4: vec4i,
unorm8: f32,
unorm8x2: vec2f,
unorm8x4: vec4f,
snorm8: f32,
snorm8x2: vec2f,
snorm8x4: vec4f,
uint16: u32,
uint16x2: vec2u,
uint16x4: vec4u,
sint16: i32,
sint16x2: vec2i,
sint16x4: vec4i,
unorm16: f32,
unorm16x2: vec2f,
unorm16x4: vec4f,
snorm16: f32,
snorm16x2: vec2f,
snorm16x4: vec4f,
float16: f32,
float16x2: vec2f,
float16x4: vec4f,
float32: f32,
float32x2: vec2f,
float32x3: vec3f,
float32x4: vec4f,
uint32: u32,
uint32x2: vec2u,
uint32x3: vec3u,
uint32x4: vec4u,
sint32: i32,
sint32x2: vec2i,
sint32x3: vec3i,
sint32x4: vec4i,
"unorm10-10-10-2": vec4f,
"unorm8x4-bgra": vec4f
};
const packedFormats = new Set(Object.keys(formatToWGSLType));
const uint8 = new TgpuVertexFormatDataImpl("uint8");
const uint8x2 = new TgpuVertexFormatDataImpl("uint8x2");
const uint8x4 = new TgpuVertexFormatDataImpl("uint8x4");
const sint8 = new TgpuVertexFormatDataImpl("sint8");
const sint8x2 = new TgpuVertexFormatDataImpl("sint8x2");
const sint8x4 = new TgpuVertexFormatDataImpl("sint8x4");
const unorm8 = new TgpuVertexFormatDataImpl("unorm8");
const unorm8x2 = new TgpuVertexFormatDataImpl("unorm8x2");
const unorm8x4 = new TgpuVertexFormatDataImpl("unorm8x4");
const snorm8 = new TgpuVertexFormatDataImpl("snorm8");
const snorm8x2 = new TgpuVertexFormatDataImpl("snorm8x2");
const snorm8x4 = new TgpuVertexFormatDataImpl("snorm8x4");
const uint16 = new TgpuVertexFormatDataImpl("uint16");
const uint16x2 = new TgpuVertexFormatDataImpl("uint16x2");
const uint16x4 = new TgpuVertexFormatDataImpl("uint16x4");
const sint16 = new TgpuVertexFormatDataImpl("sint16");
const sint16x2 = new TgpuVertexFormatDataImpl("sint16x2");
const sint16x4 = new TgpuVertexFormatDataImpl("sint16x4");
const unorm16 = new TgpuVertexFormatDataImpl("unorm16");
const unorm16x2 = new TgpuVertexFormatDataImpl("unorm16x2");
const unorm16x4 = new TgpuVertexFormatDataImpl("unorm16x4");
const snorm16 = new TgpuVertexFormatDataImpl("snorm16");
const snorm16x2 = new TgpuVertexFormatDataImpl("snorm16x2");
const snorm16x4 = new TgpuVertexFormatDataImpl("snorm16x4");
const float16 = new TgpuVertexFormatDataImpl("float16");
const float16x2 = new TgpuVertexFormatDataImpl("float16x2");
const float16x4 = new TgpuVertexFormatDataImpl("float16x4");
const float32 = new TgpuVertexFormatDataImpl("float32");
const float32x2 = new TgpuVertexFormatDataImpl("float32x2");
const float32x3 = new TgpuVertexFormatDataImpl("float32x3");
const float32x4 = new TgpuVertexFormatDataImpl("float32x4");
const uint32 = new TgpuVertexFormatDataImpl("uint32");
const uint32x2 = new TgpuVertexFormatDataImpl("uint32x2");
const uint32x3 = new TgpuVertexFormatDataImpl("uint32x3");
const uint32x4 = new TgpuVertexFormatDataImpl("uint32x4");
const sint32 = new TgpuVertexFormatDataImpl("sint32");
const sint32x2 = new TgpuVertexFormatDataImpl("sint32x2");
const sint32x3 = new TgpuVertexFormatDataImpl("sint32x3");
const sint32x4 = new TgpuVertexFormatDataImpl("sint32x4");
const unorm10_10_10_2 = new TgpuVertexFormatDataImpl("unorm10-10-10-2");
const unorm8x4_bgra = new TgpuVertexFormatDataImpl("unorm8x4-bgra");
function isPackedData(value) {
return isMarkedInternal(value) && packedFormats.has(value?.type);
}
//#endregion
//#region src/data/alignmentOf.ts
const knownAlignmentMap = {
f32: 4,
f16: 2,
i32: 4,
u32: 4,
bool: 4,
u16: 2,
vec2f: 8,
vec2h: 4,
vec2i: 8,
vec2u: 8,
"vec2<bool>": 8,
vec3f: 16,
vec3h: 8,
vec3i: 16,
vec3u: 16,
"vec3<bool>": 16,
vec4f: 16,
vec4h: 8,
vec4i: 16,
vec4u: 16,
"vec4<bool>": 16,
mat2x2f: 8,
mat3x3f: 16,
mat4x4f: 16,
atomic: 4
};
function computeAlignment(data) {
const dataType = data?.type;
const knownAlignment = knownAlignmentMap[dataType];
if (knownAlignment !== void 0) return knownAlignment;
if (isWgslStruct(data)) return Object.values(data.propTypes).map(alignmentOf).reduce((a, b) => a > b ? a : b);
if (isWgslArray(data)) return alignmentOf(data.elementType);
if (isUnstruct(data)) {
const firstProp = Object.values(data.propTypes)[0];
return firstProp ? getCustomAlignment(firstProp) ?? 1 : 1;
}
if (isDisarray(data)) return getCustomAlignment(data.elementType) ?? 1;
if (isDecorated(data) || isLooseDecorated(data)) return getCustomAlignment(data) ?? alignmentOf(data.inner);
if (packedFormats.has(dataType)) return 1;
throw new Error(`Cannot determine alignment of data: ${safeStringify(data)}`);
}
function computeCustomAlignment(data) {
if (isUnstruct(data)) {
const firstProp = Object.values(data.propTypes)[0];
return firstProp ? customAlignmentOf(firstProp) : 1;
}
if (isDisarray(data)) return customAlignmentOf(data.elementType);
if (isLooseDecorated(data)) return getCustomAlignment(data) ?? customAlignmentOf(data.inner);
return getCustomAlignment(data) ?? 1;
}
/**
* Since alignments can be inferred from data types, they are not stored on them.
* Instead, this weak map acts as an extended property of those data types.
*/
const cachedAlignments = /* @__PURE__ */ new WeakMap();
const cachedCustomAlignments = /* @__PURE__ */ new WeakMap();
function alignmentOf(data) {
let alignment = cachedAlignments.get(data);
if (alignment === void 0) {
alignment = computeAlignment(data);
cachedAlignments.set(data, alignment);
}
return alignment;
}
function customAlignmentOf(data) {
let alignment = cachedCustomAlignments.get(data);
if (alignment === void 0) {
alignment = computeCustomAlignment(data);
cachedCustomAlignments.set(data, alignment);
}
return alignment;
}
/**
* Returns the alignment (in bytes) of data represented by the `schema`.
*/
function PUBLIC_alignmentOf(schema) {
return alignmentOf(schema);
}
//#endregion
//#region src/mathUtils.ts
/**
* @param value
* @param modulo has to be power of 2
*/
const roundUp = (value, modulo) => {
const bitMask = modulo - 1;
const invBitMask = ~bitMask;
return (value & bitMask) === 0 ? value : (value & invBitMask) + modulo;
};
//#endregion
//#region src/data/schemaMemoryLayout.ts
const knownSizesMap = {
bool: 4,
f32: 4,
f16: 2,
i32: 4,
u32: 4,
u16: 2,
vec2f: 8,
vec2h: 4,
vec2i: 8,
vec2u: 8,
"vec2<bool>": 8,
vec3f: 12,
vec3h: 6,
vec3i: 12,
vec3u: 12,
"vec3<bool>": 12,
vec4f: 16,
vec4h: 8,
vec4i: 16,
vec4u: 16,
"vec4<bool>": 16,
mat2x2f: 16,
mat3x3f: 48,
mat4x4f: 64,
uint8: 1,
uint8x2: 2,
uint8x4: 4,
sint8: 1,
sint8x2: 2,
sint8x4: 4,
unorm8: 1,
unorm8x2: 2,
unorm8x4: 4,
snorm8: 1,
snorm8x2: 2,
snorm8x4: 4,
uint16: 2,
uint16x2: 4,
uint16x4: 8,
sint16: 2,
sint16x2: 4,
sint16x4: 8,
unorm16: 2,
unorm16x2: 4,
unorm16x4: 8,
snorm16: 2,
snorm16x2: 4,
snorm16x4: 8,
float16: 2,
float16x2: 4,
float16x4: 8,
float32: 4,
float32x2: 8,
float32x3: 12,
float32x4: 16,
uint32: 4,
uint32x2: 8,
uint32x3: 12,
uint32x4: 16,
sint32: 4,
sint32x2: 8,
sint32x3: 12,
sint32x4: 16,
"unorm10-10-10-2": 4,
"unorm8x4-bgra": 4,
atomic: 4
};
function computeMLOfStruct(struct) {
let size = 0;
let longestContiguousPrefix = 0;
let isContiguous = true;
let prefixEnd = false;
for (const property of Object.values(struct.propTypes)) {
if (Number.isNaN(size)) throw new Error("Only the last property of a struct can be unbounded");
const prevSize = size;
size = roundUp(size, alignmentOf(property));
const hasPadding = prevSize !== size;
const propLayout = computeMemoryLayout(property);
size += propLayout.size;
if (Number.isNaN(size) && property.type !== "array") throw new Error("Cannot nest unbounded struct within another struct");
if (prefixEnd) continue;
if (!hasPadding && propLayout.isContiguous) longestContiguousPrefix += propLayout.size;
else {
prefixEnd = true;
isContiguous = false;
if (!hasPadding) longestContiguousPrefix += propLayout.longestContiguousPrefix;
}
}
const trueSize = roundUp(size, alignmentOf(struct));
return {
isContiguous: size === trueSize && isContiguous,
size: trueSize,
longestContiguousPrefix
};
}
function computeMLOfUnstruct(data) {
let size = 0;
let longestContiguousPrefix = 0;
let isContiguous = true;
let prefixEnd = false;
for (const property of Object.values(data.propTypes)) {
const alignment = customAlignmentOf(property);
const prevSize = size;
size = roundUp(size, alignment);
const hasPadding = prevSize !== size;
if (hasPadding) isContiguous = false;
const propLayout = computeMemoryLayout(property);
size += propLayout.size;
if (prefixEnd) continue;
if (!hasPadding && propLayout.isContiguous) longestContiguousPrefix += propLayout.size;
else {
prefixEnd = true;
isContiguous = false;
if (!hasPadding) longestContiguousPrefix += propLayout.longestContiguousPrefix;
}
}
return {
isContiguous,
size,
longestContiguousPrefix
};
}
function computeMLOfWgslArray(data) {
const elementType = data.elementType;
const elementMemoryLayout = computeMemoryLayout(elementType);
const elementSize = elementMemoryLayout.size;
const stride = roundUp(elementSize, alignmentOf(elementType));
const isContiguous = !(stride > elementSize) && elementMemoryLayout.isContiguous;
const size = data.elementCount === 0 ? NaN : data.elementCount * stride;
let longestContiguousPrefix;
if (isContiguous) longestContiguousPrefix = size;
else longestContiguousPrefix = elementMemoryLayout.longestContiguousPrefix;
return {
size,
isContiguous,
longestContiguousPrefix
};
}
function computeMLOfDisarray(data) {
const elementType = data.elementType;
const elementMemoryLayout = computeMemoryLayout(elementType);
const elementSize = elementMemoryLayout.size;
const stride = roundUp(elementSize, customAlignmentOf(elementType));
const isContiguous = !(stride > elementSize) && elementMemoryLayout.isContiguous;
const size = data.elementCount * stride;
let longestContiguousPrefix;
if (isContiguous) longestContiguousPrefix = size;
else longestContiguousPrefix = elementMemoryLayout.longestContiguousPrefix;
return {
size,
isContiguous,
longestContiguousPrefix
};
}
function computeMemoryLayout(data) {
const knownSize = knownSizesMap[data.type];
if (knownSize !== void 0) return {
isContiguous: data.type !== "mat3x3f",
size: knownSize,
longestContiguousPrefix: data.type === "mat3x3f" ? 12 : knownSize
};
if (isWgslStruct(data)) return computeMLOfStruct(data);
if (isUnstruct(data)) return computeMLOfUnstruct(data);
if (isWgslArray(data)) return computeMLOfWgslArray(data);
if (isDisarray(data)) return computeMLOfDisarray(data);
if (isDecorated(data) || isLooseDecorated(data)) {
const size = getCustomSize(data);
const undecoratedLayout = computeMemoryLayout(undecorate(data));
if (size) return {
isContiguous: size === undecoratedLayout.size && undecoratedLayout.isContiguous,
size,
longestContiguousPrefix: undecoratedLayout.longestContiguousPrefix
};
return computeMemoryLayout(data.inner);
}
throw new Error(`Cannot determine memory layout of data: ${data}`);
}
/**
* Since memory layout can be inferred from data types, they are not stored on them.
* Instead, this weak map acts as an extended property of those data types.
*/
const cachedLayouts = /* @__PURE__ */ new WeakMap();
function getLayoutInfo(schema, key) {
let layout = cachedLayouts.get(schema);
if (layout === void 0) {
layout = computeMemoryLayout(schema);
cachedLayouts.set(schema, layout);
}
return layout[key];
}
//#endregion
//#region src/data/sizeOf.ts
function sizeOf(schema) {
return getLayoutInfo(schema, "size");
}
/**
* Returns the size (in bytes) of data represented by the `schema`.
*/
function PUBLIC_sizeOf(schema) {
return sizeOf(schema);
}
//#endregion
//#region src/data/attributes.ts
function attribute(data, attrib) {
if (isDecorated(data)) return new DecoratedImpl(data.inner, [attrib, ...data.attribs]);
if (isLooseDecorated(data)) return new LooseDecoratedImpl(data.inner, [attrib, ...data.attribs]);
if (isLooseData(data)) return new LooseDecoratedImpl(data, [attrib]);
return new DecoratedImpl(data, [attrib]);
}
/**
* Gives the wrapped data-type a custom byte alignment. Useful in order to
* fulfill uniform alignment requirements.
*
* @example
* const Data = d.struct({
* a: u32, // takes up 4 bytes
* // 12 bytes of padding, because `b` is custom aligned to multiples of 16 bytes
* b: d.align(16, u32),
* });
*
* @param alignment The multiple of bytes this data should align itself to.
* @param data The data-type to align.
*/
function align(alignment, data) {
return attribute(data, {
[$internal]: true,
type: "@align",
params: [alignment]
});
}
/**
* Adds padding bytes after the wrapped data-type, until the whole value takes up `size` bytes.
*
* @example
* const Data = d.struct({
* a: d.size(16, u32), // takes up 16 bytes, instead of 4
* b: u32, // starts at byte 16, because `a` has a custom size
* });
*
* @param size The amount of bytes that should be reserved for this data-type.
* @param data The data-type to wrap.
*/
function size(size, data) {
return attribute(data, {
[$internal]: true,
type: "@size",
params: [size]
});
}
/**
* Assigns an explicit numeric location to a struct member or a parameter that has this type.
*
* @example
* const VertexOutput = {
* a: d.u32, // has implicit location 0
* b: d.location(5, d.u32),
* c: d.u32, // has implicit location 6
* };
*
* @param location The explicit numeric location.
* @param data The data-type to wrap.
*/
function location(location, data) {
return attribute(data, {
[$internal]: true,
type: "@location",
params: [location]
});
}
function interpolate(interpolationType, data) {
return attribute(data, {
[$internal]: true,
type: "@interpolate",
params: [interpolationType]
});
}
/**
* Marks a position built-in output value as invariant in vertex shaders.
* If the data and control flow match for two position outputs in different
* entry points, then the result values are guaranteed to be the same.
*
* Must only be applied to the position built-in value.
*
* @example
* const VertexOutput = {
* pos: d.invariant(d.builtin.position),
* };
*
* @param data The position built-in data-type to mark as invariant.
*/
function invariant(data) {
if (!isBuiltin(data)) throw new Error("The @invariant attribute must only be applied to the position built-in value.");
const builtinAttrib = isDecorated(data) || isLooseDecorated(data) ? data.attribs.find(isBuiltinAttrib) : void 0;
if (!builtinAttrib || builtinAttrib.params[0] !== "position") throw new Error("The @invariant attribute must only be applied to the position built-in value.");
return attribute(data, {
[$internal]: true,
type: "@invariant",
params: []
});
}
function isBuiltin(value) {
return (isDecorated(value) || isLooseDecorated(value)) && value.attribs.find(isBuiltinAttrib) !== void 0;
}
function getAttributesString(field) {
if (!isDecorated(field) && !isLooseDecorated(field)) return "";
return field.attribs.map((attrib) => {
if (attrib.params.length === 0) return `${attrib.type} `;
return `${attrib.type}(${attrib.params.join(", ")}) `;
}).join("");
}
var BaseDecoratedImpl = class {
[$internal] = {};
constructor(inner, attribs) {
this.inner = inner;
this.attribs = attribs;
const alignAttrib = attribs.find(isAlignAttrib)?.params[0];
const sizeAttrib = attribs.find(isSizeAttrib)?.params[0];
if (alignAttrib !== void 0) {
if (alignAttrib <= 0) throw new Error(`Custom data alignment must be a positive number, got: ${alignAttrib}.`);
if (Math.log2(alignAttrib) % 1 !== 0) throw new Error(`Alignment has to be a power of 2, got: ${alignAttrib}.`);
if (isWgslData(this.inner)) {
if (alignAttrib % alignmentOf(this.inner) !== 0) throw new Error(`Custom alignment has to be a multiple of the standard data alignment. Got: ${alignAttrib}, expected multiple of: ${alignmentOf(this.inner)}.`);
}
}
if (sizeAttrib !== void 0) {
if (sizeAttrib < sizeOf(this.inner)) throw new Error(`Custom data size cannot be smaller then the standard data size. Got: ${sizeAttrib}, expected at least: ${sizeOf(this.inner)}.`);
if (sizeAttrib <= 0) throw new Error(`Custom data size must be a positive number. Got: ${sizeAttrib}.`);
}
}
};
var DecoratedImpl = class extends BaseDecoratedImpl {
[$internal] = {};
type = "decorated";
};
var LooseDecoratedImpl = class extends BaseDecoratedImpl {
[$internal] = {};
type = "loose-decorated";
};
//#endregion
//#region src/core/function/ioSchema.ts
function withLocations(members, locations = {}) {
let nextLocation = 0;
const usedCustomLocations = /* @__PURE__ */ new Set();
return Object.fromEntries(Object.entries(members ?? {}).map(([key, member]) => {
const customLocation = getCustomLocation(member);
if (customLocation !== void 0) {
if (usedCustomLocations.has(customLocation)) throw new Error("Duplicate custom location attributes found");
usedCustomLocations.add(customLocation);
}
return [key, member];
}).map(([key, member]) => {
if (isBuiltin(member)) return [key, member];
if (getCustomLocation(member) !== void 0) return [key, member];
if (locations[key]) return [key, location(locations[key], member)];
while (usedCustomLocations.has(nextLocation)) nextLocation++;
return [key, location(nextLocation++, member)];
}));
}
function createIoSchema(layout, locations = {}) {
return isData(layout) ? isVoid(layout) ? layout : isBuiltin(layout) ? layout : getCustomLocation(layout) !== void 0 ? layout : location(0, layout) : INTERNAL_createStruct(withLocations(layout, locations), false);
}
//#endregion
//#region src/data/autoStruct.ts
/**
* A requirement for the generated struct is that non-builtin properties need to
* have the same name in WGSL as they do in JS. This allows locations to be properly
* matched between the Vertex output and Fragment input.
*/
var AutoStruct = class {
/**
* js key -> data type
*/
#validProps;
/**
* js key -> { prop: 'wgsl key', type: ... }
* @example '$position' -> { prop: 'position', type: ... }
*/
#allocated;
#usedWgslKeys;
#locations;
#cachedStruct;
#typeForExtraProps;
constructor(validProps, typeForExtraProps, locations) {
this.#validProps = validProps;
this.#typeForExtraProps = typeForExtraProps;
this.#allocated = {};
this.#locations = locations;
this.#usedWgslKeys = /* @__PURE__ */ new Set();
}
/**
* Used for accessing builtins, varying and attributes in code.
*/
accessProp(key) {
const dataType = this.#validProps[key] ?? this.#typeForExtraProps;
if (!dataType) return;
return this.provideProp(key, dataType);
}
/**
* Used for providing new varyings.
*
* @privateRemarks
* Internally used by `accessProp`.
*/
provideProp(key, dataType) {
let alloc = this.#allocated[key];
if (!alloc) {
const wgslKey = key.replaceAll("$", "");
if (this.#usedWgslKeys.has(wgslKey)) throw new Error(`Property name '${wgslKey}' causes naming clashes. Choose a different name.`);
if (!isValidProp(wgslKey)) throw new Error(`Property key '${key}' is a reserved WGSL word. Choose a different name.`);
this.#usedWgslKeys.add(wgslKey);
alloc = {
prop: wgslKey,
type: dataType
};
this.#allocated[key] = alloc;
}
return alloc;
}
get completeStruct() {
if (!this.#cachedStruct) {
this.#cachedStruct = createIoSchema(Object.fromEntries(Object.values(this.#allocated).map((alloc) => {
return [alloc.prop, alloc.type];
})), this.#locations);
const ownName = getName(this);
if (ownName) setName(this.#cachedStruct, ownName);
}
return this.#cachedStruct;
}
[$resolve](ctx) {
return ctx.resolve(this.completeStruct);
}
toString() {
return `auto-struct:${getName(this) ?? "<unnamed>"}`;
}
};
AutoStruct.prototype[$internal] = {};
AutoStruct.prototype.type = "auto-struct";
//#endregion
//#region src/tgsl/accessProp.ts
const infixKinds = [
"vec2f",
"vec3f",
"vec4f",
"vec2h",
"vec3h",
"vec4h",
"vec2i",
"vec3i",
"vec4i",
"vec2u",
"vec3u",
"vec4u",
"mat2x2f",
"mat3x3f",
"mat4x4f"
];
const infixOperators = {
add,
sub,
mul,
div,
mod
};
const swizzleLenToType = {
f: {
1: f32,
2: vec2f,
3: vec3f,
4: vec4f
},
h: {
1: f16,
2: vec2h,
3: vec3h,
4: vec4h
},
i: {
1: i32,
2: vec2i,
3: vec3i,
4: vec4i
},
u: {
1: u32,
2: vec2u,
3: vec3u,
4: vec4u
},
b: {
1: bool,
2: vec2b,
3: vec3b,
4: vec4b
}
};
function accessProp(target, propName) {
if (infixKinds.includes(target.dataType.type) && propName in infixOperators) {
const operator = infixOperators[propName];
return snip(new InfixDispatch(propName, target, operator[$gpuCallable].call.bind(operator)), UnknownData, target.origin);
}
if (isWgslArray(target.dataType) && propName === "length") {
if (target.dataType.elementCount === 0) return snip(stitch`arrayLength(&${target})`, u32, "runtime");
return snip(target.dataType.elementCount, abstractInt, "constant");
}
if (isMat(target.dataType) && propName === "columns") return snip(new MatrixColumnsAccess(target), UnknownData, target.origin);
if (isWgslStruct(target.dataType) || isUnstruct(target.dataType)) {
let propType = target.dataType.propTypes[propName];
if (!propType) return;
propType = undecorate(propType);
return snip(stitch`${target}.${propName}`, propType, target.origin === "argument" ? "argument" : !isEphemeralSnippet(target) && !isNaturallyEphemeral(propType) ? target.origin : target.origin === "constant" || target.origin === "constant-tgpu-const-ref" ? "constant" : "runtime");
}
if (target.dataType instanceof AutoStruct) {
const result = target.dataType.accessProp(propName);
if (!result) return;
return snip(stitch`${target}.${result.prop}`, result.type, "argument");
}
if (isPtr(target.dataType)) {
const derefed = derefSnippet(target);
if (propName === "$") return derefed;
return accessProp(derefed, propName);
}
if (isVec(target.dataType)) {
if (propName === "kind") return snip(target.dataType.type, UnknownData, "constant");
}
const propLength = propName.length;
if (isVec(target.dataType) && propLength >= 1 && propLength <= 4) {
const isXYZW = /^[xyzw]+$/.test(propName);
const isRGBA = /^[rgba]+$/.test(propName);
if (!isXYZW && !isRGBA) return;
const swizzleType = swizzleLenToType[target.dataType.type.includes("bool") ? "b" : target.dataType.type[4]][propLength];
if (!swizzleType) return;
return snip(isKnownAtComptime(target) ? target.value[propName] : stitch`${target}.${propName}`, swizzleType, target.origin === "argument" && propLength === 1 ? "argument" : target.origin === "constant" || target.origin === "constant-tgpu-const-ref" ? "constant" : "runtime");
}
if (isKnownAtComptime(target) || target.dataType === UnknownData) return coerceToSnippet(target.value[propName]);
}
//#endregion
//#region src/data/array.ts
/**
* Creates an array schema that can be used to construct gpu buffers.
* Describes arrays with fixed-size length, storing elements of the same type.
*
* @example
* const LENGTH = 3;
* const array = d.arrayOf(d.u32, LENGTH);
*
* If `elementCount` is not specified, a partially applied function is returned.
* @example
* const array = d.arrayOf(d.vec3f);
* // ^? (n: number) => WgslArray<d.Vec3f>
*
* @param elementType The type of elements in the array.
* @param elementCount The number of elements in the array.
*/
const arrayOf = comptime(((elementType, elementCount) => {
if (elementCount === void 0) return comptime((count) => cpu_arrayOf(elementType, count));
return cpu_arrayOf(elementType, elementCount);
})).$name("arrayOf");
function cpu_arrayOf(elementType, elementCount) {
const arraySchema = (elements) => {
if (elements && elements.length !== elementCount) throw new Error(`Array schema of ${elementCount} elements of type ${elementType.type} called with ${elements.length} argument(s).`);
return Array.from({ length: elementCount }, (_, i) => schemaCallWrapper(elementType, elements?.[i]));
};
Object.setPrototypeOf(arraySchema, WgslArrayImpl);
if (Number.isNaN(sizeOf(elementType))) throw new Error("Cannot nest runtime sized arrays.");
arraySchema.elementType = elementType;
if (!Number.isInteger(elementCount) || elementCount < 0) throw new Error(`Cannot create array schema with invalid element count: ${elementCount}.`);
arraySchema.elementCount = elementCount;
return arraySchema;
}
const WgslArrayImpl = {
[$internal]: true,
type: "array",
toString() {
return `arrayOf(${this.elementType}, ${this.elementCount})`;
}
};
//#endregion
//#region src/builtin.ts
function defineBuiltin(dataType, value) {
return attribute(dataType, {
[$internal]: true,
type: "@builtin",
params: [value]
});
}
const builtin = {
vertexIndex: defineBuiltin(u32, "vertex_index"),
instanceIndex: defineBuiltin(u32, "instance_index"),
clipDistances: defineBuiltin(arrayOf(u32, 8), "clip_distances"),
position: defineBuiltin(vec4f, "position"),
frontFacing: defineBuiltin(bool, "front_facing"),
fragDepth: defineBuiltin(f32, "frag_depth"),
primitiveIndex: defineBuiltin(u32, "primitive_index"),
sampleIndex: defineBuiltin(u32, "sample_index"),
sampleMask: defineBuiltin(u32, "sample_mask"),
localInvocationId: defineBuiltin(vec3u, "local_invocation_id"),
localInvocationIndex: defineBuiltin(u32, "local_invocation_index"),
globalInvocationId: defineBuiltin(vec3u, "global_invocation_id"),
workgroupId: defineBuiltin(vec3u, "workgroup_id"),
numWorkgroups: defineBuiltin(vec3u, "num_workgroups"),
subgroupInvocationId: defineBuiltin(u32, "subgroup_invocation_id"),
subgroupSize: defineBuiltin(u32, "subgroup_size"),
subgroupId: defineBuiltin(u32, "subgroup_id"),
numSubgroups: defineBuiltin(u32, "num_subgroups")
};
//#endregion
export { uint32x4 as $, packedFormats as A, sint8x4 as B, float16x4 as C, float32x4 as D, float32x3 as E, sint32x2 as F, snorm8x2 as G, snorm16x2 as H, sint32x3 as I, uint16x2 as J, snorm8x4 as K, sint32x4 as L, sint16x2 as M, sint16x4 as N, formatToWGSLType as O, sint32 as P, uint32x3 as Q, sint8 as R, float16x2 as S, float32x2 as T, snorm16x4 as U, snorm16 as V, snorm8 as W, uint32 as X, uint16x4 as Y, uint32x2 as Z, roundUp as _, AutoStruct as a, unorm16x2 as at, customAlignmentOf as b, getAttributesString as c, unorm8x2 as ct, isBuiltin as d, uint8 as et, location as f, getLayoutInfo as g, sizeOf as h, infixOperators as i, unorm16 as it, sint16 as j, isPackedData as k, interpolate as l, unorm8x4 as lt, PUBLIC_sizeOf as m, arrayOf as n, uint8x4 as nt, createIoSchema as o, unorm16x4 as ot, size as p, uint16 as q, accessProp as r, unorm10_10_10_2 as rt, align as s, unorm8 as st, builtin as t, uint8x2 as tt, invariant as u, unorm8x4_bgra as ut, PUBLIC_alignmentOf as v, float32 as w, float16 as x, alignmentOf as y, sint8x2 as z };
//# sourceMappingURL=builtin-ClEnM-Ye.js.map

Sorry, the diff of this file is too big to display

import { Cn as isDisarray, Dn as undecorate, En as isUnstruct, Nn as isDecorated, Tn as isLooseDecorated, Un as isVec, Vn as isPtr, Yn as isWgslStruct, cr as $internal, dr as $repr, er as getName, gt as schemaCallWrapper, jn as isAtomic, qn as isWgslArray, rr as setName, w as comptime } from "./operators-HTxa_0k9.js";
import { _ as roundUp, b as customAlignmentOf, g as getLayoutInfo, h as sizeOf, y as alignmentOf } from "./builtin-ClEnM-Ye.js";
import { Measurer } from "typed-binary";
//#region src/data/sampler.ts
function sampler() {
return {
[$internal]: {},
type: "sampler",
[$repr]: void 0
};
}
function comparisonSampler() {
return {
[$internal]: {},
type: "sampler_comparison",
[$repr]: void 0
};
}
function isWgslSampler(value) {
return !!value[$internal] && value.type === "sampler";
}
function isWgslComparisonSampler(value) {
return !!value[$internal] && value.type === "sampler_comparison";
}
//#endregion
//#region src/data/alignIO.ts
/**
* @param io the IO to align
* @param baseAlignment must be power of 2
*/
function alignIO(io, baseAlignment) {
const currentPos = "size" in io ? io.size : io.currentByteOffset;
const bitMask = baseAlignment - 1;
const offset = currentPos & bitMask;
if ("skipBytes" in io) io.skipBytes(baseAlignment - offset & bitMask);
else io.add(baseAlignment - offset & bitMask);
}
//#endregion
//#region src/data/offsets.ts
const cachedOffsets = /* @__PURE__ */ new WeakMap();
function offsetsForProps(struct) {
const cached = cachedOffsets.get(struct);
if (cached) return cached;
const measurer = new Measurer();
const offsets = {};
let lastEntry;
for (const key in struct.propTypes) {
const prop = struct.propTypes[key];
if (prop === void 0) throw new Error(`Property ${key} is undefined in struct`);
const beforeAlignment = measurer.size;
alignIO(measurer, isUnstruct(struct) ? customAlignmentOf(prop) : alignmentOf(prop));
if (lastEntry) lastEntry.padding = measurer.size - beforeAlignment;
const propSize = sizeOf(prop);
offsets[key] = {
offset: measurer.size,
size: propSize
};
lastEntry = offsets[key];
measurer.add(propSize);
}
if (lastEntry) lastEntry.padding = roundUp(sizeOf(struct), alignmentOf(struct)) - measurer.size;
cachedOffsets.set(struct, offsets);
return offsets;
}
//#endregion
//#region src/data/atomic.ts
/**
* Marks a concrete integer scalar type schema (u32 or i32) as a WGSL atomic.
*
* @example
* const atomicU32 = d.atomic(d.u32);
* const atomicI32 = d.atomic(d.i32);
*
* @param data Underlying type schema.
*/
function atomic(data) {
return new AtomicImpl(data);
}
var AtomicImpl = class {
[$internal] = {};
type = "atomic";
constructor(inner) {
this.inner = inner;
}
};
//#endregion
//#region src/data/isContiguous.ts
function isContiguous(schema) {
return getLayoutInfo(schema, "isContiguous");
}
/**
* Returns `true` if data represented by the `schema` doesn't have padding.
*/
function PUBLIC_isContiguous(schema) {
return isContiguous(schema);
}
//#endregion
//#region src/data/getLongestContiguousPrefix.ts
function getLongestContiguousPrefix(schema) {
return getLayoutInfo(schema, "longestContiguousPrefix");
}
/**
* Returns the size (in bytes) of the longest contiguous memory prefix of data represented by the `schema`.
*/
function PUBLIC_getLongestContiguousPrefix(schema) {
return getLongestContiguousPrefix(schema);
}
//#endregion
//#region src/data/offsetUtils.ts
const OFFSET_MARKER = Symbol("indirectOffset");
const CONTIGUOUS_MARKER = Symbol("indirectContiguous");
function isOffsetProxy(value) {
return typeof value === "object" && value !== null && OFFSET_MARKER in value && CONTIGUOUS_MARKER in value;
}
function scalarNode(offset, contiguous) {
return {
[OFFSET_MARKER]: offset,
[CONTIGUOUS_MARKER]: contiguous
};
}
function getMarker(target, prop) {
if (prop === OFFSET_MARKER) return target[OFFSET_MARKER];
if (prop === CONTIGUOUS_MARKER) return target[CONTIGUOUS_MARKER];
}
function makeProxy(schema, baseOffset, contiguous = sizeOf(schema)) {
const unwrapped = undecorate(schema);
const vecComponentCount = isVec(unwrapped) ? unwrapped.componentCount : void 0;
if (vecComponentCount !== void 0) {
const componentSize = sizeOf(unwrapped.primitive);
return makeVecProxy(scalarNode(baseOffset, contiguous), componentSize, vecComponentCount);
}
if (isWgslStruct(unwrapped)) return makeStructProxy(unwrapped, scalarNode(baseOffset, contiguous));
if (isWgslArray(unwrapped)) return makeArrayProxy(unwrapped, scalarNode(baseOffset, contiguous));
return scalarNode(baseOffset, contiguous);
}
function createOffsetProxy(schema, baseOffset = 0) {
return makeProxy(schema, baseOffset, sizeOf(schema));
}
function makeVecProxy(target, componentSize, componentCount) {
const baseOffset = target[OFFSET_MARKER];
return new Proxy(target, { get(t, prop) {
const marker = getMarker(t, prop);
if (marker !== void 0) return marker;
const idx = prop === "x" || prop === "0" ? 0 : prop === "y" || prop === "1" ? 1 : prop === "z" || prop === "2" ? 2 : prop === "w" || prop === "3" ? 3 : -1;
if (idx < 0 || idx >= componentCount) return;
const byteOffset = idx * componentSize;
const contiguous = Math.max(0, t[CONTIGUOUS_MARKER] - byteOffset);
return scalarNode(baseOffset + byteOffset, contiguous);
} });
}
function makeArrayProxy(array, target) {
const elementType = array.elementType;
const elementSize = sizeOf(elementType);
const stride = roundUp(elementSize, alignmentOf(elementType));
const hasPadding = stride > elementSize;
return new Proxy(target, { get(t, prop) {
const marker = getMarker(t, prop);
if (marker !== void 0) return marker;
if (prop === "length") return array.elementCount;
if (typeof prop !== "string") return;
const index = Number(prop);
if (!Number.isInteger(index) || index < 0 || index >= array.elementCount) return;
const elementOffset = index * stride;
const remainingFromHere = !isContiguous(elementType) ? elementSize + getLongestContiguousPrefix(elementType) : Math.max(0, t[CONTIGUOUS_MARKER] - elementOffset);
const childContiguous = hasPadding ? Math.min(remainingFromHere, elementSize) : remainingFromHere;
return makeProxy(elementType, t[OFFSET_MARKER] + elementOffset, childContiguous);
} });
}
function makeStructProxy(struct, target) {
const offsets = offsetsForProps(struct);
const propTypes = struct.propTypes;
const propNames = Object.keys(propTypes);
const meta = /* @__PURE__ */ new Map();
let runStart = 0;
for (let i = 0; i < propNames.length; i++) {
const name = propNames[i];
if (!name) continue;
const type = propTypes[name];
if (!type) continue;
const info = offsets[name];
const padding = info.padding ?? 0;
const typeContiguous = isContiguous(type);
if (!(i === propNames.length - 1 || padding > 0 || !typeContiguous)) continue;
const runEnd = info.offset + (typeContiguous ? info.size : getLongestContiguousPrefix(type));
for (let j = runStart; j <= i; j++) {
const runName = propNames[j];
if (!runName) continue;
const runInfo = offsets[runName];
meta.set(runName, {
offset: runInfo.offset,
runEnd
});
}
runStart = i + 1;
}
return new Proxy(target, { get(t, prop) {
const marker = getMarker(t, prop);
if (marker !== void 0) return marker;
if (typeof prop !== "string") return;
const m = meta.get(prop);
if (!m) return;
const remainingFromHere = Math.max(0, t[CONTIGUOUS_MARKER] - m.offset);
const localLimit = Math.max(0, m.runEnd - m.offset);
const propSchema = propTypes[prop];
if (!propSchema) return;
return makeProxy(propSchema, t[OFFSET_MARKER] + m.offset, sizeOf(struct) === m.runEnd ? remainingFromHere : localLimit);
} });
}
function getRootContiguous(schema) {
const unwrapped = undecorate(schema);
if (isWgslStruct(unwrapped)) {
const offsets = offsetsForProps(unwrapped);
const propTypes = unwrapped.propTypes;
const propNames = Object.keys(propTypes);
for (let i = 0; i < propNames.length; i++) {
const name = propNames[i];
if (!name) continue;
const info = offsets[name];
const padding = info.padding ?? 0;
const runEnd = info.offset + info.size;
if (i === propNames.length - 1 || padding > 0) return runEnd;
}
return 0;
}
if (isWgslArray(unwrapped)) {
const elementType = unwrapped.elementType;
const elementSize = sizeOf(elementType);
const stride = roundUp(elementSize, alignmentOf(elementType));
const totalSize = sizeOf(schema);
if (!Number.isFinite(totalSize)) return elementSize;
return stride > elementSize ? elementSize : totalSize;
}
return sizeOf(schema);
}
/**
* A function that retrieves offset and information for a specific primitive within a data schema.
* Example usage:
* ```ts
* const Boid = d.struct({
* position: d.vec3f,
* velocity: d.vec3f,
* });
* const memLayout = d.memoryLayoutOf(Boid, (b) => b.velocity.y);
* console.log(memLayout.offset); // Byte offset of velocity.y within Boid (here 20 bytes)
* console.log(memLayout.contiguous); // Contiguous bytes available from that offset (here 8 bytes)
* ```
*
* @param schema - The data schema to analyze.
* @param accessor - Optional function that accesses a specific primitive within the schema. If omitted, uses the root offset (0).
* @returns An object containing the offset and contiguous byte information.
*/
function memoryLayoutOf(schema, accessor) {
if (!accessor) return {
offset: 0,
contiguous: getRootContiguous(schema)
};
const result = accessor(createOffsetProxy(schema));
if (isOffsetProxy(result)) return {
offset: result[OFFSET_MARKER],
contiguous: result[CONTIGUOUS_MARKER]
};
throw new Error("Invalid accessor result. Expected an offset proxy with markers.");
}
//#endregion
//#region src/data/disarray.ts
/**
* Creates an array schema that can be used to construct vertex buffers.
* Describes arrays with fixed-size length, storing elements of the same type.
*
* Elements in the schema are not aligned in respect to their `byteAlignment`,
* unless they are explicitly decorated with the custom align attribute
* via `d.align` function.
*
* @example
* const disarray = d.disarrayOf(d.vec3f, 3); // packed array of vec3f
*
* @example
* const disarray = d.disarrayOf(d.align(16, d.vec3f), 3);
*
* If `elementCount` is not specified, a partially applied function is returned.
* @example
* const disarray = d.disarrayOf(d.vec3f);
* // ^? (n: number) => Disarray<d.Vec3f>
*
* @param elementType The type of elements in the array.
* @param elementCount The number of elements in the array.
*/
const disarrayOf = comptime(((elementType, elementCount) => {
if (elementCount === void 0) return (count) => cpu_disarrayOf(elementType, count);
return cpu_disarrayOf(elementType, elementCount);
})).$name("disarrayOf");
function cpu_disarrayOf(elementType, elementCount) {
const disarraySchema = (elements) => {
if (elements && elements.length !== elementCount) throw new Error(`Disarray schema of ${elementCount} elements of type ${elementType.type} called with ${elements.length} argument(s).`);
return Array.from({ length: elementCount }, (_, i) => schemaCallWrapper(elementType, elements?.[i]));
};
Object.setPrototypeOf(disarraySchema, DisarrayImpl);
disarraySchema.elementType = elementType;
if (!Number.isInteger(elementCount) || elementCount < 0) throw new Error(`Cannot create disarray schema with invalid element count: ${elementCount}.`);
disarraySchema.elementCount = elementCount;
return disarraySchema;
}
const DisarrayImpl = {
[$internal]: true,
type: "disarray",
toString() {
return `disarrayOf(${this.elementType}, ${this.elementCount})`;
}
};
//#endregion
//#region src/data/unstruct.ts
/**
* Creates a loose struct schema that can be used to construct vertex buffers.
* Describes structs with members of both loose and non-loose types.
*
* The order of members matches the passed in properties object.
* Members are not aligned in respect to their `byteAlignment`,
* unless they are explicitly decorated with the custom align attribute
* via `d.align` function.
*
* @example
* const CircleStruct = d.unstruct({ radius: d.f32, pos: d.vec3f }); // packed struct with no padding
*
* @example
* const CircleStruct = d.unstruct({ radius: d.f32, pos: d.align(16, d.vec3f) });
*
* @param properties Record with `string` keys and `TgpuData` or `TgpuLooseData` values,
* each entry describing one struct member.
*/
function unstruct(properties) {
const unstructSchema = (instanceProps) => Object.fromEntries(Object.entries(properties).map(([key, schema]) => [key, schemaCallWrapper(schema, instanceProps?.[key])]));
Object.setPrototypeOf(unstructSchema, UnstructImpl);
unstructSchema.propTypes = properties;
return unstructSchema;
}
const UnstructImpl = {
[$internal]: true,
type: "unstruct",
$name(label) {
setName(this, label);
return this;
},
toString() {
return `unstruct:${getName(this) ?? "<unnamed>"}`;
}
};
//#endregion
//#region src/data/deepEqual.ts
/**
* Performs a deep comparison of two TypeGPU data schemas.
*
* @param a The first data schema to compare.
* @param b The second data schema to compare.
* @returns `true` if the schemas are deeply equal, `false` otherwise.
*
* @example
* ```ts
* import { vec3f, struct, deepEqual } from 'typegpu/data';
*
* const schema1 = struct({ a: vec3f });
* const schema2 = struct({ a: vec3f });
* const schema3 = struct({ b: vec3f });
*
* console.log(deepEqual(schema1, schema2)); // true
* console.log(deepEqual(schema1, schema3)); // false
* ```
*/
function deepEqual(a, b) {
if (a === b) return true;
if (a.type !== b.type) return false;
if (isWgslStruct(a) && isWgslStruct(b) || isUnstruct(a) && isUnstruct(b)) {
const aProps = a.propTypes;
const bProps = b.propTypes;
const aKeys = Object.keys(aProps);
const bKeys = Object.keys(bProps);
if (aKeys.length !== bKeys.length) return false;
for (let i = 0; i < aKeys.length; i++) {
const keyA = aKeys[i];
const keyB = bKeys[i];
if (keyA !== keyB || !keyA || !keyB || !deepEqual(aProps[keyA], bProps[keyB])) return false;
}
return true;
}
if (isWgslArray(a) && isWgslArray(b) || isDisarray(a) && isDisarray(b)) return a.elementCount === b.elementCount && deepEqual(a.elementType, b.elementType);
if (isPtr(a) && isPtr(b)) return a.addressSpace === b.addressSpace && a.access === b.access && deepEqual(a.inner, b.inner);
if (isAtomic(a) && isAtomic(b)) return deepEqual(a.inner, b.inner);
if (isDecorated(a) && isDecorated(b) || isLooseDecorated(a) && isLooseDecorated(b)) {
if (!deepEqual(a.inner, b.inner)) return false;
if (a.attribs.length !== b.attribs.length) return false;
const getAttrKey = (attr) => {
const anyAttr = attr;
return `${anyAttr.type}(${(anyAttr.params ?? []).join(",")})`;
};
const attrsA = a.attribs.map(getAttrKey);
const attrsB = b.attribs.map(getAttrKey);
for (let i = 0; i < attrsA.length; i++) if (attrsA[i] !== attrsB[i]) return false;
}
return true;
}
//#endregion
export { PUBLIC_getLongestContiguousPrefix as a, offsetsForProps as c, isWgslComparisonSampler as d, isWgslSampler as f, memoryLayoutOf as i, alignIO as l, unstruct as n, PUBLIC_isContiguous as o, sampler as p, disarrayOf as r, atomic as s, deepEqual as t, comparisonSampler as u };
//# sourceMappingURL=deepEqual-yZXvaV2C.js.map
{"version":3,"file":"deepEqual-yZXvaV2C.js","names":[],"sources":["../src/data/sampler.ts","../src/data/alignIO.ts","../src/data/offsets.ts","../src/data/atomic.ts","../src/data/isContiguous.ts","../src/data/getLongestContiguousPrefix.ts","../src/data/offsetUtils.ts","../src/data/disarray.ts","../src/data/unstruct.ts","../src/data/deepEqual.ts"],"sourcesContent":["import { $internal, $repr } from '../shared/symbols.ts';\nimport type { BaseData } from './wgslTypes.ts';\n\nexport interface WgslSamplerProps {\n addressModeU?: GPUAddressMode;\n addressModeV?: GPUAddressMode;\n /**\n * Specifies the address modes for the texture width, height, and depth\n * coordinates, respectively.\n */\n addressModeW?: GPUAddressMode;\n /**\n * Specifies the sampling behavior when the sample footprint is smaller than or equal to one\n * texel.\n */\n magFilter?: GPUFilterMode;\n /**\n * Specifies the sampling behavior when the sample footprint is larger than one texel.\n */\n minFilter?: GPUFilterMode;\n /**\n * Specifies behavior for sampling between mipmap levels.\n */\n mipmapFilter?: GPUMipmapFilterMode;\n lodMinClamp?: number;\n /**\n * Specifies the minimum and maximum levels of detail, respectively, used internally when\n * sampling a texture.\n */\n lodMaxClamp?: number;\n /**\n * Specifies the maximum anisotropy value clamp used by the sampler. Anisotropic filtering is\n * enabled when {@link GPUSamplerDescriptor.maxAnisotropy} is > 1 and the implementation supports it.\n * Anisotropic filtering improves the image quality of textures sampled at oblique viewing\n * angles. Higher {@link GPUSamplerDescriptor.maxAnisotropy} values indicate the maximum ratio of\n * anisotropy supported when filtering.\n *\n * Most implementations support {@link GPUSamplerDescriptor.maxAnisotropy} values in range\n * between 1 and 16, inclusive. The used value of {@link GPUSamplerDescriptor.maxAnisotropy}\n * will be clamped to the maximum value that the platform supports.\n * The precise filtering behavior is implementation-dependent.\n */\n maxAnisotropy?: number;\n}\n\nexport interface WgslComparisonSamplerProps {\n compare: GPUCompareFunction;\n addressModeU?: GPUAddressMode;\n addressModeV?: GPUAddressMode;\n /**\n * Specifies the address modes for the texture width, height, and depth\n * coordinates, respectively.\n */\n addressModeW?: GPUAddressMode;\n /**\n * Specifies the sampling behavior when the sample footprint is smaller than or equal to one\n * texel.\n */\n magFilter?: GPUFilterMode;\n /**\n * Specifies the sampling behavior when the sample footprint is larger than one texel.\n */\n minFilter?: GPUFilterMode;\n /**\n * Specifies behavior for sampling between mipmap levels.\n */\n mipmapFilter?: GPUMipmapFilterMode;\n lodMinClamp?: number;\n /**\n * Specifies the minimum and maximum levels of detail, respectively, used internally when\n * sampling a texture.\n */\n lodMaxClamp?: number;\n /**\n * Specifies the maximum anisotropy value clamp used by the sampler. Anisotropic filtering is\n * enabled when {@link GPUSamplerDescriptor.maxAnisotropy} is > 1 and the implementation supports it.\n * Anisotropic filtering improves the image quality of textures sampled at oblique viewing\n * angles. Higher {@link GPUSamplerDescriptor.maxAnisotropy} values indicate the maximum ratio of\n * anisotropy supported when filtering.\n *\n * Most implementations support {@link GPUSamplerDescriptor.maxAnisotropy} values in range\n * between 1 and 16, inclusive. The used value of {@link GPUSamplerDescriptor.maxAnisotropy}\n * will be clamped to the maximum value that the platform supports.\n * The precise filtering behavior is implementation-dependent.\n */\n maxAnisotropy?: number;\n}\n\nexport interface sampler {\n [$internal]: true;\n type: 'sampler';\n}\n\nexport function sampler(): WgslSampler {\n return {\n [$internal]: {},\n type: 'sampler',\n [$repr]: undefined as unknown as sampler,\n };\n}\n\nexport interface comparisonSampler {\n [$internal]: Record<string, never>;\n type: 'sampler_comparison';\n}\n\nexport function comparisonSampler(): WgslComparisonSampler {\n return {\n [$internal]: {},\n type: 'sampler_comparison',\n [$repr]: undefined as unknown as comparisonSampler,\n };\n}\n\nexport interface WgslSampler extends BaseData {\n readonly [$repr]: sampler;\n readonly type: 'sampler';\n}\n\nexport interface WgslComparisonSampler extends BaseData {\n readonly [$repr]: comparisonSampler;\n readonly type: 'sampler_comparison';\n}\n\nexport function isWgslSampler(value: unknown): value is WgslSampler {\n return (\n !!(value as WgslSampler)[$internal] &&\n (value as WgslSampler).type === 'sampler'\n );\n}\n\nexport function isWgslComparisonSampler(\n value: unknown,\n): value is WgslComparisonSampler {\n return (\n !!(value as WgslComparisonSampler)[$internal] &&\n (value as WgslComparisonSampler).type === 'sampler_comparison'\n );\n}\n","import type { IMeasurer, ISerialInput, ISerialOutput } from 'typed-binary';\n\n/**\n * @param io the IO to align\n * @param baseAlignment must be power of 2\n */\nfunction alignIO(\n io: ISerialInput | ISerialOutput | IMeasurer,\n baseAlignment: number,\n) {\n const currentPos = 'size' in io ? io.size : io.currentByteOffset;\n\n const bitMask = baseAlignment - 1;\n const offset = currentPos & bitMask;\n\n if ('skipBytes' in io) {\n io.skipBytes((baseAlignment - offset) & bitMask);\n } else {\n io.add((baseAlignment - offset) & bitMask);\n }\n}\n\nexport default alignIO;\n","import { Measurer } from 'typed-binary';\nimport { roundUp } from '../mathUtils.ts';\nimport alignIO from './alignIO.ts';\nimport { alignmentOf, customAlignmentOf } from './alignmentOf.ts';\nimport { isUnstruct, type Unstruct } from './dataTypes.ts';\nimport { sizeOf } from './sizeOf.ts';\nimport type { WgslStruct } from './wgslTypes.ts';\n\nexport interface OffsetInfo {\n offset: number;\n size: number;\n padding?: number | undefined;\n}\n\nconst cachedOffsets = new WeakMap<\n WgslStruct | Unstruct,\n Record<string, OffsetInfo>\n>();\n\nexport function offsetsForProps<T extends WgslStruct | Unstruct>(\n struct: T,\n): Record<keyof T['propTypes'], OffsetInfo> {\n type Key = keyof T['propTypes'];\n\n const cached = cachedOffsets.get(struct);\n if (cached) {\n return cached as Record<Key, OffsetInfo>;\n }\n\n const measurer = new Measurer();\n const offsets = {} as Record<Key, OffsetInfo>;\n let lastEntry: OffsetInfo | undefined;\n\n for (const key in struct.propTypes) {\n const prop = struct.propTypes[key];\n if (prop === undefined) {\n throw new Error(`Property ${key} is undefined in struct`);\n }\n\n const beforeAlignment = measurer.size;\n\n alignIO(\n measurer,\n isUnstruct(struct) ? customAlignmentOf(prop) : alignmentOf(prop),\n );\n\n if (lastEntry) {\n lastEntry.padding = measurer.size - beforeAlignment;\n }\n\n const propSize = sizeOf(prop);\n offsets[key as Key] = { offset: measurer.size, size: propSize };\n lastEntry = offsets[key];\n measurer.add(propSize);\n }\n\n if (lastEntry) {\n lastEntry.padding = roundUp(sizeOf(struct), alignmentOf(struct)) -\n measurer.size;\n }\n\n cachedOffsets.set(struct, offsets);\n return offsets;\n}\n","import type { Infer, MemIdentity } from '../shared/repr.ts';\nimport { $internal } from '../shared/symbols.ts';\nimport {\n $gpuRepr,\n $memIdent,\n $repr,\n $validStorageSchema,\n $validUniformSchema,\n $validVertexSchema,\n} from '../shared/symbols.ts';\nimport type { Atomic, atomicI32, atomicU32, I32, U32 } from './wgslTypes.ts';\n\n// ----------\n// Public API\n// ----------\n\n/**\n * Marks a concrete integer scalar type schema (u32 or i32) as a WGSL atomic.\n *\n * @example\n * const atomicU32 = d.atomic(d.u32);\n * const atomicI32 = d.atomic(d.i32);\n *\n * @param data Underlying type schema.\n */\nexport function atomic<TSchema extends U32 | I32>(\n data: TSchema,\n): Atomic<TSchema> {\n return new AtomicImpl(data);\n}\n\n// --------------\n// Implementation\n// --------------\n\nclass AtomicImpl<TSchema extends U32 | I32> implements Atomic<TSchema> {\n public readonly [$internal] = {};\n public readonly type = 'atomic';\n\n // Type-tokens, not available at runtime\n declare readonly [$repr]: Infer<TSchema>;\n declare readonly [$memIdent]: MemIdentity<TSchema>;\n declare readonly [$gpuRepr]: TSchema extends U32 ? atomicU32 : atomicI32;\n declare readonly [$validStorageSchema]: true;\n declare readonly [$validUniformSchema]: true;\n declare readonly [$validVertexSchema]: true;\n // ---\n\n constructor(public readonly inner: TSchema) {}\n}\n","import type { AnyData } from './dataTypes.ts';\nimport type { BaseData } from './wgslTypes.ts';\nimport { getLayoutInfo } from './schemaMemoryLayout.ts';\n\nexport function isContiguous(schema: BaseData): boolean {\n return getLayoutInfo(schema, 'isContiguous');\n}\n\n/**\n * Returns `true` if data represented by the `schema` doesn't have padding.\n */\nexport function PUBLIC_isContiguous(schema: AnyData): boolean {\n return isContiguous(schema);\n}\n","import type { AnyData } from './dataTypes.ts';\nimport type { BaseData } from './wgslTypes.ts';\nimport { getLayoutInfo } from './schemaMemoryLayout.ts';\n\nexport function getLongestContiguousPrefix(schema: BaseData): number {\n return getLayoutInfo(schema, 'longestContiguousPrefix');\n}\n\n/**\n * Returns the size (in bytes) of the longest contiguous memory prefix of data represented by the `schema`.\n */\nexport function PUBLIC_getLongestContiguousPrefix(schema: AnyData): number {\n return getLongestContiguousPrefix(schema);\n}\n","import { roundUp } from '../mathUtils.ts';\nimport { alignmentOf } from './alignmentOf.ts';\nimport {\n type OffsetInfo as PropOffsetInfo,\n offsetsForProps,\n} from './offsets.ts';\nimport { sizeOf } from './sizeOf.ts';\nimport { isContiguous } from './isContiguous.ts';\nimport { getLongestContiguousPrefix } from './getLongestContiguousPrefix.ts';\nimport type {\n AnyWgslData,\n BaseData,\n VecData,\n WgslArray,\n WgslStruct,\n} from './wgslTypes.ts';\nimport { isVec, isWgslArray, isWgslStruct } from './wgslTypes.ts';\nimport { undecorate } from './dataTypes.ts';\nimport type { Infer } from '../shared/repr.ts';\n\nconst OFFSET_MARKER = Symbol('indirectOffset');\nconst CONTIGUOUS_MARKER = Symbol('indirectContiguous');\n\ninterface OffsetProxy {\n [OFFSET_MARKER]: number;\n [CONTIGUOUS_MARKER]: number;\n}\n\nfunction isOffsetProxy(value: unknown): value is OffsetProxy {\n return (\n typeof value === 'object' &&\n value !== null &&\n OFFSET_MARKER in value &&\n CONTIGUOUS_MARKER in value\n );\n}\n\nfunction scalarNode(offset: number, contiguous: number): OffsetProxy {\n return { [OFFSET_MARKER]: offset, [CONTIGUOUS_MARKER]: contiguous };\n}\n\nfunction getMarker(target: OffsetProxy, prop: PropertyKey): number | undefined {\n if (prop === OFFSET_MARKER) {\n return target[OFFSET_MARKER];\n }\n if (prop === CONTIGUOUS_MARKER) {\n return target[CONTIGUOUS_MARKER];\n }\n return undefined;\n}\n\nfunction makeProxy(\n schema: AnyWgslData,\n baseOffset: number,\n contiguous = sizeOf(schema),\n): unknown {\n const unwrapped = undecorate(schema);\n\n const vecComponentCount = isVec(unwrapped)\n ? unwrapped.componentCount\n : undefined;\n\n if (vecComponentCount !== undefined) {\n const componentSize = sizeOf((unwrapped as VecData).primitive);\n return makeVecProxy(\n scalarNode(baseOffset, contiguous),\n componentSize,\n vecComponentCount,\n );\n }\n\n if (isWgslStruct(unwrapped)) {\n return makeStructProxy(unwrapped, scalarNode(baseOffset, contiguous));\n }\n\n if (isWgslArray(unwrapped)) {\n return makeArrayProxy(unwrapped, scalarNode(baseOffset, contiguous));\n }\n\n return scalarNode(baseOffset, contiguous);\n}\n\nexport function createOffsetProxy<T extends BaseData>(\n schema: T,\n baseOffset = 0,\n): unknown {\n return makeProxy(schema as AnyWgslData, baseOffset, sizeOf(schema));\n}\n\nfunction makeVecProxy(\n target: OffsetProxy,\n componentSize: number,\n componentCount: 2 | 3 | 4,\n): unknown {\n const baseOffset = target[OFFSET_MARKER];\n\n return new Proxy(target, {\n get(t, prop) {\n const marker = getMarker(t, prop);\n if (marker !== undefined) {\n return marker;\n }\n\n const idx = prop === 'x' || prop === '0'\n ? 0\n : prop === 'y' || prop === '1'\n ? 1\n : prop === 'z' || prop === '2'\n ? 2\n : prop === 'w' || prop === '3'\n ? 3\n : -1;\n\n if (idx < 0 || idx >= componentCount) {\n return undefined;\n }\n\n const byteOffset = idx * componentSize;\n const contiguous = Math.max(0, t[CONTIGUOUS_MARKER] - byteOffset);\n\n return scalarNode(baseOffset + byteOffset, contiguous);\n },\n });\n}\n\nfunction makeArrayProxy(array: WgslArray, target: OffsetProxy): unknown {\n const elementType = array.elementType as AnyWgslData;\n const elementSize = sizeOf(elementType);\n const stride = roundUp(elementSize, alignmentOf(elementType));\n const hasPadding = stride > elementSize;\n\n return new Proxy(target, {\n get(t, prop) {\n const marker = getMarker(t, prop);\n if (marker !== undefined) {\n return marker;\n }\n\n if (prop === 'length') {\n return array.elementCount;\n }\n\n if (typeof prop !== 'string') {\n return undefined;\n }\n\n const index = Number(prop);\n if (\n !Number.isInteger(index) ||\n index < 0 || index >= array.elementCount\n ) {\n return undefined;\n }\n\n const elementOffset = index * stride;\n const remainingFromHere = !isContiguous(elementType)\n ? elementSize + getLongestContiguousPrefix(elementType) // it is too much, but we correct it later\n : Math.max(\n 0,\n t[CONTIGUOUS_MARKER] - elementOffset,\n );\n\n const childContiguous = hasPadding\n ? Math.min(remainingFromHere, elementSize)\n : remainingFromHere;\n\n return makeProxy(\n elementType,\n t[OFFSET_MARKER] + elementOffset,\n childContiguous,\n );\n },\n });\n}\n\ntype StructFieldMeta = {\n offset: number;\n runEnd: number;\n};\n\nfunction makeStructProxy(struct: WgslStruct, target: OffsetProxy): unknown {\n const offsets = offsetsForProps(struct);\n const propTypes = struct.propTypes as Record<string, AnyWgslData>;\n const propNames = Object.keys(propTypes);\n\n const meta = new Map<string, StructFieldMeta>();\n\n let runStart = 0;\n for (let i = 0; i < propNames.length; i++) {\n const name = propNames[i];\n if (!name) {\n continue;\n }\n const type = propTypes[name];\n if (!type) {\n continue;\n }\n\n const info = offsets[name] as PropOffsetInfo;\n const padding = info.padding ?? 0;\n\n const typeContiguous = isContiguous(type);\n const isRunEnd = i === propNames.length - 1 || padding > 0 ||\n !typeContiguous;\n if (!isRunEnd) {\n continue;\n }\n\n const runEnd = info.offset +\n (typeContiguous ? info.size : getLongestContiguousPrefix(type));\n for (let j = runStart; j <= i; j++) {\n const runName = propNames[j];\n if (!runName) {\n continue;\n }\n const runInfo = offsets[runName] as PropOffsetInfo;\n meta.set(runName, { offset: runInfo.offset, runEnd });\n }\n runStart = i + 1;\n }\n\n return new Proxy(target, {\n get(t, prop) {\n const marker = getMarker(t, prop);\n if (marker !== undefined) {\n return marker;\n }\n\n if (typeof prop !== 'string') {\n return undefined;\n }\n\n const m = meta.get(prop);\n if (!m) {\n return undefined;\n }\n\n const remainingFromHere = Math.max(\n 0,\n t[CONTIGUOUS_MARKER] - m.offset,\n );\n const localLimit = Math.max(0, m.runEnd - m.offset);\n const propSchema = propTypes[prop];\n if (!propSchema) {\n return undefined;\n }\n\n return makeProxy(\n propSchema,\n t[OFFSET_MARKER] + m.offset,\n sizeOf(struct) === m.runEnd ? remainingFromHere : localLimit,\n );\n },\n });\n}\n\nfunction getRootContiguous(schema: AnyWgslData): number {\n const unwrapped = undecorate(schema);\n\n if (isWgslStruct(unwrapped)) {\n const offsets = offsetsForProps(unwrapped);\n const propTypes = unwrapped.propTypes as Record<string, AnyWgslData>;\n const propNames = Object.keys(propTypes);\n\n for (let i = 0; i < propNames.length; i++) {\n const name = propNames[i];\n if (!name) {\n continue;\n }\n const info = offsets[name] as PropOffsetInfo;\n const padding = info.padding ?? 0;\n\n const runEnd = info.offset + info.size;\n const isRunEnd = i === propNames.length - 1 || padding > 0;\n if (isRunEnd) {\n return runEnd;\n }\n }\n\n return 0;\n }\n\n if (isWgslArray(unwrapped)) {\n const elementType = unwrapped.elementType as AnyWgslData;\n const elementSize = sizeOf(elementType);\n const stride = roundUp(elementSize, alignmentOf(elementType));\n const totalSize = sizeOf(schema);\n if (!Number.isFinite(totalSize)) {\n return elementSize;\n }\n return stride > elementSize ? elementSize : totalSize;\n }\n\n return sizeOf(schema);\n}\n\n/**\n * Interface containing information about the offset and the available contiguous after a selected primitive.\n */\nexport interface PrimitiveOffsetInfo {\n /** The byte offset of the primitive within the buffer. */\n offset: number;\n /** The number of contiguous bytes available from the offset. */\n contiguous: number;\n}\n\n/**\n * A function that retrieves offset and information for a specific primitive within a data schema.\n * Example usage:\n * ```ts\n * const Boid = d.struct({\n * position: d.vec3f,\n * velocity: d.vec3f,\n * });\n * const memLayout = d.memoryLayoutOf(Boid, (b) => b.velocity.y);\n * console.log(memLayout.offset); // Byte offset of velocity.y within Boid (here 20 bytes)\n * console.log(memLayout.contiguous); // Contiguous bytes available from that offset (here 8 bytes)\n * ```\n *\n * @param schema - The data schema to analyze.\n * @param accessor - Optional function that accesses a specific primitive within the schema. If omitted, uses the root offset (0).\n * @returns An object containing the offset and contiguous byte information.\n */\nexport function memoryLayoutOf<T extends BaseData>(\n schema: T,\n accessor?: (proxy: Infer<T>) => number,\n): PrimitiveOffsetInfo {\n if (!accessor) {\n return {\n offset: 0,\n contiguous: getRootContiguous(schema as AnyWgslData),\n };\n }\n\n const proxy = createOffsetProxy(schema);\n const result = accessor(proxy as Infer<T>);\n\n if (isOffsetProxy(result)) {\n return {\n offset: result[OFFSET_MARKER],\n contiguous: result[CONTIGUOUS_MARKER],\n };\n }\n\n throw new Error(\n 'Invalid accessor result. Expected an offset proxy with markers.',\n );\n}\n","import { comptime } from '../core/function/comptime.ts';\nimport { $internal } from '../shared/symbols.ts';\nimport type { AnyData, Disarray } from './dataTypes.ts';\nimport { schemaCallWrapper } from './schemaCallWrapper.ts';\n\n// ----------\n// Public API\n// ----------\n\ninterface DisarrayConstructor {\n <TElement extends AnyData>(\n elementType: TElement,\n ): (elementCount: number) => Disarray<TElement>;\n\n <TElement extends AnyData>(\n elementType: TElement,\n elementCount: number,\n ): Disarray<TElement>;\n}\n\n/**\n * Creates an array schema that can be used to construct vertex buffers.\n * Describes arrays with fixed-size length, storing elements of the same type.\n *\n * Elements in the schema are not aligned in respect to their `byteAlignment`,\n * unless they are explicitly decorated with the custom align attribute\n * via `d.align` function.\n *\n * @example\n * const disarray = d.disarrayOf(d.vec3f, 3); // packed array of vec3f\n *\n * @example\n * const disarray = d.disarrayOf(d.align(16, d.vec3f), 3);\n *\n * If `elementCount` is not specified, a partially applied function is returned.\n * @example\n * const disarray = d.disarrayOf(d.vec3f);\n * // ^? (n: number) => Disarray<d.Vec3f>\n *\n * @param elementType The type of elements in the array.\n * @param elementCount The number of elements in the array.\n */\nexport const disarrayOf = comptime(\n ((elementType, elementCount) => {\n if (elementCount === undefined) {\n return (count: number) => cpu_disarrayOf(elementType, count);\n }\n return cpu_disarrayOf(elementType, elementCount);\n }) as DisarrayConstructor,\n).$name('disarrayOf');\n\nexport function cpu_disarrayOf<TElement extends AnyData>(\n elementType: TElement,\n elementCount: number,\n): Disarray<TElement> {\n // In the schema call, create and return a deep copy\n // by wrapping all the values in `elementType` schema calls.\n const disarraySchema = (elements?: TElement[]) => {\n if (elements && elements.length !== elementCount) {\n throw new Error(\n `Disarray schema of ${elementCount} elements of type ${elementType.type} called with ${elements.length} argument(s).`,\n );\n }\n\n return Array.from(\n { length: elementCount },\n (_, i) => schemaCallWrapper(elementType, elements?.[i]),\n );\n };\n Object.setPrototypeOf(disarraySchema, DisarrayImpl);\n\n disarraySchema.elementType = elementType;\n\n if (!Number.isInteger(elementCount) || elementCount < 0) {\n throw new Error(\n `Cannot create disarray schema with invalid element count: ${elementCount}.`,\n );\n }\n disarraySchema.elementCount = elementCount;\n\n return disarraySchema as unknown as Disarray<TElement>;\n}\n\n// --------------\n// Implementation\n// --------------\n\nconst DisarrayImpl = {\n [$internal]: true,\n type: 'disarray',\n\n toString(this: Disarray): string {\n return `disarrayOf(${this.elementType}, ${this.elementCount})`;\n },\n};\n","import { getName, setName } from '../shared/meta.ts';\nimport { $internal } from '../shared/symbols.ts';\nimport type { AnyData, Unstruct } from './dataTypes.ts';\nimport { schemaCallWrapper } from './schemaCallWrapper.ts';\n\n// ----------\n// Public API\n// ----------\n\n/**\n * Creates a loose struct schema that can be used to construct vertex buffers.\n * Describes structs with members of both loose and non-loose types.\n *\n * The order of members matches the passed in properties object.\n * Members are not aligned in respect to their `byteAlignment`,\n * unless they are explicitly decorated with the custom align attribute\n * via `d.align` function.\n *\n * @example\n * const CircleStruct = d.unstruct({ radius: d.f32, pos: d.vec3f }); // packed struct with no padding\n *\n * @example\n * const CircleStruct = d.unstruct({ radius: d.f32, pos: d.align(16, d.vec3f) });\n *\n * @param properties Record with `string` keys and `TgpuData` or `TgpuLooseData` values,\n * each entry describing one struct member.\n */\nexport function unstruct<TProps extends Record<string, AnyData>>(\n properties: TProps,\n): Unstruct<TProps> {\n // In the schema call, create and return a deep copy\n // by wrapping all the values in corresponding schema calls.\n const unstructSchema = (instanceProps?: TProps) =>\n Object.fromEntries(\n Object.entries(properties).map(([key, schema]) => [\n key,\n schemaCallWrapper(schema, instanceProps?.[key]),\n ]),\n );\n Object.setPrototypeOf(unstructSchema, UnstructImpl);\n unstructSchema.propTypes = properties;\n\n return unstructSchema as unknown as Unstruct<TProps>;\n}\n\n// --------------\n// Implementation\n// --------------\n\nconst UnstructImpl = {\n [$internal]: true,\n type: 'unstruct',\n\n $name(label: string) {\n setName(this, label);\n return this;\n },\n\n toString(): string {\n return `unstruct:${getName(this) ?? '<unnamed>'}`;\n },\n};\n","import type { AnyAttribute } from './attributes.ts';\nimport { isDisarray, isLooseDecorated, isUnstruct } from './dataTypes.ts';\nimport type { AnyData } from './dataTypes.ts';\nimport {\n isAtomic,\n isDecorated,\n isPtr,\n isWgslArray,\n isWgslStruct,\n} from './wgslTypes.ts';\n\n/**\n * Performs a deep comparison of two TypeGPU data schemas.\n *\n * @param a The first data schema to compare.\n * @param b The second data schema to compare.\n * @returns `true` if the schemas are deeply equal, `false` otherwise.\n *\n * @example\n * ```ts\n * import { vec3f, struct, deepEqual } from 'typegpu/data';\n *\n * const schema1 = struct({ a: vec3f });\n * const schema2 = struct({ a: vec3f });\n * const schema3 = struct({ b: vec3f });\n *\n * console.log(deepEqual(schema1, schema2)); // true\n * console.log(deepEqual(schema1, schema3)); // false\n * ```\n */\nexport function deepEqual(a: AnyData, b: AnyData): boolean {\n if (a === b) {\n return true;\n }\n\n if (a.type !== b.type) {\n return false;\n }\n\n if (\n (isWgslStruct(a) && isWgslStruct(b)) ||\n (isUnstruct(a) && isUnstruct(b))\n ) {\n const aProps = a.propTypes;\n const bProps = b.propTypes;\n const aKeys = Object.keys(aProps);\n const bKeys = Object.keys(bProps);\n\n if (aKeys.length !== bKeys.length) {\n return false;\n }\n\n for (let i = 0; i < aKeys.length; i++) {\n const keyA = aKeys[i];\n const keyB = bKeys[i];\n if (\n keyA !== keyB || !keyA || !keyB ||\n !deepEqual(aProps[keyA] as AnyData, bProps[keyB] as AnyData)\n ) {\n return false;\n }\n }\n return true;\n }\n\n if ((isWgslArray(a) && isWgslArray(b)) || (isDisarray(a) && isDisarray(b))) {\n return (\n a.elementCount === b.elementCount &&\n deepEqual(a.elementType as AnyData, b.elementType as AnyData)\n );\n }\n\n if (isPtr(a) && isPtr(b)) {\n return (\n a.addressSpace === b.addressSpace &&\n a.access === b.access &&\n deepEqual(a.inner as AnyData, b.inner as AnyData)\n );\n }\n\n if (isAtomic(a) && isAtomic(b)) {\n return deepEqual(a.inner, b.inner);\n }\n\n if (\n (isDecorated(a) && isDecorated(b)) ||\n (isLooseDecorated(a) && isLooseDecorated(b))\n ) {\n if (!deepEqual(a.inner as AnyData, b.inner as AnyData)) {\n return false;\n }\n if (a.attribs.length !== b.attribs.length) {\n return false;\n }\n\n // Create comparable string representations for each attribute\n const getAttrKey = (attr: unknown): string => {\n const anyAttr = attr as AnyAttribute;\n return `${anyAttr.type}(${(anyAttr.params ?? []).join(',')})`;\n };\n\n const attrsA = a.attribs.map(getAttrKey);\n const attrsB = b.attribs.map(getAttrKey);\n\n for (let i = 0; i < attrsA.length; i++) {\n if (attrsA[i] !== attrsB[i]) {\n return false;\n }\n }\n }\n\n // All other types have been checked for equality at the start\n return true;\n}\n"],"mappings":"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"}

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

import { $n as getMetaData, At as stitch, Bn as isNaturallyEphemeral, Cn as isDisarray, Dn as undecorate, Jn as isWgslData, Kt as isWgsl, Mt as getResolutionCtx, O as coerceToSnippet, Un as isVec, Vn as isPtr, Vt as getOwnSnippet, W as vec3f, Wt as isKnownAtComptime, Y as vec4f, Yn as isWgslStruct, _n as MatrixColumnsAccess, ar as $getNameForward, bt as derefSnippet, cr as $internal, dn as isEphemeralSnippet, er as getName, fr as $resolve, kn as Void, lr as $ownSnippet, mn as snip, nn as MissingLinksError, nr as isNamable, qn as isWgslArray, rr as setName, sr as $gpuValueOf, tr as hasTinyestMetadata, vn as UnknownData, wn as isLooseData, z as vec2f } from "./operators-HTxa_0k9.js";
import { c as getAttributesString, o as createIoSchema, r as accessProp, t as builtin } from "./builtin-ClEnM-Ye.js";
//#region src/getGPUValue.ts
function getGPUValue(object) {
return object?.[$gpuValueOf];
}
//#endregion
//#region src/tgsl/accessIndex.ts
const indexableTypeToResult = {
mat2x2f: vec2f,
mat3x3f: vec3f,
mat4x4f: vec4f
};
function accessIndex(target, indexArg) {
const index = typeof indexArg === "number" ? coerceToSnippet(indexArg) : indexArg;
if (isWgslArray(target.dataType) || isDisarray(target.dataType)) {
const elementType = target.dataType.elementType;
const isElementNatEph = isNaturallyEphemeral(elementType);
const isTargetEphemeral = isEphemeralSnippet(target);
const isIndexConstant = index.origin === "constant";
let origin;
if (target.origin === "constant-tgpu-const-ref") if (isIndexConstant) origin = isElementNatEph ? "constant" : "constant-tgpu-const-ref";
else origin = isElementNatEph ? "runtime" : "runtime-tgpu-const-ref";
else if (target.origin === "runtime-tgpu-const-ref") origin = isElementNatEph ? "runtime" : "runtime-tgpu-const-ref";
else if (!isTargetEphemeral && !isElementNatEph) origin = target.origin;
else if (isIndexConstant && target.origin === "constant") origin = "constant";
else origin = "runtime";
return snip(isKnownAtComptime(target) && isKnownAtComptime(index) ? target.value[index.value] : stitch`${target}[${index}]`, elementType, origin);
}
if (isVec(target.dataType)) return snip(isKnownAtComptime(target) && isKnownAtComptime(index) ? target.value[index.value] : stitch`${target}[${index}]`, target.dataType.primitive, target.origin === "constant" || target.origin === "constant-tgpu-const-ref" ? "constant" : "runtime");
if (isPtr(target.dataType)) return accessIndex(derefSnippet(target), index);
if (target.value instanceof MatrixColumnsAccess) {
const propType = indexableTypeToResult[target.value.matrix.dataType.type];
return snip(stitch`${target.value.matrix}[${index}]`, propType, target.origin);
}
if (target.dataType.type in indexableTypeToResult) throw new Error("The only way of accessing matrix elements in TypeGPU functions is through the 'columns' property.");
if (isKnownAtComptime(target) && isKnownAtComptime(index) || target.dataType === UnknownData) return coerceToSnippet(target.value[index.value]);
if (isWgslStruct(target.dataType) && isKnownAtComptime(index) && typeof index.value === "string") return accessProp(target, index.value);
}
//#endregion
//#region src/core/valueProxyUtils.ts
const valueProxyHandler = { get(target, prop) {
if (prop in target) return Reflect.get(target, prop);
if (prop === "toString" || prop === Symbol.toStringTag || prop === Symbol.toPrimitive) return () => target.toString();
if (typeof prop === "symbol") return;
const targetSnippet = getOwnSnippet(target);
const index = Number(prop);
if (!Number.isNaN(index)) {
const accessed = accessIndex(targetSnippet, index);
if (!accessed) return;
return new Proxy({
[$internal]: true,
[$resolve]: (ctx) => ctx.resolve(accessed.value, accessed.dataType),
[$ownSnippet]: accessed,
toString: () => `${String(target)}[${prop}]`
}, valueProxyHandler);
}
const accessed = accessProp(targetSnippet, String(prop));
if (!accessed) return;
return new Proxy({
[$internal]: true,
[$resolve]: (ctx) => ctx.resolve(accessed.value, accessed.dataType),
[$ownSnippet]: accessed,
toString: () => `${String(target)}.${prop}`
}, valueProxyHandler);
} };
function getGpuValueRecursively(value) {
let unwrapped = value;
while (true) {
const gpuValue = getGPUValue(unwrapped);
if (!gpuValue) break;
unwrapped = gpuValue;
}
return unwrapped;
}
//#endregion
//#region src/core/resolve/externals.ts
/**
* Merges two external maps into one. If a key is present in both maps, the value from the new map is used.
* If the external value is a namable object, it is given a name if it does not already have one.
* @param existing - The existing external map.
* @param newExternals - The new external map.
*/
function applyExternals(existing, newExternals) {
for (const [key, value] of Object.entries(newExternals)) {
existing[key] = value;
if (value && (typeof value === "object" || typeof value === "function") && getName(value) === void 0) setName(value, key);
}
}
function addArgTypesToExternals(implementation, argTypes, applyExternals) {
const argTypeNames = [...implementation.matchAll(/:\s*(?<arg>.*?)\s*[,)]/g)].map((found) => found ? found[1] : void 0);
applyExternals(Object.fromEntries(argTypes.flatMap((argType, i) => {
const argTypeName = argTypeNames ? argTypeNames[i] : void 0;
return isWgslStruct(argType) && argTypeName !== void 0 ? [[argTypeName, argType]] : [];
})));
}
function addReturnTypeToExternals(implementation, returnType, applyExternals) {
const matched = implementation.match(/->\s(?<output>[\w\d_]+)\s{/);
const outputName = matched ? matched[1]?.trim() : void 0;
if (isWgslStruct(returnType) && outputName && !/\s/g.test(outputName)) applyExternals({ [outputName]: returnType });
}
function identifierRegex(name) {
return new RegExp(`(?<![\\w\\$_.])${name.replaceAll(".", "\\.").replaceAll("$", "\\$")}(?![\\w\\$_])`, "g");
}
/**
* Replaces all occurrences of external names in WGSL code with their resolved values.
* It adds all necessary definitions to the resolution context.
* @param ctx - The resolution context.
* @param externalMap - The external map.
* @param wgsl - The WGSL code.
*
* @returns The WGSL code with all external names replaced with their resolved values.
*/
function replaceExternalsInWgsl(ctx, externalMap, wgsl) {
return Object.entries(externalMap).reduce((acc, [externalName, external]) => {
const externalRegex = identifierRegex(externalName);
if (wgsl && externalName !== "Out" && externalName !== "In" && !externalRegex.test(wgsl)) console.warn(`The external '${externalName}' wasn't used in the resolved template.`);
if (isWgsl(external) || isLooseData(external) || hasTinyestMetadata(external)) return acc.replaceAll(externalRegex, ctx.resolve(external).value);
if (external !== null && typeof external === "object") {
const foundProperties = [...wgsl.matchAll(new RegExp(`${externalName.replaceAll(".", "\\.").replaceAll("$", "\\$")}\\.(?<prop>.*?)(?![\\w\\$_])`, "g"))].map((found) => found[1]);
return [...new Set(foundProperties)].reduce((innerAcc, prop) => prop && prop in external ? replaceExternalsInWgsl(ctx, { [`${externalName}.${prop}`]: external[prop] }, innerAcc) : innerAcc, acc);
}
console.warn(`During resolution, the external '${externalName}' has been omitted. Only TGPU resources, 'use gpu' functions, primitives, and plain JS objects can be used as externals.`);
return acc;
}, wgsl);
}
//#endregion
//#region src/core/function/extractArgs.ts
/**
* Extracts info about arguments of a given WGSL function string.
* @example
* const code = `
* fn add(a: i32, @location(0) b: i32, c) -> i32 {
* return a + b + c;
* }`;
*
* extractArgs(code);
* // {
* // args: [
* // { identifier: 'a', attributes: [], type: 'i32' },
* // { identifier: 'b', attributes: ['@location(0)'], type: 'i32' },
* // { identifier: 'c', attributes: [], type: undefined }
* // ],
* // ret: { type: 'i32', attributes: [] },
* // range: { begin: 11, end: 51 }
* // }
*/
function extractArgs(rawCode) {
const { strippedCode, argRange: range } = strip(rawCode);
const code = new ParsableString(strippedCode);
code.consume("(");
const args = [];
while (!code.isAt(")")) {
const attributes = [];
while (code.isAt("@")) {
code.parseUntil(closingParenthesis, parentheses);
code.consume(")");
attributes.push(code.lastParsed);
}
code.parseUntil(identifierEndSymbols);
const identifier = code.lastParsed;
let maybeType;
if (code.isAt(":")) {
code.consume(":");
code.parseUntil(typeEndSymbols, angleBrackets);
maybeType = code.lastParsed;
}
args.push({
identifier,
attributes,
type: maybeType
});
if (code.isAt(",")) code.consume(",");
}
code.consume(")");
let maybeRet;
if (code.isAt("->")) {
code.consume("->");
const attributes = [];
while (code.isAt("@")) {
code.parseUntil(closingParenthesis, parentheses);
code.consume(")");
attributes.push(code.lastParsed);
}
maybeRet = {
type: code.str.slice(code.pos),
attributes
};
}
return {
args,
ret: maybeRet,
range: {
begin: range[0],
end: range[1]
}
};
}
/**
* Strips comments, whitespaces, the name and the body of the function.
* @example
* const code = `
* fn add( a, // first argument
* @location(0) b : i32 ) -> i32 {
* return a + b; // returns the sum
* }`;
*
* strip(code); // "(a,@location(0)b:i32)->i32"
*/
function strip(rawCode) {
const code = new ParsableString(rawCode);
let strippedCode = "";
let argsStart;
while (!code.isFinished()) {
if (code.isAt(blankSpaces)) {
code.advanceBy(1);
continue;
}
if (code.isAt("//")) {
code.consume("//");
code.parseUntil(lineBreaks);
code.advanceBy(1);
continue;
}
if (code.isAt("/*")) {
code.parseUntil(openingCommentBlock, commentBlocks);
code.consume("*/");
continue;
}
if (code.isAt("{")) return {
strippedCode,
argRange: [argsStart, code.pos]
};
if (code.isAt("(") && argsStart === void 0) argsStart = code.pos;
if (argsStart !== void 0) strippedCode += code.str[code.pos];
code.advanceBy(1);
}
throw new Error("Invalid wgsl code!");
}
var ParsableString = class {
#parseStartPos;
#pos;
constructor(str) {
this.str = str;
this.#pos = 0;
}
get pos() {
return this.#pos;
}
/**
* This property is equivalent to the substring of `this.str`
* from the position of the last `parseUntil` call, to the current position.
*/
get lastParsed() {
if (this.#parseStartPos === void 0) throw new Error("Parse was not called yet!");
return this.str.slice(this.#parseStartPos, this.pos);
}
isFinished() {
return this.#pos >= this.str.length;
}
isAt(substr) {
if (typeof substr === "string") {
for (let i = 0; i < substr.length; i++) if (this.str[this.#pos + i] !== substr[i]) return false;
return true;
}
for (const elem of substr) if (this.isAt(elem)) return true;
return false;
}
/**
* @param toFind a set of strings either of which satisfy the search.
* @param brackets a pair of brackets that has to be closed for result to be valid. This includes the found character(s).
* @example
* // internal state:
* // '(@attribute(0) identifier: type)'
* // ^
* this.parse(new Set(')'), ['(', ')']);
* // internal state:
* // '(@attribute(0) identifier: type)'
* // ^
*/
parseUntil(toFind, brackets) {
this.#parseStartPos = this.#pos;
let openedBrackets = 0;
while (this.#pos < this.str.length) {
if (brackets && this.isAt(brackets[0])) openedBrackets += 1;
if (brackets && this.isAt(brackets[1])) openedBrackets -= 1;
if (openedBrackets === 0) {
if (this.isAt(toFind)) return this.#pos;
}
this.#pos += 1;
}
throw new Error("Reached the end of the string without finding a match!");
}
advanceBy(steps) {
this.#pos += steps;
}
consume(str) {
if (!this.isAt(str)) throw new Error(`Expected '${str}' at position ${this.#pos}, but found '${this.str.slice(this.#pos, this.#pos + str.length)}'`);
this.advanceBy(str.length);
}
};
const lineBreaks = new Set([
"\n",
"\v",
"\f",
"\r",
"…",
"\u2028",
"\u2029"
]);
const blankSpaces = new Set([
...lineBreaks,
" ",
" ",
"‎",
"‏"
]);
const closingParenthesis = new Set([")"]);
const identifierEndSymbols = new Set([
":",
",",
")"
]);
const typeEndSymbols = new Set([",", ")"]);
const openingCommentBlock = new Set(["*/"]);
const parentheses = ["(", ")"];
const angleBrackets = ["<", ">"];
const commentBlocks = ["/*", "*/"];
//#endregion
//#region src/core/function/fnCore.ts
function createFnCore(implementation, fnAttribute = "") {
/**
* External application has to be deferred until resolution because
* some externals can reference the owner function which has not been
* initialized yet (like when accessing the Output struct of a vertex
* entry fn).
*/
const externalsToApply = [];
return {
[$getNameForward]: typeof implementation === "function" ? implementation : void 0,
applyExternals(newExternals) {
externalsToApply.push(newExternals);
},
resolve(ctx, argTypes, returnType) {
const externalMap = {};
for (const externals of externalsToApply) applyExternals(externalMap, externals);
const id = ctx.getUniqueName(this);
if (typeof implementation === "string") {
if (!returnType) throw new Error("Explicit return type is required for string implementation");
const replacedImpl = replaceExternalsInWgsl(ctx, externalMap, implementation);
let header = "";
let body = "";
if (fnAttribute !== "") {
const input = isWgslStruct(argTypes[0]) ? `(in: ${ctx.resolve(argTypes[0]).value})` : "()";
const attributes = isWgslData(returnType) ? getAttributesString(returnType) : "";
header = `${input} ${returnType !== Void ? isWgslStruct(returnType) ? `-> ${ctx.resolve(returnType).value}` : `-> ${attributes !== "" ? attributes : "@location(0)"} ${ctx.resolve(returnType).value}` : ""} `;
body = replacedImpl;
} else {
const providedArgs = extractArgs(replacedImpl);
if (providedArgs.args.length !== argTypes.length) throw new Error(`WGSL implementation has ${providedArgs.args.length} arguments, while the shell has ${argTypes.length} arguments.`);
header = `(${providedArgs.args.map((argInfo, i) => `${argInfo.identifier}: ${checkAndReturnType(ctx, `parameter ${argInfo.identifier}`, argInfo.type, argTypes[i])}`).join(", ")}) ${returnType === Void ? "" : `-> ${checkAndReturnType(ctx, "return type", providedArgs.ret?.type, returnType)}`}`;
body = replacedImpl.slice(providedArgs.range.end);
}
ctx.addDeclaration(`${fnAttribute}fn ${id}${header}${body}`);
return snip(id, returnType, "runtime");
}
const pluginData = getMetaData(implementation);
const pluginExternals = typeof pluginData?.externals === "function" ? pluginData.externals() : pluginData?.externals;
if (pluginExternals) applyExternals(externalMap, Object.fromEntries(Object.entries(pluginExternals).filter(([name]) => !(name in externalMap))));
const ast = pluginData?.ast;
if (!ast) throw new Error("Missing metadata for tgpu.fn function body (either missing 'use gpu' directive, or misconfigured `unplugin-typegpu`)");
const missingExternals = ast.externalNames.filter((name) => !(name in externalMap));
if (missingExternals.length > 0) throw new MissingLinksError(getName(this), missingExternals);
const maybeSecondArg = ast.params[1];
if (maybeSecondArg && maybeSecondArg.type === "i" && fnAttribute !== "") applyExternals(externalMap, { [maybeSecondArg.name]: undecorate(returnType) });
const { head, body, returnType: actualReturnType } = ctx.fnToWgsl({
functionType: fnAttribute.includes("@compute") ? "compute" : fnAttribute.includes("@vertex") ? "vertex" : fnAttribute.includes("@fragment") ? "fragment" : "normal",
argTypes,
params: ast.params,
returnType,
body: ast.body,
externalMap
});
ctx.addDeclaration(`${fnAttribute}fn ${id}${ctx.resolve(head).value}${ctx.resolve(body).value}`);
return snip(id, actualReturnType, "runtime");
}
};
}
function checkAndReturnType(ctx, name, wgslType, jsType) {
const resolvedJsType = ctx.resolve(jsType).value.replace(/\s/g, "");
if (!wgslType) return resolvedJsType;
const resolvedWgslType = wgslType.replace(/\s/g, "");
if (resolvedWgslType !== resolvedJsType) throw new Error(`Type mismatch between TGPU shell and WGSL code string: ${name}, JS type "${resolvedJsType}", WGSL type "${resolvedWgslType}".`);
return wgslType;
}
//#endregion
//#region src/core/function/templateUtils.ts
function stripTemplate(arg, ...values) {
return isTemplateStringsArray(arg) ? templateLiteralIdentity(arg, ...values) : arg;
}
function isTemplateStringsArray(value) {
return Array.isArray(value) && "raw" in value && Array.isArray(value.raw) && value.raw.every((item) => typeof item === "string");
}
function templateLiteralIdentity(strings, ...values) {
return strings.slice(1).reduce((acc, elem, index) => `${acc}${values[index]}${elem}`, strings[0]);
}
//#endregion
//#region src/core/slot/slot.ts
function slot(defaultValue) {
return new TgpuSlotImpl(defaultValue);
}
var TgpuSlotImpl = class {
[$internal] = true;
resourceType = "slot";
constructor(defaultValue = void 0) {
this.defaultValue = defaultValue;
}
$name(label) {
setName(this, label);
return this;
}
areEqual(a, b) {
return Object.is(a, b);
}
toString() {
return `slot:${getName(this) ?? "<unnamed>"}`;
}
get [$gpuValueOf]() {
const ctx = getResolutionCtx();
if (!ctx) throw new Error(`Cannot access tgpu.slot's value outside of resolution.`);
return getGpuValueRecursively(ctx.unwrap(this));
}
get value() {
return this[$gpuValueOf];
}
get $() {
return this.value;
}
};
//#endregion
//#region src/core/slot/internalSlots.ts
const shaderStageSlot = slot(void 0);
//#endregion
//#region src/core/function/tgpuVertexFn.ts
/**
* Creates a shell of a typed entry function for the vertex shader stage. Any function
* that implements this shell can run for each vertex, allowing the inner code to process
* attributes and determine the final position of the vertex.
*
* @param options.in
* Vertex attributes and builtins to be made available to functions that implement this shell.
* @param options.out
* A record containing the final position of the vertex, and any information
* passed onto the fragment shader stage.
*/
function vertexFn(options) {
if (Object.keys(options.out).length === 0) throw new Error(`A vertexFn output cannot be empty since it must include the 'position' builtin.`);
const shell = {
in: options.in,
out: options.out,
argTypes: options.in && Object.keys(options.in).length !== 0 ? [createIoSchema(options.in)] : [],
entryPoint: "vertex"
};
const call = (arg, ...values) => createVertexFn(shell, stripTemplate(arg, ...values));
return Object.assign(call, shell);
}
function isTgpuVertexFn(value) {
return value?.shell?.entryPoint === "vertex";
}
function createVertexFn(shell, implementation) {
const core = createFnCore(implementation, "@vertex ");
const inputType = shell.argTypes[0];
return {
shell,
$uses(newExternals) {
core.applyExternals(newExternals);
return this;
},
[$internal]: true,
[$getNameForward]: core,
$name(newLabel) {
setName(this, newLabel);
if (isNamable(inputType)) inputType.$name(`${newLabel}_Input`);
return this;
},
[$resolve](ctx) {
const outputWithLocation = createIoSchema(shell.out, ctx.varyingLocations).$name(`${getName(this) ?? ""}_Output`);
if (typeof implementation === "string") {
if (inputType) core.applyExternals({ In: inputType });
core.applyExternals({ Out: outputWithLocation });
}
return ctx.withSlots([[shaderStageSlot, "vertex"]], () => core.resolve(ctx, shell.argTypes, outputWithLocation));
},
toString() {
return `vertexFn:${getName(core) ?? "<unnamed>"}`;
}
};
}
//#endregion
//#region src/common/fullScreenTriangle.ts
/**
* A vertex function that defines a single full-screen triangle out
* of three points.
*
* @example
* ```ts
* import { common } from 'typegpu';
*
* const pipeline = root.createRenderPipeline({
* vertex: common.fullScreenTriangle,
* fragment: yourFragmentShader,
* });
*
* pipeline.draw(3);
* ```
*/
const fullScreenTriangle = vertexFn({
in: { vertexIndex: builtin.vertexIndex },
out: {
pos: builtin.position,
uv: vec2f
}
})`{
const pos = array<vec2f, 3>(vec2f(-1, -1), vec2f(3, -1), vec2f(-1, 3));
const uv = array<vec2f, 3>(vec2f(0, 1), vec2f(2, 1), vec2f(0, -1));
return Out(vec4f(pos[in.vertexIndex], 0, 1), uv[in.vertexIndex]);
}`;
//#endregion
export { slot as a, addArgTypesToExternals as c, replaceExternalsInWgsl as d, getGpuValueRecursively as f, shaderStageSlot as i, addReturnTypeToExternals as l, accessIndex as m, isTgpuVertexFn as n, stripTemplate as o, valueProxyHandler as p, vertexFn as r, createFnCore as s, fullScreenTriangle as t, applyExternals as u };
//# sourceMappingURL=fullScreenTriangle-MdLGaAMR.js.map
{"version":3,"file":"fullScreenTriangle-MdLGaAMR.js","names":["#pos","#parseStartPos"],"sources":["../src/getGPUValue.ts","../src/tgsl/accessIndex.ts","../src/core/valueProxyUtils.ts","../src/core/resolve/externals.ts","../src/core/function/extractArgs.ts","../src/core/function/fnCore.ts","../src/core/function/templateUtils.ts","../src/core/slot/slot.ts","../src/core/slot/internalSlots.ts","../src/core/function/tgpuVertexFn.ts","../src/common/fullScreenTriangle.ts"],"sourcesContent":["import { $gpuValueOf } from './shared/symbols.ts';\nimport type { WithGPUValue } from './types.ts';\n\nexport function getGPUValue(\n object: unknown,\n): unknown {\n return (object as WithGPUValue<unknown>)?.[$gpuValueOf];\n}\n","import { stitch } from '../core/resolve/stitch.ts';\nimport {\n isDisarray,\n MatrixColumnsAccess,\n UnknownData,\n} from '../data/dataTypes.ts';\nimport { derefSnippet } from '../data/ref.ts';\nimport {\n isEphemeralSnippet,\n type Origin,\n snip,\n type Snippet,\n} from '../data/snippet.ts';\nimport { vec2f, vec3f, vec4f } from '../data/vector.ts';\nimport {\n type BaseData,\n isNaturallyEphemeral,\n isPtr,\n isVec,\n isWgslArray,\n isWgslStruct,\n} from '../data/wgslTypes.ts';\nimport { isKnownAtComptime } from '../types.ts';\nimport { accessProp } from './accessProp.ts';\nimport { coerceToSnippet } from './generationHelpers.ts';\n\nconst indexableTypeToResult = {\n mat2x2f: vec2f,\n mat3x3f: vec3f,\n mat4x4f: vec4f,\n} as const;\n\nexport function accessIndex(\n target: Snippet,\n indexArg: Snippet | number,\n): Snippet | undefined {\n const index = typeof indexArg === 'number'\n ? coerceToSnippet(indexArg)\n : indexArg;\n\n // array\n if (isWgslArray(target.dataType) || isDisarray(target.dataType)) {\n const elementType = target.dataType.elementType;\n const isElementNatEph = isNaturallyEphemeral(elementType);\n const isTargetEphemeral = isEphemeralSnippet(target);\n const isIndexConstant = index.origin === 'constant';\n\n let origin: Origin;\n\n if (target.origin === 'constant-tgpu-const-ref') {\n // Constant refs stay const unless the element/index forces runtime materialization\n if (isIndexConstant) {\n origin = isElementNatEph ? 'constant' : 'constant-tgpu-const-ref';\n } else {\n origin = isElementNatEph ? 'runtime' : 'runtime-tgpu-const-ref';\n }\n } else if (target.origin === 'runtime-tgpu-const-ref') {\n // Runtime refs keep their ref semantics unless the element is ephemeral only\n origin = isElementNatEph ? 'runtime' : 'runtime-tgpu-const-ref';\n } else if (!isTargetEphemeral && !isElementNatEph) {\n // Stable containers can forward their origin information\n origin = target.origin;\n } else if (isIndexConstant && target.origin === 'constant') {\n // Plain constants indexed with constants stay constant\n origin = 'constant';\n } else {\n // Everything else must be produced at runtime\n origin = 'runtime';\n }\n\n return snip(\n isKnownAtComptime(target) && isKnownAtComptime(index)\n // oxlint-disable-next-line typescript/no-explicit-any it's fine, it's there\n ? (target.value as any)[index.value as number]\n : stitch`${target}[${index}]`,\n elementType,\n /* origin */ origin,\n );\n }\n\n // vector\n if (isVec(target.dataType)) {\n return snip(\n isKnownAtComptime(target) && isKnownAtComptime(index)\n // oxlint-disable-next-line typescript/no-explicit-any it's fine, it's there\n ? (target.value as any)[index.value as any]\n : stitch`${target}[${index}]`,\n target.dataType.primitive,\n /* origin */ target.origin === 'constant' ||\n target.origin === 'constant-tgpu-const-ref'\n ? 'constant'\n : 'runtime',\n );\n }\n\n if (isPtr(target.dataType)) {\n // Sometimes values that are typed as pointers aren't instances of `d.ref`, so we\n // allow indexing as if it wasn't a pointer.\n return accessIndex(derefSnippet(target), index);\n }\n\n // matrix.columns\n if (target.value instanceof MatrixColumnsAccess) {\n const propType = indexableTypeToResult[\n (target.value.matrix.dataType as BaseData)\n .type as keyof typeof indexableTypeToResult\n ];\n\n return snip(\n stitch`${target.value.matrix}[${index}]`,\n propType,\n /* origin */ target.origin,\n );\n }\n\n // matrix\n if ((target.dataType as BaseData).type in indexableTypeToResult) {\n throw new Error(\n \"The only way of accessing matrix elements in TypeGPU functions is through the 'columns' property.\",\n );\n }\n\n if (\n (isKnownAtComptime(target) && isKnownAtComptime(index)) ||\n target.dataType === UnknownData\n ) {\n // No idea what the type is, so we act on the snippet's value and try to guess\n return coerceToSnippet(\n // oxlint-disable-next-line typescript/no-explicit-any we're inspecting the value, and it could be any value\n (target.value as any)[index.value as number],\n );\n }\n\n if (\n isWgslStruct(target.dataType) && isKnownAtComptime(index) &&\n typeof index.value === 'string'\n ) {\n return accessProp(target, index.value);\n }\n\n return undefined;\n}\n","import type { Snippet } from '../data/snippet.ts';\nimport { getGPUValue } from '../getGPUValue.ts';\nimport { $internal, $ownSnippet, $resolve } from '../shared/symbols.ts';\nimport { accessIndex } from '../tgsl/accessIndex.ts';\nimport { accessProp } from '../tgsl/accessProp.ts';\nimport {\n getOwnSnippet,\n type SelfResolvable,\n type WithOwnSnippet,\n} from '../types.ts';\n\nexport const valueProxyHandler: ProxyHandler<\n SelfResolvable & WithOwnSnippet\n> = {\n get(target, prop) {\n if (prop in target) {\n return Reflect.get(target, prop);\n }\n\n if (\n prop === 'toString' ||\n prop === Symbol.toStringTag ||\n prop === Symbol.toPrimitive\n ) {\n return () => target.toString();\n }\n\n if (typeof prop === 'symbol') {\n return undefined;\n }\n\n const targetSnippet = getOwnSnippet(target) as Snippet;\n\n const index = Number(prop);\n if (!Number.isNaN(index)) {\n const accessed = accessIndex(targetSnippet, index);\n if (!accessed) {\n // Prop was not found, must be missing from this object\n return undefined;\n }\n\n return new Proxy({\n [$internal]: true,\n [$resolve]: (ctx) => ctx.resolve(accessed.value, accessed.dataType),\n [$ownSnippet]: accessed,\n toString: () => `${String(target)}[${prop}]`,\n }, valueProxyHandler);\n }\n\n const accessed = accessProp(targetSnippet, String(prop));\n if (!accessed) {\n // Prop was not found, must be missing from this object\n return undefined;\n }\n\n return new Proxy({\n [$internal]: true,\n [$resolve]: (ctx) => ctx.resolve(accessed.value, accessed.dataType),\n [$ownSnippet]: accessed,\n toString: () => `${String(target)}.${prop}`,\n }, valueProxyHandler);\n },\n};\n\nexport function getGpuValueRecursively<T>(value: unknown): T {\n let unwrapped = value;\n\n while (true) {\n const gpuValue = getGPUValue(unwrapped);\n if (!gpuValue) {\n break;\n }\n unwrapped = gpuValue;\n }\n\n return unwrapped as T;\n}\n","import { isLooseData } from '../../data/dataTypes.ts';\nimport { isWgslStruct } from '../../data/wgslTypes.ts';\nimport { getName, hasTinyestMetadata, setName } from '../../shared/meta.ts';\nimport { isWgsl, type ResolutionCtx } from '../../types.ts';\n\n/**\n * A key-value mapping where keys represent identifiers within shader code,\n * and values can be any type that can be resolved to a code string.\n */\nexport type ExternalMap = Record<string, unknown>;\n\n/**\n * Merges two external maps into one. If a key is present in both maps, the value from the new map is used.\n * If the external value is a namable object, it is given a name if it does not already have one.\n * @param existing - The existing external map.\n * @param newExternals - The new external map.\n */\nexport function applyExternals(\n existing: ExternalMap,\n newExternals: ExternalMap,\n) {\n for (const [key, value] of Object.entries(newExternals)) {\n existing[key] = value;\n\n // Giving name to external value, if it does not already have one.\n if (\n value && (typeof value === 'object' || typeof value === 'function') &&\n getName(value) === undefined\n ) {\n setName(value, key);\n }\n }\n}\n\nexport function addArgTypesToExternals(\n implementation: string,\n argTypes: unknown[],\n applyExternals: (externals: ExternalMap) => void,\n) {\n const argTypeNames = [\n ...implementation.matchAll(/:\\s*(?<arg>.*?)\\s*[,)]/g),\n ].map((found) => (found ? found[1] : undefined));\n\n applyExternals(\n Object.fromEntries(\n argTypes.flatMap((argType, i) => {\n const argTypeName = argTypeNames ? argTypeNames[i] : undefined;\n return isWgslStruct(argType) && argTypeName !== undefined\n ? [[argTypeName, argType]]\n : [];\n }),\n ),\n );\n}\n\nexport function addReturnTypeToExternals(\n implementation: string,\n returnType: unknown,\n applyExternals: (externals: ExternalMap) => void,\n) {\n const matched = implementation.match(/->\\s(?<output>[\\w\\d_]+)\\s{/);\n const outputName = matched ? matched[1]?.trim() : undefined;\n\n if (isWgslStruct(returnType) && outputName && !/\\s/g.test(outputName)) {\n applyExternals({ [outputName]: returnType });\n }\n}\n\nfunction identifierRegex(name: string) {\n return new RegExp(\n `(?<![\\\\w\\\\$_.])${\n name.replaceAll('.', '\\\\.').replaceAll('$', '\\\\$')\n }(?![\\\\w\\\\$_])`,\n 'g',\n );\n}\n\n/**\n * Replaces all occurrences of external names in WGSL code with their resolved values.\n * It adds all necessary definitions to the resolution context.\n * @param ctx - The resolution context.\n * @param externalMap - The external map.\n * @param wgsl - The WGSL code.\n *\n * @returns The WGSL code with all external names replaced with their resolved values.\n */\nexport function replaceExternalsInWgsl(\n ctx: ResolutionCtx,\n externalMap: ExternalMap,\n wgsl: string,\n): string {\n return Object.entries(externalMap).reduce((acc, [externalName, external]) => {\n const externalRegex = identifierRegex(externalName);\n if (\n wgsl &&\n externalName !== 'Out' &&\n externalName !== 'In' &&\n !externalRegex.test(wgsl)\n ) {\n console.warn(\n `The external '${externalName}' wasn't used in the resolved template.`,\n );\n // continue anyway, we still might need to resolve the external\n }\n\n if (\n isWgsl(external) || isLooseData(external) || hasTinyestMetadata(external)\n ) {\n return acc.replaceAll(externalRegex, ctx.resolve(external).value);\n }\n\n if (external !== null && typeof external === 'object') {\n const foundProperties = [\n ...wgsl.matchAll(\n new RegExp(\n `${\n externalName.replaceAll('.', '\\\\.').replaceAll('$', '\\\\$')\n }\\\\.(?<prop>.*?)(?![\\\\w\\\\$_])`,\n 'g',\n ),\n ),\n ].map((found) => found[1]);\n const uniqueProperties = [...new Set(foundProperties)];\n\n return uniqueProperties.reduce(\n (innerAcc: string, prop) =>\n prop && prop in external\n ? replaceExternalsInWgsl(\n ctx,\n {\n [`${externalName}.${prop}`]:\n external[prop as keyof typeof external],\n },\n innerAcc,\n )\n : innerAcc,\n acc,\n );\n }\n\n console.warn(\n `During resolution, the external '${externalName}' has been omitted. Only TGPU resources, 'use gpu' functions, primitives, and plain JS objects can be used as externals.`,\n );\n\n return acc;\n }, wgsl);\n}\n","interface FunctionArgsInfo {\n args: ArgInfo[];\n ret: ReturnInfo | undefined;\n range: {\n begin: number;\n end: number;\n };\n}\n\ninterface ArgInfo {\n identifier: string;\n attributes: string[];\n type: string | undefined;\n}\n\ninterface ReturnInfo {\n attributes: string[];\n type: string;\n}\n\n/**\n * Extracts info about arguments of a given WGSL function string.\n * @example\n * const code = `\n * fn add(a: i32, @location(0) b: i32, c) -> i32 {\n * return a + b + c;\n * }`;\n *\n * extractArgs(code);\n * // {\n * // args: [\n * // { identifier: 'a', attributes: [], type: 'i32' },\n * // { identifier: 'b', attributes: ['@location(0)'], type: 'i32' },\n * // { identifier: 'c', attributes: [], type: undefined }\n * // ],\n * // ret: { type: 'i32', attributes: [] },\n * // range: { begin: 11, end: 51 }\n * // }\n */\nexport function extractArgs(rawCode: string): FunctionArgsInfo {\n const { strippedCode, argRange: range } = strip(rawCode);\n const code = new ParsableString(strippedCode);\n code.consume('(');\n\n const args: ArgInfo[] = [];\n while (!code.isAt(')')) {\n // In each loop iteration, process all the attributes, the identifier and the potential type of a single argument.\n\n const attributes = [];\n while (code.isAt('@')) {\n code.parseUntil(closingParenthesis, parentheses);\n code.consume(')');\n attributes.push(code.lastParsed);\n }\n\n code.parseUntil(identifierEndSymbols);\n const identifier = code.lastParsed;\n\n let maybeType: string | undefined;\n if (code.isAt(':')) {\n code.consume(':');\n code.parseUntil(typeEndSymbols, angleBrackets);\n maybeType = code.lastParsed;\n }\n\n args.push({\n identifier,\n attributes,\n type: maybeType,\n });\n\n if (code.isAt(',')) {\n code.consume(',');\n }\n }\n code.consume(')');\n\n let maybeRet: ReturnInfo | undefined;\n if (code.isAt('->')) {\n code.consume('->');\n\n const attributes = [];\n while (code.isAt('@')) {\n code.parseUntil(closingParenthesis, parentheses);\n code.consume(')');\n attributes.push(code.lastParsed);\n }\n\n maybeRet = { type: code.str.slice(code.pos), attributes };\n }\n\n return {\n args,\n ret: maybeRet,\n range: { begin: range[0], end: range[1] },\n };\n}\n\n/**\n * Strips comments, whitespaces, the name and the body of the function.\n * @example\n * const code = `\n * fn add( a, // first argument\n * @location(0) b : i32 ) -> i32 {\n * return a + b; // returns the sum\n * }`;\n *\n * strip(code); // \"(a,@location(0)b:i32)->i32\"\n */\nfunction strip(\n rawCode: string,\n): { strippedCode: string; argRange: [number, number] } {\n const code = new ParsableString(rawCode);\n let strippedCode = '';\n let argsStart: number | undefined;\n\n while (!code.isFinished()) {\n // parse character by character while ignoring comments and blankspaces until you find a `{`.\n\n // skip any blankspace\n if (code.isAt(blankSpaces)) {\n code.advanceBy(1); // the blankspace character\n continue;\n }\n\n // skip line comments\n if (code.isAt('//')) {\n code.consume('//');\n code.parseUntil(lineBreaks);\n code.advanceBy(1); // the line break\n continue;\n }\n\n // skip block comments\n if (code.isAt('/*')) {\n code.parseUntil(openingCommentBlock, commentBlocks);\n code.consume('*/');\n continue;\n }\n\n if (code.isAt('{')) {\n return {\n strippedCode,\n argRange: [argsStart as number, code.pos],\n };\n }\n\n if (code.isAt('(') && argsStart === undefined) {\n argsStart = code.pos;\n }\n\n if (argsStart !== undefined) {\n strippedCode += code.str[code.pos];\n }\n code.advanceBy(1); // parsed character\n }\n throw new Error('Invalid wgsl code!');\n}\n\nclass ParsableString {\n #parseStartPos: number | undefined;\n #pos: number;\n constructor(public readonly str: string) {\n this.#pos = 0;\n }\n\n get pos(): number {\n return this.#pos;\n }\n\n /**\n * This property is equivalent to the substring of `this.str`\n * from the position of the last `parseUntil` call, to the current position.\n */\n get lastParsed(): string {\n if (this.#parseStartPos === undefined) {\n throw new Error('Parse was not called yet!');\n }\n return this.str.slice(this.#parseStartPos, this.pos);\n }\n\n isFinished() {\n return this.#pos >= this.str.length;\n }\n\n isAt(substr: string | Set<string>): boolean {\n if (typeof substr === 'string') {\n for (let i = 0; i < substr.length; i++) {\n if (this.str[this.#pos + i] !== substr[i]) {\n return false;\n }\n }\n return true;\n }\n for (const elem of substr) {\n if (this.isAt(elem)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * @param toFind a set of strings either of which satisfy the search.\n * @param brackets a pair of brackets that has to be closed for result to be valid. This includes the found character(s).\n * @example\n * // internal state:\n * // '(@attribute(0) identifier: type)'\n * // ^\n * this.parse(new Set(')'), ['(', ')']);\n * // internal state:\n * // '(@attribute(0) identifier: type)'\n * // ^\n */\n parseUntil(\n toFind: Set<string>,\n brackets?: readonly [string, string],\n ): number {\n this.#parseStartPos = this.#pos;\n let openedBrackets = 0;\n while (this.#pos < this.str.length) {\n if (brackets && this.isAt(brackets[0])) {\n openedBrackets += 1;\n }\n if (brackets && this.isAt(brackets[1])) {\n openedBrackets -= 1;\n }\n if (openedBrackets === 0) {\n if (this.isAt(toFind)) {\n return this.#pos;\n }\n }\n this.#pos += 1;\n }\n throw new Error('Reached the end of the string without finding a match!');\n }\n\n advanceBy(steps: number) {\n this.#pos += steps;\n }\n\n consume(str: string): void {\n if (!this.isAt(str)) {\n throw new Error(\n `Expected '${str}' at position ${this.#pos}, but found '${\n this.str.slice(this.#pos, this.#pos + str.length)\n }'`,\n );\n }\n this.advanceBy(str.length);\n }\n}\n\nconst lineBreaks = new Set<string>([\n '\\u000A', // line feed\n '\\u000B', // vertical tab\n '\\u000C', // form feed\n '\\u000D', // carriage return\n '\\u0085', // next line\n '\\u2028', // line separator\n '\\u2029', // paragraph separator\n]);\nconst blankSpaces = new Set<string>([\n ...lineBreaks,\n '\\u0020', // space\n '\\u0009', // horizontal tab\n '\\u200E', // left-to-right mark\n '\\u200F', // right-to-left mark\n]);\nconst closingParenthesis = new Set<string>([')']);\nconst identifierEndSymbols = new Set([':', ',', ')']);\nconst typeEndSymbols = new Set([',', ')']);\nconst openingCommentBlock = new Set(['*/']);\n\nconst parentheses = ['(', ')'] as const;\nconst angleBrackets = ['<', '>'] as const;\nconst commentBlocks = ['/*', '*/'] as const;\n","import { getAttributesString } from '../../data/attributes.ts';\nimport { undecorate } from '../../data/dataTypes.ts';\nimport { type ResolvedSnippet, snip } from '../../data/snippet.ts';\nimport {\n type BaseData,\n isWgslData,\n isWgslStruct,\n Void,\n} from '../../data/wgslTypes.ts';\nimport { MissingLinksError } from '../../errors.ts';\nimport { getMetaData, getName } from '../../shared/meta.ts';\nimport { $getNameForward } from '../../shared/symbols.ts';\nimport type { ResolutionCtx } from '../../types.ts';\nimport {\n applyExternals,\n type ExternalMap,\n replaceExternalsInWgsl,\n} from '../resolve/externals.ts';\nimport { extractArgs } from './extractArgs.ts';\nimport type { Implementation } from './fnTypes.ts';\n\nexport interface FnCore {\n applyExternals: (newExternals: ExternalMap) => void;\n resolve(\n ctx: ResolutionCtx,\n /**\n * The argument types can be AutoStruct if they're determined based on usage\n * (like in auto-entry functions).\n */\n argTypes: BaseData[],\n /**\n * The return type of the function. If undefined, the type should be inferred\n * from the implementation (relevant for shellless functions).\n */\n returnType: BaseData | undefined,\n ): ResolvedSnippet;\n}\n\nexport function createFnCore(\n implementation: Implementation,\n fnAttribute = '',\n): FnCore {\n /**\n * External application has to be deferred until resolution because\n * some externals can reference the owner function which has not been\n * initialized yet (like when accessing the Output struct of a vertex\n * entry fn).\n */\n const externalsToApply: ExternalMap[] = [];\n\n const core = {\n // Making the implementation the holder of the name, as long as it's\n // a function (and not a string implementation)\n [$getNameForward]: typeof implementation === 'function'\n ? implementation\n : undefined,\n applyExternals(newExternals: ExternalMap): void {\n externalsToApply.push(newExternals);\n },\n\n resolve(\n ctx: ResolutionCtx,\n argTypes: BaseData[],\n returnType: BaseData | undefined,\n ): ResolvedSnippet {\n const externalMap: ExternalMap = {};\n\n for (const externals of externalsToApply) {\n applyExternals(externalMap, externals);\n }\n\n const id = ctx.getUniqueName(this);\n\n if (typeof implementation === 'string') {\n if (!returnType) {\n throw new Error(\n 'Explicit return type is required for string implementation',\n );\n }\n\n const replacedImpl = replaceExternalsInWgsl(\n ctx,\n externalMap,\n implementation,\n );\n\n let header = '';\n let body = '';\n\n if (fnAttribute !== '') {\n const input = isWgslStruct(argTypes[0])\n ? `(in: ${ctx.resolve(argTypes[0]).value})`\n : '()';\n\n const attributes = isWgslData(returnType)\n ? getAttributesString(returnType)\n : '';\n const output = returnType !== Void\n ? isWgslStruct(returnType)\n ? `-> ${ctx.resolve(returnType).value}`\n : `-> ${attributes !== '' ? attributes : '@location(0)'} ${\n ctx.resolve(returnType).value\n }`\n : '';\n\n header = `${input} ${output} `;\n body = replacedImpl;\n } else {\n const providedArgs = extractArgs(replacedImpl);\n\n if (providedArgs.args.length !== argTypes.length) {\n throw new Error(\n `WGSL implementation has ${providedArgs.args.length} arguments, while the shell has ${argTypes.length} arguments.`,\n );\n }\n\n const input = providedArgs.args.map((argInfo, i) =>\n `${argInfo.identifier}: ${\n checkAndReturnType(\n ctx,\n `parameter ${argInfo.identifier}`,\n argInfo.type,\n argTypes[i],\n )\n }`\n ).join(', ');\n\n const output = returnType === Void ? '' : `-> ${\n checkAndReturnType(\n ctx,\n 'return type',\n providedArgs.ret?.type,\n returnType,\n )\n }`;\n\n header = `(${input}) ${output}`;\n\n body = replacedImpl.slice(providedArgs.range.end);\n }\n\n ctx.addDeclaration(`${fnAttribute}fn ${id}${header}${body}`);\n return snip(id, returnType, /* origin */ 'runtime');\n }\n\n // get data generated by the plugin\n const pluginData = getMetaData(implementation);\n\n // Passing a record happens prior to version 0.9.0\n // TODO: Support for this can be removed down the line\n const pluginExternals = typeof pluginData?.externals === 'function'\n ? pluginData.externals()\n : pluginData?.externals;\n\n if (pluginExternals) {\n const missing = Object.fromEntries(\n Object.entries(pluginExternals).filter(\n ([name]) => !(name in externalMap),\n ),\n );\n\n applyExternals(externalMap, missing);\n }\n\n const ast = pluginData?.ast;\n if (!ast) {\n throw new Error(\n \"Missing metadata for tgpu.fn function body (either missing 'use gpu' directive, or misconfigured `unplugin-typegpu`)\",\n );\n }\n\n // verify all required externals are present\n const missingExternals = ast.externalNames.filter(\n (name) => !(name in externalMap),\n );\n if (missingExternals.length > 0) {\n throw new MissingLinksError(getName(this), missingExternals);\n }\n\n // If an entrypoint implementation has a second argument, it represents the output schema.\n // We look at the identifier chosen by the user and add it to externals.\n const maybeSecondArg = ast.params[1];\n if (\n maybeSecondArg && maybeSecondArg.type === 'i' && fnAttribute !== ''\n ) {\n applyExternals(\n externalMap,\n {\n // oxlint-disable-next-line typescript/no-non-null-assertion entry functions cannot be shellless\n [maybeSecondArg.name]: undecorate(returnType!),\n },\n );\n }\n\n // generate wgsl string\n\n const { head, body, returnType: actualReturnType } = ctx.fnToWgsl({\n functionType: fnAttribute.includes('@compute')\n ? 'compute'\n : fnAttribute.includes('@vertex')\n ? 'vertex'\n : fnAttribute.includes('@fragment')\n ? 'fragment'\n : 'normal',\n argTypes,\n params: ast.params,\n returnType,\n body: ast.body,\n externalMap,\n });\n\n ctx.addDeclaration(\n `${fnAttribute}fn ${id}${ctx.resolve(head).value}${\n ctx.resolve(body).value\n }`,\n );\n\n return snip(id, actualReturnType, /* origin */ 'runtime');\n },\n };\n\n return core;\n}\n\nfunction checkAndReturnType(\n ctx: ResolutionCtx,\n name: string,\n wgslType: string | undefined,\n jsType: unknown,\n) {\n const resolvedJsType = ctx.resolve(jsType).value.replace(/\\s/g, '');\n\n if (!wgslType) {\n return resolvedJsType;\n }\n\n const resolvedWgslType = wgslType.replace(/\\s/g, '');\n\n if (resolvedWgslType !== resolvedJsType) {\n throw new Error(\n `Type mismatch between TGPU shell and WGSL code string: ${name}, JS type \"${resolvedJsType}\", WGSL type \"${resolvedWgslType}\".`,\n );\n }\n\n return wgslType;\n}\n","import type { Implementation } from './fnTypes.ts';\n\nexport function stripTemplate(\n arg: Implementation | TemplateStringsArray,\n ...values: unknown[]\n): Implementation {\n return isTemplateStringsArray(arg)\n ? templateLiteralIdentity(arg, ...values)\n : arg;\n}\n\nfunction isTemplateStringsArray(value: unknown): value is TemplateStringsArray {\n return (\n Array.isArray(value) &&\n 'raw' in value &&\n Array.isArray(value.raw) &&\n value.raw.every((item) => typeof item === 'string')\n );\n}\n\nfunction templateLiteralIdentity(\n strings: TemplateStringsArray,\n ...values: unknown[]\n): string {\n return strings\n .slice(1)\n .reduce(\n (acc, elem, index) => `${acc}${values[index]}${elem}`,\n strings[0] as string,\n );\n}\n","import { getResolutionCtx } from '../../execMode.ts';\nimport { getName, setName } from '../../shared/meta.ts';\nimport type { GPUValueOf } from '../../shared/repr.ts';\nimport { $gpuValueOf, $internal } from '../../shared/symbols.ts';\nimport { getGpuValueRecursively } from '../valueProxyUtils.ts';\nimport type { TgpuSlot } from './slotTypes.ts';\n\n// ----------\n// Public API\n// ----------\n\nexport function slot<T>(defaultValue?: T): TgpuSlot<T> {\n return new TgpuSlotImpl(defaultValue);\n}\n\n// --------------\n// Implementation\n// --------------\n\nclass TgpuSlotImpl<T> implements TgpuSlot<T> {\n public readonly [$internal] = true;\n public readonly resourceType = 'slot';\n\n constructor(public defaultValue: T | undefined = undefined) {}\n\n $name(label: string) {\n setName(this, label);\n return this;\n }\n\n areEqual(a: T, b: T): boolean {\n return Object.is(a, b);\n }\n\n toString(): string {\n return `slot:${getName(this) ?? '<unnamed>'}`;\n }\n\n get [$gpuValueOf](): GPUValueOf<T> {\n const ctx = getResolutionCtx();\n if (!ctx) {\n throw new Error(`Cannot access tgpu.slot's value outside of resolution.`);\n }\n\n return getGpuValueRecursively(ctx.unwrap(this));\n }\n\n get value(): GPUValueOf<T> {\n return this[$gpuValueOf];\n }\n\n get $(): GPUValueOf<T> {\n return this.value;\n }\n}\n","import type { ShaderStage } from '../../types.ts';\nimport { slot } from './slot.ts';\n\nexport const shaderStageSlot = slot<ShaderStage>(undefined);\n","import type {\n AnyVertexInputBuiltin,\n AnyVertexOutputBuiltin,\n OmitBuiltins,\n} from '../../builtin.ts';\nimport type { UndecorateRecord } from '../../data/dataTypes.ts';\nimport type { ResolvedSnippet } from '../../data/snippet.ts';\nimport type {\n BaseData,\n Decorated,\n Interpolate,\n Location,\n} from '../../data/wgslTypes.ts';\nimport {\n getName,\n isNamable,\n setName,\n type TgpuNamable,\n} from '../../shared/meta.ts';\nimport { $getNameForward, $internal, $resolve } from '../../shared/symbols.ts';\nimport type { Prettify } from '../../shared/utilityTypes.ts';\nimport type { ResolutionCtx, SelfResolvable } from '../../types.ts';\nimport { shaderStageSlot } from '../slot/internalSlots.ts';\nimport { createFnCore, type FnCore } from './fnCore.ts';\nimport type {\n BaseIOData,\n Implementation,\n InferIO,\n IORecord,\n} from './fnTypes.ts';\nimport { createIoSchema, type IOLayoutToSchema } from './ioSchema.ts';\nimport { stripTemplate } from './templateUtils.ts';\n\n// ----------\n// Public API\n// ----------\n\ntype VertexInConstrained = IORecord<\n BaseIOData | Decorated<BaseIOData, Location[]> | AnyVertexInputBuiltin\n>;\n\ntype VertexOutConstrained = IORecord<\n | BaseIOData\n | Decorated<BaseIOData, (Location | Interpolate)[]>\n | AnyVertexOutputBuiltin\n>;\n\n/**\n * Describes a vertex entry function signature (its arguments, return type and attributes)\n */\ntype TgpuVertexFnShellHeader<\n VertexIn extends TgpuVertexFn.In,\n VertexOut extends TgpuVertexFn.Out,\n> = {\n readonly in: VertexIn | undefined;\n readonly out: VertexOut;\n readonly argTypes: [IOLayoutToSchema<VertexIn>] | [];\n readonly entryPoint: 'vertex';\n};\n\ntype CleanIO<T> = T extends Record<string, BaseData>\n ? Prettify<UndecorateRecord<OmitBuiltins<T>>>\n : Prettify<UndecorateRecord<OmitBuiltins<{ a: T }>>> extends\n { a: infer Result } ? Result\n : never;\n\n/**\n * Describes a vertex entry function signature (its arguments, return type and attributes).\n * Allows creating tgpu vertex functions by calling this shell\n * and passing the implementation (as WGSL string or JS function) as the argument.\n */\nexport interface TgpuVertexFnShell<\n // We force the variance to be covariant, since shells are just containers of\n // schemas that coincidentally can be called to create a vertex function.\n // @ts-expect-error: We override the variance\n out TIn extends TgpuVertexFn.In,\n // @ts-expect-error: We override the variance\n out TOut extends TgpuVertexFn.Out,\n> extends TgpuVertexFnShellHeader<TIn, TOut> {\n (\n implementation: (\n input: InferIO<TIn>,\n out: IOLayoutToSchema<TOut>,\n ) => InferIO<TOut>,\n ): TgpuVertexFn<CleanIO<TIn>, CleanIO<TOut>>;\n (\n implementation: string,\n ): TgpuVertexFn<CleanIO<TIn>, CleanIO<TOut>>;\n (\n strings: TemplateStringsArray,\n ...values: unknown[]\n ): TgpuVertexFn<CleanIO<TIn>, CleanIO<TOut>>;\n}\n\nexport interface TgpuVertexFn<\n // @ts-expect-error: We override the variance\n in VertexIn extends TgpuVertexFn.In = Record<string, never>,\n out VertexOut extends TgpuVertexFn.Out = TgpuVertexFn.Out,\n> extends TgpuNamable {\n readonly [$internal]: true;\n readonly shell: TgpuVertexFnShellHeader<VertexIn, VertexOut>;\n $uses(dependencyMap: Record<string, unknown>): this;\n}\n\nexport declare namespace TgpuVertexFn {\n type In = BaseData | Record<string, BaseData>;\n type Out = Record<string, BaseData>;\n}\n\nexport function vertexFn<VertexOut extends VertexOutConstrained>(options: {\n out: VertexOut;\n}): TgpuVertexFnShell<{}, VertexOut>;\n\nexport function vertexFn<\n VertexIn extends VertexInConstrained,\n // Not allowing single-value output, as it is better practice\n // to properly label what the vertex shader is outputting.\n VertexOut extends VertexOutConstrained,\n>(options: {\n in: VertexIn;\n out: VertexOut;\n}): TgpuVertexFnShell<VertexIn, VertexOut>;\n\n/**\n * Creates a shell of a typed entry function for the vertex shader stage. Any function\n * that implements this shell can run for each vertex, allowing the inner code to process\n * attributes and determine the final position of the vertex.\n *\n * @param options.in\n * Vertex attributes and builtins to be made available to functions that implement this shell.\n * @param options.out\n * A record containing the final position of the vertex, and any information\n * passed onto the fragment shader stage.\n */\nexport function vertexFn<\n VertexIn extends VertexInConstrained,\n // Not allowing single-value output, as it is better practice\n // to properly label what the vertex shader is outputting.\n VertexOut extends VertexOutConstrained,\n>(options: {\n in?: VertexIn;\n out: VertexOut;\n}): TgpuVertexFnShell<VertexIn, VertexOut> {\n if (Object.keys(options.out).length === 0) {\n throw new Error(\n `A vertexFn output cannot be empty since it must include the 'position' builtin.`,\n );\n }\n const shell: TgpuVertexFnShellHeader<VertexIn, VertexOut> = {\n in: options.in,\n out: options.out,\n argTypes: options.in && Object.keys(options.in).length !== 0\n ? [createIoSchema(options.in)]\n : [],\n entryPoint: 'vertex',\n };\n\n const call = (\n arg: Implementation | TemplateStringsArray,\n ...values: unknown[]\n ) => createVertexFn(shell, stripTemplate(arg, ...values));\n\n return Object.assign(call, shell) as unknown as TgpuVertexFnShell<\n VertexIn,\n VertexOut\n >;\n}\n\nexport function isTgpuVertexFn<\n VertexIn extends VertexInConstrained,\n VertexOut extends VertexOutConstrained,\n>(\n value: unknown,\n): value is TgpuVertexFn<VertexIn, VertexOut> {\n return (value as TgpuVertexFn<VertexIn, VertexOut>)?.shell?.entryPoint ===\n 'vertex';\n}\n\n// --------------\n// Implementation\n// --------------\n\nfunction createVertexFn(\n shell: TgpuVertexFnShellHeader<VertexInConstrained, VertexOutConstrained>,\n implementation: Implementation,\n): TgpuVertexFn<VertexInConstrained, VertexOutConstrained> {\n type This =\n & TgpuVertexFn<VertexInConstrained, VertexOutConstrained>\n & SelfResolvable\n & {\n [$internal]: true;\n [$getNameForward]: FnCore;\n };\n\n const core = createFnCore(implementation, '@vertex ');\n const inputType = shell.argTypes[0];\n\n const result: This = {\n shell,\n\n $uses(newExternals) {\n core.applyExternals(newExternals);\n return this;\n },\n\n [$internal]: true,\n [$getNameForward]: core,\n $name(newLabel: string): This {\n setName(this, newLabel);\n if (isNamable(inputType)) {\n inputType.$name(`${newLabel}_Input`);\n }\n return this;\n },\n\n [$resolve](ctx: ResolutionCtx): ResolvedSnippet {\n const outputWithLocation = createIoSchema(\n shell.out,\n ctx.varyingLocations,\n ).$name(`${getName(this) ?? ''}_Output`);\n\n if (typeof implementation === 'string') {\n if (inputType) {\n core.applyExternals({ In: inputType });\n }\n core.applyExternals({ Out: outputWithLocation });\n }\n\n return ctx.withSlots([[shaderStageSlot, 'vertex']], () =>\n core.resolve(\n ctx,\n shell.argTypes,\n outputWithLocation,\n ));\n },\n\n toString() {\n return `vertexFn:${getName(core) ?? '<unnamed>'}`;\n },\n };\n return result;\n}\n","import { builtin } from '../builtin.ts';\nimport { vertexFn } from '../core/function/tgpuVertexFn.ts';\nimport { vec2f } from '../data/vector.ts';\n\n/**\n * A vertex function that defines a single full-screen triangle out\n * of three points.\n *\n * @example\n * ```ts\n * import { common } from 'typegpu';\n *\n * const pipeline = root.createRenderPipeline({\n * vertex: common.fullScreenTriangle,\n * fragment: yourFragmentShader,\n * });\n *\n * pipeline.draw(3);\n * ```\n */\nexport const fullScreenTriangle = vertexFn({\n in: { vertexIndex: builtin.vertexIndex },\n out: { pos: builtin.position, uv: vec2f },\n})`{\n const pos = array<vec2f, 3>(vec2f(-1, -1), vec2f(3, -1), vec2f(-1, 3));\n const uv = array<vec2f, 3>(vec2f(0, 1), vec2f(2, 1), vec2f(0, -1));\n\n return Out(vec4f(pos[in.vertexIndex], 0, 1), uv[in.vertexIndex]);\n}`;\n"],"mappings":"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"}

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

import { cr as $internal, dr as $repr, it as f32 } from "./operators-HTxa_0k9.js";
//#region src/data/texture.ts
function textureDescriptorToSchema(desc) {
if ("multisampled" in desc) {
if (desc.multisampled) {
if (desc.dimension === "2d") return textureMultisampled2d(desc.sampleType);
throw new Error(`Multisampled textures only support '2d' dimension, got '${desc.dimension}'`);
}
switch (desc.dimension) {
case "1d": return texture1d(desc.sampleType);
case "2d": return texture2d(desc.sampleType);
case "2d-array": return texture2dArray(desc.sampleType);
case "3d": return texture3d(desc.sampleType);
case "cube": return textureCube(desc.sampleType);
case "cube-array": return textureCubeArray(desc.sampleType);
default: throw new Error(`Unsupported texture dimension: '${desc.dimension}'`);
}
}
if (!("access" in desc)) throw new Error("Descriptor is neither a sampled nor a storage texture");
switch (desc.dimension) {
case "1d": return textureStorage1d(desc.format, desc.access);
case "2d": return textureStorage2d(desc.format, desc.access);
case "2d-array": return textureStorage2dArray(desc.format, desc.access);
case "3d": return textureStorage3d(desc.format, desc.access);
default: throw new Error(`Unsupported storage texture dimension: '${desc.dimension}'`);
}
}
function createTexture(type, props) {
const sampleTypes = type.startsWith("texture_depth") ? [
"depth",
"float",
"unfilterable-float"
] : props.sampleType.type === "i32" ? ["sint"] : props.sampleType.type === "u32" ? ["uint"] : ["float", "unfilterable-float"];
return {
[$internal]: {},
[$repr]: void 0,
type,
bindingSampleType: sampleTypes,
...props
};
}
function createStorageTexture(type, props) {
return {
[$internal]: {},
[$repr]: void 0,
type,
...props
};
}
const textureCache = /* @__PURE__ */ new Map();
const accessModeMap = {
"write-only": "write",
"read-only": "read",
"read-write": "read_write"
};
function getOrCreate(key, factory) {
let cached = textureCache.get(key);
if (!cached) {
cached = factory();
textureCache.set(key, cached);
}
return cached;
}
function texture1d(sampleType) {
const actualSampleType = sampleType || f32;
return getOrCreate(`texture_1d<${actualSampleType.type}>`, () => createTexture("texture_1d", {
dimension: "1d",
sampleType: actualSampleType,
multisampled: false
}));
}
function texture2d(sampleType) {
const actualSampleType = sampleType || f32;
return getOrCreate(`texture_2d<${actualSampleType.type}>`, () => createTexture("texture_2d", {
dimension: "2d",
sampleType: actualSampleType,
multisampled: false
}));
}
function textureMultisampled2d(sampleType) {
const actualSampleType = sampleType || f32;
return getOrCreate(`texture_multisampled_2d<${actualSampleType.type}>`, () => createTexture("texture_multisampled_2d", {
dimension: "2d",
sampleType: actualSampleType,
multisampled: true
}));
}
function texture2dArray(sampleType) {
const actualSampleType = sampleType || f32;
return getOrCreate(`texture_2d_array<${actualSampleType.type}>`, () => createTexture("texture_2d_array", {
dimension: "2d-array",
sampleType: actualSampleType,
multisampled: false
}));
}
function textureCube(sampleType) {
const actualSampleType = sampleType || f32;
return getOrCreate(`texture_cube<${actualSampleType.type}>`, () => createTexture("texture_cube", {
dimension: "cube",
sampleType: actualSampleType,
multisampled: false
}));
}
function textureCubeArray(sampleType) {
const actualSampleType = sampleType || f32;
return getOrCreate(`texture_cube_array<${actualSampleType.type}>`, () => createTexture("texture_cube_array", {
dimension: "cube-array",
sampleType: actualSampleType,
multisampled: false
}));
}
function texture3d(sampleType) {
const actualSampleType = sampleType || f32;
return getOrCreate(`texture_3d<${actualSampleType.type}>`, () => createTexture("texture_3d", {
dimension: "3d",
sampleType: actualSampleType,
multisampled: false
}));
}
function textureStorage1d(format, access) {
const actualAccess = access || "write-only";
return getOrCreate(`texture_storage_1d<${format}, ${accessModeMap[actualAccess]}>`, () => createStorageTexture("texture_storage_1d", {
dimension: "1d",
format,
access: actualAccess
}));
}
function textureStorage2d(format, access) {
const actualAccess = access || "write-only";
return getOrCreate(`texture_storage_2d<${format}, ${accessModeMap[actualAccess]}>`, () => createStorageTexture("texture_storage_2d", {
dimension: "2d",
format,
access: actualAccess
}));
}
function textureStorage2dArray(format, access) {
const actualAccess = access || "write-only";
return getOrCreate(`texture_storage_2d_array<${format}, ${accessModeMap[actualAccess]}>`, () => createStorageTexture("texture_storage_2d_array", {
dimension: "2d-array",
format,
access: actualAccess
}));
}
function textureStorage3d(format, access) {
const actualAccess = access || "write-only";
return getOrCreate(`texture_storage_3d<${format}, ${accessModeMap[actualAccess]}>`, () => createStorageTexture("texture_storage_3d", {
dimension: "3d",
format,
access: actualAccess
}));
}
function textureDepth2d() {
return getOrCreate("texture_depth_2d", () => createTexture("texture_depth_2d", {
dimension: "2d",
sampleType: f32,
multisampled: false
}));
}
function textureDepthMultisampled2d() {
return getOrCreate("texture_depth_multisampled_2d", () => createTexture("texture_depth_multisampled_2d", {
dimension: "2d",
sampleType: f32,
multisampled: true
}));
}
function textureDepth2dArray() {
return getOrCreate("texture_depth_2d_array", () => createTexture("texture_depth_2d_array", {
dimension: "2d-array",
sampleType: f32,
multisampled: false
}));
}
function textureDepthCube() {
return getOrCreate("texture_depth_cube", () => createTexture("texture_depth_cube", {
dimension: "cube",
sampleType: f32,
multisampled: false
}));
}
function textureDepthCubeArray() {
return getOrCreate("texture_depth_cube_array", () => createTexture("texture_depth_cube_array", {
dimension: "cube-array",
sampleType: f32,
multisampled: false
}));
}
function textureExternal() {
return getOrCreate("texture_external", () => ({
[$internal]: {},
[$repr]: void 0,
type: "texture_external",
dimension: "2d"
}));
}
function isWgslTexture(value) {
return !!value[$internal] && typeof value.multisampled === "boolean";
}
function isWgslStorageTexture(value) {
return !!value[$internal] && typeof value.format === "string" && typeof value.access === "string";
}
//#endregion
export { textureMultisampled2d as _, texture2d as a, textureStorage2dArray as b, textureCube as c, textureDepth2dArray as d, textureDepthCube as f, textureExternal as g, textureDescriptorToSchema as h, texture1d as i, textureCubeArray as l, textureDepthMultisampled2d as m, isWgslStorageTexture as n, texture2dArray as o, textureDepthCubeArray as p, isWgslTexture as r, texture3d as s, accessModeMap as t, textureDepth2d as u, textureStorage1d as v, textureStorage3d as x, textureStorage2d as y };
//# sourceMappingURL=texture-Dg5ybJro.js.map
{"version":3,"file":"texture-Dg5ybJro.js","names":[],"sources":["../src/data/texture.ts"],"sourcesContent":["import type { StorageTextureFormats } from '../core/texture/textureFormats.ts';\nimport { $internal, $repr } from '../shared/symbols.ts';\nimport type { Default, WithDefaults } from '../shared/utilityTypes.ts';\nimport { f32 } from './numeric.ts';\nimport type { F32 } from './wgslTypes.ts';\nimport type { BaseData, TextureSampleTypes } from './wgslTypes.ts';\n\nexport type StorageTextureDimension = '1d' | '2d' | '2d-array' | '3d';\n\nexport type WgslTextureProps = {\n dimension: GPUTextureViewDimension;\n sampleType: TextureSampleTypes;\n multisampled: boolean;\n};\n\nexport type WgslStorageTextureProps = {\n dimension: StorageTextureDimension;\n format: StorageTextureFormats;\n access: GPUStorageTextureAccess;\n};\n\ntype ResolvedTextureProps<\n TProps extends Partial<WgslTextureProps>,\n> = WithDefaults<TProps, WgslTextureProps>;\n\ntype ResolvedStorageTextureProps<\n TProps extends Partial<WgslStorageTextureProps>,\n> = WithDefaults<TProps, WgslStorageTextureProps>;\n\ntype SampledTextureLiteral = `texture_${\n | '1d'\n | '2d'\n | '2d_array'\n | '3d'\n | 'cube'\n | 'cube_array'\n | 'multisampled_2d'\n | 'depth_multisampled_2d'\n | 'depth_2d'\n | 'depth_2d_array'\n | 'depth_cube'\n | 'depth_cube_array'}`;\ntype StorageTextureLiteral = `texture_storage_${\n | '1d'\n | '2d'\n | '2d_array'\n | '3d'}`;\n\nexport interface WgslTexture<\n TProps extends Partial<WgslTextureProps> = WgslTextureProps,\n> extends BaseData {\n readonly [$repr]: unknown;\n readonly type: SampledTextureLiteral;\n\n readonly sampleType: ResolvedTextureProps<TProps>['sampleType'];\n readonly dimension: ResolvedTextureProps<TProps>['dimension'];\n readonly multisampled: ResolvedTextureProps<TProps>['multisampled'];\n readonly bindingSampleType: [GPUTextureSampleType, ...GPUTextureSampleType[]];\n}\n\nexport interface WgslStorageTexture<\n TProps extends Partial<WgslStorageTextureProps> = WgslStorageTextureProps,\n> extends BaseData {\n readonly [$repr]: unknown;\n readonly type: StorageTextureLiteral;\n\n readonly format: ResolvedStorageTextureProps<TProps>['format'];\n readonly dimension: ResolvedStorageTextureProps<TProps>['dimension'];\n readonly access: ResolvedStorageTextureProps<TProps>['access'];\n}\n\nexport interface WgslExternalTexture extends BaseData {\n readonly [$repr]: textureExternal;\n readonly type: 'texture_external';\n\n readonly dimension: '2d';\n}\n\nexport interface WgslTexture1d<\n TSample extends TextureSampleTypes = TextureSampleTypes,\n> extends\n WgslTexture<{\n dimension: '1d';\n sampleType: TSample;\n multisampled: false;\n }> {\n readonly type: 'texture_1d';\n readonly [$repr]: texture1d<TSample>;\n}\n\nexport interface WgslTexture2d<\n TSample extends TextureSampleTypes = TextureSampleTypes,\n> extends\n WgslTexture<{\n dimension: '2d';\n sampleType: TSample;\n multisampled: false;\n }> {\n readonly type: 'texture_2d';\n readonly [$repr]: texture2d<TSample>;\n}\n\nexport interface WgslTextureMultisampled2d<\n TSample extends TextureSampleTypes = TextureSampleTypes,\n> extends\n WgslTexture<{\n dimension: '2d';\n sampleType: TSample;\n multisampled: true;\n }> {\n readonly type: 'texture_multisampled_2d';\n readonly [$repr]: textureMultisampled2d<TSample>;\n}\n\nexport interface WgslTexture2dArray<\n TSample extends TextureSampleTypes = TextureSampleTypes,\n> extends\n WgslTexture<{\n dimension: '2d-array';\n sampleType: TSample;\n multisampled: false;\n }> {\n readonly type: 'texture_2d_array';\n readonly [$repr]: texture2dArray<TSample>;\n}\n\nexport interface WgslTextureCube<\n TSample extends TextureSampleTypes = TextureSampleTypes,\n> extends\n WgslTexture<{\n dimension: 'cube';\n sampleType: TSample;\n multisampled: false;\n }> {\n readonly type: 'texture_cube';\n readonly [$repr]: textureCube<TSample>;\n}\n\nexport interface WgslTextureCubeArray<\n TSample extends TextureSampleTypes = TextureSampleTypes,\n> extends\n WgslTexture<{\n dimension: 'cube-array';\n sampleType: TSample;\n multisampled: false;\n }> {\n readonly type: 'texture_cube_array';\n readonly [$repr]: textureCubeArray<TSample>;\n}\n\nexport interface WgslTexture3d<\n TSample extends TextureSampleTypes = TextureSampleTypes,\n> extends\n WgslTexture<{\n dimension: '3d';\n sampleType: TSample;\n multisampled: false;\n }> {\n readonly type: 'texture_3d';\n readonly [$repr]: texture3d<TSample>;\n}\n\n// Depth textures (sample type is always f32)\nexport interface WgslTextureDepth2d extends\n WgslTexture<{\n dimension: '2d';\n sampleType: F32;\n multisampled: false;\n }> {\n readonly type: 'texture_depth_2d';\n readonly [$repr]: textureDepth2d;\n}\n\nexport interface WgslTextureDepthMultisampled2d extends\n WgslTexture<{\n dimension: '2d';\n sampleType: F32;\n multisampled: true;\n }> {\n readonly type: 'texture_depth_multisampled_2d';\n readonly [$repr]: textureDepthMultisampled2d;\n}\n\nexport interface WgslTextureDepth2dArray extends\n WgslTexture<{\n dimension: '2d-array';\n sampleType: F32;\n multisampled: false;\n }> {\n readonly type: 'texture_depth_2d_array';\n readonly [$repr]: textureDepth2dArray;\n}\n\nexport interface WgslTextureDepthCube extends\n WgslTexture<{\n dimension: 'cube';\n sampleType: F32;\n multisampled: false;\n }> {\n readonly type: 'texture_depth_cube';\n readonly [$repr]: textureDepthCube;\n}\n\nexport interface WgslTextureDepthCubeArray extends\n WgslTexture<{\n dimension: 'cube-array';\n sampleType: F32;\n multisampled: false;\n }> {\n readonly type: 'texture_depth_cube_array';\n readonly [$repr]: textureDepthCubeArray;\n}\n\n// Storage textures\nexport interface WgslStorageTexture1d<\n TFormat extends StorageTextureFormats = StorageTextureFormats,\n TAccess extends GPUStorageTextureAccess = GPUStorageTextureAccess,\n> extends\n WgslStorageTexture<{\n dimension: '1d';\n format: TFormat;\n access: TAccess;\n }> {\n readonly type: 'texture_storage_1d';\n readonly [$repr]: textureStorage1d<TFormat, TAccess>;\n}\n\nexport interface WgslStorageTexture2d<\n TFormat extends StorageTextureFormats = StorageTextureFormats,\n TAccess extends GPUStorageTextureAccess = GPUStorageTextureAccess,\n> extends\n WgslStorageTexture<{\n dimension: '2d';\n format: TFormat;\n access: TAccess;\n }> {\n readonly type: 'texture_storage_2d';\n readonly [$repr]: textureStorage2d<TFormat, TAccess>;\n}\n\nexport interface WgslStorageTexture2dArray<\n TFormat extends StorageTextureFormats = StorageTextureFormats,\n TAccess extends GPUStorageTextureAccess = GPUStorageTextureAccess,\n> extends\n WgslStorageTexture<{\n dimension: '2d-array';\n format: TFormat;\n access: TAccess;\n }> {\n readonly type: 'texture_storage_2d_array';\n readonly [$repr]: textureStorage2dArray<TFormat, TAccess>;\n}\n\nexport interface WgslStorageTexture3d<\n TFormat extends StorageTextureFormats = StorageTextureFormats,\n TAccess extends GPUStorageTextureAccess = GPUStorageTextureAccess,\n> extends\n WgslStorageTexture<{\n dimension: '3d';\n format: TFormat;\n access: TAccess;\n }> {\n readonly type: 'texture_storage_3d';\n readonly [$repr]: textureStorage3d<TFormat, TAccess>;\n}\n\ntype SampledTextureSchemaMap<T extends WgslTextureProps> = {\n multisampled: {\n '1d': never;\n '2d': WgslTextureMultisampled2d<T['sampleType']>;\n '2d-array': never;\n '3d': never;\n cube: never;\n 'cube-array': never;\n };\n sampled: {\n '1d': WgslTexture1d<T['sampleType']>;\n '2d': WgslTexture2d<T['sampleType']>;\n '2d-array': WgslTexture2dArray<T['sampleType']>;\n '3d': WgslTexture3d<T['sampleType']>;\n cube: WgslTextureCube<T['sampleType']>;\n 'cube-array': WgslTextureCubeArray<T['sampleType']>;\n };\n};\n\ntype StorageTextureSchemaMap<T extends WgslStorageTextureProps> = {\n '1d': WgslStorageTexture1d<T['format'], T['access']>;\n '2d': WgslStorageTexture2d<T['format'], T['access']>;\n '2d-array': WgslStorageTexture2dArray<T['format'], T['access']>;\n '3d': WgslStorageTexture3d<T['format'], T['access']>;\n};\n\nexport type TextureSchemaForDescriptor<\n T extends WgslTextureProps | WgslStorageTextureProps,\n> = T extends WgslTextureProps\n ? T['multisampled'] extends true\n ? SampledTextureSchemaMap<T>['multisampled'][T['dimension']]\n : SampledTextureSchemaMap<T>['sampled'][T['dimension']]\n : T extends WgslStorageTextureProps\n ? StorageTextureSchemaMap<T>[T['dimension']]\n : never;\n\nexport function textureDescriptorToSchema<\n T extends WgslTextureProps | WgslStorageTextureProps,\n>(desc: T): TextureSchemaForDescriptor<T> {\n if ('multisampled' in desc) {\n if (desc.multisampled) {\n if (desc.dimension === '2d') {\n return textureMultisampled2d(\n desc.sampleType,\n ) as TextureSchemaForDescriptor<T>;\n }\n throw new Error(\n `Multisampled textures only support '2d' dimension, got '${desc.dimension}'`,\n );\n }\n\n switch (desc.dimension) {\n case '1d':\n return texture1d(desc.sampleType) as TextureSchemaForDescriptor<T>;\n case '2d':\n return texture2d(desc.sampleType) as TextureSchemaForDescriptor<T>;\n case '2d-array':\n return texture2dArray(\n desc.sampleType,\n ) as TextureSchemaForDescriptor<T>;\n case '3d':\n return texture3d(desc.sampleType) as TextureSchemaForDescriptor<T>;\n case 'cube':\n return textureCube(\n desc.sampleType,\n ) as TextureSchemaForDescriptor<T>;\n case 'cube-array':\n return textureCubeArray(\n desc.sampleType,\n ) as TextureSchemaForDescriptor<T>;\n default:\n throw new Error(\n // @ts-expect-error\n `Unsupported texture dimension: '${desc.dimension}'`,\n );\n }\n }\n if (!('access' in desc)) {\n throw new Error('Descriptor is neither a sampled nor a storage texture');\n }\n\n switch (desc.dimension) {\n case '1d':\n return textureStorage1d(\n desc.format,\n desc.access,\n ) as TextureSchemaForDescriptor<T>;\n case '2d':\n return textureStorage2d(\n desc.format,\n desc.access,\n ) as TextureSchemaForDescriptor<T>;\n case '2d-array':\n return textureStorage2dArray(\n desc.format,\n desc.access,\n ) as TextureSchemaForDescriptor<T>;\n case '3d':\n return textureStorage3d(\n desc.format,\n desc.access,\n ) as TextureSchemaForDescriptor<T>;\n default:\n throw new Error(\n // @ts-expect-error\n `Unsupported storage texture dimension: '${desc.dimension}'`,\n );\n }\n}\n\nfunction createTexture<TProps extends WgslTextureProps>(\n type: SampledTextureLiteral,\n props: TProps,\n): WgslTexture<TProps> {\n const isDepth = type.startsWith('texture_depth');\n const sampleTypes: [GPUTextureSampleType, ...GPUTextureSampleType[]] = isDepth\n ? ['depth', 'float', 'unfilterable-float']\n : props.sampleType.type === 'i32'\n ? ['sint']\n : props.sampleType.type === 'u32'\n ? ['uint']\n : ['float', 'unfilterable-float'];\n\n return {\n [$internal]: {},\n [$repr]: undefined as unknown as WgslTexture<TProps>,\n type,\n bindingSampleType: sampleTypes,\n ...props,\n };\n}\n\nfunction createStorageTexture<TProps extends WgslStorageTextureProps>(\n type: StorageTextureLiteral,\n props: TProps,\n): WgslStorageTexture<TProps> {\n return {\n [$internal]: {},\n [$repr]: undefined as unknown as WgslStorageTexture<TProps>,\n type,\n ...props,\n };\n}\n\nconst textureCache = new Map<\n string,\n WgslTexture | WgslStorageTexture | WgslExternalTexture\n>();\n\nexport const accessModeMap: Record<GPUStorageTextureAccess, string> = {\n 'write-only': 'write',\n 'read-only': 'read',\n 'read-write': 'read_write',\n};\n\nfunction getOrCreate<\n T extends WgslTexture | WgslStorageTexture | WgslExternalTexture,\n>(key: string, factory: () => T): T {\n let cached = textureCache.get(key) as T | undefined;\n if (!cached) {\n cached = factory();\n textureCache.set(key, cached);\n }\n return cached;\n}\n\nexport interface texture1d<T extends TextureSampleTypes = TextureSampleTypes> {\n readonly kind: `texture_1d<${T['type']}>`;\n [$internal]: T;\n}\n\nexport function texture1d<T extends TextureSampleTypes>(\n sampleType: T,\n): WgslTexture1d<T>;\nexport function texture1d(): WgslTexture1d<F32>;\nexport function texture1d<T extends TextureSampleTypes>(sampleType?: T) {\n const actualSampleType = (sampleType || f32) as Default<T, F32>;\n const key = `texture_1d<${actualSampleType.type}>`;\n return getOrCreate(key, () =>\n createTexture('texture_1d', {\n dimension: '1d',\n sampleType: actualSampleType,\n multisampled: false,\n }));\n}\n\nexport interface texture2d<T extends TextureSampleTypes = TextureSampleTypes> {\n readonly kind: `texture_2d<${T['type']}>`;\n [$internal]: T;\n}\n\nexport function texture2d<T extends TextureSampleTypes>(\n sampleType: T,\n): WgslTexture2d<T>;\nexport function texture2d(): WgslTexture2d<F32>;\nexport function texture2d<T extends TextureSampleTypes>(sampleType?: T) {\n const actualSampleType = (sampleType || f32) as Default<T, F32>;\n const key = `texture_2d<${actualSampleType.type}>`;\n return getOrCreate(key, () =>\n createTexture('texture_2d', {\n dimension: '2d',\n sampleType: actualSampleType,\n multisampled: false,\n }));\n}\n\nexport interface textureMultisampled2d<\n T extends TextureSampleTypes = TextureSampleTypes,\n> {\n readonly kind: `texture_multisampled_2d<${T['type']}>`;\n [$internal]: T;\n}\n\nexport function textureMultisampled2d<T extends TextureSampleTypes>(\n sampleType: T,\n): WgslTextureMultisampled2d<T>;\nexport function textureMultisampled2d(): WgslTextureMultisampled2d<F32>;\nexport function textureMultisampled2d<T extends TextureSampleTypes>(\n sampleType?: T,\n) {\n const actualSampleType = (sampleType || f32) as Default<T, F32>;\n const key = `texture_multisampled_2d<${actualSampleType.type}>`;\n return getOrCreate(key, () =>\n createTexture('texture_multisampled_2d', {\n dimension: '2d',\n sampleType: actualSampleType,\n multisampled: true,\n }));\n}\n\nexport interface texture2dArray<\n T extends TextureSampleTypes = TextureSampleTypes,\n> {\n readonly kind: `texture_2d_array<${T['type']}>`;\n [$internal]: T;\n}\n\nexport function texture2dArray<T extends TextureSampleTypes>(\n sampleType: T,\n): WgslTexture2dArray<T>;\nexport function texture2dArray(): WgslTexture2dArray<F32>;\nexport function texture2dArray<T extends TextureSampleTypes>(sampleType?: T) {\n const actualSampleType = (sampleType || f32) as Default<T, F32>;\n const key = `texture_2d_array<${actualSampleType.type}>`;\n return getOrCreate(key, () =>\n createTexture('texture_2d_array', {\n dimension: '2d-array',\n sampleType: actualSampleType,\n multisampled: false,\n }));\n}\n\nexport interface textureCube<\n T extends TextureSampleTypes = TextureSampleTypes,\n> {\n readonly kind: `texture_cube<${T['type']}>`;\n [$internal]: T;\n}\n\nexport function textureCube<T extends TextureSampleTypes>(\n sampleType: T,\n): WgslTextureCube<T>;\nexport function textureCube(): WgslTextureCube<F32>;\nexport function textureCube<T extends TextureSampleTypes>(sampleType?: T) {\n const actualSampleType = (sampleType || f32) as Default<T, F32>;\n const key = `texture_cube<${actualSampleType.type}>`;\n return getOrCreate(key, () =>\n createTexture('texture_cube', {\n dimension: 'cube',\n sampleType: actualSampleType,\n multisampled: false,\n }));\n}\n\nexport interface textureCubeArray<\n T extends TextureSampleTypes = TextureSampleTypes,\n> {\n readonly kind: `texture_cube_array<${T['type']}>`;\n [$internal]: T;\n}\n\nexport function textureCubeArray<T extends TextureSampleTypes>(\n sampleType: T,\n): WgslTextureCubeArray<T>;\nexport function textureCubeArray(): WgslTextureCubeArray<F32>;\nexport function textureCubeArray<T extends TextureSampleTypes>(\n sampleType?: T,\n) {\n const actualSampleType = (sampleType || f32) as Default<T, F32>;\n const key = `texture_cube_array<${actualSampleType.type}>`;\n return getOrCreate(key, () =>\n createTexture('texture_cube_array', {\n dimension: 'cube-array',\n sampleType: actualSampleType,\n multisampled: false,\n }));\n}\n\nexport interface texture3d<T extends TextureSampleTypes = TextureSampleTypes> {\n readonly kind: `texture_3d<${T['type']}>`;\n [$internal]: T;\n}\n\nexport function texture3d<T extends TextureSampleTypes>(\n sampleType: T,\n): WgslTexture3d<T>;\nexport function texture3d(): WgslTexture3d<F32>;\nexport function texture3d<T extends TextureSampleTypes>(sampleType?: T) {\n const actualSampleType = (sampleType || f32) as Default<T, F32>;\n const key = `texture_3d<${actualSampleType.type}>`;\n return getOrCreate(key, () =>\n createTexture('texture_3d', {\n dimension: '3d',\n sampleType: actualSampleType,\n multisampled: false,\n }));\n}\n\nexport interface textureStorage1d<\n TFormat extends StorageTextureFormats = StorageTextureFormats,\n TAccess extends GPUStorageTextureAccess = GPUStorageTextureAccess,\n> {\n readonly kind: `texture_storage_1d<${TFormat}, ${TAccess}>`;\n [$internal]: [TFormat, TAccess];\n}\n\nexport function textureStorage1d<\n TFormat extends StorageTextureFormats,\n TAccess extends GPUStorageTextureAccess,\n>(format: TFormat, access: TAccess): WgslStorageTexture1d<TFormat, TAccess>;\nexport function textureStorage1d<TFormat extends StorageTextureFormats>(\n format: TFormat,\n): WgslStorageTexture1d<TFormat, 'write-only'>;\nexport function textureStorage1d<\n TFormat extends StorageTextureFormats,\n TAccess extends GPUStorageTextureAccess,\n>(format: TFormat, access?: TAccess) {\n const actualAccess = (access || 'write-only') as Default<\n TAccess,\n 'write-only'\n >;\n const key = `texture_storage_1d<${format}, ${accessModeMap[actualAccess]}>`;\n return getOrCreate(key, () =>\n createStorageTexture('texture_storage_1d', {\n dimension: '1d',\n format,\n access: actualAccess,\n }));\n}\n\nexport interface textureStorage2d<\n TFormat extends StorageTextureFormats = StorageTextureFormats,\n TAccess extends GPUStorageTextureAccess = GPUStorageTextureAccess,\n> {\n readonly kind: `texture_storage_2d<${TFormat}, ${TAccess}>`;\n [$internal]: [TFormat, TAccess];\n}\n\nexport function textureStorage2d<\n TFormat extends StorageTextureFormats,\n TAccess extends GPUStorageTextureAccess,\n>(format: TFormat, access: TAccess): WgslStorageTexture2d<TFormat, TAccess>;\nexport function textureStorage2d<TFormat extends StorageTextureFormats>(\n format: TFormat,\n): WgslStorageTexture2d<TFormat, 'write-only'>;\nexport function textureStorage2d<\n TFormat extends StorageTextureFormats,\n TAccess extends GPUStorageTextureAccess,\n>(format: TFormat, access?: TAccess) {\n const actualAccess = (access || 'write-only') as Default<\n TAccess,\n 'write-only'\n >;\n const key = `texture_storage_2d<${format}, ${accessModeMap[actualAccess]}>`;\n return getOrCreate(key, () =>\n createStorageTexture('texture_storage_2d', {\n dimension: '2d',\n format,\n access: actualAccess,\n }));\n}\n\nexport interface textureStorage2dArray<\n TFormat extends StorageTextureFormats = StorageTextureFormats,\n TAccess extends GPUStorageTextureAccess = GPUStorageTextureAccess,\n> {\n readonly kind: `texture_storage_2d_array<${TFormat}, ${TAccess}>`;\n [$internal]: [TFormat, TAccess];\n}\n\nexport function textureStorage2dArray<\n TFormat extends StorageTextureFormats,\n TAccess extends GPUStorageTextureAccess,\n>(\n format: TFormat,\n access: TAccess,\n): WgslStorageTexture2dArray<TFormat, TAccess>;\nexport function textureStorage2dArray<TFormat extends StorageTextureFormats>(\n format: TFormat,\n): WgslStorageTexture2dArray<TFormat, 'write-only'>;\nexport function textureStorage2dArray<\n TFormat extends StorageTextureFormats,\n TAccess extends GPUStorageTextureAccess,\n>(format: TFormat, access?: TAccess) {\n const actualAccess = (access || 'write-only') as Default<\n TAccess,\n 'write-only'\n >;\n const key = `texture_storage_2d_array<${format}, ${\n accessModeMap[actualAccess]\n }>`;\n return getOrCreate(\n key,\n () =>\n createStorageTexture('texture_storage_2d_array', {\n dimension: '2d-array',\n format,\n access: actualAccess,\n }),\n );\n}\n\nexport interface textureStorage3d<\n TFormat extends StorageTextureFormats = StorageTextureFormats,\n TAccess extends GPUStorageTextureAccess = GPUStorageTextureAccess,\n> {\n readonly kind: `texture_storage_3d<${TFormat}, ${TAccess}>`;\n [$internal]: [TFormat, TAccess];\n}\n\nexport function textureStorage3d<\n TFormat extends StorageTextureFormats,\n TAccess extends GPUStorageTextureAccess,\n>(format: TFormat, access: TAccess): WgslStorageTexture3d<TFormat, TAccess>;\nexport function textureStorage3d<TFormat extends StorageTextureFormats>(\n format: TFormat,\n): WgslStorageTexture3d<TFormat, 'write-only'>;\nexport function textureStorage3d<\n TFormat extends StorageTextureFormats,\n TAccess extends GPUStorageTextureAccess,\n>(format: TFormat, access?: TAccess) {\n const actualAccess = (access || 'write-only') as Default<\n TAccess,\n 'write-only'\n >;\n const key = `texture_storage_3d<${format}, ${accessModeMap[actualAccess]}>`;\n return getOrCreate(key, () =>\n createStorageTexture('texture_storage_3d', {\n dimension: '3d',\n format,\n access: actualAccess,\n }));\n}\n\nexport interface textureDepth2d {\n readonly kind: 'texture_depth_2d';\n [$internal]: F32;\n}\n\nexport function textureDepth2d() {\n const key = 'texture_depth_2d';\n return getOrCreate(key, () =>\n createTexture('texture_depth_2d', {\n dimension: '2d',\n sampleType: f32,\n multisampled: false,\n })) as WgslTextureDepth2d;\n}\n\nexport interface textureDepthMultisampled2d {\n readonly kind: 'texture_depth_multisampled_2d';\n [$internal]: F32;\n}\n\nexport function textureDepthMultisampled2d() {\n const key = 'texture_depth_multisampled_2d';\n return getOrCreate(key, () =>\n createTexture('texture_depth_multisampled_2d', {\n dimension: '2d',\n sampleType: f32,\n multisampled: true,\n })) as WgslTextureDepthMultisampled2d;\n}\n\nexport interface textureDepth2dArray {\n readonly kind: 'texture_depth_2d_array';\n [$internal]: F32;\n}\n\nexport function textureDepth2dArray() {\n const key = 'texture_depth_2d_array';\n return getOrCreate(key, () =>\n createTexture('texture_depth_2d_array', {\n dimension: '2d-array',\n sampleType: f32,\n multisampled: false,\n })) as WgslTextureDepth2dArray;\n}\n\nexport interface textureDepthCube {\n readonly kind: 'texture_depth_cube';\n [$internal]: F32;\n}\n\nexport function textureDepthCube() {\n const key = 'texture_depth_cube';\n return getOrCreate(key, () =>\n createTexture('texture_depth_cube', {\n dimension: 'cube',\n sampleType: f32,\n multisampled: false,\n })) as WgslTextureDepthCube;\n}\n\nexport interface textureDepthCubeArray {\n readonly kind: 'texture_depth_cube_array';\n [$internal]: F32;\n}\n\nexport function textureDepthCubeArray() {\n const key = 'texture_depth_cube_array';\n return getOrCreate(key, () =>\n createTexture('texture_depth_cube_array', {\n dimension: 'cube-array',\n sampleType: f32,\n multisampled: false,\n })) as WgslTextureDepthCubeArray;\n}\n\nexport interface textureExternal {\n readonly kind: 'texture_external';\n [$internal]: true;\n}\n\nexport function textureExternal() {\n const key = 'texture_external';\n return getOrCreate(key, () => ({\n [$internal]: {},\n [$repr]: undefined as unknown as textureExternal,\n type: 'texture_external',\n dimension: '2d',\n })) as WgslExternalTexture;\n}\n\nexport function isWgslTexture(value: unknown): value is WgslTexture {\n return (\n !!(value as WgslTexture)[$internal] &&\n typeof (value as WgslTexture).multisampled === 'boolean'\n );\n}\n\nexport function isWgslStorageTexture(\n value: unknown,\n): value is WgslStorageTexture {\n return (\n !!(value as WgslStorageTexture)[$internal] &&\n typeof (value as WgslStorageTexture).format === 'string' &&\n typeof (value as WgslStorageTexture).access === 'string'\n );\n}\n\nexport function isWgslExternalTexture(\n value: unknown,\n): value is WgslExternalTexture {\n return (\n !!(value as WgslExternalTexture)[$internal] &&\n (value as WgslExternalTexture).type === 'texture_external'\n );\n}\n"],"mappings":"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"}

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display