typegpu 0.10.1 → 0.10.2
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/{chunk-BYypO7fO.js → _virtual/_rolldown/runtime.js} +1 -1
- package/builtin.d.ts +50 -0
- package/builtin.js +37 -0
- package/common/fullScreenTriangle.d.ts +26 -0
- package/common/fullScreenTriangle.js +36 -0
- package/common/index.d.ts +2 -3
- package/common/index.js +3 -4
- package/core/buffer/buffer.d.ts +74 -0
- package/core/buffer/buffer.js +197 -0
- package/core/buffer/bufferShorthand.d.ts +48 -0
- package/core/buffer/bufferShorthand.js +49 -0
- package/core/buffer/bufferUsage.d.ts +45 -0
- package/core/buffer/bufferUsage.js +163 -0
- package/core/constant/tgpuConstant.d.ts +28 -0
- package/core/constant/tgpuConstant.js +67 -0
- package/core/declare/tgpuDeclare.d.ts +18 -0
- package/core/declare/tgpuDeclare.js +40 -0
- package/core/function/autoIO.d.ts +37 -0
- package/core/function/autoIO.js +87 -0
- package/core/function/comptime.d.ts +39 -0
- package/core/function/comptime.js +51 -0
- package/core/function/createCallableSchema.js +42 -0
- package/core/function/dualImpl.js +54 -0
- package/core/function/extractArgs.js +204 -0
- package/core/function/fnCore.js +79 -0
- package/core/function/fnTypes.d.ts +34 -0
- package/core/function/ioSchema.d.ts +10 -0
- package/core/function/ioSchema.js +30 -0
- package/core/function/shelllessImpl.d.ts +28 -0
- package/core/function/shelllessImpl.js +23 -0
- package/core/function/templateUtils.js +13 -0
- package/core/function/tgpuComputeFn.d.ts +49 -0
- package/core/function/tgpuComputeFn.js +62 -0
- package/core/function/tgpuFn.d.ts +52 -0
- package/core/function/tgpuFn.js +170 -0
- package/core/function/tgpuFragmentFn.d.ts +68 -0
- package/core/function/tgpuFragmentFn.js +68 -0
- package/core/function/tgpuVertexFn.d.ts +55 -0
- package/core/function/tgpuVertexFn.js +65 -0
- package/core/pipeline/applyPipelineState.js +37 -0
- package/core/pipeline/computePipeline.d.ts +58 -0
- package/core/pipeline/computePipeline.js +226 -0
- package/core/pipeline/connectAttachmentToShader.js +26 -0
- package/core/pipeline/connectTargetsToShader.js +29 -0
- package/core/pipeline/limitsOverflow.js +13 -0
- package/core/pipeline/renderPipeline.d.ts +266 -0
- package/core/pipeline/renderPipeline.js +471 -0
- package/core/pipeline/timeable.d.ts +23 -0
- package/core/pipeline/timeable.js +61 -0
- package/core/pipeline/typeGuards.js +29 -0
- package/core/querySet/querySet.d.ts +22 -0
- package/core/querySet/querySet.js +103 -0
- package/core/rawCodeSnippet/tgpuRawCodeSnippet.d.ts +59 -0
- package/core/rawCodeSnippet/tgpuRawCodeSnippet.js +96 -0
- package/core/resolve/externals.d.ts +10 -0
- package/core/resolve/externals.js +58 -0
- package/core/resolve/namespace.d.ts +38 -0
- package/core/resolve/namespace.js +41 -0
- package/core/resolve/resolveData.js +146 -0
- package/core/resolve/stitch.js +25 -0
- package/core/resolve/tgpuResolve.d.ts +151 -0
- package/core/resolve/tgpuResolve.js +68 -0
- package/core/root/configurableImpl.js +18 -0
- package/core/root/init.d.ts +69 -0
- package/core/root/init.js +457 -0
- package/core/root/rootTypes.d.ts +622 -0
- package/core/sampler/sampler.d.ts +35 -0
- package/core/sampler/sampler.js +116 -0
- package/core/simulate/tgpuSimulate.d.ts +36 -0
- package/core/simulate/tgpuSimulate.js +76 -0
- package/core/slot/accessor.d.ts +13 -0
- package/core/slot/accessor.js +97 -0
- package/core/slot/internalSlots.js +7 -0
- package/core/slot/lazy.d.ts +6 -0
- package/core/slot/lazy.js +42 -0
- package/core/slot/slot.d.ts +6 -0
- package/core/slot/slot.js +40 -0
- package/core/slot/slotTypes.d.ts +92 -0
- package/core/slot/slotTypes.js +21 -0
- package/core/texture/externalTexture.d.ts +12 -0
- package/core/texture/externalTexture.js +48 -0
- package/core/texture/texture.d.ts +118 -0
- package/core/texture/texture.js +312 -0
- package/core/texture/textureFormats.d.ts +29 -0
- package/core/texture/textureFormats.js +99 -0
- package/core/texture/textureProps.d.ts +11 -0
- package/core/texture/textureUtils.js +224 -0
- package/core/texture/usageExtension.d.ts +21 -0
- package/core/texture/usageExtension.js +21 -0
- package/core/unroll/tgpuUnroll.d.ts +13 -0
- package/core/unroll/tgpuUnroll.js +36 -0
- package/core/valueProxyUtils.js +44 -0
- package/core/variable/tgpuVariable.d.ts +38 -0
- package/core/variable/tgpuVariable.js +101 -0
- package/core/vertexLayout/connectAttributesToShader.js +59 -0
- package/core/vertexLayout/vertexAttribute.d.ts +29 -0
- package/core/vertexLayout/vertexLayout.d.ts +19 -0
- package/core/vertexLayout/vertexLayout.js +103 -0
- package/data/alignIO.js +15 -0
- package/data/alignmentOf.d.ts +10 -0
- package/data/alignmentOf.js +88 -0
- package/data/array.d.ts +28 -0
- package/data/array.js +48 -0
- package/data/atomic.d.ts +15 -0
- package/data/atomic.js +25 -0
- package/data/attributes.d.ts +121 -0
- package/data/attributes.js +145 -0
- package/data/autoStruct.d.ts +3 -0
- package/data/autoStruct.js +83 -0
- package/data/compiledIO.js +231 -0
- package/data/dataIO.js +549 -0
- package/data/dataTypes.d.ts +115 -0
- package/data/dataTypes.js +97 -0
- package/data/deepEqual.d.ts +25 -0
- package/data/deepEqual.js +58 -0
- package/data/disarray.d.ts +34 -0
- package/data/disarray.js +52 -0
- package/data/getLongestContiguousPrefix.d.ts +10 -0
- package/data/getLongestContiguousPrefix.js +15 -0
- package/data/index.d.ts +26 -4
- package/data/index.js +27 -7
- package/data/instanceToSchema.d.ts +33 -0
- package/data/isContiguous.d.ts +10 -0
- package/data/isContiguous.js +15 -0
- package/data/matrix.d.ts +126 -0
- package/data/matrix.js +517 -0
- package/data/numberOps.js +24 -0
- package/data/numeric.d.ts +81 -0
- package/data/numeric.js +234 -0
- package/data/offsetUtils.d.ts +33 -0
- package/data/offsetUtils.js +167 -0
- package/data/offsets.js +36 -0
- package/data/partialIO.js +68 -0
- package/data/ptr.d.ts +12 -0
- package/data/ptr.js +46 -0
- package/data/ref.d.ts +37 -0
- package/data/ref.js +96 -0
- package/data/sampler.d.ts +107 -0
- package/data/sampler.js +26 -0
- package/data/schemaCallWrapper.js +32 -0
- package/data/schemaMemoryLayout.js +200 -0
- package/data/sizeOf.d.ts +10 -0
- package/data/sizeOf.js +15 -0
- package/data/snippet.d.ts +26 -0
- package/data/snippet.js +61 -0
- package/data/struct.d.ts +17 -0
- package/data/struct.js +46 -0
- package/data/texture.d.ts +292 -0
- package/{texture-BagDrrks.js → data/texture.js} +6 -3
- package/data/unstruct.d.ts +24 -0
- package/data/unstruct.js +43 -0
- package/data/vector.d.ts +191 -0
- package/data/vector.js +247 -0
- package/data/vectorImpl.js +516 -0
- package/data/vectorOps.js +664 -0
- package/data/vertexFormatData.d.ts +190 -0
- package/data/vertexFormatData.js +110 -0
- package/data/wgslTypes.d.ts +896 -0
- package/data/wgslTypes.js +215 -0
- package/errors.d.ts +44 -0
- package/errors.js +128 -0
- package/execMode.js +51 -0
- package/extension.d.ts +11 -0
- package/extension.js +18 -0
- package/getGPUValue.js +9 -0
- package/index.d.ts +40 -243
- package/index.js +19 -6318
- package/indexNamedExports.d.ts +38 -0
- package/mathUtils.js +13 -0
- package/memo.js +22 -0
- package/nameRegistry.d.ts +30 -0
- package/nameRegistry.js +449 -0
- package/package.js +5 -0
- package/package.json +23 -23
- package/resolutionCtx.d.ts +29 -0
- package/resolutionCtx.js +546 -0
- package/shared/env.js +13 -0
- package/shared/generators.js +14 -0
- package/shared/meta.d.ts +39 -0
- package/shared/meta.js +63 -0
- package/shared/repr.d.ts +108 -0
- package/shared/stringify.js +22 -0
- package/shared/symbols.d.ts +61 -0
- package/shared/symbols.js +71 -0
- package/shared/utilityTypes.d.ts +29 -0
- package/shared/utilityTypes.js +7 -0
- package/shared/vertexFormat.d.ts +70 -0
- package/shared/vertexFormat.js +64 -0
- package/std/array.d.ts +7 -0
- package/std/array.js +27 -0
- package/std/atomic.d.ts +19 -0
- package/std/atomic.js +113 -0
- package/std/bitcast.d.ts +10 -0
- package/std/bitcast.js +43 -0
- package/std/boolean.d.ts +127 -0
- package/std/boolean.js +274 -0
- package/std/derivative.d.ts +16 -0
- package/std/derivative.js +89 -0
- package/std/discard.d.ts +6 -0
- package/std/discard.js +16 -0
- package/std/extensions.d.ts +8 -0
- package/std/extensions.js +14 -0
- package/std/index.d.ts +15 -3
- package/std/index.js +16 -5
- package/std/matrix.d.ts +41 -0
- package/std/matrix.js +87 -0
- package/std/numeric.d.ts +254 -0
- package/std/numeric.js +847 -0
- package/std/operators.d.ts +48 -0
- package/std/operators.js +153 -0
- package/std/packing.d.ts +26 -0
- package/std/packing.js +86 -0
- package/std/subgroup.d.ts +47 -0
- package/std/subgroup.js +220 -0
- package/std/texture.d.ts +108 -0
- package/std/texture.js +197 -0
- package/tgpu.js +44 -0
- package/tgpuBindGroupLayout.d.ts +161 -0
- package/tgpuBindGroupLayout.js +271 -0
- package/tgpuUnstable.d.ts +48 -0
- package/tgpuUnstable.js +66 -0
- package/tgsl/accessIndex.js +45 -0
- package/tgsl/accessProp.js +113 -0
- package/tgsl/consoleLog/deserializers.js +117 -0
- package/tgsl/consoleLog/logGenerator.js +86 -0
- package/tgsl/consoleLog/serializers.js +225 -0
- package/tgsl/consoleLog/types.d.ts +54 -0
- package/tgsl/consoleLog/types.js +12 -0
- package/tgsl/conversion.js +200 -0
- package/tgsl/forOfUtils.js +45 -0
- package/tgsl/generationHelpers.d.ts +37 -0
- package/tgsl/generationHelpers.js +67 -0
- package/tgsl/math.js +45 -0
- package/tgsl/shaderGenerator.d.ts +18 -0
- package/tgsl/shellless.d.ts +11 -0
- package/tgsl/shellless.js +53 -0
- package/tgsl/wgslGenerator.js +585 -0
- package/types.d.ts +255 -0
- package/types.js +43 -0
- package/unwrapper.d.ts +27 -0
- package/wgslExtensions.d.ts +5 -0
- package/wgslExtensions.js +18 -0
- package/builtin-DdtWpk2t.js +0 -818
- package/builtin-DdtWpk2t.js.map +0 -1
- package/common/index.d.ts.map +0 -1
- package/common/index.js.map +0 -1
- package/data/index.d.ts.map +0 -1
- package/data/index.js.map +0 -1
- package/deepEqual-DQxK4vdp.js +0 -413
- package/deepEqual-DQxK4vdp.js.map +0 -1
- package/extensions-DIVuAfBM.js +0 -2032
- package/extensions-DIVuAfBM.js.map +0 -1
- package/fullScreenTriangle-CfFyQd_0.js +0 -543
- package/fullScreenTriangle-CfFyQd_0.js.map +0 -1
- package/index.d.ts.map +0 -1
- package/index.js.map +0 -1
- package/indexNamedExports-oL6tyaJ9.d.ts +0 -5697
- package/indexNamedExports-oL6tyaJ9.d.ts.map +0 -1
- package/operators-d-PMVTo7.js +0 -4158
- package/operators-d-PMVTo7.js.map +0 -1
- package/std/index.d.ts.map +0 -1
- package/std/index.js.map +0 -1
- package/texture-BagDrrks.js.map +0 -1
|
@@ -0,0 +1,471 @@
|
|
|
1
|
+
import { $getNameForward, $internal, $resolve } from "../../shared/symbols.js";
|
|
2
|
+
import { PERF, getName, setName } from "../../shared/meta.js";
|
|
3
|
+
import { Void, isWgslData } from "../../data/wgslTypes.js";
|
|
4
|
+
import { getCustomLocation } from "../../data/dataTypes.js";
|
|
5
|
+
import { snip } from "../../data/snippet.js";
|
|
6
|
+
import { isGPUBuffer } from "../../types.js";
|
|
7
|
+
import { formatToWGSLType } from "../../data/vertexFormatData.js";
|
|
8
|
+
import { sizeOf } from "../../data/sizeOf.js";
|
|
9
|
+
import { isBuiltin } from "../../data/attributes.js";
|
|
10
|
+
import { namespace } from "../resolve/namespace.js";
|
|
11
|
+
import { connectAttributesToShader } from "../vertexLayout/connectAttributesToShader.js";
|
|
12
|
+
import { isTexture, isTextureView } from "../texture/texture.js";
|
|
13
|
+
import { isBindGroup, isBindGroupLayout } from "../../tgpuBindGroupLayout.js";
|
|
14
|
+
import { resolve } from "../../resolutionCtx.js";
|
|
15
|
+
import { isGPUCommandEncoder, isGPURenderBundleEncoder, isGPURenderPassEncoder } from "./typeGuards.js";
|
|
16
|
+
import { applyBindGroups, applyVertexBuffers } from "./applyPipelineState.js";
|
|
17
|
+
import { logDataFromGPU } from "../../tgsl/consoleLog/deserializers.js";
|
|
18
|
+
import { wgslExtensionToFeatureName, wgslExtensions } from "../../wgslExtensions.js";
|
|
19
|
+
import { createWithPerformanceCallback, createWithTimestampWrites, setupTimestampWrites, triggerPerformanceCallback } from "./timeable.js";
|
|
20
|
+
import { AutoFragmentFn, AutoVertexFn } from "../function/autoIO.js";
|
|
21
|
+
import { isVertexLayout } from "../vertexLayout/vertexLayout.js";
|
|
22
|
+
import { connectAttachmentToShader } from "./connectAttachmentToShader.js";
|
|
23
|
+
import { connectTargetsToShader } from "./connectTargetsToShader.js";
|
|
24
|
+
|
|
25
|
+
//#region src/core/pipeline/renderPipeline.ts
|
|
26
|
+
function INTERNAL_createRenderPipeline(options) {
|
|
27
|
+
return new TgpuRenderPipelineImpl(new RenderPipelineCore(options), {});
|
|
28
|
+
}
|
|
29
|
+
const _lastAppliedRender = /* @__PURE__ */ new WeakMap();
|
|
30
|
+
var TgpuRenderPipelineImpl = class TgpuRenderPipelineImpl {
|
|
31
|
+
[$internal];
|
|
32
|
+
resourceType = "render-pipeline";
|
|
33
|
+
[$getNameForward];
|
|
34
|
+
hasIndexBuffer = false;
|
|
35
|
+
constructor(core, priors) {
|
|
36
|
+
this[$internal] = {
|
|
37
|
+
core,
|
|
38
|
+
priors,
|
|
39
|
+
root: core.options.root
|
|
40
|
+
};
|
|
41
|
+
this[$getNameForward] = core;
|
|
42
|
+
}
|
|
43
|
+
[$resolve](ctx) {
|
|
44
|
+
return ctx.resolve(this[$internal].core);
|
|
45
|
+
}
|
|
46
|
+
toString() {
|
|
47
|
+
return `renderPipeline:${getName(this) ?? "<unnamed>"}`;
|
|
48
|
+
}
|
|
49
|
+
$name(label) {
|
|
50
|
+
setName(this, label);
|
|
51
|
+
return this;
|
|
52
|
+
}
|
|
53
|
+
with(first, resource) {
|
|
54
|
+
const internals = this[$internal];
|
|
55
|
+
if (isGPURenderPassEncoder(first) || isGPURenderBundleEncoder(first)) return new TgpuRenderPipelineImpl(internals.core, {
|
|
56
|
+
...internals.priors,
|
|
57
|
+
externalRenderEncoder: first,
|
|
58
|
+
externalEncoder: void 0
|
|
59
|
+
});
|
|
60
|
+
if (isGPUCommandEncoder(first)) return new TgpuRenderPipelineImpl(internals.core, {
|
|
61
|
+
...internals.priors,
|
|
62
|
+
externalEncoder: first,
|
|
63
|
+
externalRenderEncoder: void 0
|
|
64
|
+
});
|
|
65
|
+
if (isBindGroup(first)) return new TgpuRenderPipelineImpl(internals.core, {
|
|
66
|
+
...internals.priors,
|
|
67
|
+
bindGroupLayoutMap: new Map([...internals.priors.bindGroupLayoutMap ?? [], [first.layout, first]])
|
|
68
|
+
});
|
|
69
|
+
if (isBindGroupLayout(first)) return new TgpuRenderPipelineImpl(internals.core, {
|
|
70
|
+
...internals.priors,
|
|
71
|
+
bindGroupLayoutMap: new Map([...internals.priors.bindGroupLayoutMap ?? [], [first, resource]])
|
|
72
|
+
});
|
|
73
|
+
if (isVertexLayout(first)) return new TgpuRenderPipelineImpl(internals.core, {
|
|
74
|
+
...internals.priors,
|
|
75
|
+
vertexLayoutMap: new Map([...internals.priors.vertexLayoutMap ?? [], [first, resource]])
|
|
76
|
+
});
|
|
77
|
+
throw new Error("Unsupported value passed into .with()");
|
|
78
|
+
}
|
|
79
|
+
withPerformanceCallback(callback) {
|
|
80
|
+
const internals = this[$internal];
|
|
81
|
+
const newPriors = createWithPerformanceCallback(internals.priors, callback, internals.core.options.root);
|
|
82
|
+
return new TgpuRenderPipelineImpl(internals.core, newPriors);
|
|
83
|
+
}
|
|
84
|
+
withTimestampWrites(options) {
|
|
85
|
+
const internals = this[$internal];
|
|
86
|
+
const newPriors = createWithTimestampWrites(internals.priors, options, internals.core.options.root);
|
|
87
|
+
return new TgpuRenderPipelineImpl(internals.core, newPriors);
|
|
88
|
+
}
|
|
89
|
+
withColorAttachment(attachment) {
|
|
90
|
+
const internals = this[$internal];
|
|
91
|
+
return new TgpuRenderPipelineImpl(internals.core, {
|
|
92
|
+
...internals.priors,
|
|
93
|
+
colorAttachment: attachment
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
withDepthStencilAttachment(attachment) {
|
|
97
|
+
const internals = this[$internal];
|
|
98
|
+
return new TgpuRenderPipelineImpl(internals.core, {
|
|
99
|
+
...internals.priors,
|
|
100
|
+
depthStencilAttachment: attachment
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
withStencilReference(reference) {
|
|
104
|
+
const internals = this[$internal];
|
|
105
|
+
return new TgpuRenderPipelineImpl(internals.core, {
|
|
106
|
+
...internals.priors,
|
|
107
|
+
stencilReference: reference
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
withIndexBuffer(buffer, indexFormatOrOffset, offsetElementsOrSizeBytes, sizeElementsOrUndefined) {
|
|
111
|
+
const internals = this[$internal];
|
|
112
|
+
if (isGPUBuffer(buffer)) {
|
|
113
|
+
if (typeof indexFormatOrOffset !== "string") throw new Error("If a GPUBuffer is passed, indexFormat must be provided.");
|
|
114
|
+
return new TgpuRenderPipelineImpl(internals.core, {
|
|
115
|
+
...internals.priors,
|
|
116
|
+
indexBuffer: {
|
|
117
|
+
buffer,
|
|
118
|
+
indexFormat: indexFormatOrOffset,
|
|
119
|
+
offsetBytes: offsetElementsOrSizeBytes,
|
|
120
|
+
sizeBytes: sizeElementsOrUndefined
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
const dataTypeToIndexFormat = {
|
|
125
|
+
u32: "uint32",
|
|
126
|
+
u16: "uint16"
|
|
127
|
+
};
|
|
128
|
+
const elementType = buffer.dataType.elementType;
|
|
129
|
+
return new TgpuRenderPipelineImpl(internals.core, {
|
|
130
|
+
...internals.priors,
|
|
131
|
+
indexBuffer: {
|
|
132
|
+
buffer,
|
|
133
|
+
indexFormat: dataTypeToIndexFormat[elementType.type],
|
|
134
|
+
offsetBytes: indexFormatOrOffset !== void 0 ? indexFormatOrOffset * sizeOf(elementType) : void 0,
|
|
135
|
+
sizeBytes: sizeElementsOrUndefined !== void 0 ? sizeElementsOrUndefined * sizeOf(elementType) : void 0
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
_createRenderPass(encoder) {
|
|
140
|
+
const internals = this[$internal];
|
|
141
|
+
const { root, descriptor } = internals.core.options;
|
|
142
|
+
const memo = internals.core.unwrap();
|
|
143
|
+
const colorAttachments = descriptor.fragment ? connectAttachmentToShader(descriptor.fragment?.shell?.returnType ?? memo.fragmentOut, internals.priors.colorAttachment ?? {}).map((_attachment) => {
|
|
144
|
+
const attachment = {
|
|
145
|
+
loadOp: "clear",
|
|
146
|
+
storeOp: "store",
|
|
147
|
+
..._attachment
|
|
148
|
+
};
|
|
149
|
+
if (isTexture(attachment.view)) attachment.view = root.unwrap(attachment.view).createView();
|
|
150
|
+
else if (isTextureView(attachment.view)) attachment.view = root.unwrap(attachment.view);
|
|
151
|
+
else if (isGPUCanvasContext(attachment.view)) attachment.view = attachment.view.getCurrentTexture().createView();
|
|
152
|
+
if (isTexture(attachment.resolveTarget)) attachment.resolveTarget = root.unwrap(attachment.resolveTarget).createView();
|
|
153
|
+
else if (isTextureView(attachment.resolveTarget)) attachment.resolveTarget = root.unwrap(attachment.resolveTarget);
|
|
154
|
+
else if (isGPUCanvasContext(attachment.resolveTarget)) attachment.resolveTarget = attachment.resolveTarget.getCurrentTexture().createView();
|
|
155
|
+
return attachment;
|
|
156
|
+
}) : [];
|
|
157
|
+
const renderPassDescriptor = {
|
|
158
|
+
label: getName(internals.core) ?? "<unnamed>",
|
|
159
|
+
colorAttachments,
|
|
160
|
+
...setupTimestampWrites(internals.priors, root)
|
|
161
|
+
};
|
|
162
|
+
const depthStencil = internals.priors.depthStencilAttachment;
|
|
163
|
+
if (depthStencil !== void 0) {
|
|
164
|
+
const view = isTexture(depthStencil.view) ? root.unwrap(depthStencil.view).createView() : isTextureView(depthStencil.view) ? root.unwrap(depthStencil.view) : depthStencil.view;
|
|
165
|
+
renderPassDescriptor.depthStencilAttachment = {
|
|
166
|
+
...depthStencil,
|
|
167
|
+
view
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
return encoder.beginRenderPass(renderPassDescriptor);
|
|
171
|
+
}
|
|
172
|
+
_applyRenderState(encoder) {
|
|
173
|
+
const internals = this[$internal];
|
|
174
|
+
const memo = internals.core.unwrap();
|
|
175
|
+
const { root } = internals.core.options;
|
|
176
|
+
encoder.setPipeline(memo.pipeline);
|
|
177
|
+
applyBindGroups(encoder, root, memo.usedBindGroupLayouts, memo.catchall, (layout) => internals.priors.bindGroupLayoutMap?.get(layout));
|
|
178
|
+
applyVertexBuffers(encoder, root, memo.usedVertexLayouts, (layout) => {
|
|
179
|
+
const buffer = internals.priors.vertexLayoutMap?.get(layout);
|
|
180
|
+
return buffer ? { buffer } : void 0;
|
|
181
|
+
});
|
|
182
|
+
if (internals.priors.stencilReference !== void 0 && "setStencilReference" in encoder) encoder.setStencilReference(internals.priors.stencilReference);
|
|
183
|
+
}
|
|
184
|
+
_setIndexBuffer(encoder) {
|
|
185
|
+
const internals = this[$internal];
|
|
186
|
+
const { root } = internals.core.options;
|
|
187
|
+
if (!internals.priors.indexBuffer) throw new Error("No index buffer set for this render pipeline.");
|
|
188
|
+
const { buffer, indexFormat, offsetBytes, sizeBytes } = internals.priors.indexBuffer;
|
|
189
|
+
if (isGPUBuffer(buffer)) encoder.setIndexBuffer(buffer, indexFormat, offsetBytes, sizeBytes);
|
|
190
|
+
else encoder.setIndexBuffer(root.unwrap(buffer), indexFormat, offsetBytes, sizeBytes);
|
|
191
|
+
}
|
|
192
|
+
draw(vertexCount, instanceCount, firstVertex, firstInstance) {
|
|
193
|
+
const internals = this[$internal];
|
|
194
|
+
const { root } = internals.core.options;
|
|
195
|
+
if (internals.priors.externalRenderEncoder) {
|
|
196
|
+
if (_lastAppliedRender.get(internals.priors.externalRenderEncoder) !== this) {
|
|
197
|
+
this._applyRenderState(internals.priors.externalRenderEncoder);
|
|
198
|
+
_lastAppliedRender.set(internals.priors.externalRenderEncoder, this);
|
|
199
|
+
}
|
|
200
|
+
internals.priors.externalRenderEncoder.draw(vertexCount, instanceCount, firstVertex, firstInstance);
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
if (internals.priors.externalEncoder) {
|
|
204
|
+
const pass = this._createRenderPass(internals.priors.externalEncoder);
|
|
205
|
+
this._applyRenderState(pass);
|
|
206
|
+
pass.draw(vertexCount, instanceCount, firstVertex, firstInstance);
|
|
207
|
+
pass.end();
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
const { logResources } = internals.core.unwrap();
|
|
211
|
+
const commandEncoder = root.device.createCommandEncoder();
|
|
212
|
+
const pass = this._createRenderPass(commandEncoder);
|
|
213
|
+
this._applyRenderState(pass);
|
|
214
|
+
pass.draw(vertexCount, instanceCount, firstVertex, firstInstance);
|
|
215
|
+
pass.end();
|
|
216
|
+
root.device.queue.submit([commandEncoder.finish()]);
|
|
217
|
+
if (logResources) logDataFromGPU(logResources);
|
|
218
|
+
if (internals.priors.performanceCallback) triggerPerformanceCallback({
|
|
219
|
+
root,
|
|
220
|
+
priors: internals.priors
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
drawIndexed(indexCount, instanceCount, firstIndex, baseVertex, firstInstance) {
|
|
224
|
+
const internals = this[$internal];
|
|
225
|
+
const { root } = internals.core.options;
|
|
226
|
+
if (internals.priors.externalRenderEncoder) {
|
|
227
|
+
if (_lastAppliedRender.get(internals.priors.externalRenderEncoder) !== this) {
|
|
228
|
+
this._applyRenderState(internals.priors.externalRenderEncoder);
|
|
229
|
+
this._setIndexBuffer(internals.priors.externalRenderEncoder);
|
|
230
|
+
_lastAppliedRender.set(internals.priors.externalRenderEncoder, this);
|
|
231
|
+
}
|
|
232
|
+
internals.priors.externalRenderEncoder.drawIndexed(indexCount, instanceCount, firstIndex, baseVertex, firstInstance);
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
if (internals.priors.externalEncoder) {
|
|
236
|
+
const pass = this._createRenderPass(internals.priors.externalEncoder);
|
|
237
|
+
this._applyRenderState(pass);
|
|
238
|
+
this._setIndexBuffer(pass);
|
|
239
|
+
pass.drawIndexed(indexCount, instanceCount, firstIndex, baseVertex, firstInstance);
|
|
240
|
+
pass.end();
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
const { logResources } = internals.core.unwrap();
|
|
244
|
+
const commandEncoder = root.device.createCommandEncoder();
|
|
245
|
+
const pass = this._createRenderPass(commandEncoder);
|
|
246
|
+
this._applyRenderState(pass);
|
|
247
|
+
this._setIndexBuffer(pass);
|
|
248
|
+
pass.drawIndexed(indexCount, instanceCount, firstIndex, baseVertex, firstInstance);
|
|
249
|
+
pass.end();
|
|
250
|
+
root.device.queue.submit([commandEncoder.finish()]);
|
|
251
|
+
if (logResources) logDataFromGPU(logResources);
|
|
252
|
+
if (internals.priors.performanceCallback) triggerPerformanceCallback({
|
|
253
|
+
root,
|
|
254
|
+
priors: internals.priors
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
drawIndirect(indirectBuffer, indirectOffset = 0) {
|
|
258
|
+
const internals = this[$internal];
|
|
259
|
+
const { root } = internals.core.options;
|
|
260
|
+
const rawBuffer = isGPUBuffer(indirectBuffer) ? indirectBuffer : root.unwrap(indirectBuffer);
|
|
261
|
+
if (internals.priors.externalRenderEncoder) {
|
|
262
|
+
if (_lastAppliedRender.get(internals.priors.externalRenderEncoder) !== this) {
|
|
263
|
+
this._applyRenderState(internals.priors.externalRenderEncoder);
|
|
264
|
+
_lastAppliedRender.set(internals.priors.externalRenderEncoder, this);
|
|
265
|
+
}
|
|
266
|
+
internals.priors.externalRenderEncoder.drawIndirect(rawBuffer, indirectOffset);
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
if (internals.priors.externalEncoder) {
|
|
270
|
+
const pass = this._createRenderPass(internals.priors.externalEncoder);
|
|
271
|
+
this._applyRenderState(pass);
|
|
272
|
+
pass.drawIndirect(rawBuffer, indirectOffset);
|
|
273
|
+
pass.end();
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
const { logResources } = internals.core.unwrap();
|
|
277
|
+
const commandEncoder = root.device.createCommandEncoder();
|
|
278
|
+
const pass = this._createRenderPass(commandEncoder);
|
|
279
|
+
this._applyRenderState(pass);
|
|
280
|
+
pass.drawIndirect(rawBuffer, indirectOffset);
|
|
281
|
+
pass.end();
|
|
282
|
+
root.device.queue.submit([commandEncoder.finish()]);
|
|
283
|
+
if (logResources) logDataFromGPU(logResources);
|
|
284
|
+
if (internals.priors.performanceCallback) triggerPerformanceCallback({
|
|
285
|
+
root,
|
|
286
|
+
priors: internals.priors
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
drawIndexedIndirect(indirectBuffer, indirectOffset = 0) {
|
|
290
|
+
const internals = this[$internal];
|
|
291
|
+
const { root } = internals.core.options;
|
|
292
|
+
const rawBuffer = isGPUBuffer(indirectBuffer) ? indirectBuffer : root.unwrap(indirectBuffer);
|
|
293
|
+
if (internals.priors.externalRenderEncoder) {
|
|
294
|
+
if (_lastAppliedRender.get(internals.priors.externalRenderEncoder) !== this) {
|
|
295
|
+
this._applyRenderState(internals.priors.externalRenderEncoder);
|
|
296
|
+
this._setIndexBuffer(internals.priors.externalRenderEncoder);
|
|
297
|
+
_lastAppliedRender.set(internals.priors.externalRenderEncoder, this);
|
|
298
|
+
}
|
|
299
|
+
internals.priors.externalRenderEncoder.drawIndexedIndirect(rawBuffer, indirectOffset);
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
if (internals.priors.externalEncoder) {
|
|
303
|
+
const pass = this._createRenderPass(internals.priors.externalEncoder);
|
|
304
|
+
this._applyRenderState(pass);
|
|
305
|
+
this._setIndexBuffer(pass);
|
|
306
|
+
pass.drawIndexedIndirect(rawBuffer, indirectOffset);
|
|
307
|
+
pass.end();
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
const { logResources } = internals.core.unwrap();
|
|
311
|
+
const commandEncoder = root.device.createCommandEncoder();
|
|
312
|
+
const pass = this._createRenderPass(commandEncoder);
|
|
313
|
+
this._applyRenderState(pass);
|
|
314
|
+
this._setIndexBuffer(pass);
|
|
315
|
+
pass.drawIndexedIndirect(rawBuffer, indirectOffset);
|
|
316
|
+
pass.end();
|
|
317
|
+
root.device.queue.submit([commandEncoder.finish()]);
|
|
318
|
+
if (logResources) logDataFromGPU(logResources);
|
|
319
|
+
if (internals.priors.performanceCallback) triggerPerformanceCallback({
|
|
320
|
+
root,
|
|
321
|
+
priors: internals.priors
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
};
|
|
325
|
+
var RenderPipelineCore = class {
|
|
326
|
+
[$internal] = true;
|
|
327
|
+
_memo;
|
|
328
|
+
#latestAutoVertexIn;
|
|
329
|
+
#latestAutoFragmentOut;
|
|
330
|
+
constructor(options) {
|
|
331
|
+
this.options = options;
|
|
332
|
+
}
|
|
333
|
+
[$resolve](ctx) {
|
|
334
|
+
const { slotBindings } = this.options;
|
|
335
|
+
const { vertex, fragment, attribs = {} } = this.options.descriptor;
|
|
336
|
+
this.#latestAutoVertexIn = void 0;
|
|
337
|
+
this.#latestAutoFragmentOut = void 0;
|
|
338
|
+
const locations = matchUpVaryingLocations(vertex?.shell?.out, fragment?.shell?.in, getName(vertex) ?? "<unnamed>", getName(fragment) ?? "<unnamed>");
|
|
339
|
+
return ctx.withVaryingLocations(locations, () => ctx.withSlots(slotBindings, () => {
|
|
340
|
+
let vertexOut;
|
|
341
|
+
if (typeof vertex === "function") {
|
|
342
|
+
const autoFn = new AutoVertexFn(vertex, Object.fromEntries(Object.entries(attribs).map(([key, value]) => [key, formatToWGSLType[value.format]])), locations);
|
|
343
|
+
ctx.resolve(autoFn);
|
|
344
|
+
this.#latestAutoVertexIn = autoFn.autoIn.completeStruct.propTypes;
|
|
345
|
+
vertexOut = autoFn.autoOut.completeStruct;
|
|
346
|
+
} else vertexOut = ctx.resolve(vertex).dataType;
|
|
347
|
+
if (fragment) if (typeof fragment === "function") {
|
|
348
|
+
const varyings = Object.fromEntries(Object.entries(vertexOut.propTypes).filter(([, dataType]) => !isBuiltin(dataType)));
|
|
349
|
+
this.#latestAutoFragmentOut = ctx.resolve(new AutoFragmentFn(fragment, varyings, locations)).dataType;
|
|
350
|
+
} else ctx.resolve(fragment);
|
|
351
|
+
return snip("", Void, "runtime");
|
|
352
|
+
}));
|
|
353
|
+
}
|
|
354
|
+
toString() {
|
|
355
|
+
return "renderPipelineCore";
|
|
356
|
+
}
|
|
357
|
+
unwrap() {
|
|
358
|
+
if (this._memo !== void 0) return this._memo;
|
|
359
|
+
const { root, descriptor: tgpuDescriptor } = this.options;
|
|
360
|
+
const device = root.device;
|
|
361
|
+
const enableExtensions = wgslExtensions.filter((extension) => root.enabledFeatures.has(wgslExtensionToFeatureName[extension]));
|
|
362
|
+
let resolutionResult;
|
|
363
|
+
let resolveMeasure;
|
|
364
|
+
const ns = namespace({ names: root.nameRegistrySetting });
|
|
365
|
+
if (PERF?.enabled) {
|
|
366
|
+
const resolveStart = performance.mark("typegpu:resolution:start");
|
|
367
|
+
resolutionResult = resolve(this, {
|
|
368
|
+
namespace: ns,
|
|
369
|
+
enableExtensions,
|
|
370
|
+
shaderGenerator: root.shaderGenerator,
|
|
371
|
+
root
|
|
372
|
+
});
|
|
373
|
+
resolveMeasure = performance.measure("typegpu:resolution", { start: resolveStart.name });
|
|
374
|
+
} else resolutionResult = resolve(this, {
|
|
375
|
+
namespace: ns,
|
|
376
|
+
enableExtensions,
|
|
377
|
+
shaderGenerator: root.shaderGenerator,
|
|
378
|
+
root
|
|
379
|
+
});
|
|
380
|
+
const { code, usedBindGroupLayouts, catchall, logResources } = resolutionResult;
|
|
381
|
+
if (catchall !== void 0) usedBindGroupLayouts[catchall[0]]?.$name(`${getName(this) ?? "<unnamed>"} - Automatic Bind Group & Layout`);
|
|
382
|
+
const module = device.createShaderModule({
|
|
383
|
+
label: `${getName(this) ?? "<unnamed>"} - Shader`,
|
|
384
|
+
code
|
|
385
|
+
});
|
|
386
|
+
const { vertex, fragment, attribs = {}, targets } = this.options.descriptor;
|
|
387
|
+
const connectedAttribs = connectAttributesToShader(vertex?.shell?.in ?? this.#latestAutoVertexIn ?? {}, attribs);
|
|
388
|
+
const fragmentOut = fragment?.shell?.returnType ?? this.#latestAutoFragmentOut;
|
|
389
|
+
const connectedTargets = fragmentOut ? connectTargetsToShader(fragmentOut, targets) : [null];
|
|
390
|
+
const descriptor = {
|
|
391
|
+
layout: device.createPipelineLayout({
|
|
392
|
+
label: `${getName(this) ?? "<unnamed>"} - Pipeline Layout`,
|
|
393
|
+
bindGroupLayouts: usedBindGroupLayouts.map((l) => root.unwrap(l))
|
|
394
|
+
}),
|
|
395
|
+
vertex: {
|
|
396
|
+
module,
|
|
397
|
+
buffers: connectedAttribs.bufferDefinitions
|
|
398
|
+
}
|
|
399
|
+
};
|
|
400
|
+
const label = getName(this);
|
|
401
|
+
if (label !== void 0) descriptor.label = label;
|
|
402
|
+
if (tgpuDescriptor.fragment) descriptor.fragment = {
|
|
403
|
+
module,
|
|
404
|
+
targets: connectedTargets
|
|
405
|
+
};
|
|
406
|
+
if (tgpuDescriptor.primitive) if (isWgslData(tgpuDescriptor.primitive.stripIndexFormat)) descriptor.primitive = {
|
|
407
|
+
...tgpuDescriptor.primitive,
|
|
408
|
+
stripIndexFormat: {
|
|
409
|
+
u32: "uint32",
|
|
410
|
+
u16: "uint16"
|
|
411
|
+
}[tgpuDescriptor.primitive.stripIndexFormat.type]
|
|
412
|
+
};
|
|
413
|
+
else descriptor.primitive = tgpuDescriptor.primitive;
|
|
414
|
+
if (tgpuDescriptor.depthStencil) descriptor.depthStencil = tgpuDescriptor.depthStencil;
|
|
415
|
+
if (tgpuDescriptor.multisample) descriptor.multisample = tgpuDescriptor.multisample;
|
|
416
|
+
this._memo = {
|
|
417
|
+
pipeline: device.createRenderPipeline(descriptor),
|
|
418
|
+
usedBindGroupLayouts,
|
|
419
|
+
catchall,
|
|
420
|
+
logResources,
|
|
421
|
+
usedVertexLayouts: connectedAttribs.usedVertexLayouts,
|
|
422
|
+
fragmentOut: this.#latestAutoFragmentOut
|
|
423
|
+
};
|
|
424
|
+
if (PERF?.enabled) (async () => {
|
|
425
|
+
const start = performance.mark("typegpu:compile-start");
|
|
426
|
+
await device.queue.onSubmittedWorkDone();
|
|
427
|
+
const compileMeasure = performance.measure("typegpu:compiled", { start: start.name });
|
|
428
|
+
PERF?.record("resolution", {
|
|
429
|
+
resolveDuration: resolveMeasure?.duration,
|
|
430
|
+
compileDuration: compileMeasure.duration,
|
|
431
|
+
wgslSize: code.length
|
|
432
|
+
});
|
|
433
|
+
})();
|
|
434
|
+
return this._memo;
|
|
435
|
+
}
|
|
436
|
+
};
|
|
437
|
+
/**
|
|
438
|
+
* Assumes vertexOut and fragmentIn are matching when it comes to the keys, that is fragmentIn's keyset is a subset of vertexOut's
|
|
439
|
+
* Logs a warning, when they don't match in terms of custom locations
|
|
440
|
+
*/
|
|
441
|
+
function matchUpVaryingLocations(vertexOut = {}, fragmentIn = {}, vertexFnName, fragmentFnName) {
|
|
442
|
+
const locations = {};
|
|
443
|
+
const usedLocations = /* @__PURE__ */ new Set();
|
|
444
|
+
function saveLocation(key, location) {
|
|
445
|
+
locations[key] = location;
|
|
446
|
+
usedLocations.add(location);
|
|
447
|
+
}
|
|
448
|
+
for (const [key, value] of Object.entries(vertexOut)) {
|
|
449
|
+
const customLocation = getCustomLocation(value);
|
|
450
|
+
if (customLocation !== void 0) saveLocation(key, customLocation);
|
|
451
|
+
}
|
|
452
|
+
for (const [key, value] of Object.entries(fragmentIn)) {
|
|
453
|
+
const customLocation = getCustomLocation(value);
|
|
454
|
+
if (customLocation === void 0) continue;
|
|
455
|
+
if (locations[key] === void 0) saveLocation(key, customLocation);
|
|
456
|
+
else if (locations[key] !== customLocation) console.warn(`Mismatched location between vertexFn (${vertexFnName}) output (${locations[key]}) and fragmentFn (${fragmentFnName}) input (${customLocation}) for the key "${key}", using the location set on vertex output.`);
|
|
457
|
+
}
|
|
458
|
+
let nextLocation = 0;
|
|
459
|
+
for (const key of Object.keys(vertexOut ?? {})) {
|
|
460
|
+
if (isBuiltin(vertexOut[key]) || locations[key] !== void 0) continue;
|
|
461
|
+
while (usedLocations.has(nextLocation)) nextLocation++;
|
|
462
|
+
saveLocation(key, nextLocation);
|
|
463
|
+
}
|
|
464
|
+
return locations;
|
|
465
|
+
}
|
|
466
|
+
function isGPUCanvasContext(value) {
|
|
467
|
+
return typeof value?.getCurrentTexture === "function";
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
//#endregion
|
|
471
|
+
export { INTERNAL_createRenderPipeline };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { TgpuQuerySet } from "../querySet/querySet.js";
|
|
2
|
+
import "../root/rootTypes.js";
|
|
3
|
+
|
|
4
|
+
//#region src/core/pipeline/timeable.d.ts
|
|
5
|
+
interface Timeable {
|
|
6
|
+
withPerformanceCallback(callback: (start: bigint, end: bigint) => void | Promise<void>): this;
|
|
7
|
+
withTimestampWrites(options: {
|
|
8
|
+
querySet: TgpuQuerySet<'timestamp'> | GPUQuerySet;
|
|
9
|
+
beginningOfPassWriteIndex?: number;
|
|
10
|
+
endOfPassWriteIndex?: number;
|
|
11
|
+
}): this;
|
|
12
|
+
}
|
|
13
|
+
type TimestampWritesPriors = {
|
|
14
|
+
readonly timestampWrites?: {
|
|
15
|
+
querySet: TgpuQuerySet<'timestamp'> | GPUQuerySet;
|
|
16
|
+
beginningOfPassWriteIndex?: number;
|
|
17
|
+
endOfPassWriteIndex?: number;
|
|
18
|
+
};
|
|
19
|
+
readonly performanceCallback?: (start: bigint, end: bigint) => void | Promise<void>;
|
|
20
|
+
readonly hasAutoQuerySet?: boolean;
|
|
21
|
+
};
|
|
22
|
+
//#endregion
|
|
23
|
+
export { Timeable, TimestampWritesPriors };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { $internal } from "../../shared/symbols.js";
|
|
2
|
+
import { isQuerySet } from "../querySet/querySet.js";
|
|
3
|
+
|
|
4
|
+
//#region src/core/pipeline/timeable.ts
|
|
5
|
+
function createWithPerformanceCallback(currentPriors, callback, root) {
|
|
6
|
+
if (!root.enabledFeatures.has("timestamp-query")) throw new Error("Performance callback requires the \"timestamp-query\" feature to be enabled on GPU device.");
|
|
7
|
+
if (!currentPriors.timestampWrites) return {
|
|
8
|
+
...currentPriors,
|
|
9
|
+
performanceCallback: callback,
|
|
10
|
+
hasAutoQuerySet: true,
|
|
11
|
+
timestampWrites: {
|
|
12
|
+
querySet: root.createQuerySet("timestamp", 2),
|
|
13
|
+
beginningOfPassWriteIndex: 0,
|
|
14
|
+
endOfPassWriteIndex: 1
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
return {
|
|
18
|
+
...currentPriors,
|
|
19
|
+
performanceCallback: callback
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function createWithTimestampWrites(currentPriors, options, root) {
|
|
23
|
+
if (!root.enabledFeatures.has("timestamp-query")) throw new Error("Timestamp writes require the \"timestamp-query\" feature to be enabled on GPU device.");
|
|
24
|
+
if (currentPriors.hasAutoQuerySet && currentPriors.timestampWrites) currentPriors.timestampWrites.querySet.destroy();
|
|
25
|
+
const timestampWrites = { querySet: options.querySet };
|
|
26
|
+
if (options.beginningOfPassWriteIndex !== void 0) timestampWrites.beginningOfPassWriteIndex = options.beginningOfPassWriteIndex;
|
|
27
|
+
if (options.endOfPassWriteIndex !== void 0) timestampWrites.endOfPassWriteIndex = options.endOfPassWriteIndex;
|
|
28
|
+
return {
|
|
29
|
+
...currentPriors,
|
|
30
|
+
hasAutoQuerySet: false,
|
|
31
|
+
timestampWrites
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function setupTimestampWrites(priors, root) {
|
|
35
|
+
if (!priors.timestampWrites) return {};
|
|
36
|
+
const { querySet, beginningOfPassWriteIndex, endOfPassWriteIndex } = priors.timestampWrites;
|
|
37
|
+
const timestampWrites = { querySet: isQuerySet(querySet) ? root.unwrap(querySet) : querySet };
|
|
38
|
+
if (beginningOfPassWriteIndex !== void 0) timestampWrites.beginningOfPassWriteIndex = beginningOfPassWriteIndex;
|
|
39
|
+
if (endOfPassWriteIndex !== void 0) timestampWrites.endOfPassWriteIndex = endOfPassWriteIndex;
|
|
40
|
+
return { timestampWrites };
|
|
41
|
+
}
|
|
42
|
+
function triggerPerformanceCallback({ root, priors }) {
|
|
43
|
+
const querySet = priors.timestampWrites?.querySet;
|
|
44
|
+
const callback = priors.performanceCallback;
|
|
45
|
+
if (!querySet) throw new Error("Cannot dispatch workgroups with performance callback without a query set.");
|
|
46
|
+
if (!isQuerySet(querySet)) throw new Error("Performance callback with raw GPUQuerySet is not supported. Use TgpuQuerySet instead.");
|
|
47
|
+
const commandEncoder = root.device.createCommandEncoder();
|
|
48
|
+
commandEncoder.resolveQuerySet(root.unwrap(querySet), 0, querySet.count, querySet[$internal].resolveBuffer, 0);
|
|
49
|
+
root.device.queue.submit([commandEncoder.finish()]);
|
|
50
|
+
root.device.queue.onSubmittedWorkDone().then(async () => {
|
|
51
|
+
if (!querySet.available) return;
|
|
52
|
+
const result = await querySet.read();
|
|
53
|
+
const start = result[priors.timestampWrites?.beginningOfPassWriteIndex ?? 0];
|
|
54
|
+
const end = result[priors.timestampWrites?.endOfPassWriteIndex ?? 1];
|
|
55
|
+
if (start === void 0 || end === void 0) throw new Error("QuerySet did not return valid timestamps.");
|
|
56
|
+
await callback(start, end);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
//#endregion
|
|
61
|
+
export { createWithPerformanceCallback, createWithTimestampWrites, setupTimestampWrites, triggerPerformanceCallback };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { $internal } from "../../shared/symbols.js";
|
|
2
|
+
|
|
3
|
+
//#region src/core/pipeline/typeGuards.ts
|
|
4
|
+
function isComputePipeline(value) {
|
|
5
|
+
const maybe = value;
|
|
6
|
+
return maybe?.resourceType === "compute-pipeline" && !!maybe[$internal];
|
|
7
|
+
}
|
|
8
|
+
function isRenderPipeline(value) {
|
|
9
|
+
const maybe = value;
|
|
10
|
+
return maybe?.resourceType === "render-pipeline" && !!maybe[$internal];
|
|
11
|
+
}
|
|
12
|
+
function isPipeline(value) {
|
|
13
|
+
return isRenderPipeline(value) || isComputePipeline(value);
|
|
14
|
+
}
|
|
15
|
+
function isGPUCommandEncoder(value) {
|
|
16
|
+
return !!value && typeof value === "object" && "beginRenderPass" in value && "beginComputePass" in value;
|
|
17
|
+
}
|
|
18
|
+
function isGPUComputePassEncoder(value) {
|
|
19
|
+
return !!value && typeof value === "object" && "dispatchWorkgroups" in value && !("beginRenderPass" in value);
|
|
20
|
+
}
|
|
21
|
+
function isGPURenderPassEncoder(value) {
|
|
22
|
+
return !!value && typeof value === "object" && "executeBundles" in value && "draw" in value;
|
|
23
|
+
}
|
|
24
|
+
function isGPURenderBundleEncoder(value) {
|
|
25
|
+
return !!value && typeof value === "object" && "draw" in value && "finish" in value && !("executeBundles" in value) && !("beginRenderPass" in value) && !("dispatchWorkgroups" in value);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
//#endregion
|
|
29
|
+
export { isComputePipeline, isGPUCommandEncoder, isGPUComputePassEncoder, isGPURenderBundleEncoder, isGPURenderPassEncoder, isPipeline, isRenderPipeline };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { TgpuNamable } from "../../shared/meta.js";
|
|
2
|
+
import { $internal } from "../../shared/symbols.js";
|
|
3
|
+
import "../root/rootTypes.js";
|
|
4
|
+
|
|
5
|
+
//#region src/core/querySet/querySet.d.ts
|
|
6
|
+
interface TgpuQuerySet<T extends GPUQueryType> extends TgpuNamable {
|
|
7
|
+
readonly resourceType: 'query-set';
|
|
8
|
+
readonly type: T;
|
|
9
|
+
readonly count: number;
|
|
10
|
+
readonly querySet: GPUQuerySet;
|
|
11
|
+
readonly destroyed: boolean;
|
|
12
|
+
readonly available: boolean;
|
|
13
|
+
readonly [$internal]: {
|
|
14
|
+
readonly readBuffer: GPUBuffer;
|
|
15
|
+
readonly resolveBuffer: GPUBuffer;
|
|
16
|
+
};
|
|
17
|
+
resolve(): void;
|
|
18
|
+
read(): Promise<bigint[]>;
|
|
19
|
+
destroy(): void;
|
|
20
|
+
}
|
|
21
|
+
//#endregion
|
|
22
|
+
export { TgpuQuerySet };
|