@forgeax/engine-rhi-debug 0.1.28 → 0.1.30
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/README.md +32 -7
- package/dist/__tests__/query-set-lifecycle.unit.test.d.ts +2 -0
- package/dist/__tests__/query-set-lifecycle.unit.test.d.ts.map +1 -0
- package/dist/__tests__/query-set-replay-fixture.d.ts +39 -0
- package/dist/__tests__/query-set-replay-fixture.d.ts.map +1 -0
- package/dist/__tests__/recorder-canvas-context.unit.test.d.ts +2 -0
- package/dist/__tests__/recorder-canvas-context.unit.test.d.ts.map +1 -0
- package/dist/__tests__/timestamp-query-capture.dawn.test.d.ts +2 -0
- package/dist/__tests__/timestamp-query-capture.dawn.test.d.ts.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +527 -58
- package/dist/index.mjs.map +1 -1
- package/dist/protocol/event-semantics.d.ts +1 -1
- package/dist/protocol/event-semantics.d.ts.map +1 -1
- package/dist/protocol/types.d.ts +1 -1
- package/dist/protocol/types.d.ts.map +1 -1
- package/dist/recorder/closure.d.ts.map +1 -1
- package/dist/recorder/core.d.ts +10 -1
- package/dist/recorder/core.d.ts.map +1 -1
- package/dist/recorder/device.d.ts.map +1 -1
- package/dist/recorder/encoder.d.ts.map +1 -1
- package/dist/recorder/pass.d.ts.map +1 -1
- package/dist/recorder/pipeline.d.ts +5 -0
- package/dist/recorder/pipeline.d.ts.map +1 -0
- package/dist/recorder/proxy.d.ts +3 -1
- package/dist/recorder/proxy.d.ts.map +1 -1
- package/dist/recorder/session.d.ts +1 -1
- package/dist/recorder/session.d.ts.map +1 -1
- package/dist/recorder/shader.d.ts +3 -1
- package/dist/recorder/shader.d.ts.map +1 -1
- package/dist/recorder.d.ts +2 -2
- package/dist/recorder.d.ts.map +1 -1
- package/dist/replay/execute.d.ts.map +1 -1
- package/dist/replay/resources.d.ts +4 -1
- package/dist/replay/resources.d.ts.map +1 -1
- package/dist/replay/session.d.ts +7 -0
- package/dist/replay/session.d.ts.map +1 -1
- package/dist/types.d.ts +45 -6
- package/dist/types.d.ts.map +1 -1
- package/package.json +6 -6
- package/src/__tests__/coverage-invariant.test-d.ts +4 -5
- package/src/__tests__/coverage-invariant.unit.test.ts +6 -17
- package/src/__tests__/e2e.browser.test.ts +50 -0
- package/src/__tests__/guard-gates.test.ts +1 -1
- package/src/__tests__/query-set-lifecycle.unit.test.ts +265 -0
- package/src/__tests__/query-set-replay-fixture.ts +553 -0
- package/src/__tests__/readback-format-matrix.dawn.test.ts +9 -2
- package/src/__tests__/recorder-canvas-context.unit.test.ts +67 -0
- package/src/__tests__/recorder-session.integration.test.ts +55 -0
- package/src/__tests__/recorder-session.unit.test.ts +18 -1
- package/src/__tests__/replay-session.dawn.test.ts +171 -0
- package/src/__tests__/replay-session.test-d.ts +1 -0
- package/src/__tests__/rhi-debug-fresh-replay.dawn.test.ts +61 -0
- package/src/__tests__/timestamp-query-capture.dawn.test.ts +61 -0
- package/src/index.ts +1 -0
- package/src/protocol/event-semantics.ts +21 -2
- package/src/protocol/types.ts +1 -0
- package/src/protocol/validation.ts +36 -0
- package/src/recorder/assemble.ts +8 -1
- package/src/recorder/closure.ts +21 -1
- package/src/recorder/core.ts +11 -0
- package/src/recorder/device.ts +33 -6
- package/src/recorder/encoder.ts +60 -6
- package/src/recorder/pass.ts +7 -2
- package/src/recorder/pipeline.ts +31 -0
- package/src/recorder/proxy.ts +58 -2
- package/src/recorder/session.ts +1 -1
- package/src/recorder/shader.ts +29 -22
- package/src/recorder.ts +6 -2
- package/src/replay/execute.ts +143 -1
- package/src/replay/readback.ts +15 -3
- package/src/replay/resources.ts +6 -0
- package/src/replay/session.ts +241 -27
- package/src/types.ts +61 -14
package/dist/index.mjs
CHANGED
|
@@ -4294,11 +4294,14 @@ var eventKinds = [
|
|
|
4294
4294
|
"frameMark",
|
|
4295
4295
|
"createBuffer",
|
|
4296
4296
|
"createTexture",
|
|
4297
|
+
"createQuerySet",
|
|
4297
4298
|
"destroyBuffer",
|
|
4298
4299
|
"destroyTexture",
|
|
4300
|
+
"destroyQuerySet",
|
|
4299
4301
|
"createTextureView",
|
|
4300
4302
|
"createSampler",
|
|
4301
4303
|
"createBindGroupLayout",
|
|
4304
|
+
"getBindGroupLayout",
|
|
4302
4305
|
"createBindGroup",
|
|
4303
4306
|
"createPipelineLayout",
|
|
4304
4307
|
"createRenderPipeline",
|
|
@@ -4310,12 +4313,15 @@ var eventKinds = [
|
|
|
4310
4313
|
"copyExternalImageToTexture",
|
|
4311
4314
|
"submit",
|
|
4312
4315
|
"beginRenderPass",
|
|
4316
|
+
"beginOcclusionQuery",
|
|
4317
|
+
"endOcclusionQuery",
|
|
4313
4318
|
"beginComputePass",
|
|
4314
4319
|
"copyBufferToBuffer",
|
|
4315
4320
|
"copyBufferToTexture",
|
|
4316
4321
|
"copyTextureToBuffer",
|
|
4317
4322
|
"copyTextureToTexture",
|
|
4318
4323
|
"clearBuffer",
|
|
4324
|
+
"resolveQuerySet",
|
|
4319
4325
|
"pushDebugGroup",
|
|
4320
4326
|
"popDebugGroup",
|
|
4321
4327
|
"insertDebugMarker",
|
|
@@ -4362,6 +4368,8 @@ function resourceKindForEvent(kind) {
|
|
|
4362
4368
|
return "buffer";
|
|
4363
4369
|
case "createTexture":
|
|
4364
4370
|
return "texture";
|
|
4371
|
+
case "createQuerySet":
|
|
4372
|
+
return "query-set";
|
|
4365
4373
|
case "createTextureView":
|
|
4366
4374
|
return "texture-view";
|
|
4367
4375
|
case "createSampler":
|
|
@@ -4373,6 +4381,7 @@ function resourceKindForEvent(kind) {
|
|
|
4373
4381
|
return "pipeline";
|
|
4374
4382
|
case "createBindGroup":
|
|
4375
4383
|
case "createBindGroupLayout":
|
|
4384
|
+
case "getBindGroupLayout":
|
|
4376
4385
|
case "createPipelineLayout":
|
|
4377
4386
|
return "binding";
|
|
4378
4387
|
case "createCommandEncoder":
|
|
@@ -4388,12 +4397,12 @@ function semanticsFor(kind) {
|
|
|
4388
4397
|
created: (event) => createdHandles(event),
|
|
4389
4398
|
read: (event) => referencedHandles(event),
|
|
4390
4399
|
written: (event) => writtenHandles(event),
|
|
4391
|
-
destroyed: (event) => event.kind === "destroyBuffer" || event.kind === "destroyTexture" ? stringField(event, "handleId") : []
|
|
4400
|
+
destroyed: (event) => event.kind === "destroyBuffer" || event.kind === "destroyTexture" || event.kind === "destroyQuerySet" ? stringField(event, "handleId") : []
|
|
4392
4401
|
};
|
|
4393
4402
|
}
|
|
4394
4403
|
function categoryFor(kind) {
|
|
4395
4404
|
if (isWorkEvent(kind)) return "work";
|
|
4396
|
-
if (kind.startsWith("create") || kind.startsWith("destroy") || kind === "initialData")
|
|
4405
|
+
if (kind.startsWith("create") || kind.startsWith("destroy") || kind === "initialData" || kind === "getBindGroupLayout")
|
|
4397
4406
|
return "resource";
|
|
4398
4407
|
if (kind.includes("Pass")) return "pass";
|
|
4399
4408
|
if (kind.startsWith("copy") || kind === "clearBuffer" || kind.startsWith("write")) return "copy";
|
|
@@ -4422,6 +4431,9 @@ function referencedHandles(event) {
|
|
|
4422
4431
|
"resourceHandleIds",
|
|
4423
4432
|
"bindGroupHandleId",
|
|
4424
4433
|
"pipelineHandleId",
|
|
4434
|
+
"querySetHandleId",
|
|
4435
|
+
"occlusionQuerySetHandleId",
|
|
4436
|
+
"timestampQuerySetHandleId",
|
|
4425
4437
|
"indexBufferHandleId",
|
|
4426
4438
|
"vertexBufferHandleId"
|
|
4427
4439
|
];
|
|
@@ -5256,6 +5268,7 @@ function isResourceKind(value) {
|
|
|
5256
5268
|
return [
|
|
5257
5269
|
"buffer",
|
|
5258
5270
|
"texture",
|
|
5271
|
+
"query-set",
|
|
5259
5272
|
"texture-view",
|
|
5260
5273
|
"sampler",
|
|
5261
5274
|
"shader-module",
|
|
@@ -5268,8 +5281,10 @@ function eventResources(event) {
|
|
|
5268
5281
|
switch (event.kind) {
|
|
5269
5282
|
case "createBuffer":
|
|
5270
5283
|
case "createTexture":
|
|
5284
|
+
case "createQuerySet":
|
|
5271
5285
|
case "createSampler":
|
|
5272
5286
|
case "createBindGroupLayout":
|
|
5287
|
+
case "getBindGroupLayout":
|
|
5273
5288
|
case "createBindGroup":
|
|
5274
5289
|
case "createPipelineLayout":
|
|
5275
5290
|
case "createRenderPipeline":
|
|
@@ -5279,6 +5294,7 @@ function eventResources(event) {
|
|
|
5279
5294
|
created: [event.handleId],
|
|
5280
5295
|
reads: handleRefs(event, [
|
|
5281
5296
|
"layoutHandleId",
|
|
5297
|
+
"pipelineHandleId",
|
|
5282
5298
|
"vertexShaderModuleHandleId",
|
|
5283
5299
|
"fragmentShaderModuleHandleId",
|
|
5284
5300
|
"computeShaderModuleHandleId"
|
|
@@ -5291,6 +5307,7 @@ function eventResources(event) {
|
|
|
5291
5307
|
return { created: [event.cmdHandleId], reads: [], destroyed: [] };
|
|
5292
5308
|
case "destroyBuffer":
|
|
5293
5309
|
case "destroyTexture":
|
|
5310
|
+
case "destroyQuerySet":
|
|
5294
5311
|
return { created: [], reads: [event.handleId], destroyed: [event.handleId] };
|
|
5295
5312
|
case "writeBuffer":
|
|
5296
5313
|
case "writeTexture":
|
|
@@ -5312,6 +5329,37 @@ function eventResources(event) {
|
|
|
5312
5329
|
]),
|
|
5313
5330
|
destroyed: []
|
|
5314
5331
|
};
|
|
5332
|
+
case "resolveQuerySet":
|
|
5333
|
+
return {
|
|
5334
|
+
created: [],
|
|
5335
|
+
reads: handleRefs(event, ["cmdHandleId", "querySetHandleId", "destinationHandleId"]),
|
|
5336
|
+
destroyed: []
|
|
5337
|
+
};
|
|
5338
|
+
case "beginRenderPass":
|
|
5339
|
+
return {
|
|
5340
|
+
created: [event.passHandleId],
|
|
5341
|
+
reads: handleRefs(event, [
|
|
5342
|
+
"cmdHandleId",
|
|
5343
|
+
"occlusionQuerySetHandleId",
|
|
5344
|
+
"timestampQuerySetHandleId",
|
|
5345
|
+
"colorAttachmentViewHandleIds",
|
|
5346
|
+
"colorAttachmentResolveTargetHandleIds",
|
|
5347
|
+
"depthStencilViewHandleId"
|
|
5348
|
+
]),
|
|
5349
|
+
destroyed: []
|
|
5350
|
+
};
|
|
5351
|
+
case "beginComputePass":
|
|
5352
|
+
return {
|
|
5353
|
+
created: [event.passHandleId],
|
|
5354
|
+
reads: handleRefs(event, ["cmdHandleId", "timestampQuerySetHandleId"]),
|
|
5355
|
+
destroyed: []
|
|
5356
|
+
};
|
|
5357
|
+
case "endRenderPass":
|
|
5358
|
+
case "endComputePass":
|
|
5359
|
+
return { created: [], reads: [event.passHandleId], destroyed: [event.passHandleId] };
|
|
5360
|
+
case "beginOcclusionQuery":
|
|
5361
|
+
case "endOcclusionQuery":
|
|
5362
|
+
return { created: [], reads: handleRefs(event, ["passHandleId"]), destroyed: [] };
|
|
5315
5363
|
default:
|
|
5316
5364
|
return { created: [], reads: [], destroyed: [] };
|
|
5317
5365
|
}
|
|
@@ -6098,7 +6146,8 @@ function createdHandleId(event) {
|
|
|
6098
6146
|
if (event.kind === "beginRenderPass" || event.kind === "beginComputePass") {
|
|
6099
6147
|
return event.passHandleId;
|
|
6100
6148
|
}
|
|
6101
|
-
if (event.kind.startsWith("create") && "handleId" in event)
|
|
6149
|
+
if ((event.kind.startsWith("create") || event.kind === "getBindGroupLayout") && "handleId" in event)
|
|
6150
|
+
return event.handleId;
|
|
6102
6151
|
return void 0;
|
|
6103
6152
|
}
|
|
6104
6153
|
function resourceKind(event) {
|
|
@@ -6107,6 +6156,8 @@ function resourceKind(event) {
|
|
|
6107
6156
|
return "buffer";
|
|
6108
6157
|
case "createTexture":
|
|
6109
6158
|
return "texture";
|
|
6159
|
+
case "createQuerySet":
|
|
6160
|
+
return "query-set";
|
|
6110
6161
|
case "createTextureView":
|
|
6111
6162
|
return "texture-view";
|
|
6112
6163
|
case "createSampler":
|
|
@@ -6118,6 +6169,7 @@ function resourceKind(event) {
|
|
|
6118
6169
|
return "pipeline";
|
|
6119
6170
|
case "createBindGroup":
|
|
6120
6171
|
case "createBindGroupLayout":
|
|
6172
|
+
case "getBindGroupLayout":
|
|
6121
6173
|
case "createPipelineLayout":
|
|
6122
6174
|
return "binding";
|
|
6123
6175
|
case "createCommandEncoder":
|
|
@@ -6263,11 +6315,14 @@ function _collectFrameReferencedHandleIds(events) {
|
|
|
6263
6315
|
if (vhId !== void 0) refs.add(vhId);
|
|
6264
6316
|
}
|
|
6265
6317
|
if (we.depthStencilViewHandleId !== void 0) refs.add(we.depthStencilViewHandleId);
|
|
6318
|
+
if (we.occlusionQuerySetHandleId !== void 0) refs.add(we.occlusionQuerySetHandleId);
|
|
6319
|
+
if (we.timestampQuerySetHandleId !== void 0) refs.add(we.timestampQuerySetHandleId);
|
|
6266
6320
|
break;
|
|
6267
6321
|
}
|
|
6268
6322
|
case "beginComputePass": {
|
|
6269
6323
|
const we = e;
|
|
6270
6324
|
refs.add(we.cmdHandleId);
|
|
6325
|
+
if (we.timestampQuerySetHandleId !== void 0) refs.add(we.timestampQuerySetHandleId);
|
|
6271
6326
|
break;
|
|
6272
6327
|
}
|
|
6273
6328
|
case "finish": {
|
|
@@ -6317,6 +6372,7 @@ function _collectFrameReferencedHandleIds(events) {
|
|
|
6317
6372
|
break;
|
|
6318
6373
|
}
|
|
6319
6374
|
case "createBindGroup":
|
|
6375
|
+
case "getBindGroupLayout":
|
|
6320
6376
|
case "createPipelineLayout":
|
|
6321
6377
|
case "createRenderPipeline":
|
|
6322
6378
|
case "createComputePipeline":
|
|
@@ -6326,8 +6382,27 @@ function _collectFrameReferencedHandleIds(events) {
|
|
|
6326
6382
|
}
|
|
6327
6383
|
case "destroyBuffer":
|
|
6328
6384
|
case "destroyTexture":
|
|
6385
|
+
case "destroyQuerySet":
|
|
6329
6386
|
refs.add(e.handleId);
|
|
6330
6387
|
break;
|
|
6388
|
+
case "frameMark":
|
|
6389
|
+
case "createBuffer":
|
|
6390
|
+
case "createTexture":
|
|
6391
|
+
case "createQuerySet":
|
|
6392
|
+
case "createSampler":
|
|
6393
|
+
case "createBindGroupLayout":
|
|
6394
|
+
case "createShaderModule":
|
|
6395
|
+
case "createCommandEncoder":
|
|
6396
|
+
break;
|
|
6397
|
+
case "resolveQuerySet":
|
|
6398
|
+
refs.add(e.cmdHandleId);
|
|
6399
|
+
refs.add(e.querySetHandleId);
|
|
6400
|
+
refs.add(e.destinationHandleId);
|
|
6401
|
+
break;
|
|
6402
|
+
case "beginOcclusionQuery":
|
|
6403
|
+
case "endOcclusionQuery":
|
|
6404
|
+
refs.add(e.passHandleId);
|
|
6405
|
+
break;
|
|
6331
6406
|
}
|
|
6332
6407
|
}
|
|
6333
6408
|
return refs;
|
|
@@ -6361,8 +6436,11 @@ function _getCreateEventReferencedHandleIds(event) {
|
|
|
6361
6436
|
const e = event;
|
|
6362
6437
|
return [e.sourceHandleId];
|
|
6363
6438
|
}
|
|
6439
|
+
case "getBindGroupLayout":
|
|
6440
|
+
return [event.pipelineHandleId];
|
|
6364
6441
|
case "createBuffer":
|
|
6365
6442
|
case "createTexture":
|
|
6443
|
+
case "createQuerySet":
|
|
6366
6444
|
case "createSampler":
|
|
6367
6445
|
case "createBindGroupLayout":
|
|
6368
6446
|
case "createShaderModule":
|
|
@@ -6608,18 +6686,21 @@ function getHandleId(s, handle, kind) {
|
|
|
6608
6686
|
}
|
|
6609
6687
|
|
|
6610
6688
|
// src/recorder/shader.ts
|
|
6689
|
+
function recordShaderModule(debugInst, result, desc) {
|
|
6690
|
+
if (!result.ok) return result;
|
|
6691
|
+
const hId = debugInst.pushExternalCreateEvent(result.value, "shaderModule", {
|
|
6692
|
+
kind: "createShaderModule",
|
|
6693
|
+
handleId: "",
|
|
6694
|
+
wgslCode: desc.code
|
|
6695
|
+
});
|
|
6696
|
+
debugInst.registerShaderModule(result.value, hId);
|
|
6697
|
+
return result;
|
|
6698
|
+
}
|
|
6611
6699
|
function wrapCreateShaderModule(originalFn, debugInst) {
|
|
6612
6700
|
return async function wrappedCreateShaderModule(device, desc) {
|
|
6613
6701
|
const realDevice = device._realDevice ?? device;
|
|
6614
6702
|
const result = await originalFn(realDevice, desc);
|
|
6615
|
-
|
|
6616
|
-
const hId = debugInst.pushExternalCreateEvent(result.value, "shaderModule", {
|
|
6617
|
-
kind: "createShaderModule",
|
|
6618
|
-
handleId: "",
|
|
6619
|
-
wgslCode: desc.code
|
|
6620
|
-
});
|
|
6621
|
-
debugInst.registerShaderModule(result.value, hId);
|
|
6622
|
-
return result;
|
|
6703
|
+
return recordShaderModule(debugInst, result, desc);
|
|
6623
6704
|
};
|
|
6624
6705
|
}
|
|
6625
6706
|
|
|
@@ -6782,10 +6863,15 @@ function createRenderPassProxy(s, realPass, passHId) {
|
|
|
6782
6863
|
return realPass.executeBundles(bundles);
|
|
6783
6864
|
},
|
|
6784
6865
|
beginOcclusionQuery(queryIndex) {
|
|
6785
|
-
|
|
6866
|
+
const result = realPass.beginOcclusionQuery(queryIndex);
|
|
6867
|
+
if (result.ok)
|
|
6868
|
+
pushEvent(s, { kind: "beginOcclusionQuery", passHandleId: passHId, queryIndex });
|
|
6869
|
+
return result;
|
|
6786
6870
|
},
|
|
6787
6871
|
endOcclusionQuery() {
|
|
6788
|
-
|
|
6872
|
+
const result = realPass.endOcclusionQuery();
|
|
6873
|
+
if (result.ok) pushEvent(s, { kind: "endOcclusionQuery", passHandleId: passHId });
|
|
6874
|
+
return result;
|
|
6789
6875
|
},
|
|
6790
6876
|
end() {
|
|
6791
6877
|
pushEvent(s, { kind: "endRenderPass", passHandleId: passHId });
|
|
@@ -6870,18 +6956,25 @@ function createCommandEncoderProxy(s, realEnc, cmdHId) {
|
|
|
6870
6956
|
kind: "beginRenderPass",
|
|
6871
6957
|
cmdHandleId: cmdHId,
|
|
6872
6958
|
passHandleId: passHId,
|
|
6959
|
+
timestampQuerySetHandleId: desc?.timestampWrites === void 0 ? void 0 : getHandleId(s, desc.timestampWrites.querySet, "querySet"),
|
|
6873
6960
|
desc: {
|
|
6874
6961
|
colorAttachments: Array.from(desc.colorAttachments).map(
|
|
6875
6962
|
(attachment) => attachment === null || attachment === void 0 ? attachment : { ...attachment }
|
|
6876
6963
|
),
|
|
6877
6964
|
...desc.depthStencilAttachment === void 0 ? {} : { depthStencilAttachment: { ...desc.depthStencilAttachment } },
|
|
6878
|
-
...desc.
|
|
6879
|
-
...desc.timestampWrites === void 0 ? {} : { timestampWrites: desc.timestampWrites },
|
|
6965
|
+
...desc.timestampWrites === void 0 ? {} : { timestampWrites: recordTimestampWrites(desc.timestampWrites) },
|
|
6880
6966
|
...desc.maxDrawCount === void 0 ? {} : { maxDrawCount: desc.maxDrawCount }
|
|
6881
6967
|
},
|
|
6882
6968
|
colorAttachmentViewHandleIds,
|
|
6883
6969
|
colorAttachmentResolveTargetHandleIds,
|
|
6884
|
-
depthStencilViewHandleId
|
|
6970
|
+
depthStencilViewHandleId,
|
|
6971
|
+
...desc.occlusionQuerySet === void 0 ? {} : {
|
|
6972
|
+
occlusionQuerySetHandleId: getHandleId(
|
|
6973
|
+
s,
|
|
6974
|
+
desc.occlusionQuerySet,
|
|
6975
|
+
"querySet"
|
|
6976
|
+
)
|
|
6977
|
+
}
|
|
6885
6978
|
});
|
|
6886
6979
|
const realPass = realEnc.beginRenderPass(desc);
|
|
6887
6980
|
return createRenderPassProxy(s, realPass, passHId);
|
|
@@ -6892,7 +6985,11 @@ function createCommandEncoderProxy(s, realEnc, cmdHId) {
|
|
|
6892
6985
|
kind: "beginComputePass",
|
|
6893
6986
|
cmdHandleId: cmdHId,
|
|
6894
6987
|
passHandleId: passHId,
|
|
6895
|
-
desc
|
|
6988
|
+
timestampQuerySetHandleId: desc?.timestampWrites === void 0 ? void 0 : getHandleId(s, desc.timestampWrites.querySet, "querySet"),
|
|
6989
|
+
desc: desc === void 0 ? void 0 : {
|
|
6990
|
+
...desc.label === void 0 ? {} : { label: desc.label },
|
|
6991
|
+
timestampWrites: recordTimestampWrites(desc.timestampWrites)
|
|
6992
|
+
}
|
|
6896
6993
|
});
|
|
6897
6994
|
const realPass = realEnc.beginComputePass(desc);
|
|
6898
6995
|
return createComputePassProxy(s, realPass, passHId);
|
|
@@ -6903,7 +7000,11 @@ function createCommandEncoderProxy(s, realEnc, cmdHId) {
|
|
|
6903
7000
|
kind: "beginComputePass",
|
|
6904
7001
|
cmdHandleId: cmdHId,
|
|
6905
7002
|
passHandleId: passHId,
|
|
6906
|
-
desc
|
|
7003
|
+
timestampQuerySetHandleId: desc?.timestampWrites === void 0 ? void 0 : getHandleId(s, desc.timestampWrites.querySet, "querySet"),
|
|
7004
|
+
desc: {
|
|
7005
|
+
...desc.label === void 0 ? {} : { label: desc.label },
|
|
7006
|
+
timestampWrites: recordTimestampWrites(desc.timestampWrites)
|
|
7007
|
+
}
|
|
6907
7008
|
});
|
|
6908
7009
|
realEnc.encodeEmptyComputePass(desc);
|
|
6909
7010
|
pushEvent(s, { kind: "endComputePass", passHandleId: passHId });
|
|
@@ -7021,13 +7122,25 @@ function createCommandEncoderProxy(s, realEnc, cmdHId) {
|
|
|
7021
7122
|
realEnc.clearBuffer(buffer, offset, size);
|
|
7022
7123
|
},
|
|
7023
7124
|
resolveQuerySet(querySet, firstQuery, queryCount, destination, destinationOffset) {
|
|
7024
|
-
|
|
7125
|
+
const result = realEnc.resolveQuerySet(
|
|
7025
7126
|
querySet,
|
|
7026
7127
|
firstQuery,
|
|
7027
7128
|
queryCount,
|
|
7028
7129
|
destination,
|
|
7029
7130
|
destinationOffset
|
|
7030
7131
|
);
|
|
7132
|
+
if (result.ok) {
|
|
7133
|
+
pushEvent(s, {
|
|
7134
|
+
kind: "resolveQuerySet",
|
|
7135
|
+
cmdHandleId: cmdHId,
|
|
7136
|
+
querySetHandleId: getHandleId(s, querySet, "querySet"),
|
|
7137
|
+
firstQuery,
|
|
7138
|
+
queryCount,
|
|
7139
|
+
destinationHandleId: getHandleId(s, destination, "buffer"),
|
|
7140
|
+
destinationOffset
|
|
7141
|
+
});
|
|
7142
|
+
}
|
|
7143
|
+
return result;
|
|
7031
7144
|
},
|
|
7032
7145
|
pushDebugGroup(groupLabel) {
|
|
7033
7146
|
pushEvent(s, { kind: "pushDebugGroup", cmdHandleId: cmdHId, groupLabel });
|
|
@@ -7051,6 +7164,35 @@ function createCommandEncoderProxy(s, realEnc, cmdHId) {
|
|
|
7051
7164
|
}
|
|
7052
7165
|
};
|
|
7053
7166
|
}
|
|
7167
|
+
function recordTimestampWrites(writes) {
|
|
7168
|
+
return writes === void 0 ? void 0 : {
|
|
7169
|
+
...writes.beginningOfPassWriteIndex === void 0 ? {} : { beginningOfPassWriteIndex: writes.beginningOfPassWriteIndex },
|
|
7170
|
+
...writes.endOfPassWriteIndex === void 0 ? {} : { endOfPassWriteIndex: writes.endOfPassWriteIndex }
|
|
7171
|
+
};
|
|
7172
|
+
}
|
|
7173
|
+
|
|
7174
|
+
// src/recorder/pipeline.ts
|
|
7175
|
+
function wrapPipeline(state, pipeline, pipelineHandleId) {
|
|
7176
|
+
const operation = pipeline.getBindGroupLayout;
|
|
7177
|
+
if (operation === void 0) return pipeline;
|
|
7178
|
+
const getLayout = operation.bind(pipeline);
|
|
7179
|
+
Object.defineProperty(pipeline, "getBindGroupLayout", {
|
|
7180
|
+
configurable: true,
|
|
7181
|
+
value: (index) => {
|
|
7182
|
+
const layout = getLayout(index);
|
|
7183
|
+
const event = {
|
|
7184
|
+
kind: "getBindGroupLayout",
|
|
7185
|
+
handleId: "",
|
|
7186
|
+
pipelineHandleId,
|
|
7187
|
+
index
|
|
7188
|
+
};
|
|
7189
|
+
registerHandle(state, layout, "bindGroupLayout", event);
|
|
7190
|
+
pushEvent(state, event);
|
|
7191
|
+
return layout;
|
|
7192
|
+
}
|
|
7193
|
+
});
|
|
7194
|
+
return pipeline;
|
|
7195
|
+
}
|
|
7054
7196
|
|
|
7055
7197
|
// src/recorder/queue.ts
|
|
7056
7198
|
function createQueueProxy(s, realQueue) {
|
|
@@ -7381,9 +7523,9 @@ function createDeviceProxy(s, realDevice) {
|
|
|
7381
7523
|
vertexShaderModuleHandleId,
|
|
7382
7524
|
fragmentShaderModuleHandleId
|
|
7383
7525
|
};
|
|
7384
|
-
registerHandle(s, res.value, "renderPipeline", event);
|
|
7526
|
+
const pipelineId = registerHandle(s, res.value, "renderPipeline", event);
|
|
7385
7527
|
pushEvent(s, event);
|
|
7386
|
-
return res;
|
|
7528
|
+
return ok(wrapPipeline(s, res.value, pipelineId));
|
|
7387
7529
|
},
|
|
7388
7530
|
createComputePipeline(desc) {
|
|
7389
7531
|
const res = realDevice.createComputePipeline(desc);
|
|
@@ -7406,12 +7548,25 @@ function createDeviceProxy(s, realDevice) {
|
|
|
7406
7548
|
layoutHandleId: layoutId,
|
|
7407
7549
|
computeShaderModuleHandleId
|
|
7408
7550
|
};
|
|
7409
|
-
registerHandle(s, res.value, "computePipeline", event);
|
|
7551
|
+
const pipelineId = registerHandle(s, res.value, "computePipeline", event);
|
|
7410
7552
|
pushEvent(s, event);
|
|
7411
|
-
return res;
|
|
7553
|
+
return ok(wrapPipeline(s, res.value, pipelineId));
|
|
7412
7554
|
},
|
|
7413
7555
|
createQuerySet(desc) {
|
|
7414
|
-
|
|
7556
|
+
const res = realDevice.createQuerySet(desc);
|
|
7557
|
+
if (!res.ok) return res;
|
|
7558
|
+
const event = {
|
|
7559
|
+
kind: "createQuerySet",
|
|
7560
|
+
handleId: "",
|
|
7561
|
+
desc: {
|
|
7562
|
+
...desc.label === void 0 ? {} : { label: desc.label },
|
|
7563
|
+
type: desc.type ?? "occlusion",
|
|
7564
|
+
count: desc.count ?? 0
|
|
7565
|
+
}
|
|
7566
|
+
};
|
|
7567
|
+
registerHandle(s, res.value, "querySet", event);
|
|
7568
|
+
pushEvent(s, event);
|
|
7569
|
+
return res;
|
|
7415
7570
|
},
|
|
7416
7571
|
destroyBuffer(buf) {
|
|
7417
7572
|
const hId = s.handleMap.get(buf);
|
|
@@ -7427,7 +7582,16 @@ function createDeviceProxy(s, realDevice) {
|
|
|
7427
7582
|
return res;
|
|
7428
7583
|
},
|
|
7429
7584
|
destroyQuerySet(querySet) {
|
|
7430
|
-
|
|
7585
|
+
const hId = s.handleMap.get(querySet);
|
|
7586
|
+
const res = realDevice.destroyQuerySet(querySet);
|
|
7587
|
+
if (!res.ok) return res;
|
|
7588
|
+
if (hId !== void 0) {
|
|
7589
|
+
if (!retainsCaptureBootstrap(s) && !s.snapshotSeededHandles.has(hId) && !hasBootstrapDependency(s, hId)) {
|
|
7590
|
+
s.bootstrapCreates.delete(hId);
|
|
7591
|
+
}
|
|
7592
|
+
pushEvent(s, { kind: "destroyQuerySet", handleId: hId });
|
|
7593
|
+
}
|
|
7594
|
+
return res;
|
|
7431
7595
|
},
|
|
7432
7596
|
destroyTexture(tex) {
|
|
7433
7597
|
const hId = s.handleMap.get(tex);
|
|
@@ -8180,15 +8344,46 @@ function wrap(instance) {
|
|
|
8180
8344
|
function createRecorderProxy(backend) {
|
|
8181
8345
|
const recorder = wrap(backend.rhi);
|
|
8182
8346
|
const wrappedCreateShaderModule = wrapCreateShaderModule(backend.createShaderModule, recorder);
|
|
8347
|
+
const originalCreateShaderModuleImmediate = backend.createShaderModuleImmediate;
|
|
8348
|
+
const wrappedCreateShaderModuleImmediate = originalCreateShaderModuleImmediate === void 0 ? void 0 : (device, desc) => {
|
|
8349
|
+
const realDevice = device._realDevice ?? device;
|
|
8350
|
+
const result = originalCreateShaderModuleImmediate(realDevice, desc);
|
|
8351
|
+
if (!result.ok) return result;
|
|
8352
|
+
const hId = recorder.pushExternalCreateEvent(result.value, "shaderModule", {
|
|
8353
|
+
kind: "createShaderModule",
|
|
8354
|
+
handleId: "",
|
|
8355
|
+
wgslCode: desc.code
|
|
8356
|
+
});
|
|
8357
|
+
recorder.registerShaderModule(result.value, hId);
|
|
8358
|
+
return result;
|
|
8359
|
+
};
|
|
8183
8360
|
const acquireCanvasContext = backend.rhi.acquireCanvasContext;
|
|
8184
8361
|
const rhi = {
|
|
8185
8362
|
requestAdapter: recorder.requestAdapter.bind(recorder),
|
|
8186
8363
|
createShaderModule: wrappedCreateShaderModule,
|
|
8187
|
-
...
|
|
8364
|
+
...wrappedCreateShaderModuleImmediate === void 0 ? {} : { createShaderModuleImmediate: wrappedCreateShaderModuleImmediate },
|
|
8365
|
+
...acquireCanvasContext === void 0 ? {} : {
|
|
8366
|
+
acquireCanvasContext(canvas) {
|
|
8367
|
+
const result = acquireCanvasContext.call(backend.rhi, canvas);
|
|
8368
|
+
if (!result.ok) return result;
|
|
8369
|
+
const context = result.value;
|
|
8370
|
+
return ok({
|
|
8371
|
+
...context,
|
|
8372
|
+
configure(configuration) {
|
|
8373
|
+
const device = configuration.device._realDevice;
|
|
8374
|
+
return context.configure({
|
|
8375
|
+
...configuration,
|
|
8376
|
+
...device === void 0 ? {} : { device }
|
|
8377
|
+
});
|
|
8378
|
+
}
|
|
8379
|
+
});
|
|
8380
|
+
}
|
|
8381
|
+
}
|
|
8188
8382
|
};
|
|
8189
8383
|
const wrappedBackend = {
|
|
8190
8384
|
rhi,
|
|
8191
8385
|
createShaderModule: wrappedCreateShaderModule,
|
|
8386
|
+
...wrappedCreateShaderModuleImmediate === void 0 ? {} : { createShaderModuleImmediate: wrappedCreateShaderModuleImmediate },
|
|
8192
8387
|
unwrapDeviceForSurface(device) {
|
|
8193
8388
|
const raw = device._realDevice;
|
|
8194
8389
|
if (raw !== void 0) return ok(raw);
|
|
@@ -8619,10 +8814,20 @@ async function executeEvent(context, event, eventIndex) {
|
|
|
8619
8814
|
kind: "texture"
|
|
8620
8815
|
}
|
|
8621
8816
|
);
|
|
8817
|
+
case "createQuerySet":
|
|
8818
|
+
return createResource(
|
|
8819
|
+
context,
|
|
8820
|
+
eventIndex,
|
|
8821
|
+
event,
|
|
8822
|
+
context.device.createQuerySet(event.desc),
|
|
8823
|
+
{ kind: "query-set" }
|
|
8824
|
+
);
|
|
8622
8825
|
case "destroyBuffer":
|
|
8623
8826
|
return destroyResource(context, eventIndex, event, "buffer");
|
|
8624
8827
|
case "destroyTexture":
|
|
8625
8828
|
return destroyResource(context, eventIndex, event, "texture");
|
|
8829
|
+
case "destroyQuerySet":
|
|
8830
|
+
return destroyQuerySet(context, event, eventIndex);
|
|
8626
8831
|
case "createTextureView": {
|
|
8627
8832
|
const texture = requireResource(
|
|
8628
8833
|
context,
|
|
@@ -8659,6 +8864,25 @@ async function executeEvent(context, event, eventIndex) {
|
|
|
8659
8864
|
context.device.createBindGroupLayout(event.desc),
|
|
8660
8865
|
{ kind: "binding", role: "bind-group-layout" }
|
|
8661
8866
|
);
|
|
8867
|
+
case "getBindGroupLayout": {
|
|
8868
|
+
const pipeline = requireReplayResource(
|
|
8869
|
+
context,
|
|
8870
|
+
event.pipelineHandleId,
|
|
8871
|
+
"pipeline",
|
|
8872
|
+
eventIndex,
|
|
8873
|
+
event.kind
|
|
8874
|
+
);
|
|
8875
|
+
if (!pipeline.ok) return pipeline;
|
|
8876
|
+
return createResource(
|
|
8877
|
+
context,
|
|
8878
|
+
eventIndex,
|
|
8879
|
+
event,
|
|
8880
|
+
ok(
|
|
8881
|
+
pipeline.value.value.getBindGroupLayout(event.index)
|
|
8882
|
+
),
|
|
8883
|
+
{ kind: "binding", role: "bind-group-layout" }
|
|
8884
|
+
);
|
|
8885
|
+
}
|
|
8662
8886
|
case "createBindGroup":
|
|
8663
8887
|
return createBindGroup(context, event, eventIndex);
|
|
8664
8888
|
case "createPipelineLayout":
|
|
@@ -8690,6 +8914,18 @@ async function executeEvent(context, event, eventIndex) {
|
|
|
8690
8914
|
return beginRenderPass(context, event, eventIndex);
|
|
8691
8915
|
case "beginComputePass":
|
|
8692
8916
|
return beginComputePass(context, event, eventIndex);
|
|
8917
|
+
case "resolveQuerySet":
|
|
8918
|
+
return resolveQuerySet(context, event, eventIndex);
|
|
8919
|
+
case "beginOcclusionQuery":
|
|
8920
|
+
return passCall(context, event, eventIndex, "render-pass", (pass) => {
|
|
8921
|
+
const result = pass.beginOcclusionQuery(event.queryIndex);
|
|
8922
|
+
return result.ok ? ok(void 0) : eventFailure(eventIndex, event, "encode", result.error);
|
|
8923
|
+
});
|
|
8924
|
+
case "endOcclusionQuery":
|
|
8925
|
+
return passCall(context, event, eventIndex, "render-pass", (pass) => {
|
|
8926
|
+
const result = pass.endOcclusionQuery();
|
|
8927
|
+
return result.ok ? ok(void 0) : eventFailure(eventIndex, event, "encode", result.error);
|
|
8928
|
+
});
|
|
8693
8929
|
case "copyBufferToBuffer":
|
|
8694
8930
|
return copyBufferToBuffer(context, event, eventIndex);
|
|
8695
8931
|
case "copyBufferToTexture":
|
|
@@ -8920,6 +9156,50 @@ function destroyResource(context, eventIndex, event, kind) {
|
|
|
8920
9156
|
context.table.delete(event.handleId);
|
|
8921
9157
|
return ok(void 0);
|
|
8922
9158
|
}
|
|
9159
|
+
function destroyQuerySet(context, event, eventIndex) {
|
|
9160
|
+
const entry = context.table.get(event.handleId);
|
|
9161
|
+
if (entry?.resource.kind !== "query-set")
|
|
9162
|
+
return missingResource(eventIndex, event, event.handleId, "query-set");
|
|
9163
|
+
const result = context.device.destroyQuerySet(entry.resource.value);
|
|
9164
|
+
if (!result.ok) return eventFailure(eventIndex, event, "create", result.error);
|
|
9165
|
+
context.table.delete(event.handleId);
|
|
9166
|
+
return ok(void 0);
|
|
9167
|
+
}
|
|
9168
|
+
function resolveQuerySet(context, event, eventIndex) {
|
|
9169
|
+
const encoder = requireResource(
|
|
9170
|
+
context,
|
|
9171
|
+
event.cmdHandleId,
|
|
9172
|
+
"encoder",
|
|
9173
|
+
eventIndex,
|
|
9174
|
+
event.kind,
|
|
9175
|
+
"command"
|
|
9176
|
+
);
|
|
9177
|
+
const querySet = requireResource(
|
|
9178
|
+
context,
|
|
9179
|
+
event.querySetHandleId,
|
|
9180
|
+
"query-set",
|
|
9181
|
+
eventIndex,
|
|
9182
|
+
event.kind
|
|
9183
|
+
);
|
|
9184
|
+
const destination = requireResource(
|
|
9185
|
+
context,
|
|
9186
|
+
event.destinationHandleId,
|
|
9187
|
+
"buffer",
|
|
9188
|
+
eventIndex,
|
|
9189
|
+
event.kind
|
|
9190
|
+
);
|
|
9191
|
+
if (!encoder.ok) return encoder;
|
|
9192
|
+
if (!querySet.ok) return querySet;
|
|
9193
|
+
if (!destination.ok) return destination;
|
|
9194
|
+
const result = encoder.value.resolveQuerySet(
|
|
9195
|
+
querySet.value,
|
|
9196
|
+
event.firstQuery,
|
|
9197
|
+
event.queryCount,
|
|
9198
|
+
destination.value,
|
|
9199
|
+
event.destinationOffset
|
|
9200
|
+
);
|
|
9201
|
+
return result.ok ? ok(void 0) : eventFailure(eventIndex, event, "encode", result.error);
|
|
9202
|
+
}
|
|
8923
9203
|
async function createShaderModule(context, event, eventIndex) {
|
|
8924
9204
|
const result = await context.createShaderModule(context.device, { code: event.wgslCode });
|
|
8925
9205
|
return createResource(context, eventIndex, event, result, { kind: "shader-module" });
|
|
@@ -9145,15 +9425,23 @@ function beginRenderPass(context, event, eventIndex) {
|
|
|
9145
9425
|
};
|
|
9146
9426
|
});
|
|
9147
9427
|
const depth = event.depthStencilViewHandleId === void 0 ? void 0 : context.table.get(event.depthStencilViewHandleId)?.resource;
|
|
9428
|
+
const querySet = event.occlusionQuerySetHandleId === void 0 ? void 0 : context.table.get(event.occlusionQuerySetHandleId)?.resource;
|
|
9429
|
+
if (event.occlusionQuerySetHandleId !== void 0 && querySet?.kind !== "query-set") {
|
|
9430
|
+
return missingResource(eventIndex, event, event.occlusionQuerySetHandleId, "query-set");
|
|
9431
|
+
}
|
|
9432
|
+
const timestamp = replayTimestampWrites(context, event, eventIndex);
|
|
9433
|
+
if (!timestamp.ok) return timestamp;
|
|
9148
9434
|
const descriptor = {
|
|
9149
9435
|
...event.desc,
|
|
9436
|
+
...timestamp.value === void 0 ? {} : { timestampWrites: timestamp.value },
|
|
9150
9437
|
colorAttachments: colors,
|
|
9151
9438
|
...depth?.kind === "texture-view" ? {
|
|
9152
9439
|
depthStencilAttachment: {
|
|
9153
9440
|
...event.desc.depthStencilAttachment,
|
|
9154
9441
|
view: depth.value
|
|
9155
9442
|
}
|
|
9156
|
-
} : {}
|
|
9443
|
+
} : {},
|
|
9444
|
+
...querySet?.kind === "query-set" ? { occlusionQuerySet: querySet.value } : {}
|
|
9157
9445
|
};
|
|
9158
9446
|
const pass = encoder.value.beginRenderPass(descriptor);
|
|
9159
9447
|
return context.table.set(
|
|
@@ -9162,6 +9450,24 @@ function beginRenderPass(context, event, eventIndex) {
|
|
|
9162
9450
|
eventRecord(event)
|
|
9163
9451
|
);
|
|
9164
9452
|
}
|
|
9453
|
+
function replayTimestampWrites(context, event, eventIndex) {
|
|
9454
|
+
if (event.desc?.timestampWrites === void 0) return ok(void 0);
|
|
9455
|
+
const handle = event.timestampQuerySetHandleId;
|
|
9456
|
+
if (handle === void 0)
|
|
9457
|
+
return missingResource(eventIndex, event, "timestamp-query-set", "query-set");
|
|
9458
|
+
const query = requireResource(
|
|
9459
|
+
context,
|
|
9460
|
+
handle,
|
|
9461
|
+
"query-set",
|
|
9462
|
+
eventIndex,
|
|
9463
|
+
event.kind
|
|
9464
|
+
);
|
|
9465
|
+
if (!query.ok) return query;
|
|
9466
|
+
return ok({
|
|
9467
|
+
...event.desc.timestampWrites,
|
|
9468
|
+
querySet: query.value
|
|
9469
|
+
});
|
|
9470
|
+
}
|
|
9165
9471
|
function beginComputePass(context, event, eventIndex) {
|
|
9166
9472
|
const encoder = requireResource(
|
|
9167
9473
|
context,
|
|
@@ -9172,7 +9478,12 @@ function beginComputePass(context, event, eventIndex) {
|
|
|
9172
9478
|
"command"
|
|
9173
9479
|
);
|
|
9174
9480
|
if (!encoder.ok) return encoder;
|
|
9175
|
-
const
|
|
9481
|
+
const timestamp = replayTimestampWrites(context, event, eventIndex);
|
|
9482
|
+
if (!timestamp.ok) return timestamp;
|
|
9483
|
+
const pass = encoder.value.beginComputePass({
|
|
9484
|
+
...event.desc?.label === void 0 ? {} : { label: event.desc.label },
|
|
9485
|
+
...timestamp.value === void 0 ? {} : { timestampWrites: timestamp.value }
|
|
9486
|
+
});
|
|
9176
9487
|
return context.table.set(
|
|
9177
9488
|
event.passHandleId,
|
|
9178
9489
|
{ kind: "encoder", role: "compute-pass", value: pass },
|
|
@@ -9353,7 +9664,7 @@ async function readReplayResource(device, table, resourceId, subresource, create
|
|
|
9353
9664
|
});
|
|
9354
9665
|
}
|
|
9355
9666
|
function resolveTextureViewSubresource(view, source, requested) {
|
|
9356
|
-
if (
|
|
9667
|
+
if (isBufferRange(requested)) return ok(requested);
|
|
9357
9668
|
const sourceDescriptor = recordField(source.descriptor, "desc");
|
|
9358
9669
|
const sourceSize = textureSize(sourceDescriptor?.size);
|
|
9359
9670
|
const sourceMipCount = numberField(sourceDescriptor, "mipLevelCount") ?? 1;
|
|
@@ -9362,15 +9673,16 @@ function resolveTextureViewSubresource(view, source, requested) {
|
|
|
9362
9673
|
const baseArrayLayer = numberField(viewDescriptor, "baseArrayLayer") ?? 0;
|
|
9363
9674
|
const mipLevelCount = numberField(viewDescriptor, "mipLevelCount") ?? sourceMipCount - baseMipLevel;
|
|
9364
9675
|
const arrayLayerCount = numberField(viewDescriptor, "arrayLayerCount") ?? sourceSize.depthOrArrayLayers - baseArrayLayer;
|
|
9365
|
-
const localMipLevel = requested
|
|
9366
|
-
const localArrayLayer = requested
|
|
9676
|
+
const localMipLevel = requested?.mipLevel ?? 0;
|
|
9677
|
+
const localArrayLayer = requested?.arrayLayer ?? 0;
|
|
9367
9678
|
if (!validIndex(baseMipLevel, sourceMipCount + 1) || !validIndex(baseArrayLayer, sourceSize.depthOrArrayLayers + 1) || !validIndex(localMipLevel, mipLevelCount) || !validIndex(localArrayLayer, arrayLayerCount) || baseMipLevel + mipLevelCount > sourceMipCount || baseArrayLayer + arrayLayerCount > sourceSize.depthOrArrayLayers) {
|
|
9368
9679
|
return readbackFailure("texture view subresource is outside the recorded view extent");
|
|
9369
9680
|
}
|
|
9370
9681
|
return ok({
|
|
9371
9682
|
...requested,
|
|
9372
9683
|
mipLevel: baseMipLevel + localMipLevel,
|
|
9373
|
-
arrayLayer: baseArrayLayer + localArrayLayer
|
|
9684
|
+
arrayLayer: baseArrayLayer + localArrayLayer,
|
|
9685
|
+
aspect: requested?.aspect ?? (viewDescriptor?.aspect === "depth-only" || viewDescriptor?.aspect === "stencil-only" ? viewDescriptor.aspect : "all")
|
|
9374
9686
|
});
|
|
9375
9687
|
}
|
|
9376
9688
|
async function readBuffer(device, entry, resourceId, subresource) {
|
|
@@ -9398,6 +9710,13 @@ async function readTexture(device, entry, resourceId, subresource, createShaderM
|
|
|
9398
9710
|
const format = stringField2(descriptor, "format");
|
|
9399
9711
|
const dimension = stringField2(descriptor, "dimension") ?? "2d";
|
|
9400
9712
|
if (format === void 0) return readbackFailure(`texture ${resourceId} has no recorded format`);
|
|
9713
|
+
if ((numberField(descriptor, "sampleCount") ?? 1) > 1) {
|
|
9714
|
+
return readbackUnsupported(
|
|
9715
|
+
resourceId,
|
|
9716
|
+
format,
|
|
9717
|
+
"multisampled textures require a single-sample resolve target before readback"
|
|
9718
|
+
);
|
|
9719
|
+
}
|
|
9401
9720
|
const plan = getTextureReadbackPlan({ format, dimension });
|
|
9402
9721
|
if (!plan.supported) {
|
|
9403
9722
|
return err(
|
|
@@ -9877,6 +10196,10 @@ var ResourceTable = class {
|
|
|
9877
10196
|
const result = this.device.destroyTexture(entry.resource.value);
|
|
9878
10197
|
if (!result.ok && firstFailure === void 0)
|
|
9879
10198
|
firstFailure = resourceDisposeFailure(entry.resourceId, result.error.code);
|
|
10199
|
+
} else if (entry.resource.kind === "query-set") {
|
|
10200
|
+
const result = this.device.destroyQuerySet(entry.resource.value);
|
|
10201
|
+
if (!result.ok && firstFailure === void 0)
|
|
10202
|
+
firstFailure = resourceDisposeFailure(entry.resourceId, result.error.code);
|
|
9880
10203
|
}
|
|
9881
10204
|
}
|
|
9882
10205
|
return firstFailure ?? ok(void 0);
|
|
@@ -10009,6 +10332,42 @@ async function openReplay(tape, backend) {
|
|
|
10009
10332
|
backend.createShaderModule
|
|
10010
10333
|
);
|
|
10011
10334
|
},
|
|
10335
|
+
async readResourceAtWork(resourceId, workIndex, subresource, signal) {
|
|
10336
|
+
if (disposed) return positionError(workIndex, index.works.length);
|
|
10337
|
+
if (signal?.aborted) {
|
|
10338
|
+
return err(
|
|
10339
|
+
createRhiDebugError("readback-failed", {
|
|
10340
|
+
stage: "readback",
|
|
10341
|
+
cause: "readback was aborted"
|
|
10342
|
+
})
|
|
10343
|
+
);
|
|
10344
|
+
}
|
|
10345
|
+
const work = index.works[workIndex];
|
|
10346
|
+
if (work === void 0 || model.works[workIndex] === void 0) {
|
|
10347
|
+
return positionError(workIndex, index.works.length);
|
|
10348
|
+
}
|
|
10349
|
+
const cleared = await reset();
|
|
10350
|
+
if (!cleared.ok) return cleared;
|
|
10351
|
+
const bootstrapped = await prepare();
|
|
10352
|
+
if (!bootstrapped.ok) return bootstrapped;
|
|
10353
|
+
const replayed = await replayThroughWork(context, index, work, signal);
|
|
10354
|
+
if (!replayed.ok) return replayed;
|
|
10355
|
+
const read = await readReplayResource(
|
|
10356
|
+
backend.device,
|
|
10357
|
+
table,
|
|
10358
|
+
resourceId,
|
|
10359
|
+
subresource,
|
|
10360
|
+
backend.createShaderModule
|
|
10361
|
+
);
|
|
10362
|
+
if (!read.ok) return read;
|
|
10363
|
+
return ok({
|
|
10364
|
+
...read.value,
|
|
10365
|
+
provenance: {
|
|
10366
|
+
...read.value.provenance,
|
|
10367
|
+
selectedWorkIndex: work.workIndex
|
|
10368
|
+
}
|
|
10369
|
+
});
|
|
10370
|
+
},
|
|
10012
10371
|
async dispose() {
|
|
10013
10372
|
if (disposed) return ok(void 0);
|
|
10014
10373
|
const result = table.dispose();
|
|
@@ -10110,7 +10469,8 @@ function requiredReplayCapabilities(tape) {
|
|
|
10110
10469
|
}
|
|
10111
10470
|
async function executeBootstrapResource(context, resource, bootstrapIndex) {
|
|
10112
10471
|
const event = JSON.parse(JSON.stringify(resource.create));
|
|
10113
|
-
const
|
|
10472
|
+
const replayEvent = event.kind === "createBuffer" && resource.initialData.length > 0 ? { ...event, desc: { ...event.desc, mappedAtCreation: true } } : event;
|
|
10473
|
+
const result = await executeEvent(context, replayEvent, -bootstrapIndex - 1);
|
|
10114
10474
|
return result;
|
|
10115
10475
|
}
|
|
10116
10476
|
async function seedBootstrapResource(context, resource, bootstrapIndex) {
|
|
@@ -10128,25 +10488,41 @@ async function seedBootstrapResource(context, resource, bootstrapIndex) {
|
|
|
10128
10488
|
"bootstrap initialData requires a buffer or color texture resource"
|
|
10129
10489
|
);
|
|
10130
10490
|
}
|
|
10131
|
-
|
|
10132
|
-
|
|
10133
|
-
if (
|
|
10134
|
-
|
|
10135
|
-
|
|
10136
|
-
|
|
10137
|
-
|
|
10138
|
-
|
|
10139
|
-
|
|
10140
|
-
|
|
10141
|
-
|
|
10142
|
-
|
|
10143
|
-
|
|
10144
|
-
|
|
10145
|
-
|
|
10146
|
-
|
|
10147
|
-
|
|
10148
|
-
|
|
10491
|
+
const mapped = entry.resource.value;
|
|
10492
|
+
if (typeof mapped.getMappedRange !== "function" || typeof mapped.unmap !== "function") {
|
|
10493
|
+
if (context.device.caps.backendKind === "null") return ok(void 0);
|
|
10494
|
+
return eventFailure(
|
|
10495
|
+
-bootstrapIndex - 1,
|
|
10496
|
+
event,
|
|
10497
|
+
"write",
|
|
10498
|
+
"bootstrap buffer mapping is unavailable on the replay backend"
|
|
10499
|
+
);
|
|
10500
|
+
}
|
|
10501
|
+
try {
|
|
10502
|
+
const range = mapped.getMappedRange();
|
|
10503
|
+
if (!range.ok) return eventFailure(-bootstrapIndex - 1, event, "write", range.error);
|
|
10504
|
+
const target = new Uint8Array(range.value);
|
|
10505
|
+
for (const slice of resource.initialData) {
|
|
10506
|
+
const blob2 = context.tape.blobs.find((candidate) => candidate.hash === slice.hash);
|
|
10507
|
+
if (blob2 === void 0) {
|
|
10508
|
+
return eventFailure(-bootstrapIndex - 1, event, "lookup", `blob ${slice.hash} is missing`);
|
|
10509
|
+
}
|
|
10510
|
+
const end = slice.byteOffset + slice.byteLength;
|
|
10511
|
+
if (slice.byteOffset < 0 || slice.byteLength < 0 || end > blob2.bytes.byteLength) {
|
|
10512
|
+
return eventFailure(
|
|
10513
|
+
-bootstrapIndex - 1,
|
|
10514
|
+
event,
|
|
10515
|
+
"lookup",
|
|
10516
|
+
`blob ${slice.hash} does not contain initialData slice [${slice.byteOffset}, ${end})`
|
|
10517
|
+
);
|
|
10518
|
+
}
|
|
10519
|
+
if (slice.byteLength > target.byteLength) {
|
|
10520
|
+
return eventFailure(-bootstrapIndex - 1, event, "write", "initialData exceeds buffer size");
|
|
10521
|
+
}
|
|
10522
|
+
target.set(blob2.bytes.subarray(slice.byteOffset, end));
|
|
10149
10523
|
}
|
|
10524
|
+
} finally {
|
|
10525
|
+
mapped.unmap();
|
|
10150
10526
|
}
|
|
10151
10527
|
return ok(void 0);
|
|
10152
10528
|
}
|
|
@@ -10245,12 +10621,8 @@ async function finalizeWorkPass(context, index, work) {
|
|
|
10245
10621
|
`pass ${begin.passHandleId} is not open`
|
|
10246
10622
|
);
|
|
10247
10623
|
}
|
|
10248
|
-
|
|
10249
|
-
|
|
10250
|
-
} catch (cause) {
|
|
10251
|
-
return eventFailure(pass.endEventIndex ?? work.eventIndex, begin, "encode", cause);
|
|
10252
|
-
}
|
|
10253
|
-
context.table.delete(begin.passHandleId);
|
|
10624
|
+
const closed = closeReplayPass(context, entry, begin, pass, work.eventIndex);
|
|
10625
|
+
if (!closed.ok) return closed;
|
|
10254
10626
|
const finishEventIndex = findNextEvent(
|
|
10255
10627
|
context.tape.events,
|
|
10256
10628
|
pass.beginEventIndex,
|
|
@@ -10266,6 +10638,13 @@ async function finalizeWorkPass(context, index, work) {
|
|
|
10266
10638
|
`encoder ${begin.cmdHandleId} is not available`
|
|
10267
10639
|
);
|
|
10268
10640
|
}
|
|
10641
|
+
const closure = await replayCommandClosure(
|
|
10642
|
+
context,
|
|
10643
|
+
begin.cmdHandleId,
|
|
10644
|
+
(pass.endEventIndex ?? work.eventIndex) + 1,
|
|
10645
|
+
finishEventIndex ?? context.tape.events.length
|
|
10646
|
+
);
|
|
10647
|
+
if (!closure.ok) return closure;
|
|
10269
10648
|
const finished = encoder.resource.value.finish();
|
|
10270
10649
|
const finishEvent = context.tape.events[finishEventIndex ?? work.eventIndex] ?? begin;
|
|
10271
10650
|
if (!finished.ok)
|
|
@@ -10293,6 +10672,95 @@ async function finalizeWorkPass(context, index, work) {
|
|
|
10293
10672
|
await context.queue.onSubmittedWorkDone();
|
|
10294
10673
|
return ok(void 0);
|
|
10295
10674
|
}
|
|
10675
|
+
function closeReplayPass(context, entry, begin, pass, selectedEventIndex) {
|
|
10676
|
+
const activeQuery = activeOcclusionQuery(
|
|
10677
|
+
context.tape.events,
|
|
10678
|
+
begin.kind === "beginRenderPass" ? begin.passHandleId : void 0,
|
|
10679
|
+
pass.beginEventIndex,
|
|
10680
|
+
selectedEventIndex
|
|
10681
|
+
);
|
|
10682
|
+
if (!activeQuery.ok) return activeQuery;
|
|
10683
|
+
try {
|
|
10684
|
+
if (activeQuery.value !== void 0) {
|
|
10685
|
+
if (entry.resource.role !== "render-pass") {
|
|
10686
|
+
return eventFailure(
|
|
10687
|
+
activeQuery.value.eventIndex,
|
|
10688
|
+
activeQuery.value.event,
|
|
10689
|
+
"lookup",
|
|
10690
|
+
"an active occlusion query belongs to a non-render pass"
|
|
10691
|
+
);
|
|
10692
|
+
}
|
|
10693
|
+
const endedQuery = entry.resource.value.endOcclusionQuery();
|
|
10694
|
+
if (!endedQuery.ok) {
|
|
10695
|
+
return eventFailure(
|
|
10696
|
+
activeQuery.value.eventIndex,
|
|
10697
|
+
activeQuery.value.event,
|
|
10698
|
+
"encode",
|
|
10699
|
+
endedQuery.error
|
|
10700
|
+
);
|
|
10701
|
+
}
|
|
10702
|
+
}
|
|
10703
|
+
entry.resource.value.end();
|
|
10704
|
+
} catch (cause) {
|
|
10705
|
+
return eventFailure(pass.endEventIndex ?? selectedEventIndex, begin, "encode", cause);
|
|
10706
|
+
}
|
|
10707
|
+
context.table.delete(begin.passHandleId);
|
|
10708
|
+
return ok(void 0);
|
|
10709
|
+
}
|
|
10710
|
+
async function replayCommandClosure(context, cmdHandleId, start, end) {
|
|
10711
|
+
for (let eventIndex = start; eventIndex < end; eventIndex++) {
|
|
10712
|
+
const event = context.tape.events[eventIndex];
|
|
10713
|
+
if (event === void 0 || !isCommandClosureEvent(event)) continue;
|
|
10714
|
+
if (event.cmdHandleId !== cmdHandleId) continue;
|
|
10715
|
+
const result = await executeEvent(context, event, eventIndex);
|
|
10716
|
+
if (!result.ok) return result;
|
|
10717
|
+
}
|
|
10718
|
+
return ok(void 0);
|
|
10719
|
+
}
|
|
10720
|
+
function activeOcclusionQuery(events, passHandleId, beginEventIndex, selectedEventIndex) {
|
|
10721
|
+
if (passHandleId === void 0) return ok(void 0);
|
|
10722
|
+
let active;
|
|
10723
|
+
for (let eventIndex = beginEventIndex + 1; eventIndex <= selectedEventIndex; eventIndex++) {
|
|
10724
|
+
const event = events[eventIndex];
|
|
10725
|
+
if (event === void 0 || !("passHandleId" in event) || event.passHandleId !== passHandleId)
|
|
10726
|
+
continue;
|
|
10727
|
+
if (event.kind === "beginOcclusionQuery") {
|
|
10728
|
+
if (active !== void 0) {
|
|
10729
|
+
return eventFailure(
|
|
10730
|
+
eventIndex,
|
|
10731
|
+
event,
|
|
10732
|
+
"encode",
|
|
10733
|
+
"an occlusion query is already active for this render pass"
|
|
10734
|
+
);
|
|
10735
|
+
}
|
|
10736
|
+
active = { eventIndex, event };
|
|
10737
|
+
} else if (event.kind === "endOcclusionQuery") {
|
|
10738
|
+
if (active === void 0) {
|
|
10739
|
+
return eventFailure(
|
|
10740
|
+
eventIndex,
|
|
10741
|
+
event,
|
|
10742
|
+
"encode",
|
|
10743
|
+
"an occlusion query ended without a matching begin"
|
|
10744
|
+
);
|
|
10745
|
+
}
|
|
10746
|
+
active = void 0;
|
|
10747
|
+
}
|
|
10748
|
+
}
|
|
10749
|
+
return ok(active);
|
|
10750
|
+
}
|
|
10751
|
+
function isCommandClosureEvent(event) {
|
|
10752
|
+
switch (event.kind) {
|
|
10753
|
+
case "resolveQuerySet":
|
|
10754
|
+
case "copyBufferToBuffer":
|
|
10755
|
+
case "copyBufferToTexture":
|
|
10756
|
+
case "copyTextureToBuffer":
|
|
10757
|
+
case "copyTextureToTexture":
|
|
10758
|
+
case "clearBuffer":
|
|
10759
|
+
return true;
|
|
10760
|
+
default:
|
|
10761
|
+
return false;
|
|
10762
|
+
}
|
|
10763
|
+
}
|
|
10296
10764
|
function findNextEvent(events, start, kind, commandId) {
|
|
10297
10765
|
for (let index = start + 1; index < events.length; index++) {
|
|
10298
10766
|
const event = events[index];
|
|
@@ -10322,9 +10790,10 @@ async function readWorkAttachment(context, index, work) {
|
|
|
10322
10790
|
})
|
|
10323
10791
|
);
|
|
10324
10792
|
}
|
|
10325
|
-
const
|
|
10793
|
+
const attachmentIndex = begin.colorAttachmentViewHandleIds.findIndex(
|
|
10326
10794
|
(candidate) => candidate !== void 0
|
|
10327
10795
|
);
|
|
10796
|
+
const viewId = begin.colorAttachmentResolveTargetHandleIds?.[attachmentIndex] ?? begin.colorAttachmentViewHandleIds[attachmentIndex];
|
|
10328
10797
|
if (viewId === void 0) {
|
|
10329
10798
|
return err(
|
|
10330
10799
|
createRhiDebugError("readback-unsupported", {
|