typegpu 0.12.4 → 0.12.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin.mjs +39 -67
- package/common/index.d.ts +1 -0
- package/common/index.js +1 -0
- package/common/writeChannels.d.ts +31 -0
- package/common/writeChannels.js +32 -0
- package/core/commandEncoder/computePass.d.ts +13 -0
- package/core/commandEncoder/computePass.js +5 -2
- package/core/commandEncoder/renderPass.d.ts +18 -4
- package/core/commandEncoder/renderPass.js +6 -2
- package/core/declare/tgpuDeclare.d.ts +11 -0
- package/core/declare/tgpuDeclare.js +1 -1
- package/core/immediate/immediateVar.d.ts +52 -0
- package/core/immediate/immediateVar.js +149 -0
- package/core/pipeline/computePipeline.d.ts +23 -0
- package/core/pipeline/computePipeline.js +26 -9
- package/core/pipeline/drawState.d.ts +8 -4
- package/core/pipeline/drawState.js +41 -51
- package/core/pipeline/priors.js +1 -0
- package/core/pipeline/renderPipeline.d.ts +24 -1
- package/core/pipeline/renderPipeline.js +18 -1
- package/core/root/init.js +3 -0
- package/core/root/rootTypes.d.ts +11 -0
- package/core/slot/slotTypes.d.ts +2 -1
- package/core/texture/texture.d.ts +20 -14
- package/core/texture/texture.js +70 -65
- package/core/texture/textureUtils.d.ts +3 -6
- package/core/texture/textureUtils.js +142 -165
- package/core/texture/textureWrite.d.ts +61 -0
- package/core/texture/textureWrite.js +59 -0
- package/data/dataIO.d.ts +2 -2
- package/data/generalizeFn.d.ts +17 -1
- package/data/generalizeFn.js +39 -2
- package/data/snippet.d.ts +5 -1
- package/data/snippet.js +1 -0
- package/data/wgslTypes.d.ts +1 -1
- package/errors.d.ts +7 -0
- package/errors.js +15 -0
- package/indexNamedExports.d.ts +5 -2
- package/indexNamedExports.js +2 -1
- package/internal.d.ts +1 -1
- package/internal.js +1 -1
- package/package.json +2 -2
- package/resolutionCtx.d.ts +5 -0
- package/resolutionCtx.js +11 -0
- package/serial/restore.d.ts +3 -1
- package/serial/restore.js +2 -0
- package/shared/meta.js +1 -1
- package/shared/symbols.js +1 -1
- package/shared/tseynit.d.ts +1 -0
- package/shared/tseynit.js +39 -7
- package/shared/utilityTypes.d.ts +1 -1
- package/std/atomic.d.ts +13 -0
- package/std/atomic.js +63 -29
- package/std/bitcast.js +4 -0
- package/std/boolean.d.ts +1 -1
- package/std/boolean.js +35 -21
- package/std/derivative.js +17 -12
- package/std/index.d.ts +4 -4
- package/std/index.js +5 -5
- package/std/numeric.d.ts +5 -1
- package/std/numeric.js +75 -8
- package/std/operators.d.ts +2 -2
- package/std/operators.js +29 -17
- package/std/packing.d.ts +61 -1
- package/std/packing.js +214 -25
- package/std/subgroup.d.ts +4 -0
- package/std/subgroup.js +34 -0
- package/std/texture.d.ts +13 -0
- package/std/texture.js +48 -0
- package/tgpuUnstable.d.ts +1 -0
- package/tgpuUnstable.js +1 -0
- package/tgsl/conversion.d.ts +2 -0
- package/tgsl/conversion.js +3 -0
- package/tgsl/shaderGenerator.d.ts +1 -1
- package/tgsl/wgslGenerator.d.ts +5 -0
- package/tgsl/wgslGenerator.js +218 -50
- package/types.d.ts +9 -1
- package/types.js +5 -0
|
@@ -6,6 +6,7 @@ import { $getNameForward, $internal, $resolve, $soul } from "../../shared/symbol
|
|
|
6
6
|
import { isBindGroup, isBindGroupLayout, } from "../../tgpuBindGroupLayout.js";
|
|
7
7
|
import { INTERNAL_adoptCommandEncoder, INTERNAL_createCommandEncoder, } from "../commandEncoder/commandEncoder.js";
|
|
8
8
|
import { INTERNAL_adoptComputePass } from "../commandEncoder/computePass.js";
|
|
9
|
+
import { createImmediateSnapshot, isImmediateVar, validateImmediateUsage, } from "../immediate/immediateVar.js";
|
|
9
10
|
import { emitComputeDispatch, finalizeOwnEncoder } from "./drawState.js";
|
|
10
11
|
import { isGPUCommandEncoder, isGPUComputePassEncoder, isTgpuCommandEncoder, isTgpuComputePass, } from "./typeGuards.js";
|
|
11
12
|
import { isGPUBuffer } from "../../types.js";
|
|
@@ -30,9 +31,11 @@ export function INTERNAL_restoreComputePipeline(soul, ctx) {
|
|
|
30
31
|
// The catchall group is already one of `bindGroups`, keyed by the layout it was resolved with
|
|
31
32
|
catchall: undefined,
|
|
32
33
|
logResources: undefined,
|
|
34
|
+
usedImmediate: soul.usedImmediate,
|
|
33
35
|
});
|
|
34
36
|
const pipeline = new TgpuComputePipelineImpl(core, {
|
|
35
37
|
bindGroupLayoutMap: new Map(soul.bindGroups),
|
|
38
|
+
immediatesMap: new Map(soul.immediates),
|
|
36
39
|
});
|
|
37
40
|
return restoreTimestampPriors(pipeline, soul);
|
|
38
41
|
}
|
|
@@ -59,6 +62,8 @@ class TgpuComputePipelineImpl {
|
|
|
59
62
|
soul.raw = memo.pipeline;
|
|
60
63
|
soul.usedBindGroupLayouts = memo.usedBindGroupLayouts;
|
|
61
64
|
soul.bindGroups = collectBindGroupPairs(memo.usedBindGroupLayouts, memo.catchall, priors.bindGroupLayoutMap);
|
|
65
|
+
soul.usedImmediate = memo.usedImmediate;
|
|
66
|
+
soul.immediates = [...(priors.immediatesMap ?? [])];
|
|
62
67
|
soul.timestampWrites = priors.timestampWrites;
|
|
63
68
|
soul.performanceCallback = priors.performanceCallback;
|
|
64
69
|
soul.nonTransferablePriors = nonTransferablePriorsOf(priors);
|
|
@@ -78,7 +83,7 @@ class TgpuComputePipelineImpl {
|
|
|
78
83
|
const { core, priors } = this[$internal];
|
|
79
84
|
return new TgpuComputePipelineImpl(core, { ...priors, ...patch });
|
|
80
85
|
}
|
|
81
|
-
with(first,
|
|
86
|
+
with(first, resource) {
|
|
82
87
|
const internals = this[$internal];
|
|
83
88
|
if (isTgpuComputePass(first)) {
|
|
84
89
|
return this.#withPriors({ pass: first, encoder: undefined });
|
|
@@ -98,10 +103,15 @@ class TgpuComputePipelineImpl {
|
|
|
98
103
|
encoder: INTERNAL_adoptCommandEncoder(internals.root, first),
|
|
99
104
|
});
|
|
100
105
|
}
|
|
106
|
+
if (isImmediateVar(first)) {
|
|
107
|
+
return this.#withPriors({
|
|
108
|
+
immediatesMap: new Map(internals.priors.immediatesMap).set(first, createImmediateSnapshot(first, resource)),
|
|
109
|
+
});
|
|
110
|
+
}
|
|
101
111
|
if (isBindGroup(first) || isBindGroupLayout(first)) {
|
|
102
112
|
const [layout, group] = isBindGroup(first)
|
|
103
113
|
? [first.layout, first]
|
|
104
|
-
: [first,
|
|
114
|
+
: [first, resource];
|
|
105
115
|
return this.#withPriors({
|
|
106
116
|
bindGroupLayoutMap: new Map([
|
|
107
117
|
...(internals.priors.bindGroupLayoutMap ?? []),
|
|
@@ -111,6 +121,9 @@ class TgpuComputePipelineImpl {
|
|
|
111
121
|
}
|
|
112
122
|
throw new Error('Unsupported value passed into .with()');
|
|
113
123
|
}
|
|
124
|
+
pipe(transform) {
|
|
125
|
+
return transform(this);
|
|
126
|
+
}
|
|
114
127
|
withPerformanceCallback(callback) {
|
|
115
128
|
const internals = this[$internal];
|
|
116
129
|
if (internals.priors.timestampWrites) {
|
|
@@ -217,19 +230,20 @@ class ComputePipelineCore {
|
|
|
217
230
|
if (this.#initAsyncPromise === undefined) {
|
|
218
231
|
// the pipeline did not start resolution & compilation
|
|
219
232
|
const device = this.root.device;
|
|
220
|
-
const { resolutionResult, module } = this.resolveAndCreateShaderModule();
|
|
221
|
-
const { usedBindGroupLayouts, catchall, logResources } = resolutionResult;
|
|
233
|
+
const { resolutionResult, module, immediateSize } = this.resolveAndCreateShaderModule();
|
|
234
|
+
const { usedBindGroupLayouts, catchall, logResources, usedImmediate } = resolutionResult;
|
|
222
235
|
this.#initAsyncPromise = device
|
|
223
236
|
.createComputePipelineAsync({
|
|
224
237
|
label: getName(this) ?? '<unnamed>',
|
|
225
238
|
layout: device.createPipelineLayout({
|
|
226
239
|
label: `${getName(this) ?? '<unnamed>'} - Pipeline Layout`,
|
|
227
240
|
bindGroupLayouts: usedBindGroupLayouts.map((l) => this.root.unwrap(l)),
|
|
241
|
+
immediateSize,
|
|
228
242
|
}),
|
|
229
243
|
compute: { module },
|
|
230
244
|
})
|
|
231
245
|
.then((pipeline) => {
|
|
232
|
-
this.#memo = { pipeline, usedBindGroupLayouts, catchall, logResources };
|
|
246
|
+
this.#memo = { pipeline, usedBindGroupLayouts, catchall, logResources, usedImmediate };
|
|
233
247
|
this.#performanceTracker.measureCompile(device);
|
|
234
248
|
})
|
|
235
249
|
.finally(() => {
|
|
@@ -246,20 +260,22 @@ class ComputePipelineCore {
|
|
|
246
260
|
throw new Error("'pipeline.initAsync()' was called and is not yet resolved.");
|
|
247
261
|
}
|
|
248
262
|
const device = this.root.device;
|
|
249
|
-
const { resolutionResult, module } = this.resolveAndCreateShaderModule();
|
|
250
|
-
const { usedBindGroupLayouts, catchall, logResources } = resolutionResult;
|
|
263
|
+
const { resolutionResult, module, immediateSize } = this.resolveAndCreateShaderModule();
|
|
264
|
+
const { usedBindGroupLayouts, catchall, logResources, usedImmediate } = resolutionResult;
|
|
251
265
|
this.#memo = {
|
|
252
266
|
pipeline: device.createComputePipeline({
|
|
253
267
|
label: getName(this) ?? '<unnamed>',
|
|
254
268
|
layout: device.createPipelineLayout({
|
|
255
269
|
label: `${getName(this) ?? '<unnamed>'} - Pipeline Layout`,
|
|
256
270
|
bindGroupLayouts: usedBindGroupLayouts.map((l) => this.root.unwrap(l)),
|
|
271
|
+
immediateSize,
|
|
257
272
|
}),
|
|
258
273
|
compute: { module },
|
|
259
274
|
}),
|
|
260
275
|
usedBindGroupLayouts,
|
|
261
276
|
catchall,
|
|
262
277
|
logResources,
|
|
278
|
+
usedImmediate,
|
|
263
279
|
};
|
|
264
280
|
this.#performanceTracker.measureCompile(device);
|
|
265
281
|
}
|
|
@@ -281,15 +297,16 @@ class ComputePipelineCore {
|
|
|
281
297
|
: undefined,
|
|
282
298
|
root: this.root,
|
|
283
299
|
}));
|
|
284
|
-
const { code, usedBindGroupLayouts, catchall } = resolutionResult;
|
|
300
|
+
const { code, usedBindGroupLayouts, catchall, usedImmediate } = resolutionResult;
|
|
285
301
|
if (catchall !== undefined) {
|
|
286
302
|
usedBindGroupLayouts[catchall[0]]?.$name(`${getName(this) ?? '<unnamed>'} - Automatic Bind Group & Layout`);
|
|
287
303
|
}
|
|
288
304
|
warnIfOverflow(usedBindGroupLayouts, device.limits);
|
|
305
|
+
const immediateSize = usedImmediate ? validateImmediateUsage(usedImmediate, this.root) : 0;
|
|
289
306
|
const module = device.createShaderModule({
|
|
290
307
|
label: `${getName(this) ?? '<unnamed>'} - Shader`,
|
|
291
308
|
code,
|
|
292
309
|
});
|
|
293
|
-
return { resolutionResult, module };
|
|
310
|
+
return { resolutionResult, module, immediateSize };
|
|
294
311
|
}
|
|
295
312
|
}
|
|
@@ -5,6 +5,7 @@ import type { IndexFlag, TgpuBuffer, VertexFlag } from '../buffer/buffer.ts';
|
|
|
5
5
|
import type { TgpuCommandEncoder } from '../commandEncoder/commandEncoder.ts';
|
|
6
6
|
import type { ComputePassInternals } from '../commandEncoder/computePass.ts';
|
|
7
7
|
import type { RenderPassInternals } from '../commandEncoder/renderPass.ts';
|
|
8
|
+
import { ImmediatePassState } from '../immediate/immediateVar.ts';
|
|
8
9
|
import type { ExperimentalTgpuRoot } from '../root/rootTypes.ts';
|
|
9
10
|
import type { TgpuVertexLayout } from '../vertexLayout/vertexLayout.ts';
|
|
10
11
|
import type { TgpuComputePipeline } from './computePipeline.ts';
|
|
@@ -24,6 +25,7 @@ export interface IndexBufferEntry {
|
|
|
24
25
|
export declare class RenderDrawState {
|
|
25
26
|
readonly bindGroups: Map<TgpuBindGroupLayout<Record<string, import("../../tgpuBindGroupLayout.ts").TgpuLayoutEntry | null>>, TgpuBindGroup | GPUBindGroup>;
|
|
26
27
|
readonly vertexBuffers: Map<TgpuVertexLayout<import("../../data/wgslTypes.ts").WgslArray<BaseData> | import("../../data/dataTypes.ts").Disarray<BaseData>>, VertexBufferEntry>;
|
|
28
|
+
readonly immediates: ImmediatePassState;
|
|
27
29
|
currentPipeline: TgpuRenderPipeline | undefined;
|
|
28
30
|
indexBuffer: IndexBufferEntry | undefined;
|
|
29
31
|
stencilReference: GPUStencilValue | undefined;
|
|
@@ -35,15 +37,17 @@ export declare class RenderDrawState {
|
|
|
35
37
|
}
|
|
36
38
|
export declare class ComputeDrawState {
|
|
37
39
|
readonly bindGroups: Map<TgpuBindGroupLayout<Record<string, import("../../tgpuBindGroupLayout.ts").TgpuLayoutEntry | null>>, TgpuBindGroup | GPUBindGroup>;
|
|
40
|
+
readonly immediates: ImmediatePassState;
|
|
38
41
|
currentPipeline: TgpuComputePipeline | undefined;
|
|
39
42
|
version: number;
|
|
40
43
|
rawAccessed: boolean;
|
|
41
44
|
}
|
|
42
45
|
export declare function recordBindGroup(state: RenderDrawState | ComputeDrawState, first: TgpuBindGroup | TgpuBindGroupLayout, bindGroup: TgpuBindGroup | GPUBindGroup | undefined): void;
|
|
43
|
-
/**
|
|
44
|
-
export declare function
|
|
45
|
-
|
|
46
|
-
|
|
46
|
+
/** Makes the pipeline current; its held state is resolved at draw time, below what the pass holds */
|
|
47
|
+
export declare function selectPipeline<TPipeline>(state: {
|
|
48
|
+
currentPipeline: TPipeline | undefined;
|
|
49
|
+
version: number;
|
|
50
|
+
}, pipeline: TPipeline): void;
|
|
47
51
|
export declare function requireIndexBuffer(indexBuffer: IndexBufferEntry | undefined): void;
|
|
48
52
|
export declare function finalizeOwnEncoder(encoder: TgpuCommandEncoder, core: object, logResources: LogResources | undefined, priors: TimestampWritesPriors & {
|
|
49
53
|
readonly encoder?: TgpuCommandEncoder | undefined;
|
|
@@ -4,10 +4,12 @@ import { logger } from "../../tgpuLogger.js";
|
|
|
4
4
|
import { isBindGroup, } from "../../tgpuBindGroupLayout.js";
|
|
5
5
|
import { logDataFromGPU } from "../../tgsl/consoleLog/deserializers.js";
|
|
6
6
|
import { isBuffer } from "../../types.js";
|
|
7
|
+
import { ImmediatePassState } from "../immediate/immediateVar.js";
|
|
7
8
|
import { queueTimestampResolve } from "./timeable.js";
|
|
8
9
|
export class RenderDrawState {
|
|
9
10
|
bindGroups = new Map();
|
|
10
11
|
vertexBuffers = new Map();
|
|
12
|
+
immediates = new ImmediatePassState();
|
|
11
13
|
currentPipeline;
|
|
12
14
|
indexBuffer;
|
|
13
15
|
stencilReference;
|
|
@@ -19,6 +21,7 @@ export class RenderDrawState {
|
|
|
19
21
|
}
|
|
20
22
|
export class ComputeDrawState {
|
|
21
23
|
bindGroups = new Map();
|
|
24
|
+
immediates = new ImmediatePassState();
|
|
22
25
|
currentPipeline;
|
|
23
26
|
version = 0;
|
|
24
27
|
rawAccessed = false;
|
|
@@ -32,38 +35,12 @@ export function recordBindGroup(state, first, bindGroup) {
|
|
|
32
35
|
}
|
|
33
36
|
state.version++;
|
|
34
37
|
}
|
|
35
|
-
/**
|
|
36
|
-
export function
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
for (const [layout, group] of priors.bindGroupLayoutMap) {
|
|
41
|
-
state.bindGroups.set(layout, group);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
if (priors.vertexLayoutMap) {
|
|
45
|
-
for (const [layout, buffer] of priors.vertexLayoutMap) {
|
|
46
|
-
state.vertexBuffers.set(layout, { buffer, offset: undefined, size: undefined });
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
if (priors.indexBuffer) {
|
|
50
|
-
state.indexBuffer = priors.indexBuffer;
|
|
51
|
-
}
|
|
52
|
-
if (priors.stencilReference !== undefined) {
|
|
53
|
-
state.stencilReference = priors.stencilReference;
|
|
54
|
-
}
|
|
55
|
-
state.version++;
|
|
56
|
-
}
|
|
57
|
-
/** The compute counterpart of {@link stampRenderPipeline} */
|
|
58
|
-
export function stampComputePipeline(state, pipeline) {
|
|
59
|
-
const { priors } = pipeline[$internal];
|
|
60
|
-
state.currentPipeline = pipeline;
|
|
61
|
-
if (priors.bindGroupLayoutMap) {
|
|
62
|
-
for (const [layout, group] of priors.bindGroupLayoutMap) {
|
|
63
|
-
state.bindGroups.set(layout, group);
|
|
64
|
-
}
|
|
38
|
+
/** Makes the pipeline current; its held state is resolved at draw time, below what the pass holds */
|
|
39
|
+
export function selectPipeline(state, pipeline) {
|
|
40
|
+
if (state.currentPipeline !== pipeline) {
|
|
41
|
+
state.currentPipeline = pipeline;
|
|
42
|
+
state.version++;
|
|
65
43
|
}
|
|
66
|
-
state.version++;
|
|
67
44
|
}
|
|
68
45
|
function applyIndexBuffer(encoder, root, entry) {
|
|
69
46
|
const { buffer, indexFormat, offsetBytes, sizeBytes } = entry;
|
|
@@ -117,25 +94,36 @@ function applyVertexBuffers(encoder, root, usedVertexLayouts, resolveVertexBuffe
|
|
|
117
94
|
}
|
|
118
95
|
}
|
|
119
96
|
function applyRenderPipelineState(encoder, root, pipeline, passState) {
|
|
120
|
-
const
|
|
97
|
+
const { core, priors } = pipeline[$internal];
|
|
98
|
+
const memo = core.unwrap();
|
|
121
99
|
encoder.setPipeline(memo.pipeline);
|
|
122
|
-
applyBindGroups(encoder, root, memo.usedBindGroupLayouts, memo.catchall, (layout) => passState.bindGroups.get(layout));
|
|
123
|
-
applyVertexBuffers(encoder, root, memo.usedVertexLayouts, (vertexLayout) =>
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
100
|
+
applyBindGroups(encoder, root, memo.usedBindGroupLayouts, memo.catchall, (layout) => passState.bindGroups.get(layout) ?? priors.bindGroupLayoutMap?.get(layout));
|
|
101
|
+
applyVertexBuffers(encoder, root, memo.usedVertexLayouts, (vertexLayout) => {
|
|
102
|
+
const passEntry = passState.vertexBuffers.get(vertexLayout);
|
|
103
|
+
if (passEntry !== undefined) {
|
|
104
|
+
return passEntry;
|
|
105
|
+
}
|
|
106
|
+
const buffer = priors.vertexLayoutMap?.get(vertexLayout);
|
|
107
|
+
return buffer !== undefined ? { buffer } : undefined;
|
|
108
|
+
});
|
|
109
|
+
const indexBuffer = passState.indexBuffer ?? priors.indexBuffer;
|
|
110
|
+
if (indexBuffer !== undefined) {
|
|
111
|
+
applyIndexBuffer(encoder, root, indexBuffer);
|
|
112
|
+
}
|
|
113
|
+
if (typeof encoder.setStencilReference === 'function') {
|
|
114
|
+
const stencilReference = passState.stencilReference ?? priors.stencilReference ?? 0;
|
|
115
|
+
const dirty = passState.rawAccessed || stencilReference !== passState.appliedStencilReference;
|
|
116
|
+
if (dirty) {
|
|
117
|
+
encoder.setStencilReference(stencilReference);
|
|
118
|
+
passState.appliedStencilReference = stencilReference;
|
|
132
119
|
}
|
|
133
120
|
}
|
|
134
121
|
}
|
|
135
122
|
function applyComputePipelineState(encoder, root, pipeline, passState) {
|
|
136
|
-
const
|
|
123
|
+
const { core, priors } = pipeline[$internal];
|
|
124
|
+
const memo = core.unwrap();
|
|
137
125
|
encoder.setPipeline(memo.pipeline);
|
|
138
|
-
applyBindGroups(encoder, root, memo.usedBindGroupLayouts, memo.catchall, (layout) => passState.bindGroups.get(layout));
|
|
126
|
+
applyBindGroups(encoder, root, memo.usedBindGroupLayouts, memo.catchall, (layout) => passState.bindGroups.get(layout) ?? priors.bindGroupLayoutMap?.get(layout));
|
|
139
127
|
}
|
|
140
128
|
export function requireIndexBuffer(indexBuffer) {
|
|
141
129
|
if (!indexBuffer) {
|
|
@@ -191,11 +179,9 @@ function reportIgnoredPriors(core, owner, hasTimestampWrites, logResources, pass
|
|
|
191
179
|
export function emitRenderDraw(root, passInternals, pipeline, usesIndexBuffer, emit, ownsPass = false) {
|
|
192
180
|
const { state, rawPass } = passInternals;
|
|
193
181
|
const { core, priors } = pipeline[$internal];
|
|
194
|
-
|
|
195
|
-
stampRenderPipeline(state, pipeline);
|
|
196
|
-
}
|
|
182
|
+
selectPipeline(state, pipeline);
|
|
197
183
|
if (usesIndexBuffer) {
|
|
198
|
-
requireIndexBuffer(state.indexBuffer);
|
|
184
|
+
requireIndexBuffer(state.indexBuffer ?? priors.indexBuffer);
|
|
199
185
|
}
|
|
200
186
|
const memo = core.unwrap();
|
|
201
187
|
if (!ownsPass) {
|
|
@@ -205,14 +191,15 @@ export function emitRenderDraw(root, passInternals, pipeline, usesIndexBuffer, e
|
|
|
205
191
|
applyRenderPipelineState(rawPass, root, pipeline, state);
|
|
206
192
|
passInternals.appliedVersion = state.version;
|
|
207
193
|
}
|
|
194
|
+
if (memo.usedImmediate !== undefined) {
|
|
195
|
+
state.immediates.write(rawPass, memo.usedImmediate, priors.immediatesMap, !state.rawAccessed);
|
|
196
|
+
}
|
|
208
197
|
emit(rawPass);
|
|
209
198
|
}
|
|
210
199
|
export function emitComputeDispatch(root, passInternals, pipeline, emit, ownsPass = false) {
|
|
211
200
|
const { state, rawPass } = passInternals;
|
|
212
201
|
const { core, priors } = pipeline[$internal];
|
|
213
|
-
|
|
214
|
-
stampComputePipeline(state, pipeline);
|
|
215
|
-
}
|
|
202
|
+
selectPipeline(state, pipeline);
|
|
216
203
|
const memo = core.unwrap();
|
|
217
204
|
if (!ownsPass) {
|
|
218
205
|
reportIgnoredPriors(core, passInternals.owner, !!priors.timestampWrites, memo.logResources, 'compute');
|
|
@@ -221,5 +208,8 @@ export function emitComputeDispatch(root, passInternals, pipeline, emit, ownsPas
|
|
|
221
208
|
applyComputePipelineState(rawPass, root, pipeline, state);
|
|
222
209
|
passInternals.appliedVersion = state.version;
|
|
223
210
|
}
|
|
211
|
+
if (memo.usedImmediate !== undefined) {
|
|
212
|
+
state.immediates.write(rawPass, memo.usedImmediate, priors.immediatesMap, !state.rawAccessed);
|
|
213
|
+
}
|
|
224
214
|
emit(rawPass);
|
|
225
215
|
}
|
package/core/pipeline/priors.js
CHANGED
|
@@ -3,8 +3,9 @@ import type { IndexFlag, IndirectFlag, TgpuBuffer, VertexFlag } from '../buffer/
|
|
|
3
3
|
import type { TgpuQuerySet } from '../querySet/querySet.ts';
|
|
4
4
|
import { type Disarray, type UndecorateRecord } from '../../data/dataTypes.ts';
|
|
5
5
|
import { type ResolvedSnippet } from '../../data/snippet.ts';
|
|
6
|
-
import { type AnyVecInstance, type BaseData, type U16, type U32, type v4f, Void, type WgslArray, type WgslStruct } from '../../data/wgslTypes.ts';
|
|
6
|
+
import { type AnyVecInstance, type AnyWgslData, type BaseData, type U16, type U32, type v4f, Void, type WgslArray, type WgslStruct } from '../../data/wgslTypes.ts';
|
|
7
7
|
import type { TgpuNamable } from '../../shared/meta.ts';
|
|
8
|
+
import type { InferInput } from '../../shared/repr.ts';
|
|
8
9
|
import type { TgpuDeviceOwningSoul } from '../../shared/soul.ts';
|
|
9
10
|
import { $getNameForward, $internal, $resolve, $soul } from '../../shared/symbols.ts';
|
|
10
11
|
import type { AnyVertexAttribs } from '../../shared/vertexFormat.ts';
|
|
@@ -19,6 +20,7 @@ import type { TgpuSlot } from '../slot/slotTypes.ts';
|
|
|
19
20
|
import { type TgpuVertexLayout } from '../vertexLayout/vertexLayout.ts';
|
|
20
21
|
import { type TgpuCommandEncoder } from '../commandEncoder/commandEncoder.ts';
|
|
21
22
|
import type { ColorAttachment, DepthStencilAttachment } from '../commandEncoder/attachments.ts';
|
|
23
|
+
import { type ImmediateSnapshot, type TgpuImmediateVar } from '../immediate/immediateVar.ts';
|
|
22
24
|
import { type TgpuRenderCommands } from '../commandEncoder/renderPass.ts';
|
|
23
25
|
import { type Timeable, type TimestampWritesPriors } from './timeable.ts';
|
|
24
26
|
import { type PrimitiveOffsetInfo } from '../../data/offsetUtils.ts';
|
|
@@ -34,6 +36,8 @@ export interface TgpuRenderPipelineSoul extends TgpuDeviceOwningSoul<'render-pip
|
|
|
34
36
|
usedVertexLayouts?: TgpuVertexLayout[] | undefined;
|
|
35
37
|
fragmentOut?: BaseData | undefined;
|
|
36
38
|
bindGroups?: [TgpuBindGroupLayout, TgpuBindGroup | GPUBindGroup][] | undefined;
|
|
39
|
+
usedImmediate?: TgpuImmediateVar | undefined;
|
|
40
|
+
immediates?: [TgpuImmediateVar, ImmediateSnapshot][] | undefined;
|
|
37
41
|
vertexBuffers?: [TgpuVertexLayout, (TgpuBuffer<BaseData> & VertexFlag) | GPUBuffer][] | undefined;
|
|
38
42
|
indexBuffer?: {
|
|
39
43
|
buffer: (TgpuBuffer<BaseData> & IndexFlag) | GPUBuffer;
|
|
@@ -76,6 +80,16 @@ export interface TgpuRenderPipeline<in Targets = never> extends TgpuNamable, Sel
|
|
|
76
80
|
with<Entries extends Record<string, TgpuLayoutEntry | null>>(bindGroupLayout: TgpuBindGroupLayout<Entries>, bindGroup: TgpuBindGroup<Entries>): this;
|
|
77
81
|
with(bindGroupLayout: TgpuBindGroupLayout, bindGroup: GPUBindGroup): this;
|
|
78
82
|
with(bindGroup: TgpuBindGroup): this;
|
|
83
|
+
/**
|
|
84
|
+
* Provides a value for the given immediate variable, applied on draw like
|
|
85
|
+
* the rest of the pipeline-held state and overridden by `pass.setImmediates`.
|
|
86
|
+
* The value is captured (copied) at call time; mutating it afterwards has
|
|
87
|
+
* no effect.
|
|
88
|
+
*
|
|
89
|
+
* Passing an `ArrayBuffer` or typed array skips serialization entirely; the bytes
|
|
90
|
+
* are copied verbatim and the caller guarantees they match the schema's layout.
|
|
91
|
+
*/
|
|
92
|
+
with<T extends AnyWgslData>(immediate: TgpuImmediateVar<T>, value: InferInput<T> | ArrayBuffer | ArrayBufferView): this;
|
|
79
93
|
/**
|
|
80
94
|
* Directs subsequent draw calls into the given render pass or render bundle
|
|
81
95
|
* encoder, letting multiple pipelines share one pass (and one submission).
|
|
@@ -89,6 +103,11 @@ export interface TgpuRenderPipeline<in Targets = never> extends TgpuNamable, Sel
|
|
|
89
103
|
with(encoder: GPUCommandEncoder): this;
|
|
90
104
|
with(pass: GPURenderPassEncoder): this;
|
|
91
105
|
with(bundleEncoder: GPURenderBundleEncoder): this;
|
|
106
|
+
/**
|
|
107
|
+
* Applies a transform to this pipeline, letting packages hand out reusable
|
|
108
|
+
* configuration steps, e.g. `pipeline.pipe(mesh.inject())`.
|
|
109
|
+
*/
|
|
110
|
+
pipe<T>(transform: (pipeline: this) => T): T;
|
|
92
111
|
/**
|
|
93
112
|
* Attaches texture views to the pipeline's targets (outputs).
|
|
94
113
|
*
|
|
@@ -194,6 +213,7 @@ type TgpuRenderPipelinePriors = {
|
|
|
194
213
|
readonly pass?: TgpuRenderCommands | undefined;
|
|
195
214
|
/** An encoder the pipeline records its own passes into, but does not submit */
|
|
196
215
|
readonly encoder?: TgpuCommandEncoder | undefined;
|
|
216
|
+
readonly immediatesMap?: Map<TgpuImmediateVar, ImmediateSnapshot> | undefined;
|
|
197
217
|
} & TimestampWritesPriors;
|
|
198
218
|
type Memo = {
|
|
199
219
|
pipeline: GPURenderPipeline;
|
|
@@ -202,6 +222,7 @@ type Memo = {
|
|
|
202
222
|
logResources: LogResources | undefined;
|
|
203
223
|
usedVertexLayouts: TgpuVertexLayout[];
|
|
204
224
|
fragmentOut: BaseData | undefined;
|
|
225
|
+
usedImmediate: TgpuImmediateVar | undefined;
|
|
205
226
|
};
|
|
206
227
|
declare class TgpuRenderPipelineImpl implements TgpuRenderPipeline {
|
|
207
228
|
#private;
|
|
@@ -218,11 +239,13 @@ declare class TgpuRenderPipelineImpl implements TgpuRenderPipeline {
|
|
|
218
239
|
with(bindGroupLayout: TgpuBindGroupLayout, bindGroup: GPUBindGroup): this;
|
|
219
240
|
with(bindGroup: TgpuBindGroup): this;
|
|
220
241
|
with<TData extends WgslArray | Disarray>(vertexLayout: TgpuVertexLayout<TData>, buffer: GPUBuffer): this;
|
|
242
|
+
with<T extends AnyWgslData>(immediate: TgpuImmediateVar<T>, value: InferInput<T> | ArrayBuffer | ArrayBufferView): this;
|
|
221
243
|
with(pass: TgpuRenderCommands): this;
|
|
222
244
|
with(encoder: TgpuCommandEncoder): this;
|
|
223
245
|
with(encoder: GPUCommandEncoder): this;
|
|
224
246
|
with(pass: GPURenderPassEncoder): this;
|
|
225
247
|
with(bundleEncoder: GPURenderBundleEncoder): this;
|
|
248
|
+
pipe<T>(transform: (pipeline: this) => T): T;
|
|
226
249
|
withPerformanceCallback(callback: (start: bigint, end: bigint) => void | Promise<void>): this;
|
|
227
250
|
withTimestampWrites(options: {
|
|
228
251
|
querySet: TgpuQuerySet<'timestamp'> | GPUQuerySet;
|
|
@@ -18,6 +18,7 @@ import { isVertexLayout } from "../vertexLayout/vertexLayout.js";
|
|
|
18
18
|
import { connectAttachmentToShader } from "./connectAttachmentToShader.js";
|
|
19
19
|
import { connectTargetsToShader } from "./connectTargetsToShader.js";
|
|
20
20
|
import { INTERNAL_adoptCommandEncoder, INTERNAL_createCommandEncoder, } from "../commandEncoder/commandEncoder.js";
|
|
21
|
+
import { createImmediateSnapshot, isImmediateVar, validateImmediateUsage, } from "../immediate/immediateVar.js";
|
|
21
22
|
import { INTERNAL_adoptRenderCommands, } from "../commandEncoder/renderPass.js";
|
|
22
23
|
import { emitRenderDraw, finalizeOwnEncoder, requireIndexBuffer } from "./drawState.js";
|
|
23
24
|
import { isGPUCommandEncoder, isGPURenderBundleEncoder, isGPURenderPassEncoder, isTgpuCommandEncoder, isTgpuRenderCommands, } from "./typeGuards.js";
|
|
@@ -42,9 +43,11 @@ export function INTERNAL_restoreRenderPipeline(soul, ctx) {
|
|
|
42
43
|
logResources: undefined,
|
|
43
44
|
usedVertexLayouts: soul.usedVertexLayouts ?? [],
|
|
44
45
|
fragmentOut: soul.fragmentOut,
|
|
46
|
+
usedImmediate: soul.usedImmediate,
|
|
45
47
|
});
|
|
46
48
|
const pipeline = new TgpuRenderPipelineImpl(core, {
|
|
47
49
|
bindGroupLayoutMap: new Map(soul.bindGroups),
|
|
50
|
+
immediatesMap: new Map(soul.immediates),
|
|
48
51
|
vertexLayoutMap: new Map(soul.vertexBuffers),
|
|
49
52
|
indexBuffer: soul.indexBuffer,
|
|
50
53
|
stencilReference: soul.stencilReference,
|
|
@@ -76,6 +79,8 @@ class TgpuRenderPipelineImpl {
|
|
|
76
79
|
soul.usedVertexLayouts = memo.usedVertexLayouts;
|
|
77
80
|
soul.fragmentOut = memo.fragmentOut;
|
|
78
81
|
soul.bindGroups = collectBindGroupPairs(memo.usedBindGroupLayouts, memo.catchall, priors.bindGroupLayoutMap);
|
|
82
|
+
soul.usedImmediate = memo.usedImmediate;
|
|
83
|
+
soul.immediates = [...(priors.immediatesMap ?? [])];
|
|
79
84
|
soul.vertexBuffers = collectVertexBufferPairs(memo.usedVertexLayouts, priors.vertexLayoutMap);
|
|
80
85
|
soul.indexBuffer = priors.indexBuffer;
|
|
81
86
|
soul.stencilReference = priors.stencilReference;
|
|
@@ -141,8 +146,16 @@ class TgpuRenderPipelineImpl {
|
|
|
141
146
|
]),
|
|
142
147
|
});
|
|
143
148
|
}
|
|
149
|
+
if (isImmediateVar(first)) {
|
|
150
|
+
return this.#withPriors({
|
|
151
|
+
immediatesMap: new Map(internals.priors.immediatesMap).set(first, createImmediateSnapshot(first, resource)),
|
|
152
|
+
});
|
|
153
|
+
}
|
|
144
154
|
throw new Error('Unsupported value passed into .with()');
|
|
145
155
|
}
|
|
156
|
+
pipe(transform) {
|
|
157
|
+
return transform(this);
|
|
158
|
+
}
|
|
146
159
|
withPerformanceCallback(callback) {
|
|
147
160
|
const internals = this[$internal];
|
|
148
161
|
if (internals.priors.timestampWrites) {
|
|
@@ -344,6 +357,7 @@ class RenderPipelineCore {
|
|
|
344
357
|
logResources,
|
|
345
358
|
usedVertexLayouts: connectedAttribs.usedVertexLayouts,
|
|
346
359
|
fragmentOut,
|
|
360
|
+
usedImmediate: resolutionResult.usedImmediate,
|
|
347
361
|
};
|
|
348
362
|
this.#performanceTracker.measureCompile(device);
|
|
349
363
|
})
|
|
@@ -370,6 +384,7 @@ class RenderPipelineCore {
|
|
|
370
384
|
logResources,
|
|
371
385
|
usedVertexLayouts: connectedAttribs.usedVertexLayouts,
|
|
372
386
|
fragmentOut,
|
|
387
|
+
usedImmediate: resolutionResult.usedImmediate,
|
|
373
388
|
};
|
|
374
389
|
this.#performanceTracker.measureCompile(device);
|
|
375
390
|
}
|
|
@@ -393,11 +408,12 @@ class RenderPipelineCore {
|
|
|
393
408
|
shaderGenerator: root.shaderGeneratorClass ? new root.shaderGeneratorClass() : undefined,
|
|
394
409
|
root,
|
|
395
410
|
}));
|
|
396
|
-
const { code, usedBindGroupLayouts, catchall } = resolutionResult;
|
|
411
|
+
const { code, usedBindGroupLayouts, catchall, usedImmediate } = resolutionResult;
|
|
397
412
|
if (catchall !== undefined) {
|
|
398
413
|
usedBindGroupLayouts[catchall[0]]?.$name(`${getName(this) ?? '<unnamed>'} - Automatic Bind Group & Layout`);
|
|
399
414
|
}
|
|
400
415
|
warnIfOverflow(usedBindGroupLayouts, device.limits);
|
|
416
|
+
const immediateSize = usedImmediate ? validateImmediateUsage(usedImmediate, root) : 0;
|
|
401
417
|
const module = device.createShaderModule({
|
|
402
418
|
label: `${getName(this) ?? '<unnamed>'} - Shader`,
|
|
403
419
|
code,
|
|
@@ -414,6 +430,7 @@ class RenderPipelineCore {
|
|
|
414
430
|
layout: device.createPipelineLayout({
|
|
415
431
|
label: `${getName(this) ?? '<unnamed>'} - Pipeline Layout`,
|
|
416
432
|
bindGroupLayouts: usedBindGroupLayouts.map((l) => root.unwrap(l)),
|
|
433
|
+
immediateSize,
|
|
417
434
|
}),
|
|
418
435
|
vertex: {
|
|
419
436
|
module,
|
package/core/root/init.js
CHANGED
|
@@ -214,6 +214,9 @@ class TgpuRootImpl extends WithBindingImpl {
|
|
|
214
214
|
get minify() {
|
|
215
215
|
return this[$soul].minify;
|
|
216
216
|
}
|
|
217
|
+
get enabledWgslLanguageFeatures() {
|
|
218
|
+
return navigator.gpu?.wgslLanguageFeatures ?? new Set();
|
|
219
|
+
}
|
|
217
220
|
createBuffer(typeSchema, initialOrBuffer) {
|
|
218
221
|
return INTERNAL_createBuffer(this, typeSchema, initialOrBuffer);
|
|
219
222
|
}
|
package/core/root/rootTypes.d.ts
CHANGED
|
@@ -418,6 +418,17 @@ export interface TgpuRoot extends Unwrapper, WithBinding {
|
|
|
418
418
|
* @returns A set of strings representing the enabled features.
|
|
419
419
|
*/
|
|
420
420
|
get enabledFeatures(): ReadonlySet<GPUFeatureName>;
|
|
421
|
+
/**
|
|
422
|
+
* Retrieves a read-only list of WGSL language extensions supported in the
|
|
423
|
+
* current environment (`navigator.gpu.wgslLanguageFeatures`).
|
|
424
|
+
* Returns an empty set when WebGPU is unavailable.
|
|
425
|
+
*
|
|
426
|
+
* @example
|
|
427
|
+
* ```ts
|
|
428
|
+
* const canUseImmediates = root.enabledWgslLanguageFeatures.has('immediate_address_space');
|
|
429
|
+
* ```
|
|
430
|
+
*/
|
|
431
|
+
get enabledWgslLanguageFeatures(): ReadonlySet<string>;
|
|
421
432
|
/**
|
|
422
433
|
* Destroys all underlying resources (i.e. buffers...) created through this root object.
|
|
423
434
|
* If the object is created via `tgpu.init` instead of `tgpu.initFromDevice`,
|
package/core/slot/slotTypes.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { $gpuValueOf, $internal, $providing, $soul } from '../../shared/symbols.
|
|
|
7
7
|
import type { UnwrapRuntimeConstructor } from '../../tgpuBindGroupLayout.ts';
|
|
8
8
|
import type { TgpuBufferBinding } from '../buffer/bufferBinding.ts';
|
|
9
9
|
import type { TgpuConst } from '../constant/tgpuConstant.ts';
|
|
10
|
+
import type { TgpuImmediateVar } from '../immediate/immediateVar.ts';
|
|
10
11
|
import type { Withable } from '../root/rootTypes.ts';
|
|
11
12
|
import type { TgpuTextureView } from '../texture/texture.ts';
|
|
12
13
|
import type { TgpuVar, VariableScope } from '../variable/tgpuVariable.ts';
|
|
@@ -51,7 +52,7 @@ export interface TgpuAccessor<T extends BaseData = BaseData> extends TgpuNamable
|
|
|
51
52
|
readonly $: InferGPU<T>;
|
|
52
53
|
toString(): string;
|
|
53
54
|
}
|
|
54
|
-
type DataAccessorIn<T extends BaseData> = (() => DataAccessorIn<T>) | TgpuBufferBinding<T> | TgpuVar<VariableScope, T> | TgpuConst<T> | Infer<T>;
|
|
55
|
+
type DataAccessorIn<T extends BaseData> = (() => DataAccessorIn<T>) | TgpuBufferBinding<T> | TgpuVar<VariableScope, T> | TgpuConst<T> | TgpuImmediateVar<T> | Infer<T>;
|
|
55
56
|
type TextureAccessorIn<T extends WgslTexture | WgslStorageTexture> = (() => TextureAccessorIn<T>) | Infer<T> | TgpuTextureView<T>;
|
|
56
57
|
export declare namespace TgpuAccessor {
|
|
57
58
|
type In<T extends BaseData | ((count: number) => BaseData)> = UnwrapRuntimeConstructor<T> extends WgslTexture | WgslStorageTexture ? TextureAccessorIn<UnwrapRuntimeConstructor<T>> : DataAccessorIn<UnwrapRuntimeConstructor<T>>;
|
|
@@ -13,6 +13,7 @@ import type { ResolutionCtx, SelfResolvable } from '../../types.ts';
|
|
|
13
13
|
import type { ExperimentalTgpuRoot } from '../root/rootTypes.ts';
|
|
14
14
|
import type { TextureProps } from './textureProps.ts';
|
|
15
15
|
import type { AllowedUsages, LiteralToExtensionMap, RenderFlag, SampledFlag } from './usageExtension.ts';
|
|
16
|
+
import { type TextureBlobWriteOptions, type TextureCopyOptions, type TextureRawWriteOptions, type TextureWriteOptions } from './textureWrite.ts';
|
|
16
17
|
export type TextureInternals = {
|
|
17
18
|
root: ExperimentalTgpuRoot;
|
|
18
19
|
materialize(): GPUTexture;
|
|
@@ -38,17 +39,7 @@ type TextureViewInternals = {
|
|
|
38
39
|
readonly aspect?: GPUTextureAspect | undefined;
|
|
39
40
|
};
|
|
40
41
|
export type TexelData = Vec4u | Vec4i | Vec4f;
|
|
41
|
-
export type
|
|
42
|
-
export type TextureWriteFit = 'stretch';
|
|
43
|
-
export type TextureWriteOptions = {
|
|
44
|
-
/**
|
|
45
|
-
* How to handle a source whose dimensions do not match the texture.
|
|
46
|
-
*
|
|
47
|
-
* By default, mismatched writes throw. Use `'stretch'` to resample the
|
|
48
|
-
* source to the texture's dimensions.
|
|
49
|
-
*/
|
|
50
|
-
fit?: TextureWriteFit;
|
|
51
|
-
};
|
|
42
|
+
export type { TextureBlobWriteOptions, TextureChannel, TextureCopyOptions, TextureRawWriteOptions, TextureWriteFit, TextureWriteOptions, } from './textureWrite.ts';
|
|
52
43
|
type TgpuTextureViewDescriptor = {
|
|
53
44
|
/**
|
|
54
45
|
* Which {@link GPUTextureAspect | aspect(s)} of the texture are accessible to the texture view.
|
|
@@ -106,6 +97,12 @@ type CopyCompatibleTexture<T extends TextureProps> = TgpuTexture<{
|
|
|
106
97
|
format: T['format'];
|
|
107
98
|
sampleCount?: T['sampleCount'];
|
|
108
99
|
}>;
|
|
100
|
+
type FormatCompatibleTexture<T extends TextureProps> = TgpuTexture<{
|
|
101
|
+
size: readonly number[];
|
|
102
|
+
format: T['format'];
|
|
103
|
+
dimension?: TextureProps['dimension'];
|
|
104
|
+
sampleCount?: T['sampleCount'];
|
|
105
|
+
}>;
|
|
109
106
|
export interface TgpuTexture<TProps extends TextureProps = any> extends TgpuNamable {
|
|
110
107
|
readonly [$internal]: TextureInternals;
|
|
111
108
|
readonly [$soul]: TgpuTextureSoul<TProps>;
|
|
@@ -123,11 +120,21 @@ export interface TgpuTexture<TProps extends TextureProps = any> extends TgpuNama
|
|
|
123
120
|
sampleType?: T['sampleType'] extends F32 ? 'float' | 'unfilterable-float' : never;
|
|
124
121
|
}): TgpuTextureView<T>;
|
|
125
122
|
createView<T extends WgslStorageTexture>(schema: ValidateTextureViewSchema<this, T>, viewDescriptor?: TgpuTextureViewDescriptor): TgpuTextureView<T>;
|
|
123
|
+
/** Clears the texture to zeros */
|
|
126
124
|
clear(mipLevel?: number | 'all'): void;
|
|
125
|
+
/** Clears the texture to `color`. Requires the `'render'` usage flag */
|
|
126
|
+
clear(color: readonly [number, number, number, number], mipLevel?: number | 'all'): void;
|
|
127
127
|
generateMipmaps(baseMipLevel?: number, mipLevels?: number): void;
|
|
128
|
-
|
|
129
|
-
write(source:
|
|
128
|
+
/** Writes image sources to the texture, one per array layer. Requires the `'render'` usage flag */
|
|
129
|
+
write(source: GPUCopyExternalImageSource | GPUCopyExternalImageSource[], options?: TextureWriteOptions): void;
|
|
130
|
+
/** Writes raw texel data to the texture */
|
|
131
|
+
write(source: ArrayBuffer | TypedArray | DataView, options?: number | TextureRawWriteOptions): void;
|
|
132
|
+
/** Decodes an image blob and writes it to the texture. Requires the `'render'` usage flag */
|
|
133
|
+
writeAsync(source: Blob, options?: TextureBlobWriteOptions): Promise<void>;
|
|
134
|
+
/** Copies the contents of a texture with a matching size and format */
|
|
130
135
|
copyFrom<T extends CopyCompatibleTexture<TProps>>(source: T): void;
|
|
136
|
+
/** Copies a region between textures of the same format */
|
|
137
|
+
copyFrom<T extends FormatCompatibleTexture<TProps>>(source: T, options: TextureCopyOptions): void;
|
|
131
138
|
destroy(): void;
|
|
132
139
|
}
|
|
133
140
|
export interface TgpuTextureView<TSchema extends WgslStorageTexture | WgslTexture = WgslStorageTexture | WgslTexture> extends TgpuNamable {
|
|
@@ -170,4 +177,3 @@ export declare class TgpuTextureRenderViewImpl implements TgpuTextureRenderView
|
|
|
170
177
|
constructor(baseTexture: TgpuTexture, descriptor?: TgpuTextureViewDescriptor);
|
|
171
178
|
get descriptor(): TgpuTextureViewDescriptor;
|
|
172
179
|
}
|
|
173
|
-
export {};
|