typegpu 0.10.2 → 0.11.0
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/_virtual/_rolldown/runtime.js +6 -11
- package/builtin.js +1 -3
- package/common/fullScreenTriangle.d.ts +1 -5
- package/common/fullScreenTriangle.js +1 -3
- package/common/index.d.ts +3 -2
- package/common/index.js +6 -4
- package/common/writeSoA.d.ts +16 -0
- package/common/writeSoA.js +90 -0
- package/core/buffer/buffer.d.ts +12 -7
- package/core/buffer/buffer.js +102 -53
- package/core/buffer/bufferShorthand.d.ts +5 -5
- package/core/buffer/bufferShorthand.js +9 -5
- package/core/buffer/bufferUsage.d.ts +0 -2
- package/core/buffer/bufferUsage.js +6 -4
- package/core/constant/tgpuConstant.d.ts +2 -1
- package/core/constant/tgpuConstant.js +8 -7
- package/core/declare/tgpuDeclare.js +8 -9
- package/core/function/autoIO.d.ts +7 -6
- package/core/function/autoIO.js +1 -3
- package/core/function/comptime.js +1 -3
- package/core/function/createCallableSchema.js +4 -6
- package/core/function/dualImpl.js +1 -3
- package/core/function/entryInputRouter.js +39 -0
- package/core/function/extractArgs.js +2 -2
- package/core/function/fnCore.js +19 -8
- package/core/function/fnTypes.d.ts +14 -8
- package/core/function/ioSchema.js +24 -3
- package/core/function/shelllessImpl.js +1 -3
- package/core/function/templateUtils.js +1 -2
- package/core/function/tgpuComputeFn.d.ts +2 -3
- package/core/function/tgpuComputeFn.js +9 -16
- package/core/function/tgpuFn.d.ts +2 -2
- package/core/function/tgpuFn.js +1 -3
- package/core/function/tgpuFragmentFn.d.ts +5 -1
- package/core/function/tgpuFragmentFn.js +5 -10
- package/core/function/tgpuVertexFn.d.ts +4 -0
- package/core/function/tgpuVertexFn.js +6 -12
- package/core/pipeline/applyPipelineState.js +1 -3
- package/core/pipeline/computePipeline.d.ts +2 -6
- package/core/pipeline/computePipeline.js +64 -63
- package/core/pipeline/connectAttachmentToShader.js +1 -3
- package/core/pipeline/connectTargetsToShader.js +1 -3
- package/core/pipeline/limitsOverflow.js +1 -2
- package/core/pipeline/pipelineUtils.js +29 -0
- package/core/pipeline/renderPipeline.d.ts +23 -5
- package/core/pipeline/renderPipeline.js +32 -14
- package/core/pipeline/timeable.d.ts +0 -3
- package/core/pipeline/timeable.js +3 -9
- package/core/pipeline/typeGuards.js +1 -3
- package/core/querySet/querySet.d.ts +0 -2
- package/core/querySet/querySet.js +37 -36
- package/core/rawCodeSnippet/tgpuRawCodeSnippet.js +1 -3
- package/core/resolve/externals.d.ts +0 -2
- package/core/resolve/externals.js +2 -4
- package/core/resolve/namespace.js +1 -3
- package/core/resolve/resolveData.js +1 -3
- package/core/resolve/stitch.js +1 -3
- package/core/resolve/tgpuResolve.d.ts +3 -1
- package/core/resolve/tgpuResolve.js +3 -5
- package/core/root/configurableImpl.js +2 -3
- package/core/root/init.d.ts +0 -5
- package/core/root/init.js +35 -28
- package/core/root/rootTypes.d.ts +25 -5
- package/core/sampler/sampler.d.ts +0 -4
- package/core/sampler/sampler.js +3 -3
- package/core/simulate/tgpuSimulate.js +1 -3
- package/core/slot/accessor.d.ts +0 -4
- package/core/slot/accessor.js +1 -3
- package/core/slot/internalSlots.js +1 -3
- package/core/slot/lazy.js +1 -3
- package/core/slot/slot.js +2 -3
- package/core/slot/slotTypes.js +1 -3
- package/core/texture/externalTexture.d.ts +0 -6
- package/core/texture/externalTexture.js +2 -3
- package/core/texture/texture.d.ts +0 -4
- package/core/texture/texture.js +5 -3
- package/core/texture/textureFormats.js +1 -3
- package/core/texture/textureUtils.js +1 -3
- package/core/texture/usageExtension.js +1 -3
- package/core/unroll/tgpuUnroll.d.ts +58 -3
- package/core/unroll/tgpuUnroll.js +63 -5
- package/core/valueProxyUtils.js +1 -3
- package/core/variable/tgpuVariable.js +1 -3
- package/core/vertexLayout/connectAttributesToShader.js +1 -3
- package/core/vertexLayout/vertexLayout.js +9 -9
- package/data/alignIO.js +1 -2
- package/data/alignmentOf.d.ts +0 -1
- package/data/alignmentOf.js +1 -3
- package/data/array.d.ts +1 -3
- package/data/array.js +2 -4
- package/data/atomic.js +2 -3
- package/data/attributes.js +3 -3
- package/data/autoStruct.d.ts +1 -3
- package/data/autoStruct.js +1 -3
- package/data/compiledIO.js +83 -86
- package/data/dataIO.js +46 -39
- package/data/dataTypes.d.ts +7 -7
- package/data/dataTypes.js +6 -3
- package/data/deepEqual.js +1 -3
- package/data/disarray.d.ts +1 -3
- package/data/disarray.js +1 -3
- package/data/getLongestContiguousPrefix.d.ts +0 -1
- package/data/getLongestContiguousPrefix.js +1 -3
- package/data/index.d.ts +3 -3
- package/data/index.js +10 -3
- package/data/isContiguous.d.ts +0 -1
- package/data/isContiguous.js +1 -3
- package/data/matrix.d.ts +8 -10
- package/data/matrix.js +32 -18
- package/data/numberOps.js +1 -2
- package/data/numeric.js +16 -29
- package/data/offsetUtils.d.ts +2 -2
- package/data/offsetUtils.js +3 -5
- package/data/offsets.js +1 -3
- package/data/partialIO.js +84 -39
- package/data/ptr.d.ts +0 -1
- package/data/ptr.js +1 -3
- package/data/ref.d.ts +0 -3
- package/data/ref.js +1 -3
- package/data/sampler.js +1 -3
- package/data/schemaCallWrapper.js +1 -3
- package/data/schemaMemoryLayout.js +1 -3
- package/data/sizeOf.d.ts +0 -1
- package/data/sizeOf.js +1 -3
- package/data/snippet.js +12 -3
- package/data/struct.js +1 -3
- package/data/texture.js +1 -3
- package/data/unstruct.js +1 -3
- package/data/vector.js +4 -12
- package/data/vectorImpl.js +27 -28
- package/data/vectorOps.js +20 -3
- package/data/vertexFormatData.js +2 -3
- package/data/wgslTypes.d.ts +39 -11
- package/data/wgslTypes.js +10 -3
- package/errors.js +6 -3
- package/execMode.js +1 -3
- package/extension.js +1 -3
- package/getGPUValue.js +1 -3
- package/index.d.ts +4 -2
- package/index.js +3 -3
- package/indexNamedExports.d.ts +3 -1
- package/mathUtils.js +1 -2
- package/memo.js +8 -8
- package/nameRegistry.js +1 -3
- package/package.js +2 -3
- package/package.json +7 -7
- package/resolutionCtx.d.ts +0 -10
- package/resolutionCtx.js +84 -18
- package/shared/env.js +1 -2
- package/shared/generators.js +1 -2
- package/shared/meta.js +1 -3
- package/shared/repr.d.ts +32 -2
- package/shared/stringify.js +1 -3
- package/shared/symbols.d.ts +10 -1
- package/shared/symbols.js +10 -33
- package/shared/utilityTypes.d.ts +6 -2
- package/shared/utilityTypes.js +1 -2
- package/shared/vertexFormat.js +1 -2
- package/std/array.d.ts +1 -1
- package/std/array.js +1 -3
- package/std/atomic.d.ts +12 -12
- package/std/atomic.js +1 -3
- package/std/bitcast.d.ts +2 -2
- package/std/bitcast.js +1 -3
- package/std/boolean.d.ts +30 -16
- package/std/boolean.js +37 -12
- package/std/derivative.d.ts +9 -9
- package/std/derivative.js +1 -3
- package/std/discard.d.ts +1 -1
- package/std/discard.js +1 -3
- package/std/extensions.d.ts +1 -3
- package/std/extensions.js +1 -3
- package/std/index.d.ts +5 -4
- package/std/index.js +8 -5
- package/std/matrix.d.ts +5 -5
- package/std/matrix.js +1 -3
- package/std/numeric.d.ts +78 -132
- package/std/numeric.js +1 -3
- package/std/operators.d.ts +16 -8
- package/std/operators.js +80 -6
- package/std/packing.d.ts +4 -4
- package/std/packing.js +1 -3
- package/std/range.d.ts +24 -0
- package/std/range.js +38 -0
- package/std/subgroup.d.ts +21 -21
- package/std/subgroup.js +1 -3
- package/std/texture.d.ts +20 -11
- package/std/texture.js +13 -3
- package/tgpu.js +1 -3
- package/tgpuBindGroupLayout.js +9 -8
- package/tgpuUnstable.js +1 -3
- package/tgsl/accessIndex.js +2 -4
- package/tgsl/accessProp.js +8 -6
- package/tgsl/consoleLog/deserializers.js +1 -3
- package/tgsl/consoleLog/logGenerator.js +2 -4
- package/tgsl/consoleLog/serializers.js +24 -26
- package/tgsl/consoleLog/types.d.ts +0 -2
- package/tgsl/consoleLog/types.js +1 -2
- package/tgsl/conversion.js +1 -3
- package/tgsl/forOfUtils.js +35 -9
- package/tgsl/generationHelpers.js +3 -3
- package/tgsl/math.js +1 -3
- package/tgsl/shaderGenerator.d.ts +10 -8
- package/tgsl/shaderGenerator_members.d.ts +2 -0
- package/tgsl/shaderGenerator_members.js +6 -0
- package/tgsl/shellless.js +1 -8
- package/tgsl/wgslGenerator.d.ts +36 -0
- package/tgsl/wgslGenerator.js +144 -81
- package/types.d.ts +14 -4
- package/types.js +3 -3
- package/wgslExtensions.js +1 -2
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { $getNameForward, $internal, $resolve } from "../../shared/symbols.js";
|
|
2
|
-
import { getName,
|
|
3
|
-
import { createIoSchema } from "./ioSchema.js";
|
|
2
|
+
import { getName, setName } from "../../shared/meta.js";
|
|
3
|
+
import { createIoSchema, separateAllAsPositional } from "./ioSchema.js";
|
|
4
4
|
import { createFnCore } from "./fnCore.js";
|
|
5
5
|
import { stripTemplate } from "./templateUtils.js";
|
|
6
6
|
import { shaderStageSlot } from "../slot/internalSlots.js";
|
|
7
|
-
|
|
8
7
|
//#region src/core/function/tgpuVertexFn.ts
|
|
9
8
|
/**
|
|
10
9
|
* Creates a shell of a typed entry function for the vertex shader stage. Any function
|
|
@@ -33,7 +32,7 @@ function isTgpuVertexFn(value) {
|
|
|
33
32
|
}
|
|
34
33
|
function createVertexFn(shell, implementation) {
|
|
35
34
|
const core = createFnCore(implementation, "@vertex ");
|
|
36
|
-
const
|
|
35
|
+
const entryInput = separateAllAsPositional(shell.in ?? {});
|
|
37
36
|
return {
|
|
38
37
|
shell,
|
|
39
38
|
$uses(newExternals) {
|
|
@@ -44,22 +43,17 @@ function createVertexFn(shell, implementation) {
|
|
|
44
43
|
[$getNameForward]: core,
|
|
45
44
|
$name(newLabel) {
|
|
46
45
|
setName(this, newLabel);
|
|
47
|
-
if (isNamable(inputType)) inputType.$name(`${newLabel}_Input`);
|
|
48
46
|
return this;
|
|
49
47
|
},
|
|
50
48
|
[$resolve](ctx) {
|
|
51
49
|
const outputWithLocation = createIoSchema(shell.out, ctx.varyingLocations).$name(`${getName(this) ?? ""}_Output`);
|
|
52
|
-
if (typeof implementation === "string") {
|
|
53
|
-
|
|
54
|
-
core.applyExternals({ Out: outputWithLocation });
|
|
55
|
-
}
|
|
56
|
-
return ctx.withSlots([[shaderStageSlot, "vertex"]], () => core.resolve(ctx, shell.argTypes, outputWithLocation));
|
|
50
|
+
if (typeof implementation === "string") core.applyExternals({ Out: outputWithLocation });
|
|
51
|
+
return ctx.withSlots([[shaderStageSlot, "vertex"]], () => core.resolve(ctx, [], outputWithLocation, entryInput));
|
|
57
52
|
},
|
|
58
53
|
toString() {
|
|
59
54
|
return `vertexFn:${getName(core) ?? "<unnamed>"}`;
|
|
60
55
|
}
|
|
61
56
|
};
|
|
62
57
|
}
|
|
63
|
-
|
|
64
58
|
//#endregion
|
|
65
|
-
export { isTgpuVertexFn, vertexFn };
|
|
59
|
+
export { isTgpuVertexFn, vertexFn };
|
|
@@ -2,7 +2,6 @@ import { MissingBindGroupsError, MissingVertexBuffersError } from "../../errors.
|
|
|
2
2
|
import { isBuffer } from "../buffer/buffer.js";
|
|
3
3
|
import { isBindGroup } from "../../tgpuBindGroupLayout.js";
|
|
4
4
|
import { warnIfOverflow } from "./limitsOverflow.js";
|
|
5
|
-
|
|
6
5
|
//#region src/core/pipeline/applyPipelineState.ts
|
|
7
6
|
function applyBindGroups(encoder, root, usedBindGroupLayouts, catchall, resolveBindGroup) {
|
|
8
7
|
const missingBindGroups = new Set(usedBindGroupLayouts);
|
|
@@ -32,6 +31,5 @@ function applyVertexBuffers(encoder, root, usedVertexLayouts, resolveVertexBuffe
|
|
|
32
31
|
});
|
|
33
32
|
if (missingVertexLayouts.size > 0) throw new MissingVertexBuffersError(missingVertexLayouts);
|
|
34
33
|
}
|
|
35
|
-
|
|
36
34
|
//#endregion
|
|
37
|
-
export { applyBindGroups, applyVertexBuffers };
|
|
35
|
+
export { applyBindGroups, applyVertexBuffers };
|
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
import { TgpuNamable } from "../../shared/meta.js";
|
|
2
2
|
import { $internal } from "../../shared/symbols.js";
|
|
3
3
|
import { AnyComputeBuiltin } from "../../builtin.js";
|
|
4
|
-
import "../querySet/querySet.js";
|
|
5
|
-
import "../../data/snippet.js";
|
|
6
|
-
import "../../tgsl/consoleLog/types.js";
|
|
7
4
|
import { IORecord } from "../function/fnTypes.js";
|
|
8
5
|
import { TgpuComputeFn } from "../function/tgpuComputeFn.js";
|
|
9
|
-
import "../slot/slotTypes.js";
|
|
10
6
|
import { PrimitiveOffsetInfo } from "../../data/offsetUtils.js";
|
|
11
7
|
import { Timeable, TimestampWritesPriors } from "./timeable.js";
|
|
12
8
|
import { TgpuBindGroup, TgpuBindGroupLayout, TgpuLayoutEntry } from "../../tgpuBindGroupLayout.js";
|
|
@@ -39,10 +35,10 @@ interface TgpuComputePipeline extends TgpuNamable, SelfResolvable, Timeable {
|
|
|
39
35
|
* The buffer must contain 3 consecutive u32 values (x, y, z workgroup counts).
|
|
40
36
|
* To get the correct offset within complex data structures, use `d.memoryLayoutOf(...)`.
|
|
41
37
|
*
|
|
42
|
-
* @param indirectBuffer - Buffer marked with 'indirect' usage containing dispatch parameters
|
|
38
|
+
* @param indirectBuffer - Buffer marked with 'indirect' usage containing dispatch parameters or raw GPUBuffer
|
|
43
39
|
* @param start - PrimitiveOffsetInfo pointing to the first dispatch parameter. If not provided, starts at offset 0. To obtain safe offsets, use `d.memoryLayoutOf(...)`.
|
|
44
40
|
*/
|
|
45
|
-
dispatchWorkgroupsIndirect<T extends AnyWgslData>(indirectBuffer: TgpuBuffer<T> & IndirectFlag, start?: PrimitiveOffsetInfo | number): void;
|
|
41
|
+
dispatchWorkgroupsIndirect<T extends AnyWgslData>(indirectBuffer: (TgpuBuffer<T> & IndirectFlag) | GPUBuffer, start?: PrimitiveOffsetInfo | number): void;
|
|
46
42
|
}
|
|
47
43
|
declare namespace TgpuComputePipeline {
|
|
48
44
|
type Descriptor<Input extends IORecord<AnyComputeBuiltin> = IORecord<AnyComputeBuiltin>> = {
|
|
@@ -2,7 +2,7 @@ import { $getNameForward, $internal, $resolve } from "../../shared/symbols.js";
|
|
|
2
2
|
import { PERF, getName, setName } from "../../shared/meta.js";
|
|
3
3
|
import { Void } from "../../data/wgslTypes.js";
|
|
4
4
|
import { snip } from "../../data/snippet.js";
|
|
5
|
-
import {
|
|
5
|
+
import { isGPUBuffer } from "../../types.js";
|
|
6
6
|
import { namespace } from "../resolve/namespace.js";
|
|
7
7
|
import { isBindGroup } from "../../tgpuBindGroupLayout.js";
|
|
8
8
|
import { resolve } from "../../resolutionCtx.js";
|
|
@@ -10,125 +10,121 @@ import { isGPUCommandEncoder, isGPUComputePassEncoder } from "./typeGuards.js";
|
|
|
10
10
|
import { applyBindGroups } from "./applyPipelineState.js";
|
|
11
11
|
import { logDataFromGPU } from "../../tgsl/consoleLog/deserializers.js";
|
|
12
12
|
import { wgslExtensionToFeatureName, wgslExtensions } from "../../wgslExtensions.js";
|
|
13
|
-
import {
|
|
13
|
+
import { resolveIndirectOffset } from "./pipelineUtils.js";
|
|
14
14
|
import { createWithPerformanceCallback, createWithTimestampWrites, setupTimestampWrites, triggerPerformanceCallback } from "./timeable.js";
|
|
15
|
-
|
|
16
15
|
//#region src/core/pipeline/computePipeline.ts
|
|
17
16
|
function INTERNAL_createComputePipeline(branch, slotBindings, descriptor) {
|
|
18
17
|
return new TgpuComputePipelineImpl(new ComputePipelineCore(branch, slotBindings, descriptor), {});
|
|
19
18
|
}
|
|
20
|
-
function validateIndirectBufferSize(bufferSize, offset, requiredBytes, operation) {
|
|
21
|
-
if (offset + requiredBytes > bufferSize) throw new Error(`Buffer too small for ${operation}. Required: ${requiredBytes} bytes at offset ${offset}, but buffer is only ${bufferSize} bytes.`);
|
|
22
|
-
if (offset % 4 !== 0) throw new Error(`Indirect buffer offset must be a multiple of 4. Got: ${offset}`);
|
|
23
|
-
}
|
|
24
19
|
const _lastAppliedCompute = /* @__PURE__ */ new WeakMap();
|
|
25
20
|
var TgpuComputePipelineImpl = class TgpuComputePipelineImpl {
|
|
26
21
|
[$internal];
|
|
27
22
|
resourceType = "compute-pipeline";
|
|
28
23
|
[$getNameForward];
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
24
|
+
#core;
|
|
25
|
+
#priors;
|
|
26
|
+
constructor(core, priors) {
|
|
27
|
+
this.#core = core;
|
|
28
|
+
this.#priors = priors;
|
|
32
29
|
this[$internal] = {
|
|
33
30
|
get rawPipeline() {
|
|
34
|
-
return
|
|
31
|
+
return core.unwrap().pipeline;
|
|
35
32
|
},
|
|
36
33
|
get priors() {
|
|
37
|
-
return
|
|
34
|
+
return priors;
|
|
38
35
|
},
|
|
39
36
|
get root() {
|
|
40
|
-
return
|
|
37
|
+
return core.root;
|
|
41
38
|
}
|
|
42
39
|
};
|
|
43
|
-
this[$getNameForward] =
|
|
40
|
+
this[$getNameForward] = core;
|
|
44
41
|
}
|
|
45
42
|
[$resolve](ctx) {
|
|
46
|
-
return ctx.resolve(this
|
|
43
|
+
return ctx.resolve(this.#core);
|
|
47
44
|
}
|
|
48
45
|
toString() {
|
|
49
46
|
return `computePipeline:${getName(this) ?? "<unnamed>"}`;
|
|
50
47
|
}
|
|
51
48
|
get rawPipeline() {
|
|
52
|
-
return this.
|
|
49
|
+
return this.#core.unwrap().pipeline;
|
|
53
50
|
}
|
|
54
51
|
with(first, bindGroup) {
|
|
55
|
-
if (isGPUComputePassEncoder(first)) return new TgpuComputePipelineImpl(this
|
|
56
|
-
...this
|
|
52
|
+
if (isGPUComputePassEncoder(first)) return new TgpuComputePipelineImpl(this.#core, {
|
|
53
|
+
...this.#priors,
|
|
57
54
|
externalPass: first,
|
|
58
55
|
externalEncoder: void 0
|
|
59
56
|
});
|
|
60
|
-
if (isGPUCommandEncoder(first)) return new TgpuComputePipelineImpl(this
|
|
61
|
-
...this
|
|
57
|
+
if (isGPUCommandEncoder(first)) return new TgpuComputePipelineImpl(this.#core, {
|
|
58
|
+
...this.#priors,
|
|
62
59
|
externalEncoder: first,
|
|
63
60
|
externalPass: void 0
|
|
64
61
|
});
|
|
65
|
-
if (isBindGroup(first)) return new TgpuComputePipelineImpl(this
|
|
66
|
-
...this
|
|
67
|
-
bindGroupLayoutMap: new Map([...this.
|
|
62
|
+
if (isBindGroup(first)) return new TgpuComputePipelineImpl(this.#core, {
|
|
63
|
+
...this.#priors,
|
|
64
|
+
bindGroupLayoutMap: new Map([...this.#priors.bindGroupLayoutMap ?? [], [first.layout, first]])
|
|
68
65
|
});
|
|
69
|
-
return new TgpuComputePipelineImpl(this
|
|
70
|
-
...this
|
|
71
|
-
bindGroupLayoutMap: new Map([...this.
|
|
66
|
+
return new TgpuComputePipelineImpl(this.#core, {
|
|
67
|
+
...this.#priors,
|
|
68
|
+
bindGroupLayoutMap: new Map([...this.#priors.bindGroupLayoutMap ?? [], [first, bindGroup]])
|
|
72
69
|
});
|
|
73
70
|
}
|
|
74
71
|
withPerformanceCallback(callback) {
|
|
75
|
-
|
|
76
|
-
|
|
72
|
+
if (this.#priors.timestampWrites) return new TgpuComputePipelineImpl(this.#core, {
|
|
73
|
+
...this.#priors,
|
|
74
|
+
performanceCallback: callback
|
|
75
|
+
});
|
|
76
|
+
const querySet = this.#core.performanceCallbackQuerySet;
|
|
77
|
+
if (!querySet) {
|
|
78
|
+
console.warn("Performance callback cannot be used because the timestamp-query feature is not enabled on the root.");
|
|
79
|
+
return this;
|
|
80
|
+
}
|
|
81
|
+
const newPriors = createWithPerformanceCallback(this.#priors, callback, querySet);
|
|
82
|
+
return new TgpuComputePipelineImpl(this.#core, newPriors);
|
|
77
83
|
}
|
|
78
84
|
withTimestampWrites(options) {
|
|
79
|
-
const newPriors = createWithTimestampWrites(this
|
|
80
|
-
return new TgpuComputePipelineImpl(this
|
|
85
|
+
const newPriors = createWithTimestampWrites(this.#priors, options, this.#core.root);
|
|
86
|
+
return new TgpuComputePipelineImpl(this.#core, newPriors);
|
|
81
87
|
}
|
|
82
88
|
dispatchWorkgroups(x, y, z) {
|
|
83
89
|
this._executeComputePass((pass) => pass.dispatchWorkgroups(x, y, z));
|
|
84
90
|
}
|
|
85
91
|
dispatchWorkgroupsIndirect(indirectBuffer, start) {
|
|
86
92
|
const DISPATCH_SIZE = 12;
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
console.warn(`dispatchWorkgroupsIndirect: Provided start offset ${offsetInfo} as a raw number. Use d.memoryLayoutOf(...) to include contiguous padding info for safer validation.`);
|
|
91
|
-
offsetInfo = {
|
|
92
|
-
offset: offsetInfo,
|
|
93
|
-
contiguous: DISPATCH_SIZE
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
const { offset, contiguous } = offsetInfo;
|
|
97
|
-
validateIndirectBufferSize(sizeOf(indirectBuffer.dataType), offset, DISPATCH_SIZE, "dispatchWorkgroupsIndirect");
|
|
98
|
-
if (contiguous < DISPATCH_SIZE) console.warn(`dispatchWorkgroupsIndirect: Starting at offset ${offset}, only ${contiguous} contiguous bytes are available before padding. Dispatch requires ${DISPATCH_SIZE} bytes (3 x u32). Reading across padding may result in undefined behavior.`);
|
|
99
|
-
this._executeComputePass((pass) => pass.dispatchWorkgroupsIndirect(indirectBuffer.buffer, offset));
|
|
93
|
+
const rawBuffer = isGPUBuffer(indirectBuffer) ? indirectBuffer : indirectBuffer.buffer;
|
|
94
|
+
const offset = resolveIndirectOffset(indirectBuffer, start, DISPATCH_SIZE, "dispatchWorkgroupsIndirect");
|
|
95
|
+
this._executeComputePass((pass) => pass.dispatchWorkgroupsIndirect(rawBuffer, offset));
|
|
100
96
|
}
|
|
101
97
|
_applyComputeState(pass) {
|
|
102
|
-
const memo = this.
|
|
103
|
-
const { root } = this
|
|
98
|
+
const memo = this.#core.unwrap();
|
|
99
|
+
const { root } = this.#core;
|
|
104
100
|
pass.setPipeline(memo.pipeline);
|
|
105
|
-
applyBindGroups(pass, root, memo.usedBindGroupLayouts, memo.catchall, (layout) => this.
|
|
101
|
+
applyBindGroups(pass, root, memo.usedBindGroupLayouts, memo.catchall, (layout) => this.#priors.bindGroupLayoutMap?.get(layout));
|
|
106
102
|
}
|
|
107
103
|
_executeComputePass(dispatch) {
|
|
108
|
-
const { root } = this
|
|
109
|
-
if (this.
|
|
110
|
-
if (_lastAppliedCompute.get(this.
|
|
111
|
-
this._applyComputeState(this.
|
|
112
|
-
_lastAppliedCompute.set(this.
|
|
104
|
+
const { root } = this.#core;
|
|
105
|
+
if (this.#priors.externalPass) {
|
|
106
|
+
if (_lastAppliedCompute.get(this.#priors.externalPass) !== this) {
|
|
107
|
+
this._applyComputeState(this.#priors.externalPass);
|
|
108
|
+
_lastAppliedCompute.set(this.#priors.externalPass, this);
|
|
113
109
|
}
|
|
114
|
-
dispatch(this.
|
|
110
|
+
dispatch(this.#priors.externalPass);
|
|
115
111
|
return;
|
|
116
112
|
}
|
|
117
|
-
if (this.
|
|
113
|
+
if (this.#priors.externalEncoder) {
|
|
118
114
|
const passDescriptor = {
|
|
119
|
-
label: getName(this
|
|
120
|
-
...setupTimestampWrites(this
|
|
115
|
+
label: getName(this.#core) ?? "<unnamed>",
|
|
116
|
+
...setupTimestampWrites(this.#priors, root)
|
|
121
117
|
};
|
|
122
|
-
const pass = this.
|
|
118
|
+
const pass = this.#priors.externalEncoder.beginComputePass(passDescriptor);
|
|
123
119
|
this._applyComputeState(pass);
|
|
124
120
|
dispatch(pass);
|
|
125
121
|
pass.end();
|
|
126
122
|
return;
|
|
127
123
|
}
|
|
128
|
-
const memo = this.
|
|
124
|
+
const memo = this.#core.unwrap();
|
|
129
125
|
const passDescriptor = {
|
|
130
|
-
label: getName(this
|
|
131
|
-
...setupTimestampWrites(this
|
|
126
|
+
label: getName(this.#core) ?? "<unnamed>",
|
|
127
|
+
...setupTimestampWrites(this.#priors, root)
|
|
132
128
|
};
|
|
133
129
|
const commandEncoder = root.device.createCommandEncoder();
|
|
134
130
|
const pass = commandEncoder.beginComputePass(passDescriptor);
|
|
@@ -137,9 +133,9 @@ var TgpuComputePipelineImpl = class TgpuComputePipelineImpl {
|
|
|
137
133
|
pass.end();
|
|
138
134
|
root.device.queue.submit([commandEncoder.finish()]);
|
|
139
135
|
if (memo.logResources) logDataFromGPU(memo.logResources);
|
|
140
|
-
if (this.
|
|
136
|
+
if (this.#priors.performanceCallback) triggerPerformanceCallback({
|
|
141
137
|
root,
|
|
142
|
-
priors: this
|
|
138
|
+
priors: this.#priors
|
|
143
139
|
});
|
|
144
140
|
}
|
|
145
141
|
$name(label) {
|
|
@@ -149,9 +145,11 @@ var TgpuComputePipelineImpl = class TgpuComputePipelineImpl {
|
|
|
149
145
|
};
|
|
150
146
|
var ComputePipelineCore = class {
|
|
151
147
|
[$internal] = true;
|
|
148
|
+
root;
|
|
152
149
|
_memo;
|
|
153
150
|
#slotBindings;
|
|
154
151
|
#descriptor;
|
|
152
|
+
#performanceCallbackQuerySet;
|
|
155
153
|
constructor(root, slotBindings, descriptor) {
|
|
156
154
|
this.root = root;
|
|
157
155
|
this.#slotBindings = slotBindings;
|
|
@@ -166,6 +164,10 @@ var ComputePipelineCore = class {
|
|
|
166
164
|
toString() {
|
|
167
165
|
return "computePipelineCore";
|
|
168
166
|
}
|
|
167
|
+
get performanceCallbackQuerySet() {
|
|
168
|
+
if (!this.root.enabledFeatures.has("timestamp-query")) return;
|
|
169
|
+
return this.#performanceCallbackQuerySet ??= this.root.createQuerySet("timestamp", 2);
|
|
170
|
+
}
|
|
169
171
|
unwrap() {
|
|
170
172
|
if (this._memo === void 0) {
|
|
171
173
|
const device = this.root.device;
|
|
@@ -221,6 +223,5 @@ var ComputePipelineCore = class {
|
|
|
221
223
|
return this._memo;
|
|
222
224
|
}
|
|
223
225
|
};
|
|
224
|
-
|
|
225
226
|
//#endregion
|
|
226
|
-
export { INTERNAL_createComputePipeline };
|
|
227
|
+
export { INTERNAL_createComputePipeline };
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { isWgslStruct } from "../../data/wgslTypes.js";
|
|
2
2
|
import { isBuiltin } from "../../data/attributes.js";
|
|
3
|
-
|
|
4
3
|
//#region src/core/pipeline/connectAttachmentToShader.ts
|
|
5
4
|
function isColorAttachment(value) {
|
|
6
5
|
return !!value?.view;
|
|
@@ -21,6 +20,5 @@ function connectAttachmentToShader(fragmentOut, attachment) {
|
|
|
21
20
|
if (!isColorAttachment(attachment)) throw new Error("Expected a single color attachment, not a record.");
|
|
22
21
|
return [attachment];
|
|
23
22
|
}
|
|
24
|
-
|
|
25
23
|
//#endregion
|
|
26
|
-
export { connectAttachmentToShader };
|
|
24
|
+
export { connectAttachmentToShader };
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { isVoid, isWgslStruct } from "../../data/wgslTypes.js";
|
|
2
2
|
import { isBuiltin } from "../../data/attributes.js";
|
|
3
|
-
|
|
4
3
|
//#region src/core/pipeline/connectTargetsToShader.ts
|
|
5
4
|
function connectTargetsToShader(fragmentOut, targets) {
|
|
6
5
|
let presentationFormat;
|
|
@@ -24,6 +23,5 @@ function connectTargetsToShader(fragmentOut, targets) {
|
|
|
24
23
|
format: singleTarget?.format ?? (presentationFormat ??= navigator.gpu.getPreferredCanvasFormat())
|
|
25
24
|
}];
|
|
26
25
|
}
|
|
27
|
-
|
|
28
26
|
//#endregion
|
|
29
|
-
export { connectTargetsToShader };
|
|
27
|
+
export { connectTargetsToShader };
|
|
@@ -8,6 +8,5 @@ function warnIfOverflow(layouts, limits) {
|
|
|
8
8
|
2. Increasing the limit when requesting a device or creating a root.`);
|
|
9
9
|
if (storage > limits.maxStorageBuffersPerShaderStage) console.warn(`Total number of storage buffers (${storage}) exceeds maxStorageBuffersPerShaderStage (${limits.maxStorageBuffersPerShaderStage}).`);
|
|
10
10
|
}
|
|
11
|
-
|
|
12
11
|
//#endregion
|
|
13
|
-
export { warnIfOverflow };
|
|
12
|
+
export { warnIfOverflow };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { isGPUBuffer } from "../../types.js";
|
|
2
|
+
import { sizeOf } from "../../data/sizeOf.js";
|
|
3
|
+
import { memoryLayoutOf } from "../../data/offsetUtils.js";
|
|
4
|
+
//#region src/core/pipeline/pipelineUtils.ts
|
|
5
|
+
const IndirectOperationToRequiredData = {
|
|
6
|
+
dispatchWorkgroupsIndirect: "3 x u32",
|
|
7
|
+
drawIndirect: "4 x u32",
|
|
8
|
+
drawIndexedIndirect: "3 x u32, i32, u32"
|
|
9
|
+
};
|
|
10
|
+
function validateIndirectBufferSize(bufferSize, offset, requiredBytes, operation) {
|
|
11
|
+
if (offset + requiredBytes > bufferSize) throw new Error(`Buffer too small for ${operation}. Required: ${requiredBytes} bytes at offset ${offset}, but buffer is only ${bufferSize} bytes.`);
|
|
12
|
+
if (offset % 4 !== 0) throw new Error(`Indirect buffer offset must be a multiple of 4. Got: ${offset}`);
|
|
13
|
+
}
|
|
14
|
+
function resolveIndirectOffset(indirectBuffer, start, requiredSize, operation) {
|
|
15
|
+
if (isGPUBuffer(indirectBuffer)) {
|
|
16
|
+
const offset = typeof start === "number" ? start : start?.offset ?? 0;
|
|
17
|
+
validateIndirectBufferSize(indirectBuffer.size, offset, requiredSize, operation);
|
|
18
|
+
return offset;
|
|
19
|
+
}
|
|
20
|
+
const { offset, contiguous } = start ? typeof start === "number" ? {
|
|
21
|
+
offset: start,
|
|
22
|
+
contiguous: requiredSize
|
|
23
|
+
} : start : memoryLayoutOf(indirectBuffer.dataType);
|
|
24
|
+
validateIndirectBufferSize(sizeOf(indirectBuffer.dataType), offset, requiredSize, operation);
|
|
25
|
+
if (contiguous < requiredSize) console.warn(`${operation}: Starting at offset ${offset}, only ${contiguous} contiguous bytes are available before padding. '${operation}' requires ${requiredSize} bytes (${IndirectOperationToRequiredData[operation]}). Reading across padding may result in undefined behavior.`);
|
|
26
|
+
return offset;
|
|
27
|
+
}
|
|
28
|
+
//#endregion
|
|
29
|
+
export { resolveIndirectOffset };
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { TgpuNamable } from "../../shared/meta.js";
|
|
2
2
|
import { $internal, $resolve } from "../../shared/symbols.js";
|
|
3
3
|
import { AnyBuiltin, OmitBuiltins } from "../../builtin.js";
|
|
4
|
-
import "../querySet/querySet.js";
|
|
4
|
+
import { TgpuQuerySet } from "../querySet/querySet.js";
|
|
5
5
|
import { ResolvedSnippet } from "../../data/snippet.js";
|
|
6
6
|
import { LogResources } from "../../tgsl/consoleLog/types.js";
|
|
7
7
|
import { TgpuSlot } from "../slot/slotTypes.js";
|
|
8
|
+
import { PrimitiveOffsetInfo } from "../../data/offsetUtils.js";
|
|
8
9
|
import { Timeable, TimestampWritesPriors } from "./timeable.js";
|
|
9
10
|
import { AnyVertexAttribs } from "../../shared/vertexFormat.js";
|
|
10
11
|
import { AnyAutoCustoms, AutoFragmentIn, AutoFragmentOut, AutoVertexIn, AutoVertexOut } from "../function/autoIO.js";
|
|
@@ -14,7 +15,7 @@ import { RenderFlag } from "../texture/usageExtension.js";
|
|
|
14
15
|
import { TgpuVertexLayout } from "../vertexLayout/vertexLayout.js";
|
|
15
16
|
import { TgpuBindGroup, TgpuBindGroupLayout, TgpuLayoutEntry } from "../../tgpuBindGroupLayout.js";
|
|
16
17
|
import { ExperimentalTgpuRoot } from "../root/rootTypes.js";
|
|
17
|
-
import { IndexFlag, TgpuBuffer, VertexFlag } from "../buffer/buffer.js";
|
|
18
|
+
import { IndexFlag, IndirectFlag, TgpuBuffer, VertexFlag } from "../buffer/buffer.js";
|
|
18
19
|
import { ResolutionCtx, SelfResolvable } from "../../types.js";
|
|
19
20
|
import { AnyVecInstance, BaseData, U16, U32, Void, WgslArray, v4f } from "../../data/wgslTypes.js";
|
|
20
21
|
import { WgslTexture, WgslTextureDepth2d, WgslTextureDepthMultisampled2d } from "../../data/texture.js";
|
|
@@ -77,8 +78,24 @@ interface TgpuRenderPipeline<in Targets = never> extends TgpuNamable, SelfResolv
|
|
|
77
78
|
withIndexBuffer(buffer: TgpuBuffer<BaseData> & IndexFlag, offsetElements?: number, sizeElements?: number): this & HasIndexBuffer;
|
|
78
79
|
withIndexBuffer(buffer: GPUBuffer, indexFormat: GPUIndexFormat, offsetBytes?: number, sizeBytes?: number): this & HasIndexBuffer;
|
|
79
80
|
draw(vertexCount: number, instanceCount?: number, firstVertex?: number, firstInstance?: number): void;
|
|
80
|
-
|
|
81
|
-
|
|
81
|
+
/**
|
|
82
|
+
* Draws primitives using parameters read from a buffer.
|
|
83
|
+
* The buffer must contain 4 consecutive u32 values (vertexCount, instanceCount, firstVertex, firstInstance).
|
|
84
|
+
* To get the correct offset within complex data structures, use `d.memoryLayoutOf(...)`.
|
|
85
|
+
*
|
|
86
|
+
* @param indirectBuffer - Buffer marked with 'indirect' usage containing draw parameters or raw GPUBuffer
|
|
87
|
+
* @param indirectOffset - PrimitiveOffsetInfo pointing to the first draw parameter. If not provided, starts at offset 0. To obtain safe offsets, use `d.memoryLayoutOf(...)`.
|
|
88
|
+
*/
|
|
89
|
+
drawIndirect(indirectBuffer: (TgpuBuffer<BaseData> & IndirectFlag) | GPUBuffer, indirectOffset?: PrimitiveOffsetInfo | number): void;
|
|
90
|
+
/**
|
|
91
|
+
* Draws indexed primitives using parameters read from a buffer.
|
|
92
|
+
* The buffer must contain 5 consecutive 32-bit integer values (indexCount u32, instanceCount u32, firstIndex u32, baseVertex i32, firstInstance u32).
|
|
93
|
+
* To get the correct offset within complex data structures, use `d.memoryLayoutOf(...)`.
|
|
94
|
+
*
|
|
95
|
+
* @param indirectBuffer - Buffer marked with 'indirect' usage containing draw parameters or raw GPUBuffer
|
|
96
|
+
* @param indirectOffset - PrimitiveOffsetInfo pointing to the first draw parameter. If not provided, starts at offset 0. To obtain safe offsets, use `d.memoryLayoutOf(...)`.
|
|
97
|
+
*/
|
|
98
|
+
drawIndexedIndirect(indirectBuffer: (TgpuBuffer<BaseData> & IndirectFlag) | GPUBuffer, indirectOffset?: PrimitiveOffsetInfo | number): void;
|
|
82
99
|
}
|
|
83
100
|
declare namespace TgpuRenderPipeline {
|
|
84
101
|
interface DescriptorBase {
|
|
@@ -250,12 +267,13 @@ type Memo = {
|
|
|
250
267
|
};
|
|
251
268
|
declare class RenderPipelineCore implements SelfResolvable {
|
|
252
269
|
#private;
|
|
253
|
-
readonly options: RenderPipelineCoreOptions;
|
|
254
270
|
readonly [$internal] = true;
|
|
271
|
+
readonly options: RenderPipelineCoreOptions;
|
|
255
272
|
private _memo;
|
|
256
273
|
constructor(options: RenderPipelineCoreOptions);
|
|
257
274
|
[$resolve](ctx: ResolutionCtx): ResolvedSnippet;
|
|
258
275
|
toString(): string;
|
|
276
|
+
get performanceCallbackQuerySet(): TgpuQuerySet<"timestamp"> | undefined;
|
|
259
277
|
unwrap(): Memo;
|
|
260
278
|
}
|
|
261
279
|
/**
|
|
@@ -8,21 +8,23 @@ import { formatToWGSLType } from "../../data/vertexFormatData.js";
|
|
|
8
8
|
import { sizeOf } from "../../data/sizeOf.js";
|
|
9
9
|
import { isBuiltin } from "../../data/attributes.js";
|
|
10
10
|
import { namespace } from "../resolve/namespace.js";
|
|
11
|
-
import { connectAttributesToShader } from "../vertexLayout/connectAttributesToShader.js";
|
|
12
11
|
import { isTexture, isTextureView } from "../texture/texture.js";
|
|
13
12
|
import { isBindGroup, isBindGroupLayout } from "../../tgpuBindGroupLayout.js";
|
|
13
|
+
import { connectAttributesToShader } from "../vertexLayout/connectAttributesToShader.js";
|
|
14
14
|
import { resolve } from "../../resolutionCtx.js";
|
|
15
15
|
import { isGPUCommandEncoder, isGPURenderBundleEncoder, isGPURenderPassEncoder } from "./typeGuards.js";
|
|
16
16
|
import { applyBindGroups, applyVertexBuffers } from "./applyPipelineState.js";
|
|
17
17
|
import { logDataFromGPU } from "../../tgsl/consoleLog/deserializers.js";
|
|
18
18
|
import { wgslExtensionToFeatureName, wgslExtensions } from "../../wgslExtensions.js";
|
|
19
|
+
import { resolveIndirectOffset } from "./pipelineUtils.js";
|
|
19
20
|
import { createWithPerformanceCallback, createWithTimestampWrites, setupTimestampWrites, triggerPerformanceCallback } from "./timeable.js";
|
|
20
21
|
import { AutoFragmentFn, AutoVertexFn } from "../function/autoIO.js";
|
|
21
22
|
import { isVertexLayout } from "../vertexLayout/vertexLayout.js";
|
|
22
23
|
import { connectAttachmentToShader } from "./connectAttachmentToShader.js";
|
|
23
24
|
import { connectTargetsToShader } from "./connectTargetsToShader.js";
|
|
24
|
-
|
|
25
25
|
//#region src/core/pipeline/renderPipeline.ts
|
|
26
|
+
const DRAW_INDIRECT_SIZE = 16;
|
|
27
|
+
const DRAW_INDEXED_INDIRECT_SIZE = 20;
|
|
26
28
|
function INTERNAL_createRenderPipeline(options) {
|
|
27
29
|
return new TgpuRenderPipelineImpl(new RenderPipelineCore(options), {});
|
|
28
30
|
}
|
|
@@ -78,7 +80,16 @@ var TgpuRenderPipelineImpl = class TgpuRenderPipelineImpl {
|
|
|
78
80
|
}
|
|
79
81
|
withPerformanceCallback(callback) {
|
|
80
82
|
const internals = this[$internal];
|
|
81
|
-
|
|
83
|
+
if (internals.priors.timestampWrites) return new TgpuRenderPipelineImpl(internals.core, {
|
|
84
|
+
...internals.priors,
|
|
85
|
+
performanceCallback: callback
|
|
86
|
+
});
|
|
87
|
+
const querySet = internals.core.performanceCallbackQuerySet;
|
|
88
|
+
if (!querySet) {
|
|
89
|
+
console.warn("Performance callback cannot be used because the timestamp-query feature is not enabled on the root.");
|
|
90
|
+
return this;
|
|
91
|
+
}
|
|
92
|
+
const newPriors = createWithPerformanceCallback(internals.priors, callback, querySet);
|
|
82
93
|
return new TgpuRenderPipelineImpl(internals.core, newPriors);
|
|
83
94
|
}
|
|
84
95
|
withTimestampWrites(options) {
|
|
@@ -254,22 +265,23 @@ var TgpuRenderPipelineImpl = class TgpuRenderPipelineImpl {
|
|
|
254
265
|
priors: internals.priors
|
|
255
266
|
});
|
|
256
267
|
}
|
|
257
|
-
drawIndirect(indirectBuffer, indirectOffset
|
|
268
|
+
drawIndirect(indirectBuffer, indirectOffset) {
|
|
258
269
|
const internals = this[$internal];
|
|
259
270
|
const { root } = internals.core.options;
|
|
260
|
-
const rawBuffer = isGPUBuffer(indirectBuffer) ? indirectBuffer :
|
|
271
|
+
const rawBuffer = isGPUBuffer(indirectBuffer) ? indirectBuffer : indirectBuffer.buffer;
|
|
272
|
+
const offset = resolveIndirectOffset(indirectBuffer, indirectOffset, DRAW_INDIRECT_SIZE, "drawIndirect");
|
|
261
273
|
if (internals.priors.externalRenderEncoder) {
|
|
262
274
|
if (_lastAppliedRender.get(internals.priors.externalRenderEncoder) !== this) {
|
|
263
275
|
this._applyRenderState(internals.priors.externalRenderEncoder);
|
|
264
276
|
_lastAppliedRender.set(internals.priors.externalRenderEncoder, this);
|
|
265
277
|
}
|
|
266
|
-
internals.priors.externalRenderEncoder.drawIndirect(rawBuffer,
|
|
278
|
+
internals.priors.externalRenderEncoder.drawIndirect(rawBuffer, offset);
|
|
267
279
|
return;
|
|
268
280
|
}
|
|
269
281
|
if (internals.priors.externalEncoder) {
|
|
270
282
|
const pass = this._createRenderPass(internals.priors.externalEncoder);
|
|
271
283
|
this._applyRenderState(pass);
|
|
272
|
-
pass.drawIndirect(rawBuffer,
|
|
284
|
+
pass.drawIndirect(rawBuffer, offset);
|
|
273
285
|
pass.end();
|
|
274
286
|
return;
|
|
275
287
|
}
|
|
@@ -277,7 +289,7 @@ var TgpuRenderPipelineImpl = class TgpuRenderPipelineImpl {
|
|
|
277
289
|
const commandEncoder = root.device.createCommandEncoder();
|
|
278
290
|
const pass = this._createRenderPass(commandEncoder);
|
|
279
291
|
this._applyRenderState(pass);
|
|
280
|
-
pass.drawIndirect(rawBuffer,
|
|
292
|
+
pass.drawIndirect(rawBuffer, offset);
|
|
281
293
|
pass.end();
|
|
282
294
|
root.device.queue.submit([commandEncoder.finish()]);
|
|
283
295
|
if (logResources) logDataFromGPU(logResources);
|
|
@@ -286,24 +298,25 @@ var TgpuRenderPipelineImpl = class TgpuRenderPipelineImpl {
|
|
|
286
298
|
priors: internals.priors
|
|
287
299
|
});
|
|
288
300
|
}
|
|
289
|
-
drawIndexedIndirect(indirectBuffer, indirectOffset
|
|
301
|
+
drawIndexedIndirect(indirectBuffer, indirectOffset) {
|
|
290
302
|
const internals = this[$internal];
|
|
291
303
|
const { root } = internals.core.options;
|
|
292
304
|
const rawBuffer = isGPUBuffer(indirectBuffer) ? indirectBuffer : root.unwrap(indirectBuffer);
|
|
305
|
+
const offset = resolveIndirectOffset(indirectBuffer, indirectOffset, DRAW_INDEXED_INDIRECT_SIZE, "drawIndexedIndirect");
|
|
293
306
|
if (internals.priors.externalRenderEncoder) {
|
|
294
307
|
if (_lastAppliedRender.get(internals.priors.externalRenderEncoder) !== this) {
|
|
295
308
|
this._applyRenderState(internals.priors.externalRenderEncoder);
|
|
296
309
|
this._setIndexBuffer(internals.priors.externalRenderEncoder);
|
|
297
310
|
_lastAppliedRender.set(internals.priors.externalRenderEncoder, this);
|
|
298
311
|
}
|
|
299
|
-
internals.priors.externalRenderEncoder.drawIndexedIndirect(rawBuffer,
|
|
312
|
+
internals.priors.externalRenderEncoder.drawIndexedIndirect(rawBuffer, offset);
|
|
300
313
|
return;
|
|
301
314
|
}
|
|
302
315
|
if (internals.priors.externalEncoder) {
|
|
303
316
|
const pass = this._createRenderPass(internals.priors.externalEncoder);
|
|
304
317
|
this._applyRenderState(pass);
|
|
305
318
|
this._setIndexBuffer(pass);
|
|
306
|
-
pass.drawIndexedIndirect(rawBuffer,
|
|
319
|
+
pass.drawIndexedIndirect(rawBuffer, offset);
|
|
307
320
|
pass.end();
|
|
308
321
|
return;
|
|
309
322
|
}
|
|
@@ -312,7 +325,7 @@ var TgpuRenderPipelineImpl = class TgpuRenderPipelineImpl {
|
|
|
312
325
|
const pass = this._createRenderPass(commandEncoder);
|
|
313
326
|
this._applyRenderState(pass);
|
|
314
327
|
this._setIndexBuffer(pass);
|
|
315
|
-
pass.drawIndexedIndirect(rawBuffer,
|
|
328
|
+
pass.drawIndexedIndirect(rawBuffer, offset);
|
|
316
329
|
pass.end();
|
|
317
330
|
root.device.queue.submit([commandEncoder.finish()]);
|
|
318
331
|
if (logResources) logDataFromGPU(logResources);
|
|
@@ -324,9 +337,11 @@ var TgpuRenderPipelineImpl = class TgpuRenderPipelineImpl {
|
|
|
324
337
|
};
|
|
325
338
|
var RenderPipelineCore = class {
|
|
326
339
|
[$internal] = true;
|
|
340
|
+
options;
|
|
327
341
|
_memo;
|
|
328
342
|
#latestAutoVertexIn;
|
|
329
343
|
#latestAutoFragmentOut;
|
|
344
|
+
#performanceCallbackQuerySet;
|
|
330
345
|
constructor(options) {
|
|
331
346
|
this.options = options;
|
|
332
347
|
}
|
|
@@ -354,6 +369,10 @@ var RenderPipelineCore = class {
|
|
|
354
369
|
toString() {
|
|
355
370
|
return "renderPipelineCore";
|
|
356
371
|
}
|
|
372
|
+
get performanceCallbackQuerySet() {
|
|
373
|
+
if (!this.options.root.enabledFeatures.has("timestamp-query")) return;
|
|
374
|
+
return this.#performanceCallbackQuerySet ??= this.options.root.createQuerySet("timestamp", 2);
|
|
375
|
+
}
|
|
357
376
|
unwrap() {
|
|
358
377
|
if (this._memo !== void 0) return this._memo;
|
|
359
378
|
const { root, descriptor: tgpuDescriptor } = this.options;
|
|
@@ -466,6 +485,5 @@ function matchUpVaryingLocations(vertexOut = {}, fragmentIn = {}, vertexFnName,
|
|
|
466
485
|
function isGPUCanvasContext(value) {
|
|
467
486
|
return typeof value?.getCurrentTexture === "function";
|
|
468
487
|
}
|
|
469
|
-
|
|
470
488
|
//#endregion
|
|
471
|
-
export { INTERNAL_createRenderPipeline };
|
|
489
|
+
export { INTERNAL_createRenderPipeline };
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { TgpuQuerySet } from "../querySet/querySet.js";
|
|
2
|
-
import "../root/rootTypes.js";
|
|
3
|
-
|
|
4
2
|
//#region src/core/pipeline/timeable.d.ts
|
|
5
3
|
interface Timeable {
|
|
6
4
|
withPerformanceCallback(callback: (start: bigint, end: bigint) => void | Promise<void>): this;
|
|
@@ -17,7 +15,6 @@ type TimestampWritesPriors = {
|
|
|
17
15
|
endOfPassWriteIndex?: number;
|
|
18
16
|
};
|
|
19
17
|
readonly performanceCallback?: (start: bigint, end: bigint) => void | Promise<void>;
|
|
20
|
-
readonly hasAutoQuerySet?: boolean;
|
|
21
18
|
};
|
|
22
19
|
//#endregion
|
|
23
20
|
export { Timeable, TimestampWritesPriors };
|