@woosh/meep-engine 3.31.0 → 3.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/bundle-worker-terrain.js +1 -1
- package/package.json +1 -1
- package/src/core/collection/table/RowFirstTable.d.ts +8 -0
- package/src/core/collection/table/RowFirstTable.d.ts.map +1 -1
- package/src/core/collection/table/RowFirstTable.js +40 -11
- package/src/engine/graphics/ecs/sprite/Sprite.d.ts +3 -0
- package/src/engine/graphics/ecs/sprite/Sprite.d.ts.map +1 -1
- package/src/engine/graphics/ecs/sprite/Sprite.js +3 -0
- package/src/engine/graphics/ecs/sprite/SpriteSystemPE.d.ts +3 -0
- package/src/engine/graphics/ecs/sprite/SpriteSystemPE.d.ts.map +1 -1
- package/src/engine/graphics/ecs/sprite/SpriteSystemPE.js +3 -0
- package/src/engine/graphics3/DebugDrawSystem.d.ts.map +1 -1
- package/src/engine/graphics3/DebugDrawSystem.js +6 -2
- package/src/engine/graphics3/PathDisplaySystem.d.ts.map +1 -1
- package/src/engine/graphics3/PathDisplaySystem.js +311 -307
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/shade/RENDERER_CONTRACT.md +15 -2
- package/src/shade/device/IMMEDIATE_DATA_PLAN_2026_08_28.md +5 -0
- package/src/shade/device/ShadeGPUCommandContext.d.ts +15 -2
- package/src/shade/device/ShadeGPUCommandContext.d.ts.map +1 -1
- package/src/shade/device/ShadeGPUCommandContext.js +154 -25
- package/src/shade/device/mock/SoftwareGPURenderPassEncoder.d.ts +20 -3
- package/src/shade/device/mock/SoftwareGPURenderPassEncoder.d.ts.map +1 -1
- package/src/shade/device/mock/SoftwareGPURenderPassEncoder.js +21 -3
- package/src/shade/renderer/GraphicsContext.d.ts +20 -1
- package/src/shade/renderer/GraphicsContext.d.ts.map +1 -1
- package/src/shade/renderer/GraphicsContext.js +105 -52
- package/src/shade/renderer/Renderer.d.ts +19 -4
- package/src/shade/renderer/Renderer.d.ts.map +1 -1
- package/src/shade/renderer/Renderer.js +113 -2
- package/src/shade/renderer/animation/GPUAnimationManager.d.ts +10 -7
- package/src/shade/renderer/animation/GPUAnimationManager.d.ts.map +1 -1
- package/src/shade/renderer/animation/GPUAnimationManager.js +147 -45
- package/src/shade/renderer/buffer/GPUBufferReadbackAllocator.d.ts +6 -5
- package/src/shade/renderer/buffer/GPUBufferReadbackAllocator.d.ts.map +1 -1
- package/src/shade/renderer/buffer/GPUBufferReadbackAllocator.js +241 -240
- package/src/shade/renderer/buffer/GPUBufferStagingAllocator.d.ts +62 -2
- package/src/shade/renderer/buffer/GPUBufferStagingAllocator.d.ts.map +1 -1
- package/src/shade/renderer/buffer/GPUBufferStagingAllocator.js +306 -38
- package/src/shade/renderer/buffer/GPUBufferUploadAllocator.d.ts +60 -0
- package/src/shade/renderer/buffer/GPUBufferUploadAllocator.d.ts.map +1 -0
- package/src/shade/renderer/buffer/GPUBufferUploadAllocator.js +202 -0
- package/src/shade/renderer/buffer/GPUUploadBlock.d.ts +68 -0
- package/src/shade/renderer/buffer/GPUUploadBlock.d.ts.map +1 -0
- package/src/shade/renderer/buffer/GPUUploadBlock.js +97 -0
- package/src/shade/renderer/dynamic/DynamicMeshAVBOITChannel.d.ts +2 -1
- package/src/shade/renderer/dynamic/DynamicMeshAVBOITChannel.d.ts.map +1 -1
- package/src/shade/renderer/dynamic/DynamicMeshAVBOITChannel.js +19 -17
- package/src/shade/renderer/dynamic/GPUDynamicMeshDrawList.d.ts +70 -0
- package/src/shade/renderer/dynamic/GPUDynamicMeshDrawList.d.ts.map +1 -0
- package/src/shade/renderer/dynamic/GPUDynamicMeshDrawList.js +257 -0
- package/src/shade/renderer/dynamic/GPUDynamicMeshRenderer.d.ts +20 -7
- package/src/shade/renderer/dynamic/GPUDynamicMeshRenderer.d.ts.map +1 -1
- package/src/shade/renderer/dynamic/GPUDynamicMeshRenderer.js +39 -41
- package/src/shade/renderer/dynamic/GPUDynamicMeshResidency.d.ts +6 -20
- package/src/shade/renderer/dynamic/GPUDynamicMeshResidency.d.ts.map +1 -1
- package/src/shade/renderer/dynamic/GPUDynamicMeshResidency.js +42 -36
- package/src/shade/renderer/dynamic/chunk_dynamic_mesh_avboit_vertex.d.ts +2 -1
- package/src/shade/renderer/dynamic/chunk_dynamic_mesh_avboit_vertex.d.ts.map +1 -1
- package/src/shade/renderer/dynamic/chunk_dynamic_mesh_avboit_vertex.js +4 -3
- package/src/shade/renderer/dynamic/chunk_dynamic_mesh_vertex.d.ts +4 -3
- package/src/shade/renderer/dynamic/chunk_dynamic_mesh_vertex.d.ts.map +1 -1
- package/src/shade/renderer/dynamic/chunk_dynamic_mesh_vertex.js +7 -4
- package/src/shade/renderer/dynamic/graph_dynamic_mesh_avboit.d.ts +14 -15
- package/src/shade/renderer/dynamic/graph_dynamic_mesh_avboit.d.ts.map +1 -1
- package/src/shade/renderer/dynamic/graph_dynamic_mesh_avboit.js +49 -83
- package/src/shade/renderer/dynamic/shader_dynamic_mesh.d.ts +19 -3
- package/src/shade/renderer/dynamic/shader_dynamic_mesh.d.ts.map +1 -1
- package/src/shade/renderer/dynamic/shader_dynamic_mesh.js +26 -6
- package/src/shade/renderer/dynamic/shader_dynamic_mesh_avboit_draw.d.ts +2 -1
- package/src/shade/renderer/dynamic/shader_dynamic_mesh_avboit_draw.d.ts.map +1 -1
- package/src/shade/renderer/dynamic/shader_dynamic_mesh_avboit_draw.js +12 -6
- package/src/shade/renderer/dynamic/shader_dynamic_mesh_avboit_splat.d.ts +3 -2
- package/src/shade/renderer/dynamic/shader_dynamic_mesh_avboit_splat.d.ts.map +1 -1
- package/src/shade/renderer/dynamic/shader_dynamic_mesh_avboit_splat.js +21 -13
- package/src/shade/renderer/geometry/meshlet/build/meshoptimizer/geometry_to_meshlets_meshoptimizer.d.ts +5 -0
- package/src/shade/renderer/geometry/meshlet/build/meshoptimizer/geometry_to_meshlets_meshoptimizer.d.ts.map +1 -1
- package/src/shade/renderer/geometry/meshlet/build/meshoptimizer/geometry_to_meshlets_meshoptimizer.js +19 -0
- package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
- package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
- package/src/shade/renderer/rasterize/bucket/rasterization_has_opaque_bucket.d.ts +3 -1
- package/src/shade/renderer/rasterize/bucket/rasterization_has_opaque_bucket.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/bucket/rasterization_has_opaque_bucket.js +3 -1
- package/src/shade/renderer/rasterize/expand/bucket/mesh/shader_instances_rasterization_bucket_sort.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/bucket/mesh/shader_instances_rasterization_bucket_sort.js +134 -88
- package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_rasterization_bucket_sort.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_rasterization_bucket_sort.js +57 -26
- package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.js +28 -20
- package/src/shade/renderer/rasterize/graph_clear_raster_targets.d.ts +38 -0
- package/src/shade/renderer/rasterize/graph_clear_raster_targets.d.ts.map +1 -0
- package/src/shade/renderer/rasterize/graph_clear_raster_targets.js +105 -0
- package/src/shade/renderer/rasterize/native/avboit/AVBOIT_LEDGER.md +20 -0
- package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.d.ts +1 -1
- package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.js +21 -1
- package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.js +12 -20
- package/src/shade/renderer/shader/graph/graph_import_typed_buffer.d.ts +2 -1
- package/src/shade/renderer/shader/graph/graph_import_typed_buffer.d.ts.map +1 -1
- package/src/shade/renderer/shader/graph/graph_import_typed_buffer.js +15 -28
- package/src/shade/renderer/shader/type/serde/write_gpu_typed_buffer.d.ts.map +1 -1
- package/src/shade/renderer/shader/type/serde/write_gpu_typed_buffer.js +8 -1
- package/src/core/geom/3d/atlas/atlas_bench_lib.d.ts +0 -73
- package/src/core/geom/3d/atlas/atlas_bench_lib.d.ts.map +0 -1
- package/src/engine/graphics3/terrain/GPUTerrainSplatRenderer.d.ts +0 -59
- package/src/engine/graphics3/terrain/GPUTerrainSplatRenderer.d.ts.map +0 -1
- package/src/engine/graphics3/terrain/pack_terrain_row_table.d.ts +0 -22
- package/src/engine/graphics3/terrain/pack_terrain_row_table.d.ts.map +0 -1
- package/src/engine/graphics3/terrain/shader_terrain_splat.d.ts +0 -26
- package/src/engine/graphics3/terrain/shader_terrain_splat.d.ts.map +0 -1
- package/src/shade/renderer/animation/ANIMATION_BOUND_TRACK_GROUP_STRUCT.d.ts +0 -25
- package/src/shade/renderer/animation/ANIMATION_BOUND_TRACK_GROUP_STRUCT.d.ts.map +0 -1
- package/src/shade/renderer/animation/ANIMATION_KEYFRAME_BLOCK_STRUCT.d.ts +0 -26
- package/src/shade/renderer/animation/ANIMATION_KEYFRAME_BLOCK_STRUCT.d.ts.map +0 -1
- package/src/shade/renderer/animation/ANIMATION_SKIN_JOINT_BLOCK_STRUCT.d.ts +0 -29
- package/src/shade/renderer/animation/ANIMATION_SKIN_JOINT_BLOCK_STRUCT.d.ts.map +0 -1
|
@@ -398,14 +398,18 @@ class PathExtension extends RenderExtension {
|
|
|
398
398
|
}
|
|
399
399
|
|
|
400
400
|
const scene = frame.get(SceneColor);
|
|
401
|
+
const view = frame.get(ViewTextures);
|
|
401
402
|
|
|
402
|
-
|
|
403
|
+
const drawn = this.#renderer.graph_draw({
|
|
403
404
|
graph: frame.graph,
|
|
404
405
|
batch: this.#batch,
|
|
405
406
|
color: scene.color,
|
|
406
|
-
depth:
|
|
407
|
+
depth: view.depth,
|
|
407
408
|
camera: frame.view.camera.buffer
|
|
408
409
|
});
|
|
410
|
+
|
|
411
|
+
scene.color = drawn.color;
|
|
412
|
+
view.depth = drawn.depth;
|
|
409
413
|
}
|
|
410
414
|
}
|
|
411
415
|
|
|
@@ -590,6 +594,15 @@ which is what effects want. Set it and the pass writes depth instead: a solid su
|
|
|
590
594
|
build behind it has no depth ordering otherwise, and no CPU sort can give it one, because a painter's
|
|
591
595
|
order over triangles is wrong wherever two of them interpenetrate.
|
|
592
596
|
|
|
597
|
+
`graph_draw` hands back `{ color, depth }`, and an extension publishes both, as in §6. The depth is a
|
|
598
|
+
new handle when the pass wrote it. Anything reading the scene depth after you — depth of field,
|
|
599
|
+
motion blur, the NSS upscaler, the next extension — has to be given that handle; a development build
|
|
600
|
+
refuses the frame when it is not. Left `false`, the depth comes back as it went in.
|
|
601
|
+
|
|
602
|
+
That is also what decides the phase for solid content. At `AfterLighting` transparency has not run
|
|
603
|
+
yet, and it tests against the depth you published, so glass in front of the batch covers it. At
|
|
604
|
+
`AfterTransparency` the glass is already resolved into the colour, and the batch is drawn over it.
|
|
605
|
+
|
|
593
606
|
Residency is keyed on **the geometry**, not on batch membership, so a mesh that blinks off for a
|
|
594
607
|
frame or is removed and re-added keeps its buffers.
|
|
595
608
|
|
|
@@ -562,3 +562,8 @@ harness. Keeping the door open costs nothing; walking through it preemptively co
|
|
|
562
562
|
call sites are the strongest case for immediates, but the standing TODO there is a separate bug —
|
|
563
563
|
the 2025-09-13 note says the obvious fix produced garbage and was never chased down. Immediates
|
|
564
564
|
route around it for the ≤64-byte cases without explaining it.
|
|
565
|
+
Answered 2026-09-26: fixed independently. The garbage was frame-graph aliasing — a `queue.writeBuffer`
|
|
566
|
+
into a pooled buffer lands ahead of the whole submission, and a pass earlier in it had written that
|
|
567
|
+
buffer for another resource. The import now writes with `writeValueBuffer`, in order, and creates no
|
|
568
|
+
buffer per frame; `graph_import_typed_buffer.spec.js` pins both. Immediates would still drop the
|
|
569
|
+
buffer altogether for the ≤64-byte cases.
|
|
@@ -268,6 +268,8 @@ export class ShadeGPUCommandContext {
|
|
|
268
268
|
*/
|
|
269
269
|
allocateTransientValueBuffer<T>(type: WebGPUType, value: T, usage?: number | GPUBufferUsage): GPUBuffer;
|
|
270
270
|
/**
|
|
271
|
+
* Like {@link writeBuffer}, with the bytes serialised from `value` as `type` lays them out.
|
|
272
|
+
*
|
|
271
273
|
* @template T
|
|
272
274
|
* @param {GPUBuffer} buffer
|
|
273
275
|
* @param {number} buffer_offset
|
|
@@ -276,12 +278,22 @@ export class ShadeGPUCommandContext {
|
|
|
276
278
|
*/
|
|
277
279
|
writeValueBuffer<T_1>(buffer: GPUBuffer, buffer_offset: number, type: WebGPUType, value: T_1): void;
|
|
278
280
|
/**
|
|
279
|
-
*
|
|
281
|
+
* Write bytes into `buffer` at this point in the command stream: after everything recorded
|
|
282
|
+
* before this call, and before everything recorded after it.
|
|
283
|
+
*
|
|
284
|
+
* That is the difference from {@link GPUQueue#writeBuffer}, which lands ahead of the whole
|
|
285
|
+
* submission — ahead of passes recorded earlier in it that may still need the old contents. Here
|
|
286
|
+
* the bytes are staged, and a copy out of the staging is recorded in their place. Small writes
|
|
287
|
+
* are staged in this context's upload blocks, which reach the GPU with one queue write each when
|
|
288
|
+
* the context finishes, so a frame of thousands of them costs no mapping at all; writes of
|
|
289
|
+
* {@link MAPPED_UPLOAD_THRESHOLD} bytes or more go through a mapped staging buffer each, which is
|
|
290
|
+
* the faster road for bytes.
|
|
291
|
+
*
|
|
280
292
|
* @param {GPUBuffer} buffer
|
|
281
293
|
* @param {number} buffer_offset
|
|
282
294
|
* @param {ArrayBuffer} data
|
|
283
295
|
* @param {number} data_offset
|
|
284
|
-
* @param {number} size
|
|
296
|
+
* @param {number} size a multiple of 4, as for any buffer copy
|
|
285
297
|
*/
|
|
286
298
|
writeBuffer(buffer: GPUBuffer, buffer_offset: number, data: ArrayBuffer, data_offset: number, size: number): void;
|
|
287
299
|
/**
|
|
@@ -297,6 +309,7 @@ export type GraphicsContext = import("../renderer/GraphicsContext.js").GraphicsC
|
|
|
297
309
|
export type ShaderResourceSetDescriptor = import("../renderer/shader/resource/ShaderResourceSetDescriptor.js").ShaderResourceSetDescriptor;
|
|
298
310
|
export type WebGPUType = import("../renderer/shader/type/WebGPUType.js").WebGPUType;
|
|
299
311
|
export type TextureManager = import("../renderer/texture/TextureManager.js").TextureManager;
|
|
312
|
+
export type GPUUploadBlock = import("../renderer/buffer/GPUUploadBlock.js").GPUUploadBlock;
|
|
300
313
|
export type GPUFrameRecorder = import("./timing/profile/GPUFrameRecorder.js").GPUFrameRecorder;
|
|
301
314
|
import { GraphicsExecutionContext } from "./graph/GraphicsExecutionContext.js";
|
|
302
315
|
import { ShadeGPUComputePassEncoder } from "./pass/ShadeGPUComputePassEncoder.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShadeGPUCommandContext.d.ts","sourceRoot":"","sources":["../../../../src/shade/device/ShadeGPUCommandContext.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ShadeGPUCommandContext.d.ts","sourceRoot":"","sources":["../../../../src/shade/device/ShadeGPUCommandContext.js"],"names":[],"mappings":"AAgDA;;;;;;GAMG;AACH;IA+LI;;;;;OAKG;IACH,wBAJW,eAAe,UACf,MAAM,GACJ,sBAAsB,CA6BlC;IA5ND;;;;OAIG;IACH,iBAEC;IAED;;;OAGG;IACH,mCAEC;IASD;;;;OAIG;IACH,qCAEC;IAED;;;;;OAKG;IACH,yEAEC;IAED;;;;;;OAMG;IACH,wBAEC;IAeD;;;;;;;;OAQG;IACH,wCAIC;IAED;;;;;;OAMG;IACH,2BAJW,gBAAgB,gBAChB,MAAM,GACJ,IAAI,CAOhB;IAOD;;;OAGG;IACH,wBAEC;IAED;;;OAGG;IACH,+EAEC;IAgCD;;;OAGG;IACH,yBAA0B;IAE1B;;;OAGG;IACH,6BAA8B;IAE9B;;;OAGG;IACH,0BAcC;IA6CD;;;OAGG;IACH,2BAFa,wBAAwB,CAIpC;IAED;;;OAGG;IACH,mBAFW,UAAU,QAapB;IAED;;;;;OAKG;IACH,wCAHW,MAAM,SACN,MAAM,QAWhB;IAED;;;;OAIG;IACH,qBAEC;IAED;;;;;;;;;OASG;IACH,oDALW,MAAM,6CAEN,MAAM,SACN,MAAM,QAqChB;IAGD;;;;;OAKG;IACH,uHAKC;IAED;;;;;;OAMG;IACH,qHAMC;IAED;;;;OAIG;IACH,yDAFa,0BAA0B,CAatC;IAGD;;;;;;;;;OASG;IACH;QAP8C,QAAQ,EAA3C,yBAAyB;QACR,KAAK,GAAtB,MAAM;QAC2B,QAAQ,GAAzC,oBAAoB,EAAE;QACyC,SAAS,GAAxE;YAAC,MAAM,EAAE,YAAY,CAAC;YAAC,MAAM,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAC;QAElD,0BAA0B,CAgCtC;IAED;;;;OAIG;IACH,sBAFW,MAAM,QAOhB;IAED;;;OAGG;IACH,sBAIC;IAED;;;;OAIG;IACH,yBAFW,MAAM,QAKhB;IAED;;;;;;;;;;;OAWG;IACH;QAT4B,KAAK,GAAtB,MAAM;QAC4B,QAAQ,EAA1C,wBAAwB;QACS,QAAQ,GAAzC,oBAAoB,EAAE;QACkB,gBAAgB,EAAxD,8BAA8B;QACgB,sBAAsB;QACL,SAAS,GAAxE;YAAC,MAAM,EAAE,YAAY,CAAC;YAAC,MAAM,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAC;QAElD,yBAAyB,CAuCrC;IAED;;;;OAIG;IACH,sDAFa,yBAAyB,CAarC;IAED;;;;;;;OAOG;IACH,mDALW,MAAM,cACN,MAAM,6CAEN,MAAM,QAIhB;IAED;;;;;;OAMG;IACH,2CAFY,OAAO,CAYlB;IAUD;;;;;;OAMG;IACH,+BAJW,MAAM,iBAAe,QACrB,MAAM,aAuBhB;IAED;;;;;;;OAOG;IACH,qCANW,WAAW,UACX,MAAM,iBAAe,WACrB,MAAM,SACN,MAAM,aAwBhB;IAeD;;;;;;;;;OASG;IACH,0BAJW,2BAA2B,aAEzB;QAAC,MAAM,EAAE,YAAY,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAC,GAAC,SAAS,CA2B1E;IAED;;;;;;OAMG;IACH,sCALW,UAAU,oBAEV,MAAM,iBAAe,aAgB/B;IAED;;;;;;;;OAQG;IACH,wDAJW,MAAM,QACN,UAAU,oBA8BpB;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,8CALW,MAAM,QACN,WAAW,eACX,MAAM,QACN,MAAM,QA4ChB;IAkGD;;OAEG;IACH,eA8DC;;CACJ;uCA19BY,OAAO,2DAA2D,EAAE,wBAAwB;yBAI5F,OAAO,wDAAwD,EAAE,UAAU;wCAC3E,OAAO,6DAA6D,EAAE,yBAAyB;8BAC/F,OAAO,gCAAgC,EAAE,eAAe;0CACxD,OAAO,4DAA4D,EAAE,2BAA2B;yBAChG,OAAO,uCAAuC,EAAE,UAAU;6BAC1D,OAAO,uCAAuC,EAAE,cAAc;6BAC9D,OAAO,sCAAsC,EAAE,cAAc;+BAC7D,OAAO,sCAAsC,EAAE,gBAAgB;yCAdnC,qCAAqC;2CAPnC,sCAAsC;6BANpD,mCAAmC;0CAOtB,qCAAqC"}
|
|
@@ -10,6 +10,7 @@ import { ShadeGPURenderPassEncoder } from "./pass/ShadeGPURenderPassEncoder.js";
|
|
|
10
10
|
import { ShadeGPUContextProfiler } from "./timing/ShadeGPUContextProfiler.js";
|
|
11
11
|
import { warn_limited } from "../util/warn_limited.js";
|
|
12
12
|
import { write_gpu_typed_buffer } from "../renderer/shader/type/serde/write_gpu_typed_buffer.js";
|
|
13
|
+
import { MAPPED_UPLOAD_THRESHOLD } from "../renderer/buffer/GPUBufferUploadAllocator.js";
|
|
13
14
|
import { BufferResourceDescriptor } from "./graph/BufferResourceDescriptor.js";
|
|
14
15
|
import { GraphicsExecutionContext } from "./graph/GraphicsExecutionContext.js";
|
|
15
16
|
|
|
@@ -24,6 +25,7 @@ import { GraphicsExecutionContext } from "./graph/GraphicsExecutionContext.js";
|
|
|
24
25
|
* @typedef {import("../renderer/shader/resource/ShaderResourceSetDescriptor.js").ShaderResourceSetDescriptor} ShaderResourceSetDescriptor
|
|
25
26
|
* @typedef {import("../renderer/shader/type/WebGPUType.js").WebGPUType} WebGPUType
|
|
26
27
|
* @typedef {import("../renderer/texture/TextureManager.js").TextureManager} TextureManager
|
|
28
|
+
* @typedef {import("../renderer/buffer/GPUUploadBlock.js").GPUUploadBlock} GPUUploadBlock
|
|
27
29
|
* @typedef {import("./timing/profile/GPUFrameRecorder.js").GPUFrameRecorder} GPUFrameRecorder
|
|
28
30
|
*/
|
|
29
31
|
|
|
@@ -180,6 +182,17 @@ export class ShadeGPUCommandContext {
|
|
|
180
182
|
#transient_buffers = [];
|
|
181
183
|
|
|
182
184
|
/**
|
|
185
|
+
* Upload blocks this context has written its small uploads into, the one being filled last. Sent
|
|
186
|
+
* to the GPU just before the submit, one queue write per block, and given back when the context
|
|
187
|
+
* finishes.
|
|
188
|
+
*
|
|
189
|
+
* @type {GPUUploadBlock[]}
|
|
190
|
+
*/
|
|
191
|
+
#upload_blocks = [];
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Mapped staging buffers this context's large uploads went through, one each. Given back when the
|
|
195
|
+
* context finishes, and mapped again by their pool before it hands them out anew.
|
|
183
196
|
*
|
|
184
197
|
* @type {GPUBuffer[]}
|
|
185
198
|
*/
|
|
@@ -727,6 +740,8 @@ export class ShadeGPUCommandContext {
|
|
|
727
740
|
}
|
|
728
741
|
|
|
729
742
|
/**
|
|
743
|
+
* Like {@link writeBuffer}, with the bytes serialised from `value` as `type` lays them out.
|
|
744
|
+
*
|
|
730
745
|
* @template T
|
|
731
746
|
* @param {GPUBuffer} buffer
|
|
732
747
|
* @param {number} buffer_offset
|
|
@@ -737,30 +752,48 @@ export class ShadeGPUCommandContext {
|
|
|
737
752
|
|
|
738
753
|
assert.notOk(this.#finished, 'already finished');
|
|
739
754
|
|
|
740
|
-
const gfx = this.#graphics;
|
|
741
|
-
|
|
742
755
|
const size = type.aligned_size;
|
|
743
756
|
|
|
744
|
-
|
|
757
|
+
if (size >= MAPPED_UPLOAD_THRESHOLD) {
|
|
758
|
+
const stage = this.#graphics.buffer_allocator_staging.get(size);
|
|
759
|
+
|
|
760
|
+
// recorded before it is filled, so a fill that throws still gives it back
|
|
761
|
+
this.#staging_buffers.push(stage);
|
|
745
762
|
|
|
746
|
-
|
|
763
|
+
write_gpu_typed_buffer(value, type, stage.getMappedRange(0, size), 0);
|
|
747
764
|
|
|
748
|
-
|
|
765
|
+
stage.unmap();
|
|
749
766
|
|
|
750
|
-
|
|
767
|
+
this.copyBufferToBuffer(stage, 0, buffer, buffer_offset, size);
|
|
751
768
|
|
|
752
|
-
|
|
769
|
+
return;
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
const block = this.#upload_block_with_room(size);
|
|
773
|
+
const offset = block.allocate(size);
|
|
774
|
+
|
|
775
|
+
write_gpu_typed_buffer(value, type, block.data, offset);
|
|
753
776
|
|
|
754
|
-
this.copyBufferToBuffer(
|
|
777
|
+
this.copyBufferToBuffer(block.buffer, offset, buffer, buffer_offset, size);
|
|
755
778
|
}
|
|
756
779
|
|
|
757
780
|
/**
|
|
758
|
-
*
|
|
781
|
+
* Write bytes into `buffer` at this point in the command stream: after everything recorded
|
|
782
|
+
* before this call, and before everything recorded after it.
|
|
783
|
+
*
|
|
784
|
+
* That is the difference from {@link GPUQueue#writeBuffer}, which lands ahead of the whole
|
|
785
|
+
* submission — ahead of passes recorded earlier in it that may still need the old contents. Here
|
|
786
|
+
* the bytes are staged, and a copy out of the staging is recorded in their place. Small writes
|
|
787
|
+
* are staged in this context's upload blocks, which reach the GPU with one queue write each when
|
|
788
|
+
* the context finishes, so a frame of thousands of them costs no mapping at all; writes of
|
|
789
|
+
* {@link MAPPED_UPLOAD_THRESHOLD} bytes or more go through a mapped staging buffer each, which is
|
|
790
|
+
* the faster road for bytes.
|
|
791
|
+
*
|
|
759
792
|
* @param {GPUBuffer} buffer
|
|
760
793
|
* @param {number} buffer_offset
|
|
761
794
|
* @param {ArrayBuffer} data
|
|
762
795
|
* @param {number} data_offset
|
|
763
|
-
* @param {number} size
|
|
796
|
+
* @param {number} size a multiple of 4, as for any buffer copy
|
|
764
797
|
*/
|
|
765
798
|
writeBuffer(buffer, buffer_offset, data, data_offset, size) {
|
|
766
799
|
assert.defined(buffer, 'buffer');
|
|
@@ -769,20 +802,95 @@ export class ShadeGPUCommandContext {
|
|
|
769
802
|
assert.isNonNegativeInteger(data_offset, 'data_offset');
|
|
770
803
|
assert.isNonNegativeInteger(size, 'size');
|
|
771
804
|
|
|
772
|
-
|
|
805
|
+
assert.notOk(this.#finished, 'already finished');
|
|
806
|
+
|
|
807
|
+
if (size % 4 !== 0) {
|
|
808
|
+
// Refused here rather than left to the copy, as a mapped staging buffer of this size
|
|
809
|
+
// always was: a copy moves whole 4-byte words, and one that cannot takes the context's
|
|
810
|
+
// whole submission down with it, later, without naming the write that did it.
|
|
811
|
+
throw new RangeError(`writeBuffer: size ${size} is not a multiple of 4`);
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
if (size === 0) {
|
|
815
|
+
// a copy of nothing changes nothing
|
|
816
|
+
return;
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
if (size >= MAPPED_UPLOAD_THRESHOLD) {
|
|
820
|
+
const stage = this.#graphics.buffer_allocator_staging.get(size);
|
|
773
821
|
|
|
774
|
-
|
|
822
|
+
// recorded before it is filled, so a fill that throws still gives it back
|
|
823
|
+
this.#staging_buffers.push(stage);
|
|
775
824
|
|
|
776
|
-
|
|
825
|
+
array_buffer_copy(data, data_offset, stage.getMappedRange(0, size), 0, size);
|
|
777
826
|
|
|
778
|
-
|
|
827
|
+
stage.unmap();
|
|
779
828
|
|
|
780
|
-
|
|
829
|
+
this.copyBufferToBuffer(stage, 0, buffer, buffer_offset, size);
|
|
781
830
|
|
|
782
|
-
|
|
831
|
+
return;
|
|
832
|
+
}
|
|
783
833
|
|
|
784
|
-
|
|
834
|
+
const block = this.#upload_block_with_room(size);
|
|
835
|
+
const offset = block.allocate(size);
|
|
785
836
|
|
|
837
|
+
array_buffer_copy(data, data_offset, block.data, offset, size);
|
|
838
|
+
|
|
839
|
+
this.copyBufferToBuffer(block.buffer, offset, buffer, buffer_offset, size);
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
/**
|
|
843
|
+
* The block to take the next `size` bytes of upload from: the one being filled, or a fresh one
|
|
844
|
+
* when that is full. Every write that comes here is smaller than
|
|
845
|
+
* {@link MAPPED_UPLOAD_THRESHOLD}, so any empty block holds it.
|
|
846
|
+
*
|
|
847
|
+
* A block that cannot take the next write is not revisited: what is left in it is wasted until
|
|
848
|
+
* the context finishes, which bounds the waste at one block's tail per block and keeps every
|
|
849
|
+
* write a single contiguous copy.
|
|
850
|
+
*
|
|
851
|
+
* @param {number} size
|
|
852
|
+
* @returns {GPUUploadBlock}
|
|
853
|
+
*/
|
|
854
|
+
#upload_block_with_room(size) {
|
|
855
|
+
const blocks = this.#upload_blocks;
|
|
856
|
+
const last = blocks.length - 1;
|
|
857
|
+
|
|
858
|
+
if (last >= 0 && blocks[last].fits(size)) {
|
|
859
|
+
return blocks[last];
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
const block = this.#graphics.buffer_allocator_upload.get();
|
|
863
|
+
|
|
864
|
+
blocks.push(block);
|
|
865
|
+
|
|
866
|
+
return block;
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
/**
|
|
870
|
+
* Put this context's upload blocks on the GPU: one queue write per block, of the part written.
|
|
871
|
+
*
|
|
872
|
+
* Must come immediately before the submit, and this is the whole of why a block can go back to
|
|
873
|
+
* its pool the moment its context finishes rather than when the GPU is done with it. The queue
|
|
874
|
+
* runs its operations in order, so a write issued here lands after everything submitted before
|
|
875
|
+
* this context — including the copies of any earlier context that held the same block — and
|
|
876
|
+
* before this context's own copies read it. Nothing is mapped, so nothing is waited for.
|
|
877
|
+
*
|
|
878
|
+
* A queue write lands ahead of its whole submission, which is why it goes only into a block and
|
|
879
|
+
* never into a destination: blocks come from a pool of their own that nothing aliases, while
|
|
880
|
+
* the frame graph's buffers are aliased within a submission, and a queue write into one of those
|
|
881
|
+
* would overwrite what an earlier pass in it still needs.
|
|
882
|
+
*
|
|
883
|
+
* @param {GPUQueue} queue
|
|
884
|
+
*/
|
|
885
|
+
#send_uploads(queue) {
|
|
886
|
+
const blocks = this.#upload_blocks;
|
|
887
|
+
const count = blocks.length;
|
|
888
|
+
|
|
889
|
+
for (let i = 0; i < count; i++) {
|
|
890
|
+
const block = blocks[i];
|
|
891
|
+
|
|
892
|
+
queue.writeBuffer(block.buffer, 0, block.data, 0, block.used);
|
|
893
|
+
}
|
|
786
894
|
}
|
|
787
895
|
|
|
788
896
|
#cleanup() {
|
|
@@ -802,11 +910,29 @@ export class ShadeGPUCommandContext {
|
|
|
802
910
|
|
|
803
911
|
}
|
|
804
912
|
|
|
805
|
-
//
|
|
913
|
+
// Blocks go back now rather than when the GPU is done with them — see #send_uploads.
|
|
914
|
+
const buffer_allocator_upload = this.#graphics.buffer_allocator_upload;
|
|
915
|
+
|
|
916
|
+
for (const block of this.#upload_blocks) {
|
|
917
|
+
buffer_allocator_upload.release(block);
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
this.#upload_blocks.length = 0;
|
|
921
|
+
|
|
922
|
+
// staging buffers are mapped again by their pool, which is when they are free again
|
|
806
923
|
const buffer_allocator_staging = this.#graphics.buffer_allocator_staging;
|
|
924
|
+
|
|
807
925
|
for (const staging of this.#staging_buffers) {
|
|
926
|
+
if (staging.mapState === "mapped") {
|
|
927
|
+
// a write that threw while filling it, so no copy out of it was recorded; unmapped
|
|
928
|
+
// here so its pool maps it afresh rather than handing out a range already given out
|
|
929
|
+
staging.unmap();
|
|
930
|
+
}
|
|
931
|
+
|
|
808
932
|
buffer_allocator_staging.release(staging);
|
|
809
933
|
}
|
|
934
|
+
|
|
935
|
+
this.#staging_buffers.length = 0;
|
|
810
936
|
}
|
|
811
937
|
|
|
812
938
|
/**
|
|
@@ -844,19 +970,22 @@ export class ShadeGPUCommandContext {
|
|
|
844
970
|
|
|
845
971
|
GPUCommandEncoder.finish() throws when the encoder is locked — any pass left un-end()ed
|
|
846
972
|
anywhere in the frame graph — and queue.submit throws on a malformed argument. This used
|
|
847
|
-
to be a bare sequence, so either throw skipped #cleanup() and every buffer
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
hidden behind the hang.
|
|
973
|
+
to be a bare sequence, so either throw skipped #cleanup() and every buffer the context held
|
|
974
|
+
stayed checked out of its allocator for good — then, a staging buffer per writeBuffer
|
|
975
|
+
call, which is most of the uniform traffic, every frame, until the process ran out of GPU
|
|
976
|
+
memory. onFinished never fired either, so a promise already awaiting done never woke and
|
|
977
|
+
profiling_absorbed hung with it — a recoverable encoding bug turned into an unbounded leak
|
|
978
|
+
plus a hung frame, with the original error hidden behind the hang.
|
|
854
979
|
|
|
855
980
|
The error still propagates: it is the thing that names the misplaced end().
|
|
856
981
|
*/
|
|
857
982
|
try {
|
|
858
983
|
const command_buffer = encoder.finish();
|
|
859
984
|
|
|
985
|
+
// after finish(), so a command buffer that could not be made sends nothing, and
|
|
986
|
+
// immediately before the submit, which is what makes the blocks safe to hand back
|
|
987
|
+
this.#send_uploads(queue);
|
|
988
|
+
|
|
860
989
|
queue.submit([command_buffer]);
|
|
861
990
|
} finally {
|
|
862
991
|
// cleanup allocated memory
|
|
@@ -27,7 +27,11 @@ export class SoftwareGPURenderPassEncoder extends SoftwareGPUObjectBase implemen
|
|
|
27
27
|
* `-1` rather than a number read out of a buffer nobody filled — the same admission
|
|
28
28
|
* {@link SoftwareGPUComputePassEncoder#dispatchWorkgroupsIndirect} makes.
|
|
29
29
|
*
|
|
30
|
-
*
|
|
30
|
+
* A direct draw also records where it starts — `first_vertex` and `first_instance`, or for an
|
|
31
|
+
* indexed one `first_index`, `base_vertex` and `first_instance` — with WebGPU's defaults of 0
|
|
32
|
+
* where they were left out. An indirect one records none of them: they are in the buffer too.
|
|
33
|
+
*
|
|
34
|
+
* @type {{pipeline: GPURenderPipeline|null, bind_groups: GPUBindGroup[], dynamic_offsets: number[][], vertex_buffers: object[], index_buffer: object|null, viewport: object|null, scissor: object|null, vertex_count: number, instance_count: number, first_vertex?: number, first_index?: number, base_vertex?: number, first_instance?: number, indexed: boolean, indirect: boolean}[]}
|
|
31
35
|
*/
|
|
32
36
|
draws: {
|
|
33
37
|
pipeline: GPURenderPipeline | null;
|
|
@@ -39,6 +43,10 @@ export class SoftwareGPURenderPassEncoder extends SoftwareGPUObjectBase implemen
|
|
|
39
43
|
scissor: object | null;
|
|
40
44
|
vertex_count: number;
|
|
41
45
|
instance_count: number;
|
|
46
|
+
first_vertex?: number;
|
|
47
|
+
first_index?: number;
|
|
48
|
+
base_vertex?: number;
|
|
49
|
+
first_instance?: number;
|
|
42
50
|
indexed: boolean;
|
|
43
51
|
indirect: boolean;
|
|
44
52
|
}[];
|
|
@@ -118,15 +126,24 @@ export class SoftwareGPURenderPassEncoder extends SoftwareGPUObjectBase implemen
|
|
|
118
126
|
setStencilReference(reference: number): void;
|
|
119
127
|
stencil_reference: number;
|
|
120
128
|
/**
|
|
129
|
+
* Where the draw starts is recorded with its counts: a direct draw's `instance_index` counts from
|
|
130
|
+
* `first_instance`, and a draw that picks its row of a table through it names that row nowhere
|
|
131
|
+
* else.
|
|
132
|
+
*
|
|
121
133
|
* @param {number} vertex_count
|
|
122
134
|
* @param {number} [instance_count]
|
|
135
|
+
* @param {number} [first_vertex]
|
|
136
|
+
* @param {number} [first_instance]
|
|
123
137
|
*/
|
|
124
|
-
draw(vertex_count: number, instance_count?: number): void;
|
|
138
|
+
draw(vertex_count: number, instance_count?: number, first_vertex?: number, first_instance?: number): void;
|
|
125
139
|
/**
|
|
126
140
|
* @param {number} index_count
|
|
127
141
|
* @param {number} [instance_count]
|
|
142
|
+
* @param {number} [first_index]
|
|
143
|
+
* @param {number} [base_vertex]
|
|
144
|
+
* @param {number} [first_instance]
|
|
128
145
|
*/
|
|
129
|
-
drawIndexed(index_count: number, instance_count?: number): void;
|
|
146
|
+
drawIndexed(index_count: number, instance_count?: number, first_index?: number, base_vertex?: number, first_instance?: number): void;
|
|
130
147
|
/**
|
|
131
148
|
* @param {GPUBuffer} indirect_buffer
|
|
132
149
|
* @param {number} indirect_offset
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SoftwareGPURenderPassEncoder.d.ts","sourceRoot":"","sources":["../../../../../src/shade/device/mock/SoftwareGPURenderPassEncoder.js"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;GAcG;AACH,mFAFgB,oBAAoB;
|
|
1
|
+
{"version":3,"file":"SoftwareGPURenderPassEncoder.d.ts","sourceRoot":"","sources":["../../../../../src/shade/device/mock/SoftwareGPURenderPassEncoder.js"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;GAcG;AACH,mFAFgB,oBAAoB;IAuFhC;;;OAGG;IACH,sFAQC;IAhGD;;;;;;;;;;;;;OAaG;IACH,OAFU;QAAC,QAAQ,EAAE,oBAAkB,IAAI,CAAC;QAAC,WAAW,EAAE,cAAc,CAAC;QAAC,eAAe,EAAE,MAAM,EAAE,EAAE,CAAC;QAAC,cAAc,EAAE,MAAM,EAAE,CAAC;QAAC,YAAY,EAAE,MAAM,GAAC,IAAI,CAAC;QAAC,QAAQ,EAAE,MAAM,GAAC,IAAI,CAAC;QAAC,OAAO,EAAE,MAAM,GAAC,IAAI,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAC,EAAE,CAE9W;IAEX;;;;;;OAMG;IACH,oCAAW;IAoDX;;;;OAIG;IACH,uBAEC;IAsBD;;OAEG;IACH,+CAIC;IAED;;;;;;;;OAQG;IACH,oBANW,MAAM,8CAEN,MAAM,EAAE,GAAC,WAAW,0BACpB,MAAM,2BACN,MAAM,QA0BhB;IAED;;;;;OAKG;IACH,4BALW,MAAM,QACN,WAAW,GAAC,eAAe,gBAC3B,MAAM,cACN,MAAM,QAUhB;IAED;;;;;OAKG;IACH,sBALW,MAAM,8BAEN,MAAM,SACN,MAAM,QAShB;IAED;;;;;OAKG;IACH,yEAHW,MAAM,SACN,MAAM,QAQhB;IAED;;;;;;;OAOG;IACH,eAPW,MAAM,KACN,MAAM,SACN,MAAM,UACN,MAAM,aACN,MAAM,aACN,MAAM,QAMhB;IAED;;;;;OAKG;IACH,kBALW,MAAM,KACN,MAAM,SACN,MAAM,UACN,MAAM,QAMhB;IAED;;OAEG;IACH,wCAIC;IADG,yBAA2B;IAG/B;;OAEG;IACH,+BAFW,MAAM,QAMhB;IADG,0BAAkC;IAwCtC;;;;;;;;;OASG;IACH,mBALW,MAAM,mBACN,MAAM,iBACN,MAAM,mBACN,MAAM,QAehB;IAED;;;;;;OAMG;IACH,yBANW,MAAM,mBACN,MAAM,gBACN,MAAM,gBACN,MAAM,mBACN,MAAM,QAgBhB;IAED;;;OAGG;IACH,0DAFW,MAAM,QAkBhB;IAED;;;OAGG;IACH,iEAFW,MAAM,QAiBhB;IAED;;OAEG;IACH,sBAFW,MAAM,QAIhB;IAED,sBAEC;IAED;;OAEG;IACH,yBAFW,MAAM,QAIhB;IAED,YAQC;IAGL;;;OAGG;IACH,yCAFU,OAAO,CAEoD;;CANpE;sCA3ZqC,4BAA4B"}
|
|
@@ -28,7 +28,11 @@ export class SoftwareGPURenderPassEncoder extends SoftwareGPUObjectBase {
|
|
|
28
28
|
* `-1` rather than a number read out of a buffer nobody filled — the same admission
|
|
29
29
|
* {@link SoftwareGPUComputePassEncoder#dispatchWorkgroupsIndirect} makes.
|
|
30
30
|
*
|
|
31
|
-
*
|
|
31
|
+
* A direct draw also records where it starts — `first_vertex` and `first_instance`, or for an
|
|
32
|
+
* indexed one `first_index`, `base_vertex` and `first_instance` — with WebGPU's defaults of 0
|
|
33
|
+
* where they were left out. An indirect one records none of them: they are in the buffer too.
|
|
34
|
+
*
|
|
35
|
+
* @type {{pipeline: GPURenderPipeline|null, bind_groups: GPUBindGroup[], dynamic_offsets: number[][], vertex_buffers: object[], index_buffer: object|null, viewport: object|null, scissor: object|null, vertex_count: number, instance_count: number, first_vertex?: number, first_index?: number, base_vertex?: number, first_instance?: number, indexed: boolean, indirect: boolean}[]}
|
|
32
36
|
*/
|
|
33
37
|
draws = [];
|
|
34
38
|
|
|
@@ -291,10 +295,16 @@ export class SoftwareGPURenderPassEncoder extends SoftwareGPUObjectBase {
|
|
|
291
295
|
}
|
|
292
296
|
|
|
293
297
|
/**
|
|
298
|
+
* Where the draw starts is recorded with its counts: a direct draw's `instance_index` counts from
|
|
299
|
+
* `first_instance`, and a draw that picks its row of a table through it names that row nowhere
|
|
300
|
+
* else.
|
|
301
|
+
*
|
|
294
302
|
* @param {number} vertex_count
|
|
295
303
|
* @param {number} [instance_count]
|
|
304
|
+
* @param {number} [first_vertex]
|
|
305
|
+
* @param {number} [first_instance]
|
|
296
306
|
*/
|
|
297
|
-
draw(vertex_count, instance_count = 1) {
|
|
307
|
+
draw(vertex_count, instance_count = 1, first_vertex = 0, first_instance = 0) {
|
|
298
308
|
this.#assert_encoding();
|
|
299
309
|
this.#validate_immediates();
|
|
300
310
|
|
|
@@ -302,6 +312,8 @@ export class SoftwareGPURenderPassEncoder extends SoftwareGPUObjectBase {
|
|
|
302
312
|
...this.#snapshot(),
|
|
303
313
|
vertex_count,
|
|
304
314
|
instance_count,
|
|
315
|
+
first_vertex,
|
|
316
|
+
first_instance,
|
|
305
317
|
indexed: false,
|
|
306
318
|
indirect: false,
|
|
307
319
|
});
|
|
@@ -310,8 +322,11 @@ export class SoftwareGPURenderPassEncoder extends SoftwareGPUObjectBase {
|
|
|
310
322
|
/**
|
|
311
323
|
* @param {number} index_count
|
|
312
324
|
* @param {number} [instance_count]
|
|
325
|
+
* @param {number} [first_index]
|
|
326
|
+
* @param {number} [base_vertex]
|
|
327
|
+
* @param {number} [first_instance]
|
|
313
328
|
*/
|
|
314
|
-
drawIndexed(index_count, instance_count = 1) {
|
|
329
|
+
drawIndexed(index_count, instance_count = 1, first_index = 0, base_vertex = 0, first_instance = 0) {
|
|
315
330
|
this.#assert_encoding();
|
|
316
331
|
this.#validate_immediates();
|
|
317
332
|
|
|
@@ -319,6 +334,9 @@ export class SoftwareGPURenderPassEncoder extends SoftwareGPUObjectBase {
|
|
|
319
334
|
...this.#snapshot(),
|
|
320
335
|
vertex_count: index_count,
|
|
321
336
|
instance_count,
|
|
337
|
+
first_index,
|
|
338
|
+
base_vertex,
|
|
339
|
+
first_instance,
|
|
322
340
|
indexed: true,
|
|
323
341
|
indirect: false,
|
|
324
342
|
});
|
|
@@ -64,10 +64,17 @@ export class GraphicsContext {
|
|
|
64
64
|
*/
|
|
65
65
|
buffer_allocator_native: GPUBufferAllocatorNative;
|
|
66
66
|
/**
|
|
67
|
-
*
|
|
67
|
+
* Mapped `MAP_WRITE` buffers, one per upload: where a {@link ShadeGPUCommandContext} sends its
|
|
68
|
+
* large writes, for which a mapping is the faster road (see `MAPPED_UPLOAD_THRESHOLD`).
|
|
68
69
|
* @type {GPUBufferStagingAllocator}
|
|
69
70
|
*/
|
|
70
71
|
buffer_allocator_staging: GPUBufferStagingAllocator;
|
|
72
|
+
/**
|
|
73
|
+
* Upload blocks for {@link ShadeGPUCommandContext}'s small writes — every uniform a pass is
|
|
74
|
+
* handed by value among them. Sent with one queue write per block, not mapped.
|
|
75
|
+
* @type {GPUBufferUploadAllocator}
|
|
76
|
+
*/
|
|
77
|
+
buffer_allocator_upload: GPUBufferUploadAllocator;
|
|
71
78
|
/**
|
|
72
79
|
* Used to read data back from the GPU: `MAP_READ` buffers, held by the CPU across frames, which
|
|
73
80
|
* is why they cannot come from {@link buffer_allocator_main}.
|
|
@@ -104,6 +111,17 @@ export class GraphicsContext {
|
|
|
104
111
|
offset: number;
|
|
105
112
|
size: number;
|
|
106
113
|
}): void;
|
|
114
|
+
/**
|
|
115
|
+
* Set one bind group of `pipeline`'s layout, leaving the others as they are — for a pass whose
|
|
116
|
+
* groups change at different rates, where {@link setPipelineBindings} would set every group up
|
|
117
|
+
* to the last one on each change.
|
|
118
|
+
*
|
|
119
|
+
* @param {GPUBindingCommandsMixin} pass
|
|
120
|
+
* @param {PipelineDescriptorBase} pipeline
|
|
121
|
+
* @param {number} index the group's index in the pipeline's layout
|
|
122
|
+
* @param {GPUBindingResource[]} resources the group's entries, in binding order
|
|
123
|
+
*/
|
|
124
|
+
setPipelineBindGroup(pass: GPUBindingCommandsMixin, pipeline: PipelineDescriptorBase, index: number, resources: GPUBindingResource[]): void;
|
|
107
125
|
/**
|
|
108
126
|
*
|
|
109
127
|
* @param {BufferDescriptor} buffer_descriptor
|
|
@@ -142,6 +160,7 @@ import { BindGroupManager } from "./binding/BindGroupManager.js";
|
|
|
142
160
|
import { GPUBufferAllocator } from "./buffer/GPUBufferAllocator.js";
|
|
143
161
|
import { GPUBufferAllocatorNative } from "./buffer/GPUBufferAllocatorNative.js";
|
|
144
162
|
import { GPUBufferStagingAllocator } from "./buffer/GPUBufferStagingAllocator.js";
|
|
163
|
+
import { GPUBufferUploadAllocator } from "./buffer/GPUBufferUploadAllocator.js";
|
|
145
164
|
import { GPUBufferReadbackAllocator } from "./buffer/GPUBufferReadbackAllocator.js";
|
|
146
165
|
import { GPUTextureAllocator } from "./texture/GPUTextureAllocator.js";
|
|
147
166
|
import { GPUBufferContext } from "./buffer/GPUBufferContext.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GraphicsContext.d.ts","sourceRoot":"","sources":["../../../../src/shade/renderer/GraphicsContext.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"GraphicsContext.d.ts","sourceRoot":"","sources":["../../../../src/shade/renderer/GraphicsContext.js"],"names":[],"mappings":"AAmCA;IAqKI,yBAiCC;IArMD;;OAEG;IACH,YAFU,kBAAkB,CAEjB;IAEX;;OAEG;IACH,WAFU,kBAAkB,CAElB;IAOV;;OAEG;IACH,UAFU,iBAAiB,CAElB;IAET;;;OAGG;IACH,qDAOC;IAOD;;;OAGG;IACH,6CAEC;IAED;;OAEG;IACH,kBAFU,qBAAqB,CAEd;IAEjB;;OAEG;IACH,kBAFU,qBAAqB,CAEd;IAEjB;;OAEG;IACH,mBAFU,sBAAsB,CAEd;IAGlB;;OAEG;IACH,gBAFU,oBAAoB,CAEf;IAEf;;OAEG;IACH,UAFU,cAAc,CAEf;IAET;;;;OAIG;IACH,kBAFU,qBAAqB,CAEd;IAEjB;;OAEG;IACH,aAFU,gBAAgB,CAEd;IAQZ;;;OAGG;IACH,uBAFU,kBAAkB,CAEN;IAEtB;;;;OAIG;IACH,yBAFU,wBAAwB,CAEV;IAExB;;;;OAIG;IACH,0BAFU,yBAAyB,CAEV;IAEzB;;;;OAIG;IACH,yBAFU,wBAAwB,CAEV;IAExB;;;;OAIG;IACH,2BAFU,0BAA0B,CAEV;IAE1B;;;OAGG;IACH,oBAFU,mBAAmB,CAEV;IAUnB;;;OAGG;IACH,8BAEC;IAED,uBAQC;IAED;;;OAGG;IACH,wBAEC;IAqCD;;;;;;;;OAQG;IACH,6DANW,sBAAsB,aACtB,oBAAoB,EAAE,cACtB;QAAC,MAAM,EAAE,YAAY,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAC,QA2B9D;IAED;;;;;;;;;OASG;IACH,8DAJW,sBAAsB,SACtB,MAAM,aACN,oBAAoB,QA0C9B;IAED;;;;OAIG;IACH,gCAHW,gBAAgB,GACd,gBAAgB,CAI5B;IAED;;OAEG;IACH,+BAgBC;IAED,4BAEC;IAED,eAoDC;IAED,gBAoBC;IAGL;;;OAGG;IACH,4BAFU,OAAO,CAE0B;;CAN1C;+BArZY,OAAO,0CAA0C,EAAE,gBAAgB;qCACnE,OAAO,kDAAkD,EAAE,sBAAsB;2BAKjF,OAAO,mCAAmC,EAAE,YAAY;mCAjBlC,kCAAkC;mCAGlC,kCAAkC;kCADnC,wBAAwB;2CAEf,mDAAmD;oCAH1D,2CAA2C;sCAbzC,6CAA6C;sCAC7C,6CAA6C;uCAF5C,8CAA8C;qCAIhD,0CAA0C;+BAgBhD,6BAA6B;sCACtB,4CAA4C;iCAfjD,+BAA+B;mCAC7B,gCAAgC;yCAC1B,sCAAsC;0CAGrC,uCAAuC;yCACxC,sCAAsC;2CAFpC,wCAAwC;oCAS/C,kCAAkC;iCAVtB,8BAA8B"}
|