@woosh/meep-engine 3.12.0 → 3.13.1

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.
Files changed (301) hide show
  1. package/package.json +1 -1
  2. package/src/core/geom/3d/shape/ConvexHullShape3D.d.ts.map +1 -1
  3. package/src/core/geom/3d/shape/ConvexHullShape3D.js +41 -25
  4. package/src/core/geom/3d/shape/PosedShape3D.d.ts.map +1 -1
  5. package/src/core/geom/3d/shape/PosedShape3D.js +7 -2
  6. package/src/engine/graphics3/decal/GPUDecalRenderer.js +3 -3
  7. package/src/engine/graphics3/decal/shader_decal_composite.d.ts.map +1 -1
  8. package/src/engine/graphics3/decal/shader_decal_composite.js +4 -2
  9. package/src/engine/graphics3/highlight/GPUHighlightRenderer.d.ts.map +1 -1
  10. package/src/engine/graphics3/highlight/GPUHighlightRenderer.js +2 -3
  11. package/src/engine/graphics3/highlight/shader_highlight_outline.js +150 -150
  12. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  13. package/src/shade/RENDERER_CONTRACT.md +2 -1
  14. package/src/shade/descriptor/pipeline/compute/ComputePipelineDescriptor.d.ts +18 -0
  15. package/src/shade/descriptor/pipeline/compute/ComputePipelineDescriptor.d.ts.map +1 -1
  16. package/src/shade/descriptor/pipeline/compute/ComputePipelineDescriptor.js +73 -0
  17. package/src/shade/device/PASS_ENCODER_PROPOSAL_2026_08_31.md +755 -0
  18. package/src/shade/device/ShadeGPUCommandContext.d.ts +10 -16
  19. package/src/shade/device/ShadeGPUCommandContext.d.ts.map +1 -1
  20. package/src/shade/device/ShadeGPUCommandContext.js +801 -994
  21. package/src/shade/device/pass/ShadeGPUComputePassEncoder.d.ts +107 -0
  22. package/src/shade/device/pass/ShadeGPUComputePassEncoder.d.ts.map +1 -0
  23. package/src/shade/device/pass/ShadeGPUComputePassEncoder.js +222 -0
  24. package/src/shade/device/pass/ShadeGPURenderPassEncoder.d.ts +168 -0
  25. package/src/shade/device/pass/ShadeGPURenderPassEncoder.d.ts.map +1 -0
  26. package/src/shade/device/pass/ShadeGPURenderPassEncoder.js +317 -0
  27. package/src/shade/device/timing/GPUTimerArray.d.ts +4 -9
  28. package/src/shade/device/timing/GPUTimerArray.d.ts.map +1 -1
  29. package/src/shade/device/timing/GPUTimerArray.js +261 -289
  30. package/src/shade/device/timing/GPU_PROFILER_PROPOSAL_2026_08_28.md +20 -2
  31. package/src/shade/device/timing/ShadeGPUContextProfiler.d.ts +59 -0
  32. package/src/shade/device/timing/ShadeGPUContextProfiler.d.ts.map +1 -0
  33. package/src/shade/device/timing/ShadeGPUContextProfiler.js +182 -0
  34. package/src/shade/device/timing/profile/GPUProfileSession.d.ts +4 -4
  35. package/src/shade/device/timing/profile/GPUProfileSession.js +4 -4
  36. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_leaf_triangles.d.ts.map +1 -1
  37. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_leaf_triangles.js +3 -1
  38. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_points.d.ts.map +1 -1
  39. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_points.js +3 -1
  40. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_visibility.d.ts.map +1 -1
  41. package/src/shade/playground/skinned_blas_refit/shader_blas_audit_visibility.js +3 -1
  42. package/src/shade/playground/skinned_blas_refit/verify_leaf_triangles.js +2 -2
  43. package/src/shade/playground/skinned_blas_refit/verify_traversal_reachability.js +2 -2
  44. package/src/shade/renderer/Renderer.d.ts +0 -6
  45. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  46. package/src/shade/renderer/Renderer.js +0 -29
  47. package/src/shade/renderer/animation/GPUAnimationManager.d.ts.map +1 -1
  48. package/src/shade/renderer/animation/GPUAnimationManager.js +1 -3
  49. package/src/shade/renderer/animation/shader_animation_tick.d.ts.map +1 -1
  50. package/src/shade/renderer/animation/shader_animation_tick.js +128 -125
  51. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts.map +1 -1
  52. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +8 -18
  53. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_geometry_sphere_derive.d.ts.map +1 -1
  54. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_geometry_sphere_derive.js +100 -98
  55. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_meshlet_bounds_reduce.d.ts.map +1 -1
  56. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_meshlet_bounds_reduce.js +215 -212
  57. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_meshlet_bounds_scatter.d.ts +1 -1
  58. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_meshlet_bounds_scatter.d.ts.map +1 -1
  59. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_meshlet_bounds_scatter.js +135 -120
  60. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_skinned_mesh_bounds_refresh.d.ts.map +1 -1
  61. package/src/shade/renderer/animation/skinning/bounds_refresh/shader_skinned_mesh_bounds_refresh.js +77 -75
  62. package/src/shade/renderer/animation/skinning/shader_meshlet_apply_skinning.d.ts.map +1 -1
  63. package/src/shade/renderer/animation/skinning/shader_meshlet_apply_skinning.js +375 -371
  64. package/src/shade/renderer/atmosphere/shader_transmittance_lut.js +3 -3
  65. package/src/shade/renderer/buffer/graph_inspect_gpu_buffer.js +1 -1
  66. package/src/shade/renderer/buffer/table/GPUDatabase.d.ts.map +1 -1
  67. package/src/shade/renderer/buffer/table/GPUDatabase.js +14 -19
  68. package/src/shade/renderer/buffer/table/gpu_table_element_upload_shader.d.ts.map +1 -1
  69. package/src/shade/renderer/buffer/table/gpu_table_element_upload_shader.js +7 -2
  70. package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.d.ts.map +1 -1
  71. package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.js +325 -319
  72. package/src/shade/renderer/buffer/util/shader_buffer_copy_storage_to_storage.d.ts.map +1 -1
  73. package/src/shade/renderer/buffer/util/shader_buffer_copy_storage_to_storage.js +3 -1
  74. package/src/shade/renderer/deferred/shader_tonemap_HDR.d.ts.map +1 -1
  75. package/src/shade/renderer/deferred/shader_tonemap_HDR.js +4 -1
  76. package/src/shade/renderer/dynamic/GPUDynamicMeshResidency.d.ts +2 -2
  77. package/src/shade/renderer/dynamic/GPUDynamicMeshResidency.d.ts.map +1 -1
  78. package/src/shade/renderer/dynamic/GPUDynamicMeshResidency.js +167 -167
  79. package/src/shade/renderer/fow/GPUFogOfWarRenderer.js +3 -3
  80. package/src/shade/renderer/fow/shader_fog_of_war.d.ts.map +1 -1
  81. package/src/shade/renderer/fow/shader_fog_of_war.js +3 -1
  82. package/src/shade/renderer/geometry/bvh/record_blas_refit.js +102 -102
  83. package/src/shade/renderer/geometry/bvh/shader_blas_refit_leaf_bounds.d.ts.map +1 -1
  84. package/src/shade/renderer/geometry/bvh/shader_blas_refit_leaf_bounds.js +125 -121
  85. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts.map +1 -1
  86. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.js +766 -774
  87. package/src/shade/renderer/geometry/meshlet/shader_meshlet_metadata_address_patch.d.ts.map +1 -1
  88. package/src/shade/renderer/geometry/meshlet/shader_meshlet_metadata_address_patch.js +72 -69
  89. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts.map +1 -1
  90. package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +5 -10
  91. package/src/shade/renderer/geometry/sdf/shader_build_sdf.js +129 -129
  92. package/src/shade/renderer/geometry/sdf/shader_sdf_visualize.d.ts.map +1 -1
  93. package/src/shade/renderer/geometry/sdf/shader_sdf_visualize.js +5 -3
  94. package/src/shade/renderer/global_illumination/brick4/gpu/bake/shader_brick4_bake_probes.d.ts.map +1 -1
  95. package/src/shade/renderer/global_illumination/brick4/gpu/bake/shader_brick4_bake_probes.js +4 -1
  96. package/src/shade/renderer/global_illumination/brick4/gpu/bake/shader_brick4_bake_resolve_probes.d.ts.map +1 -1
  97. package/src/shade/renderer/global_illumination/brick4/gpu/bake/shader_brick4_bake_resolve_probes.js +3 -1
  98. package/src/shade/renderer/global_illumination/clipmap/shader_update_clipmap_cascade.d.ts.map +1 -1
  99. package/src/shade/renderer/global_illumination/clipmap/shader_update_clipmap_cascade.js +114 -112
  100. package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_lpv_store_sh.d.ts.map +1 -1
  101. package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_lpv_store_sh.js +4 -1
  102. package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_lvp_atlas_to_sh.d.ts.map +1 -1
  103. package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_lvp_atlas_to_sh.js +187 -184
  104. package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_reduce_atlas_to_sh.d.ts.map +1 -1
  105. package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_reduce_atlas_to_sh.js +4 -1
  106. package/src/shade/renderer/global_illumination/sharc/SpatialHashRadianceCache.d.ts.map +1 -1
  107. package/src/shade/renderer/global_illumination/sharc/SpatialHashRadianceCache.js +6 -8
  108. package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_evict.d.ts.map +1 -1
  109. package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_evict.js +3 -1
  110. package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_update.d.ts.map +1 -1
  111. package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_update.js +3 -1
  112. package/src/shade/renderer/gpu_primitive/bvh/GPU_BVH_BUILD_PLAN.md +3 -3
  113. package/src/shade/renderer/gpu_primitive/bvh/PHASE1_HANDOVER.md +3 -3
  114. package/src/shade/renderer/gpu_primitive/bvh/graph_bvh_build_lbvh.js +217 -217
  115. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_emit_hierarchy.d.ts.map +1 -1
  116. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_emit_hierarchy.js +145 -142
  117. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_morton.d.ts.map +1 -1
  118. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_morton.js +87 -82
  119. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_refit.d.ts.map +1 -1
  120. package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_refit.js +143 -140
  121. package/src/shade/renderer/gpu_primitive/bvh/verify_gpu_bvh_build.d.ts +2 -2
  122. package/src/shade/renderer/gpu_primitive/bvh/verify_gpu_bvh_build.d.ts.map +1 -1
  123. package/src/shade/renderer/gpu_primitive/bvh/verify_gpu_bvh_build.js +43 -8
  124. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.d.ts.map +1 -1
  125. package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.js +4 -5
  126. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_histogram.d.ts.map +1 -1
  127. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_histogram.js +88 -84
  128. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_scatter.d.ts.map +1 -1
  129. package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_scatter.js +194 -191
  130. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts.map +1 -1
  131. package/src/shade/renderer/hiz/HierarchicalZBuffer.js +33 -69
  132. package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts.map +1 -1
  133. package/src/shade/renderer/hiz/shader_hzb_reduce_any.js +6 -1
  134. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts.map +1 -1
  135. package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.js +23 -7
  136. package/src/shade/renderer/light/environment/execute_filter_environment_map.d.ts.map +1 -1
  137. package/src/shade/renderer/light/environment/execute_filter_environment_map.js +1 -2
  138. package/src/shade/renderer/light/environment/shader_convolve_reflection_map.d.ts.map +1 -1
  139. package/src/shade/renderer/light/environment/shader_convolve_reflection_map.js +6 -1
  140. package/src/shade/renderer/lightmap/bake/raster/graph_draw_lightmap_viz_buffer.d.ts.map +1 -1
  141. package/src/shade/renderer/lightmap/bake/raster/graph_draw_lightmap_viz_buffer.js +234 -219
  142. package/src/shade/renderer/lightmap/bake/raster/shader_lightmap_to_viz_buffer.js +2 -2
  143. package/src/shade/renderer/lightmap/bake/shader_lightmap_denoise_sh.js +191 -191
  144. package/src/shade/renderer/lightmap/bake/tile/shader_lightmap_accummulate_tile.d.ts.map +1 -1
  145. package/src/shade/renderer/lightmap/bake/tile/shader_lightmap_accummulate_tile.js +85 -82
  146. package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
  147. package/src/shade/renderer/particles/graph_particles.js +5 -3
  148. package/src/shade/renderer/particles/prototypeParticleSystem.js +3 -4
  149. package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
  150. package/src/shade/renderer/particles/shaders/shader_particle_emit.js +132 -117
  151. package/src/shade/renderer/particles/shaders/shader_particle_finalize.d.ts.map +1 -1
  152. package/src/shade/renderer/particles/shaders/shader_particle_finalize.js +79 -77
  153. package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
  154. package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +111 -99
  155. package/src/shade/renderer/particles/sort/shader_particle_sort.d.ts.map +1 -1
  156. package/src/shade/renderer/particles/sort/shader_particle_sort.js +187 -158
  157. package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.d.ts.map +1 -1
  158. package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.js +7 -10
  159. package/src/shade/renderer/path_tracer/accumulating/shader_accumulating_path_tracer.d.ts.map +1 -1
  160. package/src/shade/renderer/path_tracer/accumulating/shader_accumulating_path_tracer.js +4 -1
  161. package/src/shade/renderer/postprocess/bloom/shader_bloom_mix.d.ts.map +1 -1
  162. package/src/shade/renderer/postprocess/bloom/shader_bloom_mix.js +3 -1
  163. package/src/shade/renderer/postprocess/cas/shader_ffx_rcas.d.ts.map +1 -1
  164. package/src/shade/renderer/postprocess/cas/shader_ffx_rcas.js +4 -2
  165. package/src/shade/renderer/postprocess/denoise/fragment_shader_denoise_ao.js +147 -147
  166. package/src/shade/renderer/postprocess/denoise/graph_atorus_denoise_luma.d.ts.map +1 -1
  167. package/src/shade/renderer/postprocess/denoise/graph_atorus_denoise_luma.js +121 -119
  168. package/src/shade/renderer/postprocess/dof/gather/graph_postprocess_dof2.d.ts.map +1 -1
  169. package/src/shade/renderer/postprocess/dof/gather/graph_postprocess_dof2.js +1 -2
  170. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_gather_far.d.ts.map +1 -1
  171. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_gather_far.js +4 -1
  172. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_gather_near.d.ts.map +1 -1
  173. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_gather_near.js +4 -1
  174. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_recombine.d.ts.map +1 -1
  175. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_recombine.js +4 -1
  176. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_setup.d.ts.map +1 -1
  177. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_setup.js +4 -1
  178. package/src/shade/renderer/postprocess/dof/raymarch/graph_postprocess_dof.d.ts.map +1 -1
  179. package/src/shade/renderer/postprocess/dof/raymarch/graph_postprocess_dof.js +2 -4
  180. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_composite.d.ts.map +1 -1
  181. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_composite.js +4 -1
  182. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_prefilter.d.ts.map +1 -1
  183. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_prefilter.js +4 -1
  184. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_raymarch.d.ts.map +1 -1
  185. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_raymarch.js +4 -1
  186. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_raymarch_compute.d.ts.map +1 -1
  187. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_raymarch_compute.js +269 -266
  188. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_slice_compute.d.ts.map +1 -1
  189. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_slice_compute.js +273 -270
  190. package/src/shade/renderer/postprocess/dof/shader_dof_autofocus.d.ts.map +1 -1
  191. package/src/shade/renderer/postprocess/dof/shader_dof_autofocus.js +4 -1
  192. package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.d.ts.map +1 -1
  193. package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.js +8 -11
  194. package/src/shade/renderer/postprocess/eye/shader_autoexposure_adapt.d.ts.map +1 -1
  195. package/src/shade/renderer/postprocess/eye/shader_autoexposure_adapt.js +5 -1
  196. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao.d.ts.map +1 -1
  197. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao.js +11 -8
  198. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao_with_irradiance.d.ts.map +1 -1
  199. package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao_with_irradiance.js +7 -8
  200. package/src/shade/renderer/postprocess/motion_blur/shader_motion_blur_reconstruct.d.ts.map +1 -1
  201. package/src/shade/renderer/postprocess/motion_blur/shader_motion_blur_reconstruct.js +3 -1
  202. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  203. package/src/shade/renderer/postprocess/nss/shader_nss_concat.d.ts.map +1 -1
  204. package/src/shade/renderer/postprocess/nss/shader_nss_concat.js +70 -68
  205. package/src/shade/renderer/postprocess/ssr/depth_max_shader.d.ts.map +1 -1
  206. package/src/shade/renderer/postprocess/ssr/depth_max_shader.js +70 -68
  207. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_IBL.d.ts.map +1 -1
  208. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_IBL.js +3 -1
  209. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_LPV.d.ts.map +1 -1
  210. package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_LPV.js +4 -1
  211. package/src/shade/renderer/postprocess/ssr/shader_downsample_encoded_normal.d.ts.map +1 -1
  212. package/src/shade/renderer/postprocess/ssr/shader_downsample_encoded_normal.js +103 -101
  213. package/src/shade/renderer/postprocess/ssr/ssr_spatial_denoise_shader.d.ts.map +1 -1
  214. package/src/shade/renderer/postprocess/ssr/ssr_spatial_denoise_shader.js +4 -2
  215. package/src/shade/renderer/postprocess/ssr/ssr_trace_shader.d.ts.map +1 -1
  216. package/src/shade/renderer/postprocess/ssr/ssr_trace_shader.js +3 -1
  217. package/src/shade/renderer/postprocess/taa/shader_taa.d.ts.map +1 -1
  218. package/src/shade/renderer/postprocess/taa/shader_taa.js +4 -1
  219. package/src/shade/renderer/postprocess/upscale-dither/fragment_shader_upscale_dither.js +5 -5
  220. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts.map +1 -1
  221. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +339 -341
  222. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.d.ts.map +1 -1
  223. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.js +114 -109
  224. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.d.ts.map +1 -1
  225. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.js +118 -115
  226. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.d.ts.map +1 -1
  227. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.js +69 -65
  228. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.js +722 -722
  229. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.d.ts.map +1 -1
  230. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.js +1 -9
  231. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.d.ts.map +1 -1
  232. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.js +1 -6
  233. package/src/shade/renderer/restir/di/graph_restir_di.d.ts.map +1 -1
  234. package/src/shade/renderer/restir/di/graph_restir_di.js +2 -3
  235. package/src/shade/renderer/restir/di/graph_restir_di_denoise.d.ts.map +1 -1
  236. package/src/shade/renderer/restir/di/graph_restir_di_denoise.js +1 -2
  237. package/src/shade/renderer/restir/di/shader_restir_di_denoise.d.ts.map +1 -1
  238. package/src/shade/renderer/restir/di/shader_restir_di_denoise.js +139 -136
  239. package/src/shade/renderer/restir/di/shader_restir_di_resample.d.ts.map +1 -1
  240. package/src/shade/renderer/restir/di/shader_restir_di_resample.js +131 -129
  241. package/src/shade/renderer/restir/di/shader_restir_di_resolve.d.ts.map +1 -1
  242. package/src/shade/renderer/restir/di/shader_restir_di_resolve.js +101 -99
  243. package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.d.ts.map +1 -1
  244. package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.js +379 -383
  245. package/src/shade/renderer/scene/Mesh.d.ts.map +1 -1
  246. package/src/shade/renderer/scene/Mesh.js +4 -6
  247. package/src/shade/renderer/scene/shader_bvh_extract_instance_leaves.d.ts.map +1 -1
  248. package/src/shade/renderer/scene/shader_bvh_extract_instance_leaves.js +147 -144
  249. package/src/shade/renderer/shader/ComputeShader.d.ts +2 -2
  250. package/src/shade/renderer/shader/ComputeShader.d.ts.map +1 -1
  251. package/src/shade/renderer/shader/ComputeShader.js +14 -17
  252. package/src/shade/renderer/shader/pass/RenderPassDescriptor.d.ts +2 -2
  253. package/src/shade/renderer/shader/pass/RenderPassDescriptor.d.ts.map +1 -1
  254. package/src/shade/renderer/shader/pass/RenderPassDescriptor.js +189 -189
  255. package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.d.ts.map +1 -1
  256. package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.js +3 -1
  257. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts +16 -7
  258. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts.map +1 -1
  259. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.js +1342 -1326
  260. package/src/shade/renderer/shadow/map/Shadowmap.d.ts +13 -0
  261. package/src/shade/renderer/shadow/map/Shadowmap.d.ts.map +1 -1
  262. package/src/shade/renderer/shadow/map/Shadowmap.js +14 -0
  263. package/src/shade/renderer/shadow/map/ShadowmapDrawSelector.d.ts +79 -0
  264. package/src/shade/renderer/shadow/map/ShadowmapDrawSelector.d.ts.map +1 -0
  265. package/src/shade/renderer/shadow/map/ShadowmapDrawSelector.js +196 -0
  266. package/src/shade/renderer/shadow/map/ShadowmapRegistry.d.ts +91 -0
  267. package/src/shade/renderer/shadow/map/ShadowmapRegistry.d.ts.map +1 -0
  268. package/src/shade/renderer/shadow/map/ShadowmapRegistry.js +156 -0
  269. package/src/shade/renderer/shadow/map/shader/shader_shadowmap_remap_cube_to_octahedral.d.ts.map +1 -1
  270. package/src/shade/renderer/shadow/map/shader/shader_shadowmap_remap_cube_to_octahedral.js +5 -1
  271. package/src/shade/renderer/shadow/ray/shader_shadow_upscale.d.ts.map +1 -1
  272. package/src/shade/renderer/shadow/ray/shader_shadow_upscale.js +3 -1
  273. package/src/shade/renderer/shadow/ray/staged/gen/graph_gen_rays.js +73 -73
  274. package/src/shade/renderer/shadow/ray/staged/gen/shader_generate_rays.d.ts.map +1 -1
  275. package/src/shade/renderer/shadow/ray/staged/gen/shader_generate_rays.js +151 -148
  276. package/src/shade/renderer/shadow/ray/staged/trace/graph_trace_rays.d.ts.map +1 -1
  277. package/src/shade/renderer/shadow/ray/staged/trace/graph_trace_rays.js +4 -2
  278. package/src/shade/renderer/shadow/ray/staged/trace/shader_trace_rays.d.ts.map +1 -1
  279. package/src/shade/renderer/shadow/ray/staged/trace/shader_trace_rays.js +18 -4
  280. package/src/shade/renderer/shadow/sdf/cascade/CascadedSceneSDF.d.ts.map +1 -1
  281. package/src/shade/renderer/shadow/sdf/cascade/CascadedSceneSDF.js +7 -8
  282. package/src/shade/renderer/shadow/sdf/cascade/shader_build_scene_sdf_f32.d.ts.map +1 -1
  283. package/src/shade/renderer/shadow/sdf/cascade/shader_build_scene_sdf_f32.js +6 -2
  284. package/src/shade/renderer/shadow/sdf/cascade/shader_scene_sdf_debug_viz.d.ts.map +1 -1
  285. package/src/shade/renderer/shadow/sdf/cascade/shader_scene_sdf_debug_viz.js +129 -127
  286. package/src/shade/renderer/shadow/sdf/graph_draw_sdf_shadows.d.ts.map +1 -1
  287. package/src/shade/renderer/shadow/sdf/graph_draw_sdf_shadows.js +5 -3
  288. package/src/shade/renderer/texture/virtual/VirtualTextureManager.d.ts.map +1 -1
  289. package/src/shade/renderer/texture/virtual/VirtualTextureManager.js +2 -5
  290. package/src/shade/renderer/texture/virtual/build_shader_vt_feedback.d.ts.map +1 -1
  291. package/src/shade/renderer/texture/virtual/build_shader_vt_feedback.js +233 -231
  292. package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts.map +1 -1
  293. package/src/shade/renderer/volumetrics/graph_build_volumetrics.js +2 -4
  294. package/src/shade/wgsl/validate_wgsl_source.d.ts.map +1 -1
  295. package/src/shade/wgsl/validate_wgsl_source.js +8 -3
  296. package/src/shade/device/timing/profile/make_profiling_pass_encoder.d.ts +0 -21
  297. package/src/shade/device/timing/profile/make_profiling_pass_encoder.d.ts.map +0 -1
  298. package/src/shade/device/timing/profile/make_profiling_pass_encoder.js +0 -114
  299. package/src/shade/device/timing/profile/parse_workgroup_size.d.ts +0 -20
  300. package/src/shade/device/timing/profile/parse_workgroup_size.d.ts.map +0 -1
  301. package/src/shade/device/timing/profile/parse_workgroup_size.js +0 -43
