@woosh/meep-engine 3.12.0 → 3.13.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/package.json +1 -1
- package/src/engine/graphics3/decal/GPUDecalRenderer.js +3 -3
- package/src/engine/graphics3/decal/shader_decal_composite.d.ts.map +1 -1
- package/src/engine/graphics3/decal/shader_decal_composite.js +4 -2
- package/src/engine/graphics3/highlight/GPUHighlightRenderer.d.ts.map +1 -1
- package/src/engine/graphics3/highlight/GPUHighlightRenderer.js +2 -3
- package/src/engine/graphics3/highlight/shader_highlight_outline.js +150 -150
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/shade/RENDERER_CONTRACT.md +2 -1
- package/src/shade/descriptor/pipeline/compute/ComputePipelineDescriptor.d.ts +18 -0
- package/src/shade/descriptor/pipeline/compute/ComputePipelineDescriptor.d.ts.map +1 -1
- package/src/shade/descriptor/pipeline/compute/ComputePipelineDescriptor.js +73 -0
- package/src/shade/device/PASS_ENCODER_PROPOSAL_2026_08_31.md +750 -0
- package/src/shade/device/ShadeGPUCommandContext.d.ts +10 -16
- package/src/shade/device/ShadeGPUCommandContext.d.ts.map +1 -1
- package/src/shade/device/ShadeGPUCommandContext.js +801 -994
- package/src/shade/device/pass/ShadeGPUComputePassEncoder.d.ts +107 -0
- package/src/shade/device/pass/ShadeGPUComputePassEncoder.d.ts.map +1 -0
- package/src/shade/device/pass/ShadeGPUComputePassEncoder.js +222 -0
- package/src/shade/device/pass/ShadeGPURenderPassEncoder.d.ts +168 -0
- package/src/shade/device/pass/ShadeGPURenderPassEncoder.d.ts.map +1 -0
- package/src/shade/device/pass/ShadeGPURenderPassEncoder.js +317 -0
- package/src/shade/device/timing/GPUTimerArray.d.ts +4 -9
- package/src/shade/device/timing/GPUTimerArray.d.ts.map +1 -1
- package/src/shade/device/timing/GPUTimerArray.js +261 -289
- package/src/shade/device/timing/GPU_PROFILER_PROPOSAL_2026_08_28.md +20 -2
- package/src/shade/device/timing/ShadeGPUContextProfiler.d.ts +59 -0
- package/src/shade/device/timing/ShadeGPUContextProfiler.d.ts.map +1 -0
- package/src/shade/device/timing/ShadeGPUContextProfiler.js +182 -0
- package/src/shade/device/timing/profile/GPUProfileSession.d.ts +4 -4
- package/src/shade/device/timing/profile/GPUProfileSession.js +4 -4
- package/src/shade/playground/skinned_blas_refit/shader_blas_audit_leaf_triangles.d.ts.map +1 -1
- package/src/shade/playground/skinned_blas_refit/shader_blas_audit_leaf_triangles.js +3 -1
- package/src/shade/playground/skinned_blas_refit/shader_blas_audit_points.d.ts.map +1 -1
- package/src/shade/playground/skinned_blas_refit/shader_blas_audit_points.js +3 -1
- package/src/shade/playground/skinned_blas_refit/shader_blas_audit_visibility.d.ts.map +1 -1
- package/src/shade/playground/skinned_blas_refit/shader_blas_audit_visibility.js +3 -1
- package/src/shade/playground/skinned_blas_refit/verify_leaf_triangles.js +2 -2
- package/src/shade/playground/skinned_blas_refit/verify_traversal_reachability.js +2 -2
- package/src/shade/renderer/Renderer.d.ts +0 -6
- package/src/shade/renderer/Renderer.d.ts.map +1 -1
- package/src/shade/renderer/Renderer.js +0 -29
- package/src/shade/renderer/animation/GPUAnimationManager.d.ts.map +1 -1
- package/src/shade/renderer/animation/GPUAnimationManager.js +1 -3
- package/src/shade/renderer/animation/shader_animation_tick.d.ts.map +1 -1
- package/src/shade/renderer/animation/shader_animation_tick.js +128 -125
- package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts.map +1 -1
- package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +8 -18
- package/src/shade/renderer/animation/skinning/bounds_refresh/shader_geometry_sphere_derive.d.ts.map +1 -1
- package/src/shade/renderer/animation/skinning/bounds_refresh/shader_geometry_sphere_derive.js +100 -98
- package/src/shade/renderer/animation/skinning/bounds_refresh/shader_meshlet_bounds_reduce.d.ts.map +1 -1
- package/src/shade/renderer/animation/skinning/bounds_refresh/shader_meshlet_bounds_reduce.js +215 -212
- package/src/shade/renderer/animation/skinning/bounds_refresh/shader_meshlet_bounds_scatter.d.ts +1 -1
- package/src/shade/renderer/animation/skinning/bounds_refresh/shader_meshlet_bounds_scatter.d.ts.map +1 -1
- package/src/shade/renderer/animation/skinning/bounds_refresh/shader_meshlet_bounds_scatter.js +135 -120
- package/src/shade/renderer/animation/skinning/bounds_refresh/shader_skinned_mesh_bounds_refresh.d.ts.map +1 -1
- package/src/shade/renderer/animation/skinning/bounds_refresh/shader_skinned_mesh_bounds_refresh.js +77 -75
- package/src/shade/renderer/animation/skinning/shader_meshlet_apply_skinning.d.ts.map +1 -1
- package/src/shade/renderer/animation/skinning/shader_meshlet_apply_skinning.js +375 -371
- package/src/shade/renderer/atmosphere/shader_transmittance_lut.js +3 -3
- package/src/shade/renderer/buffer/graph_inspect_gpu_buffer.js +1 -1
- package/src/shade/renderer/buffer/table/GPUDatabase.d.ts.map +1 -1
- package/src/shade/renderer/buffer/table/GPUDatabase.js +14 -19
- package/src/shade/renderer/buffer/table/gpu_table_element_upload_shader.d.ts.map +1 -1
- package/src/shade/renderer/buffer/table/gpu_table_element_upload_shader.js +7 -2
- package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.d.ts.map +1 -1
- package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.js +325 -319
- package/src/shade/renderer/buffer/util/shader_buffer_copy_storage_to_storage.d.ts.map +1 -1
- package/src/shade/renderer/buffer/util/shader_buffer_copy_storage_to_storage.js +3 -1
- package/src/shade/renderer/deferred/shader_tonemap_HDR.d.ts.map +1 -1
- package/src/shade/renderer/deferred/shader_tonemap_HDR.js +4 -1
- package/src/shade/renderer/dynamic/GPUDynamicMeshResidency.d.ts +2 -2
- package/src/shade/renderer/dynamic/GPUDynamicMeshResidency.d.ts.map +1 -1
- package/src/shade/renderer/dynamic/GPUDynamicMeshResidency.js +167 -167
- package/src/shade/renderer/fow/GPUFogOfWarRenderer.js +3 -3
- package/src/shade/renderer/fow/shader_fog_of_war.d.ts.map +1 -1
- package/src/shade/renderer/fow/shader_fog_of_war.js +3 -1
- package/src/shade/renderer/geometry/bvh/record_blas_refit.js +102 -102
- package/src/shade/renderer/geometry/bvh/shader_blas_refit_leaf_bounds.d.ts.map +1 -1
- package/src/shade/renderer/geometry/bvh/shader_blas_refit_leaf_bounds.js +125 -121
- package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts.map +1 -1
- package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.js +766 -774
- package/src/shade/renderer/geometry/meshlet/shader_meshlet_metadata_address_patch.d.ts.map +1 -1
- package/src/shade/renderer/geometry/meshlet/shader_meshlet_metadata_address_patch.js +72 -69
- package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.d.ts.map +1 -1
- package/src/shade/renderer/geometry/sdf/GPUGeometrySDFManager.js +5 -10
- package/src/shade/renderer/geometry/sdf/shader_build_sdf.js +129 -129
- package/src/shade/renderer/geometry/sdf/shader_sdf_visualize.d.ts.map +1 -1
- package/src/shade/renderer/geometry/sdf/shader_sdf_visualize.js +5 -3
- package/src/shade/renderer/global_illumination/brick4/gpu/bake/shader_brick4_bake_probes.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/brick4/gpu/bake/shader_brick4_bake_probes.js +4 -1
- package/src/shade/renderer/global_illumination/brick4/gpu/bake/shader_brick4_bake_resolve_probes.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/brick4/gpu/bake/shader_brick4_bake_resolve_probes.js +3 -1
- package/src/shade/renderer/global_illumination/clipmap/shader_update_clipmap_cascade.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/clipmap/shader_update_clipmap_cascade.js +114 -112
- package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_lpv_store_sh.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_lpv_store_sh.js +4 -1
- package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_lvp_atlas_to_sh.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_lvp_atlas_to_sh.js +187 -184
- package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_reduce_atlas_to_sh.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_reduce_atlas_to_sh.js +4 -1
- package/src/shade/renderer/global_illumination/sharc/SpatialHashRadianceCache.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/sharc/SpatialHashRadianceCache.js +6 -8
- package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_evict.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_evict.js +3 -1
- package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_update.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_update.js +3 -1
- package/src/shade/renderer/gpu_primitive/bvh/GPU_BVH_BUILD_PLAN.md +3 -3
- package/src/shade/renderer/gpu_primitive/bvh/PHASE1_HANDOVER.md +3 -3
- package/src/shade/renderer/gpu_primitive/bvh/graph_bvh_build_lbvh.js +217 -217
- package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_emit_hierarchy.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_emit_hierarchy.js +145 -142
- package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_morton.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_morton.js +87 -82
- package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_refit.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_refit.js +143 -140
- package/src/shade/renderer/gpu_primitive/bvh/verify_gpu_bvh_build.d.ts +2 -2
- package/src/shade/renderer/gpu_primitive/bvh/verify_gpu_bvh_build.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/bvh/verify_gpu_bvh_build.js +43 -8
- package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/sort/graph_radix_sort.js +4 -5
- package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_histogram.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_histogram.js +88 -84
- package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_scatter.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_scatter.js +194 -191
- package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts.map +1 -1
- package/src/shade/renderer/hiz/HierarchicalZBuffer.js +33 -69
- package/src/shade/renderer/hiz/shader_hzb_reduce_any.d.ts.map +1 -1
- package/src/shade/renderer/hiz/shader_hzb_reduce_any.js +6 -1
- package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.d.ts.map +1 -1
- package/src/shade/renderer/hiz/shader_hzb_reduce_mip0_clip.js +23 -7
- package/src/shade/renderer/light/environment/execute_filter_environment_map.d.ts.map +1 -1
- package/src/shade/renderer/light/environment/execute_filter_environment_map.js +1 -2
- package/src/shade/renderer/light/environment/shader_convolve_reflection_map.d.ts.map +1 -1
- package/src/shade/renderer/light/environment/shader_convolve_reflection_map.js +6 -1
- package/src/shade/renderer/lightmap/bake/raster/graph_draw_lightmap_viz_buffer.d.ts.map +1 -1
- package/src/shade/renderer/lightmap/bake/raster/graph_draw_lightmap_viz_buffer.js +234 -219
- package/src/shade/renderer/lightmap/bake/raster/shader_lightmap_to_viz_buffer.js +2 -2
- package/src/shade/renderer/lightmap/bake/shader_lightmap_denoise_sh.js +191 -191
- package/src/shade/renderer/lightmap/bake/tile/shader_lightmap_accummulate_tile.d.ts.map +1 -1
- package/src/shade/renderer/lightmap/bake/tile/shader_lightmap_accummulate_tile.js +85 -82
- package/src/shade/renderer/particles/graph_particles.d.ts.map +1 -1
- package/src/shade/renderer/particles/graph_particles.js +5 -3
- package/src/shade/renderer/particles/prototypeParticleSystem.js +3 -4
- package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_emit.js +132 -117
- package/src/shade/renderer/particles/shaders/shader_particle_finalize.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_finalize.js +79 -77
- package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +111 -99
- package/src/shade/renderer/particles/sort/shader_particle_sort.d.ts.map +1 -1
- package/src/shade/renderer/particles/sort/shader_particle_sort.js +187 -158
- package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.d.ts.map +1 -1
- package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.js +7 -10
- package/src/shade/renderer/path_tracer/accumulating/shader_accumulating_path_tracer.d.ts.map +1 -1
- package/src/shade/renderer/path_tracer/accumulating/shader_accumulating_path_tracer.js +4 -1
- package/src/shade/renderer/postprocess/bloom/shader_bloom_mix.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/bloom/shader_bloom_mix.js +3 -1
- package/src/shade/renderer/postprocess/cas/shader_ffx_rcas.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/cas/shader_ffx_rcas.js +4 -2
- package/src/shade/renderer/postprocess/denoise/fragment_shader_denoise_ao.js +147 -147
- package/src/shade/renderer/postprocess/denoise/graph_atorus_denoise_luma.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/denoise/graph_atorus_denoise_luma.js +121 -119
- package/src/shade/renderer/postprocess/dof/gather/graph_postprocess_dof2.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/dof/gather/graph_postprocess_dof2.js +1 -2
- package/src/shade/renderer/postprocess/dof/gather/shader_dof2_gather_far.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/dof/gather/shader_dof2_gather_far.js +4 -1
- package/src/shade/renderer/postprocess/dof/gather/shader_dof2_gather_near.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/dof/gather/shader_dof2_gather_near.js +4 -1
- package/src/shade/renderer/postprocess/dof/gather/shader_dof2_recombine.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/dof/gather/shader_dof2_recombine.js +4 -1
- package/src/shade/renderer/postprocess/dof/gather/shader_dof2_setup.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/dof/gather/shader_dof2_setup.js +4 -1
- package/src/shade/renderer/postprocess/dof/raymarch/graph_postprocess_dof.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/dof/raymarch/graph_postprocess_dof.js +2 -4
- package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_composite.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_composite.js +4 -1
- package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_prefilter.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_prefilter.js +4 -1
- package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_raymarch.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_raymarch.js +4 -1
- package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_raymarch_compute.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_raymarch_compute.js +269 -266
- package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_slice_compute.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_slice_compute.js +273 -270
- package/src/shade/renderer/postprocess/dof/shader_dof_autofocus.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/dof/shader_dof_autofocus.js +4 -1
- package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/eye/GPUCameraExposureManager.js +8 -11
- package/src/shade/renderer/postprocess/eye/shader_autoexposure_adapt.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/eye/shader_autoexposure_adapt.js +5 -1
- package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao.js +11 -8
- package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao_with_irradiance.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/gtao/fragment_shader_gtao_with_irradiance.js +7 -8
- package/src/shade/renderer/postprocess/motion_blur/shader_motion_blur_reconstruct.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/motion_blur/shader_motion_blur_reconstruct.js +3 -1
- package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
- package/src/shade/renderer/postprocess/nss/shader_nss_concat.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/nss/shader_nss_concat.js +70 -68
- package/src/shade/renderer/postprocess/ssr/depth_max_shader.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/ssr/depth_max_shader.js +70 -68
- package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_IBL.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_IBL.js +3 -1
- package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_LPV.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/ssr/resolve/ssr_resolve_shader_LPV.js +4 -1
- package/src/shade/renderer/postprocess/ssr/shader_downsample_encoded_normal.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/ssr/shader_downsample_encoded_normal.js +103 -101
- package/src/shade/renderer/postprocess/ssr/ssr_spatial_denoise_shader.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/ssr/ssr_spatial_denoise_shader.js +4 -2
- package/src/shade/renderer/postprocess/ssr/ssr_trace_shader.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/ssr/ssr_trace_shader.js +3 -1
- package/src/shade/renderer/postprocess/taa/shader_taa.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/taa/shader_taa.js +4 -1
- package/src/shade/renderer/postprocess/upscale-dither/fragment_shader_upscale_dither.js +5 -5
- package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +339 -341
- package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.js +114 -109
- package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.js +118 -115
- package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.js +69 -65
- package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.js +722 -722
- 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 +1 -9
- package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.js +1 -6
- package/src/shade/renderer/restir/di/graph_restir_di.d.ts.map +1 -1
- package/src/shade/renderer/restir/di/graph_restir_di.js +2 -3
- package/src/shade/renderer/restir/di/graph_restir_di_denoise.d.ts.map +1 -1
- package/src/shade/renderer/restir/di/graph_restir_di_denoise.js +1 -2
- package/src/shade/renderer/restir/di/shader_restir_di_denoise.d.ts.map +1 -1
- package/src/shade/renderer/restir/di/shader_restir_di_denoise.js +139 -136
- package/src/shade/renderer/restir/di/shader_restir_di_resample.d.ts.map +1 -1
- package/src/shade/renderer/restir/di/shader_restir_di_resample.js +131 -129
- package/src/shade/renderer/restir/di/shader_restir_di_resolve.d.ts.map +1 -1
- package/src/shade/renderer/restir/di/shader_restir_di_resolve.js +101 -99
- package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.d.ts.map +1 -1
- package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.js +379 -383
- package/src/shade/renderer/scene/shader_bvh_extract_instance_leaves.d.ts.map +1 -1
- package/src/shade/renderer/scene/shader_bvh_extract_instance_leaves.js +147 -144
- package/src/shade/renderer/shader/ComputeShader.d.ts +2 -2
- package/src/shade/renderer/shader/ComputeShader.d.ts.map +1 -1
- package/src/shade/renderer/shader/ComputeShader.js +14 -17
- package/src/shade/renderer/shader/pass/RenderPassDescriptor.d.ts +2 -2
- package/src/shade/renderer/shader/pass/RenderPassDescriptor.d.ts.map +1 -1
- package/src/shade/renderer/shader/pass/RenderPassDescriptor.js +189 -189
- package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.d.ts.map +1 -1
- package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.js +3 -1
- package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts.map +1 -1
- package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.js +14 -18
- package/src/shade/renderer/shadow/map/shader/shader_shadowmap_remap_cube_to_octahedral.d.ts.map +1 -1
- package/src/shade/renderer/shadow/map/shader/shader_shadowmap_remap_cube_to_octahedral.js +5 -1
- package/src/shade/renderer/shadow/ray/shader_shadow_upscale.d.ts.map +1 -1
- package/src/shade/renderer/shadow/ray/shader_shadow_upscale.js +3 -1
- package/src/shade/renderer/shadow/ray/staged/gen/graph_gen_rays.js +73 -73
- package/src/shade/renderer/shadow/ray/staged/gen/shader_generate_rays.d.ts.map +1 -1
- package/src/shade/renderer/shadow/ray/staged/gen/shader_generate_rays.js +151 -148
- package/src/shade/renderer/shadow/ray/staged/trace/graph_trace_rays.d.ts.map +1 -1
- package/src/shade/renderer/shadow/ray/staged/trace/graph_trace_rays.js +4 -2
- package/src/shade/renderer/shadow/ray/staged/trace/shader_trace_rays.d.ts.map +1 -1
- package/src/shade/renderer/shadow/ray/staged/trace/shader_trace_rays.js +18 -4
- package/src/shade/renderer/shadow/sdf/cascade/CascadedSceneSDF.d.ts.map +1 -1
- package/src/shade/renderer/shadow/sdf/cascade/CascadedSceneSDF.js +7 -8
- package/src/shade/renderer/shadow/sdf/cascade/shader_build_scene_sdf_f32.d.ts.map +1 -1
- package/src/shade/renderer/shadow/sdf/cascade/shader_build_scene_sdf_f32.js +6 -2
- package/src/shade/renderer/shadow/sdf/cascade/shader_scene_sdf_debug_viz.d.ts.map +1 -1
- package/src/shade/renderer/shadow/sdf/cascade/shader_scene_sdf_debug_viz.js +129 -127
- package/src/shade/renderer/shadow/sdf/graph_draw_sdf_shadows.d.ts.map +1 -1
- package/src/shade/renderer/shadow/sdf/graph_draw_sdf_shadows.js +5 -3
- package/src/shade/renderer/texture/virtual/VirtualTextureManager.d.ts.map +1 -1
- package/src/shade/renderer/texture/virtual/VirtualTextureManager.js +2 -5
- package/src/shade/renderer/texture/virtual/build_shader_vt_feedback.d.ts.map +1 -1
- package/src/shade/renderer/texture/virtual/build_shader_vt_feedback.js +233 -231
- package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/graph_build_volumetrics.js +2 -4
- package/src/shade/wgsl/validate_wgsl_source.d.ts.map +1 -1
- package/src/shade/wgsl/validate_wgsl_source.js +8 -3
- package/src/shade/device/timing/profile/make_profiling_pass_encoder.d.ts +0 -21
- package/src/shade/device/timing/profile/make_profiling_pass_encoder.d.ts.map +0 -1
- package/src/shade/device/timing/profile/make_profiling_pass_encoder.js +0 -114
- package/src/shade/device/timing/profile/parse_workgroup_size.d.ts +0 -20
- package/src/shade/device/timing/profile/parse_workgroup_size.d.ts.map +0 -1
- package/src/shade/device/timing/profile/parse_workgroup_size.js +0 -43
|
@@ -1,995 +1,802 @@
|
|
|
1
|
-
import { assert } from "../../core/assert.js";
|
|
2
|
-
import { BinaryBuffer } from "../../core/binary/BinaryBuffer.js";
|
|
3
|
-
import { platform_compute_endianness } from "../../core/binary/platform_compute_endianness.js";
|
|
4
|
-
import { array_push_if_unique } from "../../core/collection/array/array_push_if_unique.js";
|
|
5
|
-
import { array_remove_first } from "../../core/collection/array/array_remove_first.js";
|
|
6
|
-
import { array_buffer_copy } from "../../core/collection/array/typed/array_buffer_copy.js";
|
|
7
|
-
import Signal from "../../core/events/signal/Signal.js";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
*
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* @see https://
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
*
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
*
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
*
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
*
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
*
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
*
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
*
|
|
126
|
-
* @
|
|
127
|
-
*/
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
*
|
|
134
|
-
* @
|
|
135
|
-
*/
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
*
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
* @
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
*
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
*
|
|
287
|
-
*
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
*
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
// console.log(`cmd.
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
*
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
)
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
*
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
if
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
*
|
|
508
|
-
* @param {
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
if (
|
|
525
|
-
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
const
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
graphics.
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
*
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
*
|
|
573
|
-
*
|
|
574
|
-
*
|
|
575
|
-
* @
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
assert.
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
this
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
/**
|
|
602
|
-
*
|
|
603
|
-
*
|
|
604
|
-
*
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
*
|
|
616
|
-
*
|
|
617
|
-
*
|
|
618
|
-
*
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
const
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
return
|
|
671
|
-
}
|
|
672
|
-
|
|
673
|
-
/**
|
|
674
|
-
*
|
|
675
|
-
* @param {
|
|
676
|
-
* @param {number}
|
|
677
|
-
* @param {
|
|
678
|
-
* @param {
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
this.#
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
*
|
|
706
|
-
* @
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
this.#transient_buffers
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
);
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
if (buffer === null) {
|
|
803
|
-
buffer = new BinaryBuffer();
|
|
804
|
-
|
|
805
|
-
// GPU buffer contents must match the host, and BinaryBuffer's own default is
|
|
806
|
-
// little-endian regardless of platform. Getting this wrong produces bytes that are
|
|
807
|
-
// correct on every machine anyone is likely to test on and wrong on the rest.
|
|
808
|
-
buffer.endianness = platform_compute_endianness();
|
|
809
|
-
|
|
810
|
-
this.#immediate_buffer = buffer;
|
|
811
|
-
}
|
|
812
|
-
|
|
813
|
-
buffer.position = 0;
|
|
814
|
-
|
|
815
|
-
if (!resources.writeImmediate(map, buffer)) {
|
|
816
|
-
return undefined;
|
|
817
|
-
}
|
|
818
|
-
|
|
819
|
-
return { buffer, offset: 0, size: buffer.position };
|
|
820
|
-
}
|
|
821
|
-
|
|
822
|
-
/**
|
|
823
|
-
* @template T
|
|
824
|
-
* @param {WebGPUType} type
|
|
825
|
-
* @param {T} value
|
|
826
|
-
* @param {number|GPUBufferUsage} [usage]
|
|
827
|
-
* @return {GPUBuffer}
|
|
828
|
-
*/
|
|
829
|
-
allocateTransientValueBuffer(
|
|
830
|
-
type,
|
|
831
|
-
value,
|
|
832
|
-
usage
|
|
833
|
-
) {
|
|
834
|
-
assert.defined(type, 'type');
|
|
835
|
-
assert.notNull(type, 'type');
|
|
836
|
-
|
|
837
|
-
const buffer = this.allocateTransientBuffer(usage, type.aligned_size);
|
|
838
|
-
|
|
839
|
-
this.writeValueBuffer(buffer, 0, type, value);
|
|
840
|
-
|
|
841
|
-
return buffer;
|
|
842
|
-
}
|
|
843
|
-
|
|
844
|
-
/**
|
|
845
|
-
* @template T
|
|
846
|
-
* @param {GPUBuffer} buffer
|
|
847
|
-
* @param {number} buffer_offset
|
|
848
|
-
* @param {WebGPUType} type
|
|
849
|
-
* @param {T} value
|
|
850
|
-
*/
|
|
851
|
-
writeValueBuffer(buffer, buffer_offset, type, value) {
|
|
852
|
-
|
|
853
|
-
assert.notOk(this.#finished, 'already finished');
|
|
854
|
-
|
|
855
|
-
const gfx = this.#graphics;
|
|
856
|
-
|
|
857
|
-
const size = type.aligned_size;
|
|
858
|
-
|
|
859
|
-
const stage = gfx.buffer_allocator_staging.get(size);
|
|
860
|
-
|
|
861
|
-
const mapped = stage.getMappedRange(0, size);
|
|
862
|
-
|
|
863
|
-
write_gpu_typed_buffer(value, type, mapped, 0);
|
|
864
|
-
|
|
865
|
-
stage.unmap();
|
|
866
|
-
|
|
867
|
-
this.#staging_buffers.push(stage);
|
|
868
|
-
|
|
869
|
-
this.copyBufferToBuffer(stage, 0, buffer, buffer_offset, size);
|
|
870
|
-
}
|
|
871
|
-
|
|
872
|
-
/**
|
|
873
|
-
* Very similar to {@link GPUQueue.writeBuffer}, but instead of doing the operation direction on the queue - uses a staging buffer under the hood and performs the actual write operation as part of the commmand buffer
|
|
874
|
-
* @param {GPUBuffer} buffer
|
|
875
|
-
* @param {number} buffer_offset
|
|
876
|
-
* @param {ArrayBuffer} data
|
|
877
|
-
* @param {number} data_offset
|
|
878
|
-
* @param {number} size
|
|
879
|
-
*/
|
|
880
|
-
writeBuffer(buffer, buffer_offset, data, data_offset, size) {
|
|
881
|
-
assert.defined(buffer, 'buffer');
|
|
882
|
-
assert.isNonNegativeInteger(buffer_offset, 'buffer_offset');
|
|
883
|
-
assert.defined(data, 'data');
|
|
884
|
-
assert.isNonNegativeInteger(data_offset, 'data_offset');
|
|
885
|
-
assert.isNonNegativeInteger(size, 'size');
|
|
886
|
-
|
|
887
|
-
const gfx = this.#graphics;
|
|
888
|
-
|
|
889
|
-
const stage = gfx.buffer_allocator_staging.get(size);
|
|
890
|
-
|
|
891
|
-
const mapped = stage.getMappedRange(0, size);
|
|
892
|
-
|
|
893
|
-
array_buffer_copy(data, data_offset, mapped, 0, size);
|
|
894
|
-
|
|
895
|
-
stage.unmap();
|
|
896
|
-
|
|
897
|
-
this.#staging_buffers.push(stage);
|
|
898
|
-
|
|
899
|
-
this.copyBufferToBuffer(stage, 0, buffer, buffer_offset, size);
|
|
900
|
-
|
|
901
|
-
}
|
|
902
|
-
|
|
903
|
-
#cleanup() {
|
|
904
|
-
|
|
905
|
-
// console.warn('cmd.cleanup()');
|
|
906
|
-
|
|
907
|
-
const transient_buffers = this.#transient_buffers;
|
|
908
|
-
const transient_buffer_count = transient_buffers.length;
|
|
909
|
-
|
|
910
|
-
const buffer_allocator_transient = this.#transient_allocator;
|
|
911
|
-
|
|
912
|
-
// release in reverse order to make it more likely that we'd end up in the same acquisition order next time, which is desirable for caching
|
|
913
|
-
for (let i = transient_buffer_count - 1; i >= 0; i--) {
|
|
914
|
-
const buffer = transient_buffers[i];
|
|
915
|
-
|
|
916
|
-
buffer_allocator_transient.release(buffer);
|
|
917
|
-
|
|
918
|
-
}
|
|
919
|
-
|
|
920
|
-
// staging buffers
|
|
921
|
-
const buffer_allocator_staging = this.#graphics.buffer_allocator_staging;
|
|
922
|
-
for (const staging of this.#staging_buffers) {
|
|
923
|
-
buffer_allocator_staging.release(staging);
|
|
924
|
-
}
|
|
925
|
-
}
|
|
926
|
-
|
|
927
|
-
/**
|
|
928
|
-
* Performs both {@link GPUCommandEncoder.finish} and flushed command buffer
|
|
929
|
-
*/
|
|
930
|
-
finish() {
|
|
931
|
-
if (this.#finished) {
|
|
932
|
-
console.warn('Context already finished');
|
|
933
|
-
return;
|
|
934
|
-
}
|
|
935
|
-
|
|
936
|
-
this.onBeforeFinish.send1(this);
|
|
937
|
-
|
|
938
|
-
debug_open_context_count--;
|
|
939
|
-
array_remove_first(debug_open_contexts, this);
|
|
940
|
-
|
|
941
|
-
const encoder = this.#gpu_encoder;
|
|
942
|
-
|
|
943
|
-
const debug_timers = this.#debug_timers;
|
|
944
|
-
if (debug_timers !== undefined) {
|
|
945
|
-
debug_timers.resolve(encoder);
|
|
946
|
-
}
|
|
947
|
-
|
|
948
|
-
this.#finished = true;
|
|
949
|
-
|
|
950
|
-
// release encoder reference
|
|
951
|
-
this.#gpu_encoder = undefined;
|
|
952
|
-
|
|
953
|
-
const command_buffer = encoder.finish();
|
|
954
|
-
|
|
955
|
-
const graphics = this.#graphics;
|
|
956
|
-
const queue = graphics.device.queue;
|
|
957
|
-
|
|
958
|
-
queue.submit([command_buffer]);
|
|
959
|
-
|
|
960
|
-
// cleanup allocated memory
|
|
961
|
-
this.#cleanup();
|
|
962
|
-
|
|
963
|
-
if (debug_timers !== undefined) {
|
|
964
|
-
const recorder = this.#profile_recorder;
|
|
965
|
-
const query_set_id = this.#profile_query_set_id;
|
|
966
|
-
|
|
967
|
-
debug_timers
|
|
968
|
-
.download_results()
|
|
969
|
-
.then(() => {
|
|
970
|
-
if (recorder !== null) {
|
|
971
|
-
recorder.absorb(debug_timers, query_set_id);
|
|
972
|
-
}
|
|
973
|
-
|
|
974
|
-
// The console-shaped path stays exactly as it was; a context can be doing both.
|
|
975
|
-
const table = debug_timers.results_to_console_table();
|
|
976
|
-
|
|
977
|
-
this.#debug_timers_callback(table);
|
|
978
|
-
})
|
|
979
|
-
.finally(() => {
|
|
980
|
-
debug_timers.destroy();
|
|
981
|
-
|
|
982
|
-
// In `finally` so a failed readback still releases whoever is waiting on the
|
|
983
|
-
// frame. A profile session that hangs because one download rejected is worse
|
|
984
|
-
// than one missing a frame.
|
|
985
|
-
this.#profiling_absorbed_resolve();
|
|
986
|
-
});
|
|
987
|
-
|
|
988
|
-
this.#debug_timers = undefined;
|
|
989
|
-
this.#profile_recorder = null;
|
|
990
|
-
}
|
|
991
|
-
|
|
992
|
-
this.onFinished.send1(this);
|
|
993
|
-
|
|
994
|
-
}
|
|
1
|
+
import { assert } from "../../core/assert.js";
|
|
2
|
+
import { BinaryBuffer } from "../../core/binary/BinaryBuffer.js";
|
|
3
|
+
import { platform_compute_endianness } from "../../core/binary/platform_compute_endianness.js";
|
|
4
|
+
import { array_push_if_unique } from "../../core/collection/array/array_push_if_unique.js";
|
|
5
|
+
import { array_remove_first } from "../../core/collection/array/array_remove_first.js";
|
|
6
|
+
import { array_buffer_copy } from "../../core/collection/array/typed/array_buffer_copy.js";
|
|
7
|
+
import Signal from "../../core/events/signal/Signal.js";
|
|
8
|
+
import { ShadeGPUComputePassEncoder } from "./pass/ShadeGPUComputePassEncoder.js";
|
|
9
|
+
import { ShadeGPURenderPassEncoder } from "./pass/ShadeGPURenderPassEncoder.js";
|
|
10
|
+
import { ShadeGPUContextProfiler } from "./timing/ShadeGPUContextProfiler.js";
|
|
11
|
+
import { warn_limited } from "../util/warn_limited.js";
|
|
12
|
+
import { write_gpu_typed_buffer } from "../renderer/shader/type/serde/write_gpu_typed_buffer.js";
|
|
13
|
+
import { BufferResourceDescriptor } from "./graph/BufferResourceDescriptor.js";
|
|
14
|
+
import { GraphicsExecutionContext } from "./graph/GraphicsExecutionContext.js";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Keep track of how many contexts are currently open (unfinished)
|
|
18
|
+
* Important because contexts can have transient resources allocated, and those are not cleaned up until the context is `finished`
|
|
19
|
+
* @type {number}
|
|
20
|
+
*/
|
|
21
|
+
let debug_open_context_count = 0;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
*
|
|
25
|
+
* @type {ShadeGPUCommandContext[]}
|
|
26
|
+
*/
|
|
27
|
+
const debug_open_contexts = [];
|
|
28
|
+
|
|
29
|
+
const scratch_buffer_descriptor = new BufferResourceDescriptor();
|
|
30
|
+
|
|
31
|
+
let id_counter = 0;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Abstraction on top of {@link GPUCommandEncoder}.
|
|
35
|
+
*
|
|
36
|
+
* Inspired by Intel's "MiniEngine" CommandContext
|
|
37
|
+
* @see https://github.com/GameTechDev/TAA/blob/39786709cf70a1e0906196c600f6079571a33ceb/MiniEngine/Core/CommandContext.h
|
|
38
|
+
* @see https://www.w3.org/TR/webgpu/#gpucommandencoder
|
|
39
|
+
*/
|
|
40
|
+
export class ShadeGPUCommandContext {
|
|
41
|
+
|
|
42
|
+
#id = id_counter++;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Unique identifier for this context, useful for debugging
|
|
46
|
+
*
|
|
47
|
+
* @return {number}
|
|
48
|
+
*/
|
|
49
|
+
get id() {
|
|
50
|
+
return this.#id;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
*
|
|
55
|
+
* @returns {boolean}
|
|
56
|
+
*/
|
|
57
|
+
get isGPUCommandContext() {
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Actual underlying encoder
|
|
64
|
+
* @type {GPUCommandEncoder}
|
|
65
|
+
*/
|
|
66
|
+
#gpu_encoder
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Don't circumvent {@link ShadeGPUCommandContext} unless you know what you're doing.
|
|
70
|
+
* {@link ShadeGPUCommandContext} is a wrapper around {@link GPUCommandEncoder} that provides additional spec-compliance asserts to help find errors sooner.
|
|
71
|
+
* @returns {GPUCommandEncoder}
|
|
72
|
+
*/
|
|
73
|
+
get gpu_encoder() {
|
|
74
|
+
return this.#gpu_encoder;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* This context's profiling attachment, or null when nothing is profiling — which is the
|
|
79
|
+
* ordinary case and costs one null check per pass.
|
|
80
|
+
*
|
|
81
|
+
* **Never cleared.** `finish()` is followed by a read of {@link profiling_absorbed}, and a null
|
|
82
|
+
* here reports an already-resolved promise, which closes the frame before a single timestamp has
|
|
83
|
+
* come back. It holds no GPU resources after `absorb()` destroys the timer array, so keeping the
|
|
84
|
+
* reference costs nothing.
|
|
85
|
+
*
|
|
86
|
+
* @type {ShadeGPUContextProfiler|null}
|
|
87
|
+
*/
|
|
88
|
+
#profiler = null;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Resolves after this context's timings have been read back and handed to its recorder.
|
|
92
|
+
*
|
|
93
|
+
* **Not the same moment as {@link done}.** `done` resolves from `onFinished`, which fires
|
|
94
|
+
* synchronously at submit — before any timestamp has been read. A caller that closes its frame
|
|
95
|
+
* on `done` commits an empty one, every time. Already-resolved when nothing is profiling.
|
|
96
|
+
*
|
|
97
|
+
* @returns {Promise<void>}
|
|
98
|
+
*/
|
|
99
|
+
get profiling_absorbed() {
|
|
100
|
+
const profiler = this.#profiler;
|
|
101
|
+
|
|
102
|
+
return profiler === null ? Promise.resolve() : profiler.absorbed;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Record this context's pass timings into `recorder`.
|
|
107
|
+
*
|
|
108
|
+
* @param {GPUFrameRecorder} recorder
|
|
109
|
+
* @param {number} query_set_id this context's index within the frame
|
|
110
|
+
* @returns {void}
|
|
111
|
+
*/
|
|
112
|
+
enable_profiling(recorder, query_set_id) {
|
|
113
|
+
assert.notOk(this.#finished, 'already finished');
|
|
114
|
+
assert.isNull(this.#profiler, 'already profiling');
|
|
115
|
+
|
|
116
|
+
this.#profiler = new ShadeGPUContextProfiler(this.device, recorder, query_set_id);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* @type {GraphicsContext}
|
|
121
|
+
*/
|
|
122
|
+
#graphics
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
*
|
|
126
|
+
* @return {GPUDevice}
|
|
127
|
+
*/
|
|
128
|
+
get device() {
|
|
129
|
+
return this.#graphics.device;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
*
|
|
134
|
+
* @return {TextureManager}
|
|
135
|
+
*/
|
|
136
|
+
get textures() {
|
|
137
|
+
return this.#graphics.textures;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* These are to be destroyed at the end of the context's lifetime.
|
|
142
|
+
* Need to be released at the end of the lifetime.
|
|
143
|
+
* @type {GPUBuffer[]}
|
|
144
|
+
*/
|
|
145
|
+
#transient_buffers = [];
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
*
|
|
149
|
+
* @type {GPUBuffer[]}
|
|
150
|
+
*/
|
|
151
|
+
#staging_buffers = [];
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Once finished, the encoder becomes inactive, we use this flag to track potential misuse and inform the user
|
|
155
|
+
* @type {boolean}
|
|
156
|
+
*/
|
|
157
|
+
#finished = false;
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* @readonly
|
|
161
|
+
* @type {Signal<this>}
|
|
162
|
+
*/
|
|
163
|
+
onFinished = new Signal();
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* @readonly
|
|
167
|
+
* @type {Signal<this>}
|
|
168
|
+
*/
|
|
169
|
+
onBeforeFinish = new Signal();
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
*
|
|
173
|
+
* @return {Promise<void>}
|
|
174
|
+
*/
|
|
175
|
+
get done() {
|
|
176
|
+
if (this.#finished) {
|
|
177
|
+
return Promise.resolve();
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return new Promise(resolve => {
|
|
181
|
+
this.onFinished.addOne(resolve);
|
|
182
|
+
|
|
183
|
+
if (this.#finished) {
|
|
184
|
+
// special case, double-checking to avoid race conditions
|
|
185
|
+
resolve();
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Do not call directly, always use {@link create}
|
|
193
|
+
* @private
|
|
194
|
+
*/
|
|
195
|
+
constructor() {
|
|
196
|
+
// private, do not call from the outside
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
*
|
|
201
|
+
* @param {GraphicsContext} graphics
|
|
202
|
+
* @param {string} [label]
|
|
203
|
+
* @returns {ShadeGPUCommandContext}
|
|
204
|
+
*/
|
|
205
|
+
static create(
|
|
206
|
+
graphics,
|
|
207
|
+
label = ""
|
|
208
|
+
) {
|
|
209
|
+
|
|
210
|
+
assert.defined(graphics, 'graphics');
|
|
211
|
+
assert.equal(graphics.isGraphicsContext, true, "graphics.isGraphicsContext !== true");
|
|
212
|
+
|
|
213
|
+
assert.isString(label, 'label');
|
|
214
|
+
|
|
215
|
+
const r = new ShadeGPUCommandContext();
|
|
216
|
+
|
|
217
|
+
r.#graphics = graphics;
|
|
218
|
+
r.#gpu_encoder = graphics.device.createCommandEncoder({
|
|
219
|
+
label
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
// track how many we have open
|
|
223
|
+
debug_open_context_count++;
|
|
224
|
+
array_push_if_unique(debug_open_contexts, r);
|
|
225
|
+
|
|
226
|
+
if (debug_open_context_count > 1024) {
|
|
227
|
+
warn_limited(`Too many open GPU contexts`, 20);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
return r;
|
|
231
|
+
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
*
|
|
236
|
+
* @returns {GraphicsExecutionContext}
|
|
237
|
+
*/
|
|
238
|
+
createFrameGraphContext() {
|
|
239
|
+
return new GraphicsExecutionContext(this.#graphics, this);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
*
|
|
244
|
+
* @param {FrameGraph} graph
|
|
245
|
+
*/
|
|
246
|
+
encodeGraph(graph) {
|
|
247
|
+
assert.defined(graph, 'graph');
|
|
248
|
+
assert.isObject(graph, 'graph');
|
|
249
|
+
assert.equal(graph.isFrameGraph, true, "graph.isFrameGraph !== true");
|
|
250
|
+
|
|
251
|
+
// TODO check if the graph is empty, if so, we can skip the whole thing
|
|
252
|
+
|
|
253
|
+
const ctx = this.createFrameGraphContext();
|
|
254
|
+
|
|
255
|
+
graph.compile();
|
|
256
|
+
graph.execute(ctx);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* @see https://www.w3.org/TR/webgpu/#dom-gpucommandencoder-clearbuffer
|
|
261
|
+
* @param {GPUBuffer} buffer
|
|
262
|
+
* @param {number} [offset=0]
|
|
263
|
+
* @param {number} [size]
|
|
264
|
+
*/
|
|
265
|
+
clearBuffer(buffer, offset = 0, size) {
|
|
266
|
+
assert.defined(buffer, 'buffer');
|
|
267
|
+
assert.equal(buffer.usage & GPUBufferUsage.COPY_DST, GPUBufferUsage.COPY_DST, 'buffer must include COPY_DST usage flag');
|
|
268
|
+
assert.isNonNegativeInteger(offset, 'offset');
|
|
269
|
+
assert.equal(offset % 4, 0, 'offset must be a multiple of 4');
|
|
270
|
+
|
|
271
|
+
// console.log(`cmd.clearBuffer(${buffer.label}, ${offset}, ${size})`);
|
|
272
|
+
|
|
273
|
+
this.#gpu_encoder.clearBuffer(buffer, offset, size);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Not supported, only here to offer documentation hint
|
|
278
|
+
* see {@link texture_fill_rectangle}
|
|
279
|
+
* @throws {Error} Always, documentation hint only
|
|
280
|
+
*/
|
|
281
|
+
clearTexture() {
|
|
282
|
+
throw new Error(`Documentation hint only, use texture_fill_rectangle instead`);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* NOTE: only the explicit verbose form of the API is supported, shorthand such as `copyBufferToBuffer(source, destination, size)` are not supported.
|
|
287
|
+
* see https://www.w3.org/TR/webgpu/#gpucommandencoder-copybuffertobuffer
|
|
288
|
+
* @see GPUCommandEncoder.copyBufferToBuffer
|
|
289
|
+
* @param {GPUBuffer} source The GPUBuffer to copy from.
|
|
290
|
+
* @param {number} sourceOffset Offset in bytes into the source to begin copying from.
|
|
291
|
+
* @param {GPUBuffer} destination The GPUBuffer to copy to.
|
|
292
|
+
* @param {number} destinationOffset Offset in bytes into destination to place the copied data.
|
|
293
|
+
* @param {number} [size] Bytes to copy. In not specified, defaults to `source.size - sourceOffset`
|
|
294
|
+
*/
|
|
295
|
+
copyBufferToBuffer(
|
|
296
|
+
source,
|
|
297
|
+
sourceOffset,
|
|
298
|
+
destination,
|
|
299
|
+
destinationOffset,
|
|
300
|
+
size
|
|
301
|
+
) {
|
|
302
|
+
|
|
303
|
+
assert.notEqual(source.usage & GPUBufferUsage.COPY_SRC, 0, 'source must include COPY_SRC usage flag');
|
|
304
|
+
assert.isNonNegativeInteger(sourceOffset, 'sourceOffset');
|
|
305
|
+
assert.equal(sourceOffset % 4, 0, 'sourceOffset must be a multiple of 4');
|
|
306
|
+
|
|
307
|
+
assert.notEqual(destination.usage & GPUBufferUsage.COPY_DST, 0, 'destination must include COPY_DST usage flag');
|
|
308
|
+
assert.isNonNegativeInteger(destinationOffset, 'destinationOffset');
|
|
309
|
+
assert.equal(destinationOffset % 4, 0, 'destinationOffset must be a multiple of 4');
|
|
310
|
+
|
|
311
|
+
if (size !== undefined) {
|
|
312
|
+
assert.isNonNegativeInteger(size, 'size');
|
|
313
|
+
assert.equal(size % 4, 0, 'size must be a multiple of 4');
|
|
314
|
+
|
|
315
|
+
assert.greaterThanOrEqual(source.size, sourceOffset + size, 'source underflow');
|
|
316
|
+
assert.greaterThanOrEqual(destination.size, destinationOffset + size, 'destination underflow');
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
assert.notEqual(source, destination, 'source and destination must be different');
|
|
320
|
+
|
|
321
|
+
// console.log(`cmd.copyBufferToBuffer("${source.label}", ${sourceOffset}, "${destination.label}", ${destinationOffset}, ${size})`);
|
|
322
|
+
|
|
323
|
+
this.#gpu_encoder.copyBufferToBuffer(
|
|
324
|
+
source,
|
|
325
|
+
sourceOffset,
|
|
326
|
+
destination,
|
|
327
|
+
destinationOffset,
|
|
328
|
+
size
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
*
|
|
335
|
+
* @param {GPUImageCopyTexture} source
|
|
336
|
+
* @param {GPUImageCopyTexture} destination
|
|
337
|
+
* @param {GPUExtent3DStrict} copySize
|
|
338
|
+
*/
|
|
339
|
+
copyTextureToTexture(source,
|
|
340
|
+
destination,
|
|
341
|
+
copySize
|
|
342
|
+
) {
|
|
343
|
+
this.#gpu_encoder.copyTextureToTexture(source, destination, copySize);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
*
|
|
348
|
+
* @param {GPUComputePassDescriptor} [descriptor]
|
|
349
|
+
* @returns {ShadeGPUComputePassEncoder}
|
|
350
|
+
*/
|
|
351
|
+
beginComputePass(descriptor) {
|
|
352
|
+
const encoder = this.#gpu_encoder;
|
|
353
|
+
const profiler = this.#profiler;
|
|
354
|
+
|
|
355
|
+
// console.log(`cmd.beginComputePass(${descriptor.label})`);
|
|
356
|
+
|
|
357
|
+
if (profiler === null) {
|
|
358
|
+
return new ShadeGPUComputePassEncoder(encoder.beginComputePass(descriptor), null);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
return profiler.begin_compute_pass(encoder, descriptor);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
*
|
|
367
|
+
* @param {ComputePipelineDescriptor} pipeline
|
|
368
|
+
* @param {string} [label]
|
|
369
|
+
* @param {GPUBindingResource[][]} [bindings]
|
|
370
|
+
* @returns {ShadeGPUComputePassEncoder}
|
|
371
|
+
*/
|
|
372
|
+
constructComputePass({
|
|
373
|
+
pipeline,
|
|
374
|
+
label,
|
|
375
|
+
bindings = [],
|
|
376
|
+
immediate
|
|
377
|
+
}) {
|
|
378
|
+
|
|
379
|
+
const pass_descriptor = {
|
|
380
|
+
label
|
|
381
|
+
};
|
|
382
|
+
|
|
383
|
+
if (label === undefined) {
|
|
384
|
+
pass_descriptor.label = pipeline.label;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
const graphics = this.#graphics;
|
|
388
|
+
|
|
389
|
+
const pass = this.beginComputePass(pass_descriptor);
|
|
390
|
+
|
|
391
|
+
const gpu_pipeline = graphics.compute_pipelines.obtain(pipeline);
|
|
392
|
+
|
|
393
|
+
pass.setPipeline(gpu_pipeline);
|
|
394
|
+
|
|
395
|
+
pass.record_pipeline(pipeline);
|
|
396
|
+
|
|
397
|
+
graphics.setPipelineBindings(pass, pipeline, bindings, immediate);
|
|
398
|
+
|
|
399
|
+
// console.warn(`cmd.constructComputePass(${pass_descriptor.label})`)
|
|
400
|
+
|
|
401
|
+
return pass;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* Begins a labeled debug group containing subsequent commands.
|
|
406
|
+
* @see https://gpuweb.github.io/gpuweb/#debug-markers
|
|
407
|
+
* @param {string} label
|
|
408
|
+
*/
|
|
409
|
+
pushDebugGroup(label) {
|
|
410
|
+
assert.isString(label, 'label');
|
|
411
|
+
this.#gpu_encoder.pushDebugGroup(label);
|
|
412
|
+
|
|
413
|
+
// console.group("cmd/debug_group=" + label)
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* Ends the labeled debug group most recently started by pushDebugGroup().
|
|
418
|
+
* @see https://gpuweb.github.io/gpuweb/#debug-markers
|
|
419
|
+
*/
|
|
420
|
+
popDebugGroup() {
|
|
421
|
+
this.#gpu_encoder.popDebugGroup();
|
|
422
|
+
|
|
423
|
+
// console.groupEnd();
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* Marks a point in a stream of commands with a label.
|
|
428
|
+
* @see https://gpuweb.github.io/gpuweb/#debug-markers
|
|
429
|
+
* @param {string} label
|
|
430
|
+
*/
|
|
431
|
+
insertDebugMarker(label) {
|
|
432
|
+
assert.isString(label, 'label');
|
|
433
|
+
this.#gpu_encoder.insertDebugMarker(label);
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
*
|
|
438
|
+
* @param {string} [label]
|
|
439
|
+
* @param {RenderPipelineDescriptor} pipeline
|
|
440
|
+
* @param {GPUBindingResource[][]} [bindings]
|
|
441
|
+
* @param {GPURenderPassColorAttachment[]} colorAttachments
|
|
442
|
+
* @param {GPURenderPassDepthStencilAttachment} [depthStencilAttachment]
|
|
443
|
+
* @returns {ShadeGPURenderPassEncoder}
|
|
444
|
+
*/
|
|
445
|
+
constructRenderPass({
|
|
446
|
+
label,
|
|
447
|
+
pipeline,
|
|
448
|
+
bindings,
|
|
449
|
+
colorAttachments,
|
|
450
|
+
depthStencilAttachment,
|
|
451
|
+
immediate,
|
|
452
|
+
}) {
|
|
453
|
+
assert.defined(pipeline, 'pipeline');
|
|
454
|
+
assert.equal(pipeline.isRenderPipelineDescriptor, true, "pipeline.isRenderPipelineDescriptor !== true");
|
|
455
|
+
|
|
456
|
+
const pass_descriptor = {
|
|
457
|
+
label,
|
|
458
|
+
colorAttachments,
|
|
459
|
+
depthStencilAttachment
|
|
460
|
+
};
|
|
461
|
+
|
|
462
|
+
if (label === undefined) {
|
|
463
|
+
pass_descriptor.label = pipeline.label;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
const graphics = this.#graphics;
|
|
467
|
+
|
|
468
|
+
// TODO rewrite the pipeline if necessary to achieve compatibility with colorAttachment formats
|
|
469
|
+
const gpu_pipeline = graphics.render_pipelines.obtain(pipeline);
|
|
470
|
+
|
|
471
|
+
const pass = this.beginRenderPass(pass_descriptor);
|
|
472
|
+
|
|
473
|
+
pass.setPipeline(gpu_pipeline);
|
|
474
|
+
|
|
475
|
+
pass.record_pipeline(pipeline);
|
|
476
|
+
|
|
477
|
+
graphics.setPipelineBindings(pass, pipeline, bindings, immediate);
|
|
478
|
+
|
|
479
|
+
// console.warn(`cmd.constructRenderPass(${pass_descriptor.label})`)
|
|
480
|
+
|
|
481
|
+
return pass;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/**
|
|
485
|
+
*
|
|
486
|
+
* @param {GPURenderPassDescriptor} descriptor
|
|
487
|
+
* @returns {ShadeGPURenderPassEncoder}
|
|
488
|
+
*/
|
|
489
|
+
beginRenderPass(descriptor) {
|
|
490
|
+
const encoder = this.#gpu_encoder;
|
|
491
|
+
const profiler = this.#profiler;
|
|
492
|
+
|
|
493
|
+
// console.log(`cmd.beginRenderPass(${descriptor.label})`);
|
|
494
|
+
|
|
495
|
+
if (profiler === null) {
|
|
496
|
+
return new ShadeGPURenderPassEncoder(encoder.beginRenderPass(descriptor), null);
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
return profiler.begin_render_pass(encoder, descriptor);
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
/**
|
|
503
|
+
*
|
|
504
|
+
* @param {GPUQuerySet} querySet
|
|
505
|
+
* @param {number} firstQuery
|
|
506
|
+
* @param {number} queryCount
|
|
507
|
+
* @param {GPUBuffer} destination
|
|
508
|
+
* @param {number} destinationOffset
|
|
509
|
+
*/
|
|
510
|
+
resolveQuerySet(querySet, firstQuery, queryCount, destination, destinationOffset) {
|
|
511
|
+
this.#gpu_encoder.resolveQuerySet(querySet, firstQuery, queryCount, destination, destinationOffset);
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
/**
|
|
515
|
+
* Transient buffers are automatically released at the end of the context's lifetime;
|
|
516
|
+
* however, we can explicitly release it earlier to allow for reuse.
|
|
517
|
+
*
|
|
518
|
+
* @param {GPUBuffer} buffer
|
|
519
|
+
* @return {boolean} true if buffer was released, false if it was not found
|
|
520
|
+
*/
|
|
521
|
+
releaseTransientBuffer(buffer) {
|
|
522
|
+
assert.defined(buffer, 'buffer');
|
|
523
|
+
|
|
524
|
+
if (!array_remove_first(this.#transient_buffers, buffer)) {
|
|
525
|
+
return false;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
const allocator = this.#transient_allocator;
|
|
529
|
+
|
|
530
|
+
return allocator.release(buffer);
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
/**
|
|
534
|
+
*
|
|
535
|
+
* @return {GPUBufferAllocator}
|
|
536
|
+
*/
|
|
537
|
+
get #transient_allocator() {
|
|
538
|
+
return this.#graphics.buffer_allocator_main;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
/**
|
|
542
|
+
* Allocated buffer will only be valid until the context is finished.
|
|
543
|
+
*
|
|
544
|
+
* @param {number|GPUBufferUsage} usage
|
|
545
|
+
* @param {number} size
|
|
546
|
+
* @returns {GPUBuffer} managed buffer
|
|
547
|
+
*/
|
|
548
|
+
allocateTransientBuffer(
|
|
549
|
+
usage = GPUBufferUsage.UNIFORM,
|
|
550
|
+
size
|
|
551
|
+
) {
|
|
552
|
+
assert.isNonNegativeInteger(size, 'size');
|
|
553
|
+
assert.isInteger(usage, 'usage');
|
|
554
|
+
|
|
555
|
+
assert.notOk(this.#finished, 'already finished');
|
|
556
|
+
|
|
557
|
+
scratch_buffer_descriptor.size = size;
|
|
558
|
+
// COPY_DST is needed to write the data
|
|
559
|
+
scratch_buffer_descriptor.usage = usage | GPUBufferUsage.COPY_DST;
|
|
560
|
+
|
|
561
|
+
const allocator = this.#transient_allocator;
|
|
562
|
+
const buffer = allocator.get(scratch_buffer_descriptor, this);
|
|
563
|
+
|
|
564
|
+
// remember so we can clean up at the end
|
|
565
|
+
this.#transient_buffers.push(buffer);
|
|
566
|
+
|
|
567
|
+
return buffer;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
/**
|
|
571
|
+
*
|
|
572
|
+
* @param {ArrayBuffer} data CPU-side data to place into the GPU buffer
|
|
573
|
+
* @param {number|GPUBufferUsage} [usage=GPUBufferUsage.UNIFORM]
|
|
574
|
+
* @param {number} [offset] offset into source data where to start copying from
|
|
575
|
+
* @param {number} [size] in bytes
|
|
576
|
+
* @returns {GPUBuffer} managed buffer, will be automatically destroyed when context is finished
|
|
577
|
+
*/
|
|
578
|
+
allocateTransientBufferAndLoad(
|
|
579
|
+
data,
|
|
580
|
+
usage = GPUBufferUsage.UNIFORM,
|
|
581
|
+
offset = 0,
|
|
582
|
+
size = data.byteLength
|
|
583
|
+
) {
|
|
584
|
+
assert.isInstanceOf(data, ArrayBuffer, 'data');
|
|
585
|
+
assert.isInteger(usage, 'usage');
|
|
586
|
+
assert.isNonNegativeInteger(offset, 'offset');
|
|
587
|
+
assert.isNonNegativeInteger(size, 'size');
|
|
588
|
+
|
|
589
|
+
assert.notOk(this.#finished, 'already finished');
|
|
590
|
+
|
|
591
|
+
const buffer = this.allocateTransientBuffer(
|
|
592
|
+
usage,
|
|
593
|
+
size
|
|
594
|
+
);
|
|
595
|
+
|
|
596
|
+
this.writeBuffer(buffer, 0, data, offset, size);
|
|
597
|
+
|
|
598
|
+
return buffer;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
/**
|
|
602
|
+
* Scratch for immediate data, created on first use and reused for the life of the context.
|
|
603
|
+
*
|
|
604
|
+
* One buffer is enough, and `position` returns to 0 for every write, because `setImmediates`
|
|
605
|
+
* copies the bytes it is given at the point of the call — the region is free again the moment
|
|
606
|
+
* the pass encoder has taken it. Nothing here ever grows: the default capacity is far above the
|
|
607
|
+
* 64-byte ceiling {@link ShaderResourceSetDescriptor#setImmediate} enforces, so the backing
|
|
608
|
+
* `ArrayBuffer` is allocated once and never reallocated.
|
|
609
|
+
*
|
|
610
|
+
* @type {BinaryBuffer|null}
|
|
611
|
+
*/
|
|
612
|
+
#immediate_buffer = null;
|
|
613
|
+
|
|
614
|
+
/**
|
|
615
|
+
* Serialise a shader's immediate data ready for `setImmediates`, or return undefined when the
|
|
616
|
+
* shader declares none.
|
|
617
|
+
*
|
|
618
|
+
* Allocates nothing after the first call.
|
|
619
|
+
*
|
|
620
|
+
* @param {ShaderResourceSetDescriptor} resources
|
|
621
|
+
* @param {Object} map the shader's binding map
|
|
622
|
+
* @returns {{buffer: BinaryBuffer, offset: number, size: number}|undefined}
|
|
623
|
+
*/
|
|
624
|
+
writeImmediate(resources, map) {
|
|
625
|
+
if (resources.immediateSize === 0) {
|
|
626
|
+
return undefined;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
let buffer = this.#immediate_buffer;
|
|
630
|
+
|
|
631
|
+
if (buffer === null) {
|
|
632
|
+
buffer = new BinaryBuffer();
|
|
633
|
+
|
|
634
|
+
// GPU buffer contents must match the host, and BinaryBuffer's own default is
|
|
635
|
+
// little-endian regardless of platform. Getting this wrong produces bytes that are
|
|
636
|
+
// correct on every machine anyone is likely to test on and wrong on the rest.
|
|
637
|
+
buffer.endianness = platform_compute_endianness();
|
|
638
|
+
|
|
639
|
+
this.#immediate_buffer = buffer;
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
buffer.position = 0;
|
|
643
|
+
|
|
644
|
+
if (!resources.writeImmediate(map, buffer)) {
|
|
645
|
+
return undefined;
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
return { buffer, offset: 0, size: buffer.position };
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
/**
|
|
652
|
+
* @template T
|
|
653
|
+
* @param {WebGPUType} type
|
|
654
|
+
* @param {T} value
|
|
655
|
+
* @param {number|GPUBufferUsage} [usage]
|
|
656
|
+
* @return {GPUBuffer}
|
|
657
|
+
*/
|
|
658
|
+
allocateTransientValueBuffer(
|
|
659
|
+
type,
|
|
660
|
+
value,
|
|
661
|
+
usage
|
|
662
|
+
) {
|
|
663
|
+
assert.defined(type, 'type');
|
|
664
|
+
assert.notNull(type, 'type');
|
|
665
|
+
|
|
666
|
+
const buffer = this.allocateTransientBuffer(usage, type.aligned_size);
|
|
667
|
+
|
|
668
|
+
this.writeValueBuffer(buffer, 0, type, value);
|
|
669
|
+
|
|
670
|
+
return buffer;
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
/**
|
|
674
|
+
* @template T
|
|
675
|
+
* @param {GPUBuffer} buffer
|
|
676
|
+
* @param {number} buffer_offset
|
|
677
|
+
* @param {WebGPUType} type
|
|
678
|
+
* @param {T} value
|
|
679
|
+
*/
|
|
680
|
+
writeValueBuffer(buffer, buffer_offset, type, value) {
|
|
681
|
+
|
|
682
|
+
assert.notOk(this.#finished, 'already finished');
|
|
683
|
+
|
|
684
|
+
const gfx = this.#graphics;
|
|
685
|
+
|
|
686
|
+
const size = type.aligned_size;
|
|
687
|
+
|
|
688
|
+
const stage = gfx.buffer_allocator_staging.get(size);
|
|
689
|
+
|
|
690
|
+
const mapped = stage.getMappedRange(0, size);
|
|
691
|
+
|
|
692
|
+
write_gpu_typed_buffer(value, type, mapped, 0);
|
|
693
|
+
|
|
694
|
+
stage.unmap();
|
|
695
|
+
|
|
696
|
+
this.#staging_buffers.push(stage);
|
|
697
|
+
|
|
698
|
+
this.copyBufferToBuffer(stage, 0, buffer, buffer_offset, size);
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
/**
|
|
702
|
+
* Very similar to {@link GPUQueue.writeBuffer}, but instead of doing the operation direction on the queue - uses a staging buffer under the hood and performs the actual write operation as part of the commmand buffer
|
|
703
|
+
* @param {GPUBuffer} buffer
|
|
704
|
+
* @param {number} buffer_offset
|
|
705
|
+
* @param {ArrayBuffer} data
|
|
706
|
+
* @param {number} data_offset
|
|
707
|
+
* @param {number} size
|
|
708
|
+
*/
|
|
709
|
+
writeBuffer(buffer, buffer_offset, data, data_offset, size) {
|
|
710
|
+
assert.defined(buffer, 'buffer');
|
|
711
|
+
assert.isNonNegativeInteger(buffer_offset, 'buffer_offset');
|
|
712
|
+
assert.defined(data, 'data');
|
|
713
|
+
assert.isNonNegativeInteger(data_offset, 'data_offset');
|
|
714
|
+
assert.isNonNegativeInteger(size, 'size');
|
|
715
|
+
|
|
716
|
+
const gfx = this.#graphics;
|
|
717
|
+
|
|
718
|
+
const stage = gfx.buffer_allocator_staging.get(size);
|
|
719
|
+
|
|
720
|
+
const mapped = stage.getMappedRange(0, size);
|
|
721
|
+
|
|
722
|
+
array_buffer_copy(data, data_offset, mapped, 0, size);
|
|
723
|
+
|
|
724
|
+
stage.unmap();
|
|
725
|
+
|
|
726
|
+
this.#staging_buffers.push(stage);
|
|
727
|
+
|
|
728
|
+
this.copyBufferToBuffer(stage, 0, buffer, buffer_offset, size);
|
|
729
|
+
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
#cleanup() {
|
|
733
|
+
|
|
734
|
+
// console.warn('cmd.cleanup()');
|
|
735
|
+
|
|
736
|
+
const transient_buffers = this.#transient_buffers;
|
|
737
|
+
const transient_buffer_count = transient_buffers.length;
|
|
738
|
+
|
|
739
|
+
const buffer_allocator_transient = this.#transient_allocator;
|
|
740
|
+
|
|
741
|
+
// release in reverse order to make it more likely that we'd end up in the same acquisition order next time, which is desirable for caching
|
|
742
|
+
for (let i = transient_buffer_count - 1; i >= 0; i--) {
|
|
743
|
+
const buffer = transient_buffers[i];
|
|
744
|
+
|
|
745
|
+
buffer_allocator_transient.release(buffer);
|
|
746
|
+
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
// staging buffers
|
|
750
|
+
const buffer_allocator_staging = this.#graphics.buffer_allocator_staging;
|
|
751
|
+
for (const staging of this.#staging_buffers) {
|
|
752
|
+
buffer_allocator_staging.release(staging);
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
/**
|
|
757
|
+
* Performs both {@link GPUCommandEncoder.finish} and flushed command buffer
|
|
758
|
+
*/
|
|
759
|
+
finish() {
|
|
760
|
+
if (this.#finished) {
|
|
761
|
+
console.warn('Context already finished');
|
|
762
|
+
return;
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
this.onBeforeFinish.send1(this);
|
|
766
|
+
|
|
767
|
+
debug_open_context_count--;
|
|
768
|
+
array_remove_first(debug_open_contexts, this);
|
|
769
|
+
|
|
770
|
+
const encoder = this.#gpu_encoder;
|
|
771
|
+
|
|
772
|
+
const profiler = this.#profiler;
|
|
773
|
+
|
|
774
|
+
if (profiler !== null) {
|
|
775
|
+
profiler.resolve(encoder);
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
this.#finished = true;
|
|
779
|
+
|
|
780
|
+
// release encoder reference
|
|
781
|
+
this.#gpu_encoder = undefined;
|
|
782
|
+
|
|
783
|
+
const command_buffer = encoder.finish();
|
|
784
|
+
|
|
785
|
+
const graphics = this.#graphics;
|
|
786
|
+
const queue = graphics.device.queue;
|
|
787
|
+
|
|
788
|
+
queue.submit([command_buffer]);
|
|
789
|
+
|
|
790
|
+
// cleanup allocated memory
|
|
791
|
+
this.#cleanup();
|
|
792
|
+
|
|
793
|
+
if (profiler !== null) {
|
|
794
|
+
// Kept, not cleared — `profiling_absorbed` is read after `finish()` and a null here
|
|
795
|
+
// would report an already-resolved promise. See the field.
|
|
796
|
+
profiler.absorb();
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
this.onFinished.send1(this);
|
|
800
|
+
|
|
801
|
+
}
|
|
995
802
|
}
|