@carbonenginejs/runtime-resource 0.10.0 → 0.11.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.
Files changed (254) hide show
  1. package/dist/format/effect/effectPermutationGraph.js +257 -0
  2. package/dist/format/effect/effectPermutationGraph.js.map +1 -0
  3. package/dist/format/effect/effectReflectionPackage.js +636 -0
  4. package/dist/format/effect/effectReflectionPackage.js.map +1 -0
  5. package/dist/format/effect/sha256.js +114 -0
  6. package/dist/format/effect/sha256.js.map +1 -0
  7. package/dist/formats/dxbc/CjsDxbcFormat.js +142 -0
  8. package/dist/formats/dxbc/CjsDxbcFormat.js.map +1 -0
  9. package/dist/formats/dxbc/core/DxbcReader.js +266 -0
  10. package/dist/formats/dxbc/core/DxbcReader.js.map +1 -0
  11. package/dist/formats/dxbc/core/container.js +169 -0
  12. package/dist/formats/dxbc/core/container.js.map +1 -0
  13. package/dist/formats/dxbc/core/decoder.js +789 -0
  14. package/dist/formats/dxbc/core/decoder.js.map +1 -0
  15. package/dist/formats/dxbc/core/errors.js +19 -0
  16. package/dist/formats/dxbc/core/errors.js.map +1 -0
  17. package/dist/formats/dxbc/core/helpers.js +220 -0
  18. package/dist/formats/dxbc/core/helpers.js.map +1 -0
  19. package/dist/formats/dxbc/core/opcodes.js +45 -0
  20. package/dist/formats/dxbc/core/opcodes.js.map +1 -0
  21. package/dist/formats/dxbc/core/program.js +91 -0
  22. package/dist/formats/dxbc/core/program.js.map +1 -0
  23. package/dist/formats/dxbc/core/signature.js +172 -0
  24. package/dist/formats/dxbc/core/signature.js.map +1 -0
  25. package/dist/formats/dxbc/index.js +2 -0
  26. package/dist/formats/dxbc/index.js.map +1 -0
  27. package/dist/formats/hlsl/CjsHlslFormat.js +254 -0
  28. package/dist/formats/hlsl/CjsHlslFormat.js.map +1 -0
  29. package/dist/formats/hlsl/core/HlslBinaryUtils.js +15 -0
  30. package/dist/formats/hlsl/core/HlslBinaryUtils.js.map +1 -0
  31. package/dist/formats/hlsl/core/HlslEffectReadError.js +19 -0
  32. package/dist/formats/hlsl/core/HlslEffectReadError.js.map +1 -0
  33. package/dist/formats/hlsl/core/HlslEffectStateManager.js +130 -0
  34. package/dist/formats/hlsl/core/HlslEffectStateManager.js.map +1 -0
  35. package/dist/formats/hlsl/core/HlslReader.js +266 -0
  36. package/dist/formats/hlsl/core/HlslReader.js.map +1 -0
  37. package/dist/formats/hlsl/core/HlslRenderStateSetup.js +37 -0
  38. package/dist/formats/hlsl/core/HlslRenderStateSetup.js.map +1 -0
  39. package/dist/formats/hlsl/core/HlslResourceSetDescription.js +94 -0
  40. package/dist/formats/hlsl/core/HlslResourceSetDescription.js.map +1 -0
  41. package/dist/formats/hlsl/core/HlslShaderBytecode.js +44 -0
  42. package/dist/formats/hlsl/core/HlslShaderBytecode.js.map +1 -0
  43. package/dist/formats/hlsl/core/analysis.js +51 -0
  44. package/dist/formats/hlsl/core/analysis.js.map +1 -0
  45. package/dist/formats/hlsl/core/helpers.js +270 -0
  46. package/dist/formats/hlsl/core/helpers.js.map +1 -0
  47. package/dist/formats/hlsl/core/json.js +284 -0
  48. package/dist/formats/hlsl/core/json.js.map +1 -0
  49. package/dist/formats/hlsl/core/metadata.js +327 -0
  50. package/dist/formats/hlsl/core/metadata.js.map +1 -0
  51. package/dist/formats/hlsl/core/portableReflection.js +848 -0
  52. package/dist/formats/hlsl/core/portableReflection.js.map +1 -0
  53. package/dist/formats/hlsl/core/render-states.js +280 -0
  54. package/dist/formats/hlsl/core/render-states.js.map +1 -0
  55. package/dist/formats/hlsl/core/tr2/HlslRenderContextEnum.js +43 -0
  56. package/dist/formats/hlsl/core/tr2/HlslRenderContextEnum.js.map +1 -0
  57. package/dist/formats/hlsl/core/tr2/resources/HlslEffectRes.js +294 -0
  58. package/dist/formats/hlsl/core/tr2/resources/HlslEffectRes.js.map +1 -0
  59. package/dist/formats/hlsl/core/tr2/resources/HlslShaderPermutation.js +33 -0
  60. package/dist/formats/hlsl/core/tr2/resources/HlslShaderPermutation.js.map +1 -0
  61. package/dist/formats/hlsl/core/tr2/shader/HlslEffectBindingManifest.js +416 -0
  62. package/dist/formats/hlsl/core/tr2/shader/HlslEffectBindingManifest.js.map +1 -0
  63. package/dist/formats/hlsl/core/tr2/shader/HlslEffectConstant.js +40 -0
  64. package/dist/formats/hlsl/core/tr2/shader/HlslEffectConstant.js.map +1 -0
  65. package/dist/formats/hlsl/core/tr2/shader/HlslEffectDescription.js +742 -0
  66. package/dist/formats/hlsl/core/tr2/shader/HlslEffectDescription.js.map +1 -0
  67. package/dist/formats/hlsl/core/tr2/shader/HlslEffectLibrary.js +52 -0
  68. package/dist/formats/hlsl/core/tr2/shader/HlslEffectLibrary.js.map +1 -0
  69. package/dist/formats/hlsl/core/tr2/shader/HlslEffectParameterAnnotation.js +38 -0
  70. package/dist/formats/hlsl/core/tr2/shader/HlslEffectParameterAnnotation.js.map +1 -0
  71. package/dist/formats/hlsl/core/tr2/shader/HlslEffectResource.js +50 -0
  72. package/dist/formats/hlsl/core/tr2/shader/HlslEffectResource.js.map +1 -0
  73. package/dist/formats/hlsl/core/tr2/shader/HlslEffectStageInput.js +86 -0
  74. package/dist/formats/hlsl/core/tr2/shader/HlslEffectStageInput.js.map +1 -0
  75. package/dist/formats/hlsl/core/tr2/shader/HlslEffectTechnique.js +31 -0
  76. package/dist/formats/hlsl/core/tr2/shader/HlslEffectTechnique.js.map +1 -0
  77. package/dist/formats/hlsl/core/tr2/shader/HlslPass.js +42 -0
  78. package/dist/formats/hlsl/core/tr2/shader/HlslPass.js.map +1 -0
  79. package/dist/formats/hlsl/core/tr2/shader/HlslSamplerDescription.js +55 -0
  80. package/dist/formats/hlsl/core/tr2/shader/HlslSamplerDescription.js.map +1 -0
  81. package/dist/formats/hlsl/core/tr2/shader/HlslSamplerSetup.js +29 -0
  82. package/dist/formats/hlsl/core/tr2/shader/HlslSamplerSetup.js.map +1 -0
  83. package/dist/formats/hlsl/core/tr2/shader/HlslShader.js +220 -0
  84. package/dist/formats/hlsl/core/tr2/shader/HlslShader.js.map +1 -0
  85. package/dist/formats/hlsl/core/tr2/shader/HlslShaderOption.js +30 -0
  86. package/dist/formats/hlsl/core/tr2/shader/HlslShaderOption.js.map +1 -0
  87. package/dist/formats/hlsl/index.js +2 -0
  88. package/dist/formats/hlsl/index.js.map +1 -0
  89. package/dist/formats/hlsl/portable.js +2 -0
  90. package/dist/formats/hlsl/portable.js.map +1 -0
  91. package/dist/formats/index.js +4 -0
  92. package/dist/formats/index.js.map +1 -1
  93. package/dist/formats/webgl/CjsWebglFormat.js +221 -0
  94. package/dist/formats/webgl/CjsWebglFormat.js.map +1 -0
  95. package/dist/formats/webgl/core/cewg/CewgPackage.js +339 -0
  96. package/dist/formats/webgl/core/cewg/CewgPackage.js.map +1 -0
  97. package/dist/formats/webgl/core/cewg/CewgPackageBuilder.js +104 -0
  98. package/dist/formats/webgl/core/cewg/CewgPackageBuilder.js.map +1 -0
  99. package/dist/formats/webgl/core/cewg/binary.js +101 -0
  100. package/dist/formats/webgl/core/cewg/binary.js.map +1 -0
  101. package/dist/formats/webgl/core/cewgCompleteness.js +81 -0
  102. package/dist/formats/webgl/core/cewgCompleteness.js.map +1 -0
  103. package/dist/formats/webgl/core/effectPackage.js +789 -0
  104. package/dist/formats/webgl/core/effectPackage.js.map +1 -0
  105. package/dist/formats/webgl/core/effectPackageValidation.js +331 -0
  106. package/dist/formats/webgl/core/effectPackageValidation.js.map +1 -0
  107. package/dist/formats/webgl/core/errors.js +27 -0
  108. package/dist/formats/webgl/core/errors.js.map +1 -0
  109. package/dist/formats/webgl/core/glsl/DxbcGlslEmitter.js +2678 -0
  110. package/dist/formats/webgl/core/glsl/DxbcGlslEmitter.js.map +1 -0
  111. package/dist/formats/webgl/core/glsl/DxbcGlslHelpers.js +89 -0
  112. package/dist/formats/webgl/core/glsl/DxbcGlslHelpers.js.map +1 -0
  113. package/dist/formats/webgl/core/glsl/DxbcGlslOperandFormatter.js +428 -0
  114. package/dist/formats/webgl/core/glsl/DxbcGlslOperandFormatter.js.map +1 -0
  115. package/dist/formats/webgl/core/helpers.js +306 -0
  116. package/dist/formats/webgl/core/helpers.js.map +1 -0
  117. package/dist/formats/webgl/index.js +2 -0
  118. package/dist/formats/webgl/index.js.map +1 -0
  119. package/dist/formats/webgpu/CjsWebgpuFormat.js +376 -0
  120. package/dist/formats/webgpu/CjsWebgpuFormat.js.map +1 -0
  121. package/dist/formats/webgpu/core/cewgpu/CewgpuPackage.js +415 -0
  122. package/dist/formats/webgpu/core/cewgpu/CewgpuPackage.js.map +1 -0
  123. package/dist/formats/webgpu/core/cewgpu/CewgpuPackageBuilder.js +100 -0
  124. package/dist/formats/webgpu/core/cewgpu/CewgpuPackageBuilder.js.map +1 -0
  125. package/dist/formats/webgpu/core/cewgpu/binary.js +93 -0
  126. package/dist/formats/webgpu/core/cewgpu/binary.js.map +1 -0
  127. package/dist/formats/webgpu/core/cewgpu/tags.js +17 -0
  128. package/dist/formats/webgpu/core/cewgpu/tags.js.map +1 -0
  129. package/dist/formats/webgpu/core/effectAnalysis.js +82 -0
  130. package/dist/formats/webgpu/core/effectAnalysis.js.map +1 -0
  131. package/dist/formats/webgpu/core/effectBackendBodySet.js +305 -0
  132. package/dist/formats/webgpu/core/effectBackendBodySet.js.map +1 -0
  133. package/dist/formats/webgpu/core/effectPackageValidation.js +1078 -0
  134. package/dist/formats/webgpu/core/effectPackageValidation.js.map +1 -0
  135. package/dist/formats/webgpu/core/errors.js +20 -0
  136. package/dist/formats/webgpu/core/errors.js.map +1 -0
  137. package/dist/formats/webgpu/core/helpers.js +448 -0
  138. package/dist/formats/webgpu/core/helpers.js.map +1 -0
  139. package/dist/formats/webgpu/core/ir/analyzeRegisterValues.js +223 -0
  140. package/dist/formats/webgpu/core/ir/analyzeRegisterValues.js.map +1 -0
  141. package/dist/formats/webgpu/core/ir/buildControlFlow.js +220 -0
  142. package/dist/formats/webgpu/core/ir/buildControlFlow.js.map +1 -0
  143. package/dist/formats/webgpu/core/ir/indexableTemps.js +137 -0
  144. package/dist/formats/webgpu/core/ir/indexableTemps.js.map +1 -0
  145. package/dist/formats/webgpu/core/ir/inferValueTypes.js +454 -0
  146. package/dist/formats/webgpu/core/ir/inferValueTypes.js.map +1 -0
  147. package/dist/formats/webgpu/core/ir/lowerDxbcToIr.js +494 -0
  148. package/dist/formats/webgpu/core/ir/lowerDxbcToIr.js.map +1 -0
  149. package/dist/formats/webgpu/core/ir/resolveRegisterFlow.js +177 -0
  150. package/dist/formats/webgpu/core/ir/resolveRegisterFlow.js.map +1 -0
  151. package/dist/formats/webgpu/core/ir/sourceLanes.js +61 -0
  152. package/dist/formats/webgpu/core/ir/sourceLanes.js.map +1 -0
  153. package/dist/formats/webgpu/core/packageEffect.js +300 -0
  154. package/dist/formats/webgpu/core/packageEffect.js.map +1 -0
  155. package/dist/formats/webgpu/core/packageEffectSelection.js +164 -0
  156. package/dist/formats/webgpu/core/packageEffectSelection.js.map +1 -0
  157. package/dist/formats/webgpu/core/packageMetadata.js +8 -0
  158. package/dist/formats/webgpu/core/packageMetadata.js.map +1 -0
  159. package/dist/formats/webgpu/core/schema.js +4 -0
  160. package/dist/formats/webgpu/core/schema.js.map +1 -0
  161. package/dist/formats/webgpu/core/wgsl/buildResourceTransformPlan.js +275 -0
  162. package/dist/formats/webgpu/core/wgsl/buildResourceTransformPlan.js.map +1 -0
  163. package/dist/formats/webgpu/core/wgsl/buildWgslBindingPlan.js +182 -0
  164. package/dist/formats/webgpu/core/wgsl/buildWgslBindingPlan.js.map +1 -0
  165. package/dist/formats/webgpu/core/wgsl/buildWgslSet.js +324 -0
  166. package/dist/formats/webgpu/core/wgsl/buildWgslSet.js.map +1 -0
  167. package/dist/formats/webgpu/core/wgsl/emitWgsl.js +356 -0
  168. package/dist/formats/webgpu/core/wgsl/emitWgsl.js.map +1 -0
  169. package/dist/formats/webgpu/core/wgsl/hoistEscapingValues.js +77 -0
  170. package/dist/formats/webgpu/core/wgsl/hoistEscapingValues.js.map +1 -0
  171. package/dist/formats/webgpu/core/wgsl/lowerBindingLayout.js +451 -0
  172. package/dist/formats/webgpu/core/wgsl/lowerBindingLayout.js.map +1 -0
  173. package/dist/formats/webgpu/core/wgsl/lowerComputeProgram.js +754 -0
  174. package/dist/formats/webgpu/core/wgsl/lowerComputeProgram.js.map +1 -0
  175. package/dist/formats/webgpu/core/wgsl/lowerCreateHistogramsComputeProgram.js +457 -0
  176. package/dist/formats/webgpu/core/wgsl/lowerCreateHistogramsComputeProgram.js.map +1 -0
  177. package/dist/formats/webgpu/core/wgsl/lowerFragmentProgram.js +1572 -0
  178. package/dist/formats/webgpu/core/wgsl/lowerFragmentProgram.js.map +1 -0
  179. package/dist/formats/webgpu/core/wgsl/lowerMergeHistogramsComputeProgram.js +659 -0
  180. package/dist/formats/webgpu/core/wgsl/lowerMergeHistogramsComputeProgram.js.map +1 -0
  181. package/dist/formats/webgpu/core/wgsl/lowerParticleClearComputePrograms.js +734 -0
  182. package/dist/formats/webgpu/core/wgsl/lowerParticleClearComputePrograms.js.map +1 -0
  183. package/dist/formats/webgpu/core/wgsl/lowerParticleEmitComputeProgram.js +583 -0
  184. package/dist/formats/webgpu/core/wgsl/lowerParticleEmitComputeProgram.js.map +1 -0
  185. package/dist/formats/webgpu/core/wgsl/lowerSkinVerticesComputeProgram.js +621 -0
  186. package/dist/formats/webgpu/core/wgsl/lowerSkinVerticesComputeProgram.js.map +1 -0
  187. package/dist/formats/webgpu/core/wgsl/lowerSortComputeProgram.js +824 -0
  188. package/dist/formats/webgpu/core/wgsl/lowerSortComputeProgram.js.map +1 -0
  189. package/dist/formats/webgpu/core/wgsl/lowerSortInnerComputeProgram.js +697 -0
  190. package/dist/formats/webgpu/core/wgsl/lowerSortInnerComputeProgram.js.map +1 -0
  191. package/dist/formats/webgpu/core/wgsl/lowerSortStepComputeProgram.js +559 -0
  192. package/dist/formats/webgpu/core/wgsl/lowerSortStepComputeProgram.js.map +1 -0
  193. package/dist/formats/webgpu/core/wgsl/lowerVertexProgram.js +1328 -0
  194. package/dist/formats/webgpu/core/wgsl/lowerVertexProgram.js.map +1 -0
  195. package/dist/formats/webgpu/core/wgsl/particleEmitSemanticDigest.js +110 -0
  196. package/dist/formats/webgpu/core/wgsl/particleEmitSemanticDigest.js.map +1 -0
  197. package/dist/formats/webgpu/core/wgsl/precisionControls.js +55 -0
  198. package/dist/formats/webgpu/core/wgsl/precisionControls.js.map +1 -0
  199. package/dist/formats/webgpu/core/wgsl/selectionPlans.js +758 -0
  200. package/dist/formats/webgpu/core/wgsl/selectionPlans.js.map +1 -0
  201. package/dist/formats/webgpu/core/wgsl/uniformity.js +78 -0
  202. package/dist/formats/webgpu/core/wgsl/uniformity.js.map +1 -0
  203. package/dist/formats/webgpu/core/wgsl/validateExactComputeIr.js +196 -0
  204. package/dist/formats/webgpu/core/wgsl/validateExactComputeIr.js.map +1 -0
  205. package/dist/formats/webgpu/core/wgsl/validateHandleOperand.js +37 -0
  206. package/dist/formats/webgpu/core/wgsl/validateHandleOperand.js.map +1 -0
  207. package/dist/formats/webgpu/index.js +2 -0
  208. package/dist/formats/webgpu/index.js.map +1 -0
  209. package/dist/resource/shader/Tr2EffectRes.js +159 -150
  210. package/dist/resource/shader/Tr2EffectRes.js.map +1 -1
  211. package/dist/resource/shader/Tr2MaterialArea.js +23 -28
  212. package/dist/resource/shader/Tr2MaterialArea.js.map +1 -1
  213. package/dist/resource/shader/Tr2MaterialMesh.js +21 -27
  214. package/dist/resource/shader/Tr2MaterialMesh.js.map +1 -1
  215. package/dist/resource/shader/Tr2MaterialRes.js +24 -29
  216. package/dist/resource/shader/Tr2MaterialRes.js.map +1 -1
  217. package/dist/resource/shader/Tr2Shader.js +45 -39
  218. package/dist/resource/shader/Tr2Shader.js.map +1 -1
  219. package/dist/resource/shader/Tr2ShaderPermutation.js +30 -32
  220. package/dist/resource/shader/Tr2ShaderPermutation.js.map +1 -1
  221. package/dist/resource/shader/reflection/Tr2EffectConstant.js +113 -78
  222. package/dist/resource/shader/reflection/Tr2EffectConstant.js.map +1 -1
  223. package/dist/resource/shader/reflection/Tr2EffectDefine.js +17 -23
  224. package/dist/resource/shader/reflection/Tr2EffectDefine.js.map +1 -1
  225. package/dist/resource/shader/reflection/Tr2EffectDescription.js +23 -29
  226. package/dist/resource/shader/reflection/Tr2EffectDescription.js.map +1 -1
  227. package/dist/resource/shader/reflection/Tr2EffectLibrary.js +44 -40
  228. package/dist/resource/shader/reflection/Tr2EffectLibrary.js.map +1 -1
  229. package/dist/resource/shader/reflection/Tr2EffectParameterAnnotation.js +82 -86
  230. package/dist/resource/shader/reflection/Tr2EffectParameterAnnotation.js.map +1 -1
  231. package/dist/resource/shader/reflection/Tr2EffectResource.js +55 -61
  232. package/dist/resource/shader/reflection/Tr2EffectResource.js.map +1 -1
  233. package/dist/resource/shader/reflection/Tr2EffectStageInput.js +49 -45
  234. package/dist/resource/shader/reflection/Tr2EffectStageInput.js.map +1 -1
  235. package/dist/resource/shader/reflection/Tr2EffectTechnique.js +25 -30
  236. package/dist/resource/shader/reflection/Tr2EffectTechnique.js.map +1 -1
  237. package/dist/resource/shader/reflection/Tr2Pass.js +30 -32
  238. package/dist/resource/shader/reflection/Tr2Pass.js.map +1 -1
  239. package/dist/resource/shader/sampler/Tr2SamplerSetup.js +21 -26
  240. package/dist/resource/shader/sampler/Tr2SamplerSetup.js.map +1 -1
  241. package/docs/formats/README.md +4 -0
  242. package/docs/formats/provenance.md +11 -3
  243. package/docs/reference/classes/formats.md +440 -0
  244. package/format-notices/dxbc/LICENSE +21 -0
  245. package/format-notices/dxbc/NOTICE +20 -0
  246. package/format-notices/hlsl/LICENSE +21 -0
  247. package/format-notices/hlsl/NOTICE +25 -0
  248. package/format-notices/webgl/LICENSE +21 -0
  249. package/format-notices/webgl/NOTICE +35 -0
  250. package/format-notices/webgpu/LICENSE +21 -0
  251. package/format-notices/webgpu/NOTICE +31 -0
  252. package/package.json +6 -1
  253. package/dist/resource/shader/portableValidation.js +0 -461
  254. package/dist/resource/shader/portableValidation.js.map +0 -1