@@ -1,290 +1,262 @@
1
- import { assert } from "../../../core/assert.js";
2
- import IdPool from "../../../core/IdPool.js";
3
-
4
- export class GPUTimerArray {
5
-
6
- /**
7
- * @type {GPUDevice}
8
- */
9
- #device;
10
-
11
- #size = 0;
12
-
13
- /**
14
- * @type {GPUQuerySet}
15
- */
16
- #query_set;
17
-
18
- /**
19
- * @type {GPUBuffer}
20
- */
21
- #resolve_buffer;
22
- /**
23
- * @type {GPUBuffer}
24
- */
25
- #results_buffer;
26
-
27
- /**
28
- * @type {BigInt64Array}
29
- */
30
- #results
31
-
32
- #slots = new IdPool();
33
-
34
- /**
35
- *
36
- * @type {{type: string, label: string}[]}
37
- */
38
- #slot_metadata = [];
39
-
40
- /**
41
- * Passes that asked for a slot after the array ran out.
42
- *
43
- * Reported rather than swallowed. A profile capture instruments far more passes than a one-off
44
- * debug frame does, and a silent shortfall reads downstream as "those passes were free".
45
- *
46
- * @type {number}
47
- */
48
- #dropped_count = 0;
49
-
50
- /**
51
- * How many passes went untimed because {@link size} was too small for the frame.
52
- *
53
- * @returns {number}
54
- */
55
- get dropped_count() {
56
- return this.#dropped_count;
57
- }
58
-
59
- /**
60
- * Claim a slot, or report that there is none.
61
- *
62
- * The bound check is the point. `IdPool` hands out ids indefinitely, and an id at or past
63
- * {@link size} addresses a query index the query set does not have — which WebGPU rejects at
64
- * the `beginRenderPass` that used it, blaming a pass that did nothing wrong and saying nothing
65
- * about the one that exhausted the array.
66
- *
67
- * @param {string} label
68
- * @param {string} type
69
- * @return {number} slot id, or -1 when the array is full
70
- */
71
- #bind_slot(label, type) {
72
-
73
- if (this.#slots.peek() >= this.#size) {
74
- this.#dropped_count++;
75
-
76
- return -1;
77
- }
78
-
79
- const id = this.#slots.get();
80
-
81
- this.#slot_metadata[id] = {
82
- label,
83
- type
84
- };
85
-
86
- return id;
87
- }
88
-
89
- /**
90
- * @param {string} label
91
- * @param {string} type one of 'compute', 'render'
92
- * @returns {GPUComputePassTimestampWrites|GPURenderPassTimestampWrites|undefined} undefined when
93
- * there is no slot left, in which case the caller must leave `timestampWrites` off its
94
- * descriptor — an untimed pass is the correct degradation, an invalid one is not
95
- */
96
- #get_writes(label, type) {
97
-
98
- const querySet = this.#query_set;
99
-
100
- if (querySet === undefined) {
101
- // same guard as `resolve` and `download_results`: with the feature withheld the timers
102
- // go quiet rather than taking the frame down
103
- return undefined;
104
- }
105
-
106
- const id = this.#bind_slot(label, type);
107
-
108
- if (id === -1) {
109
- return undefined;
110
- }
111
-
112
- const index0 = id * 2;
113
-
114
- return {
115
- querySet,
116
- beginningOfPassWriteIndex: index0,
117
- endOfPassWriteIndex: index0 + 1,
118
- };
119
- }
120
-
121
- /**
122
- *
123
- * @param {string} label
124
- * @returns {GPUComputePassTimestampWrites|undefined} undefined when the array is full
125
- */
126
- getComputeWrites(label) {
127
- return this.#get_writes(label, 'compute');
128
- }
129
-
130
- /**
131
- *
132
- * @param {string} label
133
- * @returns {GPURenderPassTimestampWrites|undefined} undefined when the array is full
134
- */
135
- getRenderWrites(label) {
136
- return this.#get_writes(label, 'render');
137
- }
138
-
139
- /**
140
- * Visit every slot that was claimed this frame, in slot order, with its raw timestamps.
141
- *
142
- * Raw: nanoseconds as the device reported them, `BigInt`, unscaled. {@link
143
- * results_to_console_table} is the same data rounded for a human to read at a glance; a
144
- * recording needs the values themselves, and the difference matters once quantization is in
145
- * play — see the profiler's treatment of `timestamp_period_ns`.
146
- *
147
- * @param {(slot_id: number, label: string, type: string, t_begin: bigint, t_end: bigint) => void} visitor
148
- * @returns {void}
149
- */
150
- traverse_results(visitor) {
151
- assert.isFunction(visitor, 'visitor');
152
-
153
- const results = this.#results;
154
-
155
- if (results === undefined) {
156
- return;
157
- }
158
-
159
- this.#slots.traverseUsed(slot_id => {
160
- const meta = this.#slot_metadata[slot_id];
161
-
162
- visitor(
163
- slot_id,
164
- meta.label,
165
- meta.type,
166
- results[slot_id * 2],
167
- results[slot_id * 2 + 1]
168
- );
169
- });
170
- }
171
-
172
- /**
173
- *
174
- * @param {GPUDevice} device
175
- * @param {number} [size] number of query slots
176
- */
177
- constructor(
178
- device,
179
- size = 1024
180
- ) {
181
- assert.defined(device, 'device');
182
- assert.isNonNegativeInteger(size, 'size');
183
-
184
- this.#device = device;
185
-
186
- this.#size = size;
187
-
188
- // see GPUTimer: a withheld profiling feature makes the timers quiet, not fatal
189
- if (!device.features.has('timestamp-query')) {
190
- return;
191
- }
192
-
193
- this.#query_set = device.createQuerySet({
194
- type: 'timestamp',
195
- count: size * 2
196
- });
197
-
198
- this.#resolve_buffer = device.createBuffer({
199
- label: 'GPUTimerArray',
200
- size: this.#size * 2 * 8, // start + end, 64bit uint
201
- usage: GPUBufferUsage.QUERY_RESOLVE | GPUBufferUsage.COPY_SRC
202
- });
203
-
204
- this.#results_buffer = this.#device.createBuffer({
205
- label: 'GPUTimerArray/results',
206
- size: this.#size * 2 * 8,
207
- usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
208
- });
209
-
210
- this.#results = new BigInt64Array(size * 2);
211
- }
212
-
213
- destroy() {
214
- if (this.#query_set === undefined) {
215
- return;
216
- }
217
-
218
- this.#query_set.destroy();
219
- this.#resolve_buffer.destroy();
220
- this.#results_buffer.destroy();
221
- }
222
-
223
- /**
224
- *
225
- * @param {GPUCommandEncoder} encoder
226
- */
227
- resolve(encoder) {
228
-
229
- if (this.#query_set === undefined) {
230
- return;
231
- }
232
-
233
- encoder.resolveQuerySet(this.#query_set, 0, this.#query_set.count, this.#resolve_buffer, 0);
234
- encoder.copyBufferToBuffer(this.#resolve_buffer, 0, this.#results_buffer, 0);
235
- }
236
-
237
- async download_results() {
238
-
239
- const results_buffer = this.#results_buffer;
240
-
241
- if (results_buffer === undefined) {
242
- // Same guard as `resolve` and `destroy`: with the profiling feature withheld there is no
243
- // query set and no buffers, and the timers are supposed to go quiet rather than take the
244
- // frame down with them. Without it, `enable_debug_timers` on such a device raises an
245
- // unhandled rejection out of `ShadeGPUCommandContext.finish`, which calls this
246
- // unconditionally — `results_to_console_table` then reports an empty table, which is
247
- // what "quiet" means.
248
- return;
249
- }
250
-
251
- await results_buffer.mapAsync(GPUMapMode.READ)
252
-
253
- const mapped = results_buffer.getMappedRange(
254
- 0, results_buffer.size,
255
- );
256
-
257
- this.#results.set(new BigInt64Array(mapped));
258
-
259
- results_buffer.unmap();
260
-
261
- }
262
-
263
- /**
264
- * prepare tabular formatting for console output
265
- * @returns {Object}
266
- */
267
- results_to_console_table() {
268
- const result = [];
269
-
270
- this.#slots.traverseUsed(slot_id => {
271
- const meta = this.#slot_metadata[slot_id];
272
- const t_start = this.#results[slot_id * 2];
273
- const t_end = this.#results[slot_id * 2 + 1];
274
-
275
- const duration_ns = Number(t_end - t_start);
276
- const duration_ms = duration_ns * 1e-6;
277
-
278
- result.push({
279
- label: meta.label,
280
- type: meta.type,
281
- duration_ms: duration_ms,
282
- start: t_start,
283
- end: t_end,
284
- });
285
- });
286
-
287
- return result;
288
- }
289
-
1
+ import { assert } from "../../../core/assert.js";
2
+ import IdPool from "../../../core/IdPool.js";
3
+
4
+ export class GPUTimerArray {
5
+
6
+ /**
7
+ * @type {GPUDevice}
8
+ */
9
+ #device;
10
+
11
+ #size = 0;
12
+
13
+ /**
14
+ * @type {GPUQuerySet}
15
+ */
16
+ #query_set;
17
+
18
+ /**
19
+ * @type {GPUBuffer}
20
+ */
21
+ #resolve_buffer;
22
+ /**
23
+ * @type {GPUBuffer}
24
+ */
25
+ #results_buffer;
26
+
27
+ /**
28
+ * @type {BigInt64Array}
29
+ */
30
+ #results
31
+
32
+ #slots = new IdPool();
33
+
34
+ /**
35
+ *
36
+ * @type {{type: string, label: string}[]}
37
+ */
38
+ #slot_metadata = [];
39
+
40
+ /**
41
+ * Passes that asked for a slot after the array ran out.
42
+ *
43
+ * Reported rather than swallowed. A profile capture instruments far more passes than a one-off
44
+ * debug frame does, and a silent shortfall reads downstream as "those passes were free".
45
+ *
46
+ * @type {number}
47
+ */
48
+ #dropped_count = 0;
49
+
50
+ /**
51
+ * How many passes went untimed because {@link size} was too small for the frame.
52
+ *
53
+ * @returns {number}
54
+ */
55
+ get dropped_count() {
56
+ return this.#dropped_count;
57
+ }
58
+
59
+ /**
60
+ * Claim a slot, or report that there is none.
61
+ *
62
+ * The bound check is the point. `IdPool` hands out ids indefinitely, and an id at or past
63
+ * {@link size} addresses a query index the query set does not have — which WebGPU rejects at
64
+ * the `beginRenderPass` that used it, blaming a pass that did nothing wrong and saying nothing
65
+ * about the one that exhausted the array.
66
+ *
67
+ * @param {string} label
68
+ * @param {string} type
69
+ * @return {number} slot id, or -1 when the array is full
70
+ */
71
+ #bind_slot(label, type) {
72
+
73
+ if (this.#slots.peek() >= this.#size) {
74
+ this.#dropped_count++;
75
+
76
+ return -1;
77
+ }
78
+
79
+ const id = this.#slots.get();
80
+
81
+ this.#slot_metadata[id] = {
82
+ label,
83
+ type
84
+ };
85
+
86
+ return id;
87
+ }
88
+
89
+ /**
90
+ * @param {string} label
91
+ * @param {string} type one of 'compute', 'render'
92
+ * @returns {GPUComputePassTimestampWrites|GPURenderPassTimestampWrites|undefined} undefined when
93
+ * there is no slot left, in which case the caller must leave `timestampWrites` off its
94
+ * descriptor — an untimed pass is the correct degradation, an invalid one is not
95
+ */
96
+ #get_writes(label, type) {
97
+
98
+ const querySet = this.#query_set;
99
+
100
+ if (querySet === undefined) {
101
+ // same guard as `resolve` and `download_results`: with the feature withheld the timers
102
+ // go quiet rather than taking the frame down
103
+ return undefined;
104
+ }
105
+
106
+ const id = this.#bind_slot(label, type);
107
+
108
+ if (id === -1) {
109
+ return undefined;
110
+ }
111
+
112
+ const index0 = id * 2;
113
+
114
+ return {
115
+ querySet,
116
+ beginningOfPassWriteIndex: index0,
117
+ endOfPassWriteIndex: index0 + 1,
118
+ };
119
+ }
120
+
121
+ /**
122
+ *
123
+ * @param {string} label
124
+ * @returns {GPUComputePassTimestampWrites|undefined} undefined when the array is full
125
+ */
126
+ getComputeWrites(label) {
127
+ return this.#get_writes(label, 'compute');
128
+ }
129
+
130
+ /**
131
+ *
132
+ * @param {string} label
133
+ * @returns {GPURenderPassTimestampWrites|undefined} undefined when the array is full
134
+ */
135
+ getRenderWrites(label) {
136
+ return this.#get_writes(label, 'render');
137
+ }
138
+
139
+ /**
140
+ * Visit every slot that was claimed this frame, in slot order, with its raw timestamps.
141
+ *
142
+ * Raw: nanoseconds as the device reported them, `BigInt`, unscaled. Rounding belongs to
143
+ * whoever is displaying them; a recording needs the values themselves, and the difference
144
+ * matters once quantization is in play see the profiler's treatment of
145
+ * `timestamp_period_ns`.
146
+ *
147
+ * @param {(slot_id: number, label: string, type: string, t_begin: bigint, t_end: bigint) => void} visitor
148
+ * @returns {void}
149
+ */
150
+ traverse_results(visitor) {
151
+ assert.isFunction(visitor, 'visitor');
152
+
153
+ const results = this.#results;
154
+
155
+ if (results === undefined) {
156
+ return;
157
+ }
158
+
159
+ this.#slots.traverseUsed(slot_id => {
160
+ const meta = this.#slot_metadata[slot_id];
161
+
162
+ visitor(
163
+ slot_id,
164
+ meta.label,
165
+ meta.type,
166
+ results[slot_id * 2],
167
+ results[slot_id * 2 + 1]
168
+ );
169
+ });
170
+ }
171
+
172
+ /**
173
+ *
174
+ * @param {GPUDevice} device
175
+ * @param {number} [size] number of query slots
176
+ */
177
+ constructor(
178
+ device,
179
+ size = 1024
180
+ ) {
181
+ assert.defined(device, 'device');
182
+ assert.isNonNegativeInteger(size, 'size');
183
+
184
+ this.#device = device;
185
+
186
+ this.#size = size;
187
+
188
+ // see GPUTimer: a withheld profiling feature makes the timers quiet, not fatal
189
+ if (!device.features.has('timestamp-query')) {
190
+ return;
191
+ }
192
+
193
+ this.#query_set = device.createQuerySet({
194
+ type: 'timestamp',
195
+ count: size * 2
196
+ });
197
+
198
+ this.#resolve_buffer = device.createBuffer({
199
+ label: 'GPUTimerArray',
200
+ size: this.#size * 2 * 8, // start + end, 64bit uint
201
+ usage: GPUBufferUsage.QUERY_RESOLVE | GPUBufferUsage.COPY_SRC
202
+ });
203
+
204
+ this.#results_buffer = this.#device.createBuffer({
205
+ label: 'GPUTimerArray/results',
206
+ size: this.#size * 2 * 8,
207
+ usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
208
+ });
209
+
210
+ this.#results = new BigInt64Array(size * 2);
211
+ }
212
+
213
+ destroy() {
214
+ if (this.#query_set === undefined) {
215
+ return;
216
+ }
217
+
218
+ this.#query_set.destroy();
219
+ this.#resolve_buffer.destroy();
220
+ this.#results_buffer.destroy();
221
+ }
222
+
223
+ /**
224
+ *
225
+ * @param {GPUCommandEncoder} encoder
226
+ */
227
+ resolve(encoder) {
228
+
229
+ if (this.#query_set === undefined) {
230
+ return;
231
+ }
232
+
233
+ encoder.resolveQuerySet(this.#query_set, 0, this.#query_set.count, this.#resolve_buffer, 0);
234
+ encoder.copyBufferToBuffer(this.#resolve_buffer, 0, this.#results_buffer, 0);
235
+ }
236
+
237
+ async download_results() {
238
+
239
+ const results_buffer = this.#results_buffer;
240
+
241
+ if (results_buffer === undefined) {
242
+ // Same guard as `resolve` and `destroy`: with the profiling feature withheld there is no
243
+ // query set and no buffers, and the timers are supposed to go quiet rather than take the
244
+ // frame down with them. Without it, profiling on such a device raises an unhandled
245
+ // rejection out of `ShadeGPUContextProfiler.absorb`, which calls this unconditionally.
246
+ // `traverse_results` then visits nothing, which is what "quiet" means.
247
+ return;
248
+ }
249
+
250
+ await results_buffer.mapAsync(GPUMapMode.READ)
251
+
252
+ const mapped = results_buffer.getMappedRange(
253
+ 0, results_buffer.size,
254
+ );
255
+
256
+ this.#results.set(new BigInt64Array(mapped));
257
+
258
+ results_buffer.unmap();
259
+
260
+ }
261
+
290
262
  }
@@ -2,6 +2,12 @@
2
2
 
3
3
  Proposal, 2026-08-28. Decisions folded in 2026-08-29. Alex Goldring / Company Named Limited.
4
4
 
5
+ > **Partly superseded, 2026-08-31**, by
6
+ > [PASS_ENCODER_PROPOSAL_2026_08_31.md](../PASS_ENCODER_PROPOSAL_2026_08_31.md). The recording
7
+ > proxy of §6.2 hook 3 and M4 is now a pair of decorator classes; `enable_debug_timers`,
8
+ > `Renderer.add_debug_frame` and `Renderer.onFrameDebug` — which §6.1 kept — are gone, leaving the
9
+ > profiler as the only path. §§1–5 remain a record of the state this design was written against.
10
+
5
11
  Scope: a **recording** side that ships with the engine, a **binary container** that carries a
6
12
  capture, and an **inspector** web application under `packages/gpu-inspector-tool/` that reads the
7
13
  container and nothing else.
@@ -628,8 +634,13 @@ Three things fall out of the caller owning it, and all three are why this is the
628
634
  `frame_limit` reaching zero stops the session exactly as `stop()` does. Both resolve the same
629
635
  promise, so a caller that wants "500 frames or until I say" writes one `await`.
630
636
 
631
- `add_debug_frame` and `onFrameDebug` stay exactly as they are — cheap, synchronous, console-shaped,
632
- and a different tool for a different question.
637
+ ~~`add_debug_frame` and `onFrameDebug` stay exactly as they are — cheap, synchronous, console-shaped,
638
+ and a different tool for a different question.~~
639
+
640
+ > **Reversed 2026-08-31.** They were not a different tool, they were a worse view of the same one
641
+ > reached through a second API — no graph-pass attribution, no workload, no pipeline identity — and
642
+ > `onFrameDebug` never acquired a subscriber. Removed; the profiler is the only path. "Profile the
643
+ > next N frames" is `new GPUProfileSession({ frame_limit: N })`.
633
644
 
634
645
  ### 6.2 The five hooks
635
646
 
@@ -809,6 +820,13 @@ renderer only while profiling. Dispatch and draw counts, pipeline identity, and
809
820
  parsed from WGSL where it is a literal — an override expression records as *unknown*, which is not
810
821
  the same as zero.
811
822
 
823
+ > **Reversed 2026-08-31.** The argument holds only while the wrapper is *conditional*; that is what
824
+ > makes a missing method silent. `ShadeGPUComputePassEncoder` / `ShadeGPURenderPassEncoder` wrap
825
+ > every pass, so a gap throws on the first frame of every build. The workgroup size now comes off
826
+ > `ComputePipelineDescriptor`, which reads it as its code is set, with the parser that resolves
827
+ > `const` references — a size it cannot read refuses to build the descriptor rather than recording
828
+ > as unknown.
829
+
812
830
  No `PIPE` table in the end: a pass's pipeline label and workgroup size ride in its own workload
813
831
  block, which costs a symbol reference and avoids a second id space.
814
832
 
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Everything one {@link ShadeGPUCommandContext} needs in order to be profiled: its timer array, the
3
+ * recorder its timings go to, and which query set it is within the frame.
4
+ *
5
+ * **It opens the passes itself.** Two values are needed at two different instants — the
6
+ * `timestampWrites` before the encoder exists, the {@link GPUProfileWork} after — and any shape that
7
+ * hands both back to the caller has to carry them across that gap. The predecessor carried them in a
8
+ * private field on the command context, consumed by whatever ran next, which is the kind of coupling
9
+ * that breaks the moment a line is inserted between the two halves. Handing the profiler the encoder
10
+ * collapses the gap: both values are produced and consumed inside one method and there is nothing to
11
+ * carry.
12
+ *
13
+ * Off by default and constructed only by `enable_profiling`, so a context that is not being profiled
14
+ * holds one null field and allocates no query set.
15
+ *
16
+ * @author Alex Goldring
17
+ * @copyright Company Named Limited (c) 2026
18
+ */
19
+ export class ShadeGPUContextProfiler {
20
+ /**
21
+ * @param {GPUDevice} device
22
+ * @param {GPUFrameRecorder} recorder
23
+ * @param {number} query_set_id this context's index within the frame
24
+ */
25
+ constructor(device: GPUDevice, recorder: GPUFrameRecorder, query_set_id: number);
26
+ /**
27
+ * Resolves after this context's timings have been read back and handed to the recorder.
28
+ *
29
+ * @returns {Promise<void>}
30
+ */
31
+ get absorbed(): Promise<void>;
32
+ /**
33
+ * @param {GPUCommandEncoder} encoder
34
+ * @param {GPUComputePassDescriptor} [descriptor]
35
+ * @returns {ShadeGPUComputePassEncoder}
36
+ */
37
+ begin_compute_pass(encoder: GPUCommandEncoder, descriptor?: GPUComputePassDescriptor): ShadeGPUComputePassEncoder;
38
+ /**
39
+ * @param {GPUCommandEncoder} encoder
40
+ * @param {GPURenderPassDescriptor} descriptor
41
+ * @returns {ShadeGPURenderPassEncoder}
42
+ */
43
+ begin_render_pass(encoder: GPUCommandEncoder, descriptor: GPURenderPassDescriptor): ShadeGPURenderPassEncoder;
44
+ /**
45
+ * @param {GPUCommandEncoder} encoder
46
+ * @returns {void}
47
+ */
48
+ resolve(encoder: GPUCommandEncoder): void;
49
+ /**
50
+ * Read the timings back and hand them to the recorder. Resolves {@link absorbed} either way.
51
+ *
52
+ * @returns {void}
53
+ */
54
+ absorb(): void;
55
+ #private;
56
+ }
57
+ import { ShadeGPUComputePassEncoder } from "../pass/ShadeGPUComputePassEncoder.js";
58
+ import { ShadeGPURenderPassEncoder } from "../pass/ShadeGPURenderPassEncoder.js";
59
+ //# sourceMappingURL=ShadeGPUContextProfiler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ShadeGPUContextProfiler.d.ts","sourceRoot":"","sources":["../../../../../src/shade/device/timing/ShadeGPUContextProfiler.js"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;GAiBG;AACH;IA+BI;;;;OAIG;IACH,yEAFW,MAAM,EAchB;IAED;;;;OAIG;IACH,8BAEC;IAED;;;;OAIG;IACH,uFAFa,0BAA0B,CAYtC;IAED;;;;OAIG;IACH,oFAFa,yBAAyB,CAYrC;IAmCD;;;OAGG;IACH,qCAFa,IAAI,CAIhB;IAED;;;;OAIG;IACH,UAFa,IAAI,CAoBhB;;CACJ;2CApL0C,uCAAuC;0CACxC,sCAAsC"}