@@ -0,0 +1,583 @@
1
+ import { analyzeRegisterValues } from '../ir/analyzeRegisterValues.js';
2
+ import { buildControlFlow } from '../ir/buildControlFlow.js';
3
+ import { inferValueTypes } from '../ir/inferValueTypes.js';
4
+ import { resolveRegisterFlow } from '../ir/resolveRegisterFlow.js';
5
+ import { lowerBindingLayout } from './lowerBindingLayout.js';
6
+ import { particleEmitSemanticDigest } from './particleEmitSemanticDigest.js';
7
+ import { requireRefactoringAllowed } from './precisionControls.js';
8
+ import { buildSelectionPlans } from './selectionPlans.js';
9
+
10
+ const DECLARATION_OPCODES = Object.freeze(["dcl_global_flags", "dcl_constant_buffer", "dcl_unordered_access_view_structured", "dcl_unordered_access_view_typed", "dcl_unordered_access_view_structured", "dcl_input", "dcl_input", "dcl_input", "dcl_temps", "dcl_thread_group_shared_memory_raw", "dcl_thread_group"]);
11
+ const OPCODES_SM50 = Object.freeze(["if", "imul", "store_raw", "store_raw", "store_raw", "store_raw", "store_raw", "store_raw", "store_raw", "endif", "sync", "ld_raw", "ushr", "iadd", "xor", "ushr", "xor", "imul", "ushr", "xor", "imul", "ushr", "xor", "imad", "ld_raw", "ld_raw", "add", "ld_raw", "ge", "movc", "add", "ld_raw", "ld_raw", "add", "ld_raw", "mov", "add", "ld_raw", "add", "mov", "mov", "mov", "loop", "uge", "breakc", "imm_atomic_iadd", "iadd", "ige", "if", "ishl", "xor", "ushr", "xor", "ishl", "xor", "utof", "mul", "mad", "dp3", "rsq", "mul", "ishl", "xor", "ushr", "xor", "ishl", "xor", "utof", "mul", "ishl", "xor", "ushr", "xor", "ishl", "xor", "utof", "ishl", "xor", "ushr", "xor", "ishl", "xor", "mad", "mul", "sincos", "mul", "sincos", "mul", "mul", "mul", "mul", "mul", "mad", "mul", "mad", "mul", "mad", "mad", "mad", "mad", "mad", "mad", "mad", "lt", "movc", "mul", "mad", "dp3", "rsq", "mul", "mul", "mad", "mul", "mad", "mad", "ld_structured", "mad", "mad", "ishl", "xor", "ushr", "xor", "ishl", "xor", "utof", "mul", "mad", "mad", "mad", "ishl", "xor", "ushr", "xor", "ishl", "xor", "bfi", "store_structured", "store_structured", "else", "break", "endif", "iadd", "endloop", "ret"]);
12
+ const OPCODES_SM51 = Object.freeze(["if", "imul", "store_raw", "store_raw", "store_raw", "store_raw", "store_raw", "store_raw", "store_raw", "endif", "sync", "ld_raw", "ushr", "iadd", "xor", "ushr", "xor", "imul", "ushr", "xor", "imul", "ushr", "xor", "imad", "ld_raw", "ld_raw", "ld_raw", "add", "ld_raw", "ge", "mov", "mov", "mov", "loop", "uge", "breakc", "imm_atomic_iadd", "iadd", "ige", "if", "ishl", "xor", "ushr", "xor", "ishl", "xor", "utof", "mul", "mad", "dp3", "rsq", "mul", "ishl", "xor", "ushr", "xor", "ishl", "xor", "utof", "mul", "ishl", "xor", "ushr", "xor", "ishl", "xor", "utof", "ishl", "xor", "ushr", "xor", "ishl", "xor", "if", "mov", "else", "mov", "endif", "add", "mad", "mul", "sincos", "mul", "sincos", "mul", "mul", "mul", "mul", "mul", "mad", "mul", "mad", "mul", "mad", "mad", "mad", "mad", "mad", "mad", "mad", "lt", "movc", "mul", "mad", "dp3", "rsq", "mul", "mul", "mad", "mul", "mad", "mad", "ld_structured", "ld_raw", "ld_raw", "add", "mad", "mad", "ld_raw", "ld_raw", "ishl", "xor", "ushr", "xor", "ishl", "xor", "utof", "mul", "add", "mad", "ld_raw", "add", "mad", "mad", "ishl", "xor", "ushr", "xor", "ishl", "xor", "bfi", "store_structured", "store_structured", "else", "break", "endif", "iadd", "endloop", "ret"]);
13
+ const PARTICLE_EMIT_SEMANTIC_DIGESTS = Object.freeze({
14
+ 0: "34136a691e74b7b0dabda66147d71bb6d663e962e300aaddda453e26cbcd8190",
15
+ 1: "70a206cc8d2c0cbfb44ad7ce1ae96bb1c5d90787ea63b5ae6bcefd4e50917dd1"
16
+ });
17
+ function deepFreeze(value) {
18
+ if (!value || typeof value !== "object" || Object.isFrozen(value)) return value;
19
+ for (const entry of Object.values(value)) deepFreeze(entry);
20
+ return Object.freeze(value);
21
+ }
22
+ function ownData(value, key) {
23
+ const descriptor = value && typeof value === "object" ? Object.getOwnPropertyDescriptor(value, key) : null;
24
+ if (!descriptor) return {
25
+ missing: key
26
+ };
27
+ if (!Object.hasOwn(descriptor, "value")) return {
28
+ accessor: key
29
+ };
30
+ return descriptor.value;
31
+ }
32
+ function exactRecordEqual(actual, expected) {
33
+ if (Object.is(actual, expected)) return true;
34
+ if (!actual || !expected || typeof actual !== "object" || typeof expected !== "object" || Object.getPrototypeOf(actual) !== Object.getPrototypeOf(expected)) {
35
+ return false;
36
+ }
37
+ const actualKeys = Reflect.ownKeys(actual);
38
+ const expectedKeys = Reflect.ownKeys(expected);
39
+ if (actualKeys.some(key => typeof key !== "string") || expectedKeys.some(key => typeof key !== "string")) {
40
+ return false;
41
+ }
42
+ actualKeys.sort();
43
+ expectedKeys.sort();
44
+ if (actualKeys.length !== expectedKeys.length || actualKeys.some((key, index) => key !== expectedKeys[index])) {
45
+ return false;
46
+ }
47
+ return actualKeys.every(key => {
48
+ const actualDescriptor = Object.getOwnPropertyDescriptor(actual, key);
49
+ const expectedDescriptor = Object.getOwnPropertyDescriptor(expected, key);
50
+ const actualHasValue = Object.hasOwn(actualDescriptor, "value");
51
+ return actualHasValue && Object.hasOwn(expectedDescriptor, "value") && exactRecordEqual(actualDescriptor.value, expectedDescriptor.value);
52
+ });
53
+ }
54
+ function clonePlain(value) {
55
+ if (Array.isArray(value)) return value.map(clonePlain);
56
+ if (value && typeof value === "object") {
57
+ return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, clonePlain(entry)]));
58
+ }
59
+ return value;
60
+ }
61
+ function buildBlocks(instructions) {
62
+ const before = new Set(["loop", "else", "endif", "endloop", "case", "default", "endswitch"]);
63
+ const after = new Set(["if", "loop", "switch", "break", "breakc", "continue", "continuec", "ret", "retc", "discard", "else", "endif", "endloop", "case", "default", "endswitch"]);
64
+ const control = {
65
+ loop: "loop",
66
+ breakc: "loop",
67
+ break: "loop",
68
+ endloop: "loop",
69
+ if: "selection",
70
+ else: "selection",
71
+ endif: "selection",
72
+ ret: "termination"
73
+ };
74
+ const leaders = new Set([0]);
75
+ instructions.forEach((instruction, index) => {
76
+ if (before.has(instruction.opcodeName)) leaders.add(index);
77
+ if (after.has(instruction.opcodeName) && index + 1 < instructions.length) {
78
+ leaders.add(index + 1);
79
+ }
80
+ });
81
+ const starts = Array.from(leaders).sort((left, right) => left - right);
82
+ return starts.map((start, blockIndex) => {
83
+ const end = (starts[blockIndex + 1] ?? instructions.length) - 1;
84
+ return {
85
+ kind: "basic-block",
86
+ id: `block${blockIndex}`,
87
+ index: blockIndex,
88
+ startInstruction: start,
89
+ endInstruction: end,
90
+ startDxbcOffset: instructions[start].dxbcOffset,
91
+ endDxbcOffset: instructions[end].dxbcOffset,
92
+ instructionIndices: Array.from({
93
+ length: end - start + 1
94
+ }, (_, offset) => start + offset),
95
+ terminator: control[instructions[end].opcodeName] ? instructions[end].opcodeName : null
96
+ };
97
+ });
98
+ }
99
+ function analysisSnapshot(program) {
100
+ return {
101
+ blocks: program.blocks,
102
+ controlFlow: program.controlFlow,
103
+ values: program.values,
104
+ instructions: program.instructions.map(instruction => ({
105
+ dataflow: instruction.dataflow,
106
+ typeInfo: instruction.typeInfo
107
+ }))
108
+ };
109
+ }
110
+ function firstDifference(left, right, path = "$") {
111
+ if (Object.is(left, right)) return null;
112
+ if (Array.isArray(left) && Array.isArray(right)) {
113
+ if (left.length !== right.length) {
114
+ return `${path}.length (${left.length} != ${right.length})`;
115
+ }
116
+ for (let index = 0; index < left.length; index += 1) {
117
+ const difference = firstDifference(left[index], right[index], `${path}[${index}]`);
118
+ if (difference) return difference;
119
+ }
120
+ return null;
121
+ }
122
+ if (left && right && typeof left === "object" && typeof right === "object") {
123
+ const keys = Array.from(new Set([...Object.keys(left), ...Object.keys(right)])).sort();
124
+ for (const key of keys) {
125
+ const difference = firstDifference(left[key], right[key], `${path}.${key}`);
126
+ if (difference) return difference;
127
+ }
128
+ return null;
129
+ }
130
+ return `${path} (${JSON.stringify(left)} != ${JSON.stringify(right)})`;
131
+ }
132
+ function validateAnalysis(program) {
133
+ const rebuilt = clonePlain(program);
134
+ rebuilt.instructions = rebuilt.instructions.map(instruction => {
135
+ delete instruction.dataflow;
136
+ delete instruction.typeInfo;
137
+ return instruction;
138
+ });
139
+ rebuilt.blocks = buildBlocks(rebuilt.instructions);
140
+ delete rebuilt.controlFlow;
141
+ delete rebuilt.values;
142
+ buildControlFlow(rebuilt);
143
+ analyzeRegisterValues(rebuilt);
144
+ resolveRegisterFlow(rebuilt);
145
+ inferValueTypes(rebuilt);
146
+ if (JSON.stringify(analysisSnapshot(program)) !== JSON.stringify(analysisSnapshot(rebuilt))) {
147
+ const difference = firstDifference(analysisSnapshot(program), analysisSnapshot(rebuilt));
148
+ throw new Error("WGSL particle emit CFG, SSA, or type metadata is inconsistent" + (difference ? ` at ${difference}` : ""));
149
+ }
150
+ const plans = buildSelectionPlans(program, "particle emit compute");
151
+ if (plans.size !== 3 || plans.get(0)?.kind !== "selection" || plans.get(0).hasElse || plans.get(0).merges.length || plans.get(42)?.kind !== "loop" || plans.get(42).merges.length !== 2 || plans.get(42).exitMerges.length || plans.get(48)?.kind !== "selection" || !plans.get(48).hasElse || plans.get(48).merges.length) {
152
+ throw new Error("WGSL particle emit requires the exact initialization, loop, and atomic-result selection plan");
153
+ }
154
+ }
155
+
156
+ /**
157
+ * Declaration-family selector for the particle emit shader.
158
+ *
159
+ * @param {object} program CJS shader IR.
160
+ * @returns {boolean} Whether particle-emit validation owns this program.
161
+ */
162
+ function isParticleEmitComputeCandidate(program) {
163
+ if (program?.kind !== "shader-program" || program.format !== "CJS_SHADER_IR" || program.formatVersion !== 1 || program.stage !== "compute" || program.programType !== 5 || program.shaderModel?.major !== 5 || ![0, 1].includes(program.shaderModel.minor) || program.declarations?.length !== DECLARATION_OPCODES.length || DECLARATION_OPCODES.some((opcode, index) => program.declarations[index]?.opcodeName !== opcode)) {
164
+ return false;
165
+ }
166
+ const [, constants, particle, counter, dead, flattened, groupId, localId, temps, shared, group] = program.declarations;
167
+ const familyMatches = constants.data?.registerIndex === 3 && constants.data?.sizeInVec4 === 4096 && particle.data?.structureStride === 32 && counter.data?.resourceDimensionName === "buffer" && counter.data?.returnType?.returnTypeNames?.every(entry => entry === "sint") && dead.data?.structureStride === 4 && flattened.data?.operandTypeName === "input_thread_id_in_group_flattened" && groupId.data?.operandTypeName === "input_thread_group_id" && localId.data?.operandTypeName === "input_thread_id_in_group" && temps.data?.tempCount === (program.shaderModel.minor ? 11 : 14) && shared.data?.byteCount === 112 && group.data?.threadGroupX === 16 && group.data.threadGroupY === 16 && group.data.threadGroupZ === 1;
168
+ if (!familyMatches) return false;
169
+ try {
170
+ return particleEmitSemanticDigest(program) === PARTICLE_EMIT_SEMANTIC_DIGESTS[program.shaderModel.minor];
171
+ } catch {
172
+ return false;
173
+ }
174
+ }
175
+
176
+ /**
177
+ * Resolves the signed typed-UAV layout owned by the particle-emit profile.
178
+ * Admission is self-proving: the exact declaration family and semantic digest
179
+ * checked by `isParticleEmitComputeCandidate` are the whole proof, so binding
180
+ * plans and the lowerer share one identity source instead of duplicating an
181
+ * unvalidated list.
182
+ *
183
+ * @param {object} program CJS shader IR.
184
+ * @returns {object|null} Narrow lowerBindingLayout policy.
185
+ */
186
+ function particleEmitSignedAtomicLayoutPolicy(program) {
187
+ if (!isParticleEmitComputeCandidate(program)) return null;
188
+ return {
189
+ signedAtomicI32Identities: ["storage-resource:0:1"]
190
+ };
191
+ }
192
+ function validateProgram(program) {
193
+ if (!isParticleEmitComputeCandidate(program)) {
194
+ throw new Error("WGSL particle emit requires the exact declaration family");
195
+ }
196
+ const expectedOpcodes = program.shaderModel.minor === 0 ? OPCODES_SM50 : OPCODES_SM51;
197
+ if (program.instructions?.length !== expectedOpcodes.length || expectedOpcodes.some((opcode, index) => program.instructions[index]?.opcodeName !== opcode)) {
198
+ throw new Error("WGSL particle emit requires the exact backend instruction schedule");
199
+ }
200
+ if (program.shaderModel.minor === 1) {
201
+ throw new Error("WGSL particle emit SM5.1 is comparison-only; only the literal SM5.0 schedule may emit WGSL");
202
+ }
203
+ requireRefactoringAllowed(program, "particle emit compute");
204
+ const identity = {
205
+ kind: ownData(program, "kind"),
206
+ format: ownData(program, "format"),
207
+ formatVersion: ownData(program, "formatVersion"),
208
+ stage: ownData(program, "stage"),
209
+ programType: ownData(program, "programType"),
210
+ shaderModel: ownData(program, "shaderModel")
211
+ };
212
+ if (!exactRecordEqual(identity, {
213
+ kind: "shader-program",
214
+ format: "CJS_SHADER_IR",
215
+ formatVersion: 1,
216
+ stage: "compute",
217
+ programType: 5,
218
+ shaderModel: {
219
+ major: 5,
220
+ minor: 0
221
+ }
222
+ })) {
223
+ throw new Error("WGSL particle emit requires exact own SM5.0 program identity fields");
224
+ }
225
+ if (!exactRecordEqual(ownData(program, "signatures"), {
226
+ input: [],
227
+ output: [],
228
+ patch: []
229
+ }) || ownData(program, "immediateConstantBuffer") !== null || ownData(program, "constTables") !== null) {
230
+ throw new Error("WGSL particle emit requires exact dense empty signatures and null constant tables");
231
+ }
232
+ const instructions = ownData(program, "instructions");
233
+ if (!Array.isArray(instructions) || instructions.length !== 144 || instructions.some((instruction, index) => instruction?.kind !== "instruction" || !Number.isInteger(instruction.opcode) || instruction.opcodeName !== OPCODES_SM50[index])) {
234
+ throw new Error("WGSL particle emit requires exact instruction kind, numeric opcode, and opcode name fields");
235
+ }
236
+ validateAnalysis(program);
237
+ }
238
+ function validateBindings(bindings) {
239
+ const expected = [["uniform-buffer", "cb3", "var<uniform>", "array<vec4<f32>, 4096>", "uniform", 65536, null], ["storage-resource", "u0", "var<storage, read_write>", "array<u32>", "storage", 32, 32], ["storage-resource", "u1", "var<storage, read_write>", "array<atomic<i32>>", "storage", 4, null], ["storage-resource", "u2", "var<storage, read_write>", "array<u32>", "storage", 4, 4]];
240
+ if (bindings.length !== expected.length || expected.some((entry, index) => {
241
+ const binding = bindings[index];
242
+ return binding?.resourceKind !== entry[0] || binding.generatedSymbol !== entry[1] || binding.registerIndex !== [3, 0, 1, 2][index] || binding.registerSpace !== 0 || binding.rangeId !== null || binding.group !== 0 || binding.binding !== index || binding.visibility !== "compute" || binding.declaration !== entry[2] || binding.type !== entry[3] || binding.buffer?.type !== entry[4] || binding.buffer.hasDynamicOffset !== false || binding.buffer.minBindingSize !== entry[5] || (binding.structureStride ?? null) !== entry[6];
243
+ })) {
244
+ throw new Error("WGSL particle emit requires the exact cb3/u0/u1/u2 layout");
245
+ }
246
+ }
247
+ function location(instruction) {
248
+ return {
249
+ instructionIndex: instruction.index,
250
+ dxbcOffset: instruction.dxbcOffset
251
+ };
252
+ }
253
+ function expression(code, type) {
254
+ return {
255
+ code,
256
+ type
257
+ };
258
+ }
259
+ function call(instruction, code) {
260
+ return {
261
+ kind: "call",
262
+ ...location(instruction),
263
+ expression: expression(code, "void")
264
+ };
265
+ }
266
+ function assign(instruction, name, code) {
267
+ return {
268
+ kind: "value-assignment",
269
+ ...location(instruction),
270
+ name,
271
+ expression: expression(code, "u32")
272
+ };
273
+ }
274
+ function immediate(bits) {
275
+ return `0x${(bits >>> 0).toString(16).padStart(8, "0")}u`;
276
+ }
277
+ function valueWidth(operand, requested) {
278
+ if (requested) return requested;
279
+ if (operand.selected) return 1;
280
+ if (operand.swizzle) return operand.swizzle.length;
281
+ if (operand.immediateValues?.length) return operand.immediateValues.length;
282
+ return 1;
283
+ }
284
+ function vector(type, width, values) {
285
+ if (width === 1) return values[0];
286
+ return `vec${width}<${type}>(${values.join(", ")})`;
287
+ }
288
+ function rawSource(operand, requestedWidth) {
289
+ const width = valueWidth(operand, requestedWidth);
290
+ if (operand.typeName === "temp") {
291
+ const selector = operand.selected || operand.swizzle;
292
+ const components = selector ? Array.from({
293
+ length: width
294
+ }, (_, index) => selector[Math.min(index, selector.length - 1)]) : ["x", "y", "z", "w"].slice(0, width);
295
+ if (width === 1) return `r${operand.registerIndex}.${components[0]}`;
296
+ return `r${operand.registerIndex}.${components.join("")}`;
297
+ }
298
+ if (operand.typeName === "immediate32") {
299
+ const bits = operand.immediateValues.map(entry => immediate(entry.uint32));
300
+ const values = Array.from({
301
+ length: width
302
+ }, (_, index) => bits[Math.min(index, bits.length - 1)]);
303
+ return vector("u32", width, values);
304
+ }
305
+ if (operand.typeName === "input_thread_id_in_group_flattened") {
306
+ return width === 1 ? "local_index" : `vec${width}<u32>(local_index)`;
307
+ }
308
+ if (operand.typeName === "input_thread_group_id") {
309
+ const component = operand.selected || "x";
310
+ return width === 1 ? `workgroup_id.${component}` : `vec${width}<u32>(workgroup_id.${component})`;
311
+ }
312
+ if (operand.typeName === "input_thread_id_in_group") {
313
+ const component = operand.selected || "x";
314
+ return width === 1 ? `local_invocation_id.${component}` : `vec${width}<u32>(local_invocation_id.${component})`;
315
+ }
316
+ throw new Error(`WGSL particle emit cannot translate source ${operand.typeName}`);
317
+ }
318
+ function typedSource(operand, type, width) {
319
+ const raw = rawSource(operand, width);
320
+ const shape = width === 1 ? type : `vec${width}<${type}>`;
321
+ let code = type === "u32" ? raw : `bitcast<${shape}>(${raw})`;
322
+ if (operand.modifierName === "neg") code = `(-${code})`;else if (operand.modifierName === "abs") code = `abs(${code})`;
323
+ return code;
324
+ }
325
+ function bitsCode(code, type, width) {
326
+ if (type === "u32" || type === "bitpattern32") return code;
327
+ const shape = width === 1 ? "u32" : `vec${width}<u32>`;
328
+ return `bitcast<${shape}>(${code})`;
329
+ }
330
+ function destination(instruction, operandIndex, code, type) {
331
+ const operand = instruction.operands[operandIndex];
332
+ const mask = operand.mask;
333
+ const width = mask.length;
334
+ return assign(instruction, `r${operand.registerIndex}.${mask}`, bitsCode(code, type, width));
335
+ }
336
+ function comparison(instruction, type, operator) {
337
+ const destinationOperand = instruction.operands[0];
338
+ const width = destinationOperand.mask.length;
339
+ const left = typedSource(instruction.operands[1], type, width);
340
+ const right = typedSource(instruction.operands[2], type, width);
341
+ const zero = width === 1 ? "0u" : `vec${width}<u32>(0u)`;
342
+ const ones = width === 1 ? "0xffffffffu" : `vec${width}<u32>(0xffffffffu)`;
343
+ return destination(instruction, 0, `select(${zero}, ${ones}, ${left} ${operator} ${right})`, "u32");
344
+ }
345
+ function translateArithmetic(instruction) {
346
+ const op = instruction.opcodeName;
347
+ const destinationIndex = op === "imul" ? 1 : 0;
348
+ const destinationOperand = instruction.operands[destinationIndex];
349
+ const width = destinationOperand.mask.length;
350
+ const sourceStart = op === "imul" ? 2 : 1;
351
+ if (op === "mov") {
352
+ return [destination(instruction, 0, rawSource(instruction.operands[1], width), "bitpattern32")];
353
+ }
354
+ if (op === "xor") {
355
+ return [destination(instruction, 0, `(${typedSource(instruction.operands[1], "u32", width)} ^ ` + `${typedSource(instruction.operands[2], "u32", width)})`, "u32")];
356
+ }
357
+ if (op === "ushr") {
358
+ return [destination(instruction, 0, `(${typedSource(instruction.operands[1], "u32", width)} >> ` + `${typedSource(instruction.operands[2], "u32", width)})`, "u32")];
359
+ }
360
+ if (op === "ishl") {
361
+ return [destination(instruction, 0, `(${typedSource(instruction.operands[1], "i32", width)} << ` + `${typedSource(instruction.operands[2], "u32", width)})`, "i32")];
362
+ }
363
+ if (op === "iadd" || op === "imul" || op === "imad") {
364
+ const sources = instruction.operands.slice(sourceStart).map(operand => typedSource(operand, "i32", width));
365
+ const code = op === "imad" ? `((${sources[0]} * ${sources[1]}) + ${sources[2]})` : `(${sources[0]} ${op === "iadd" ? "+" : "*"} ${sources[1]})`;
366
+ return [destination(instruction, destinationIndex, code, "i32")];
367
+ }
368
+ if (op === "utof") {
369
+ const type = width === 1 ? "f32" : `vec${width}<f32>`;
370
+ return [destination(instruction, 0, `${type}(${typedSource(instruction.operands[1], "u32", width)})`, "f32")];
371
+ }
372
+ if (op === "uge") return [comparison(instruction, "u32", ">=")];
373
+ if (op === "ige") return [comparison(instruction, "i32", ">=")];
374
+ if (op === "ge") return [comparison(instruction, "f32", ">=")];
375
+ if (op === "lt") return [comparison(instruction, "f32", "<")];
376
+ if (["add", "mul", "mad"].includes(op)) {
377
+ const sources = instruction.operands.slice(1).map(operand => typedSource(operand, "f32", width));
378
+ const code = op === "mad" ? `((${sources[0]} * ${sources[1]}) + ${sources[2]})` : `(${sources[0]} ${op === "add" ? "+" : "*"} ${sources[1]})`;
379
+ return [destination(instruction, 0, code, "f32")];
380
+ }
381
+ if (op === "dp3") {
382
+ const code = `dot(${typedSource(instruction.operands[1], "f32", 3)}, ${typedSource(instruction.operands[2], "f32", 3)})`;
383
+ return [destination(instruction, 0, code, "f32")];
384
+ }
385
+ if (op === "rsq") {
386
+ return [destination(instruction, 0, `inverseSqrt(${typedSource(instruction.operands[1], "f32", width)})`, "f32")];
387
+ }
388
+ if (op === "movc") {
389
+ const condition = typedSource(instruction.operands[1], "u32", width);
390
+ const zero = width === 1 ? "0u" : `vec${width}<u32>(0u)`;
391
+ const whenTrue = typedSource(instruction.operands[2], "f32", width);
392
+ const whenFalse = typedSource(instruction.operands[3], "f32", width);
393
+ return [destination(instruction, 0, `select(${whenFalse}, ${whenTrue}, ${condition} != ${zero})`, "f32")];
394
+ }
395
+ if (op === "sincos") {
396
+ const width = instruction.operands[0].mask.length;
397
+ const source = typedSource(instruction.operands[2], "f32", width);
398
+ return [destination(instruction, 0, `sin(${source})`, "f32"), destination(instruction, 1, `cos(${source})`, "f32")];
399
+ }
400
+ throw new Error(`WGSL particle emit cannot translate ${op}`);
401
+ }
402
+ function translateRawLoad(instruction) {
403
+ const destinationOperand = instruction.operands[0];
404
+ const width = destinationOperand.mask.length;
405
+ const byteOffset = instruction.operands[1].immediateValues[0].uint32;
406
+ const firstWord = byteOffset / 4;
407
+ const words = Array.from({
408
+ length: width
409
+ }, (_, index) => `g0[${firstWord + index}u]`);
410
+ return [destination(instruction, 0, vector("u32", width, words), "u32")];
411
+ }
412
+ function translateInstruction(program, index, bindings) {
413
+ const instruction = program.instructions[index];
414
+ if (instruction.opcodeName === "ld_raw") {
415
+ return translateRawLoad(instruction);
416
+ }
417
+ if (instruction.opcodeName === "imm_atomic_iadd") {
418
+ return [destination(instruction, 0, `atomicAdd(&${bindings[2].generatedSymbol}[0u], -1i)`, "i32")];
419
+ }
420
+ if (instruction.opcodeName === "ld_structured") {
421
+ const dead = bindings[3].generatedSymbol;
422
+ return [{
423
+ kind: "let",
424
+ ...location(instruction),
425
+ name: "dead_length",
426
+ type: "u32",
427
+ expression: expression(`arrayLength(&${dead})`, "u32")
428
+ }, {
429
+ kind: "let",
430
+ ...location(instruction),
431
+ name: "dead_safe_index",
432
+ type: "u32",
433
+ expression: expression("min(r7.y, dead_length - 1u)", "u32")
434
+ }, assign(instruction, "r7.y", `select(0u, ${dead}[dead_safe_index], r7.y < dead_length)`)];
435
+ }
436
+ if (instruction.opcodeName === "bfi") {
437
+ return [assign(instruction, "r9.w", "((r7.x & 0x0000ffffu) | (r1.x << 16u))")];
438
+ }
439
+ return translateArithmetic(instruction);
440
+ }
441
+ function initializeShared(program, constants) {
442
+ const first = program.instructions[0];
443
+ const body = [translateInstruction(program, 1, [])[0]];
444
+ for (let row = 1; row <= 7; row += 1) {
445
+ const instruction = program.instructions[row + 1];
446
+ body.push({
447
+ kind: "let",
448
+ ...location(instruction),
449
+ name: `cb_row_${row}`,
450
+ type: "u32",
451
+ expression: expression(`(r0.x + ${row}u)`, "u32")
452
+ });
453
+ body.push({
454
+ kind: "let",
455
+ ...location(instruction),
456
+ name: `cb_value_${row}`,
457
+ type: "vec4<f32>",
458
+ expression: expression(`select(vec4<f32>(), ${constants}[min(cb_row_${row}, 4095u)], cb_row_${row} < 4096u)`, "vec4<f32>")
459
+ });
460
+ const components = row === 7 ? ["x"] : ["x", "y", "z", "w"];
461
+ const firstWord = (row - 1) * 4;
462
+ components.forEach((component, index) => {
463
+ body.push(assign(instruction, `g0[${firstWord + index}u]`, `bitcast<u32>(cb_value_${row}.${component})`));
464
+ });
465
+ }
466
+ return {
467
+ kind: "if",
468
+ ...location(first),
469
+ condition: expression("local_index == 0u", "bool"),
470
+ statements: body
471
+ };
472
+ }
473
+ function recordStores(program, particle) {
474
+ const first = program.instructions[136];
475
+ const second = program.instructions[137];
476
+ const words = [...["x", "y", "z", "w"].map((component, index) => assign(first, `u0[(record_word_base + ${index}u)]`, `r8.${component}`)), ...["x", "y", "z", "w"].map((component, index) => assign(second, `u0[(record_word_base + ${index + 4}u)]`, `r9.${component}`))];
477
+ return {
478
+ kind: "if",
479
+ ...location(first),
480
+ condition: expression(`r7.y < (arrayLength(&${particle}) / 8u)`, "bool"),
481
+ statements: [{
482
+ kind: "let",
483
+ ...location(first),
484
+ name: "record_word_base",
485
+ type: "u32",
486
+ expression: expression("(r7.y * 8u)", "u32")
487
+ }, ...words]
488
+ };
489
+ }
490
+ function lowerBody(program, bindings) {
491
+ const statements = [...Array.from({
492
+ length: 14
493
+ }, (_, index) => ({
494
+ kind: "var",
495
+ name: `r${index}`,
496
+ type: "vec4<u32>",
497
+ expression: expression("vec4<u32>(0u)", "vec4<u32>")
498
+ })), {
499
+ kind: "let",
500
+ name: "local_index",
501
+ type: "u32",
502
+ expression: expression("((local_invocation_id.y * 16u) + local_invocation_id.x)", "u32")
503
+ }, initializeShared(program, bindings[0].generatedSymbol), call(program.instructions[10], "workgroupBarrier()")];
504
+ for (let index = 11; index <= 41; index += 1) {
505
+ statements.push(...translateInstruction(program, index, bindings));
506
+ }
507
+ const loopStatements = [...translateInstruction(program, 43, bindings), {
508
+ kind: "if",
509
+ ...location(program.instructions[44]),
510
+ condition: expression("r7.y != 0u", "bool"),
511
+ statements: [{
512
+ kind: "break",
513
+ ...location(program.instructions[44])
514
+ }]
515
+ }, ...translateInstruction(program, 45, bindings), ...translateInstruction(program, 46, bindings), ...translateInstruction(program, 47, bindings)];
516
+ const successful = [];
517
+ for (let index = 49; index <= 135; index += 1) {
518
+ successful.push(...translateInstruction(program, index, bindings));
519
+ }
520
+ successful.push(recordStores(program, bindings[1].generatedSymbol));
521
+ loopStatements.push({
522
+ kind: "if",
523
+ ...location(program.instructions[48]),
524
+ condition: expression("r7.z != 0u", "bool"),
525
+ statements: successful,
526
+ elseStatements: [{
527
+ kind: "break",
528
+ ...location(program.instructions[139])
529
+ }]
530
+ });
531
+ loopStatements.push(...translateInstruction(program, 141, bindings));
532
+ statements.push({
533
+ kind: "loop",
534
+ ...location(program.instructions[42]),
535
+ statements: loopStatements
536
+ });
537
+ statements.push({
538
+ kind: "return",
539
+ ...location(program.instructions[143])
540
+ });
541
+ return statements;
542
+ }
543
+
544
+ /**
545
+ * Lowers the one audited SM5.0 particle-emit schedule.
546
+ *
547
+ * @param {object} program Frozen CJS shader IR.
548
+ * @param {object} [options] Optional exact compute binding plan.
549
+ * @returns {object} Frozen typed compute program.
550
+ */
551
+ function lowerParticleEmitComputeProgram(program, options = {}) {
552
+ validateProgram(program);
553
+ const bindings = lowerBindingLayout(program, options.bindingPlan ?? null, particleEmitSignedAtomicLayoutPolicy(program));
554
+ validateBindings(bindings);
555
+ return deepFreeze({
556
+ kind: "typed-shader-program",
557
+ format: "CJS_TYPED_SHADER",
558
+ formatVersion: 1,
559
+ source: program.source,
560
+ stage: "compute",
561
+ entryPoint: "main",
562
+ builtinInputs: [{
563
+ builtin: "workgroup_id",
564
+ name: "workgroup_id",
565
+ type: "vec3<u32>"
566
+ }, {
567
+ builtin: "local_invocation_id",
568
+ name: "local_invocation_id",
569
+ type: "vec3<u32>"
570
+ }],
571
+ threadGroupSize: [16, 16, 1],
572
+ workgroupVariables: [{
573
+ name: "g0",
574
+ elementType: "u32",
575
+ elementCount: 28
576
+ }],
577
+ bindings,
578
+ statements: lowerBody(program, bindings)
579
+ });
580
+ }
581
+
582
+ export { isParticleEmitComputeCandidate, lowerParticleEmitComputeProgram, particleEmitSignedAtomicLayoutPolicy };
583
+ //# sourceMappingURL=lowerParticleEmitComputeProgram.js.map