@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,789 @@
1
+ import { EFFECT_INFO_VERSION } from './effectPackageValidation.js';
2
+ import { CjsHlslFormat } from '../../hlsl/CjsHlslFormat.js';
3
+ import { HlslEffectBindingManifest } from '../../hlsl/core/tr2/shader/HlslEffectBindingManifest.js';
4
+ import { HlslRenderContextEnum, hlslShaderStageName } from '../../hlsl/core/tr2/HlslRenderContextEnum.js';
5
+ import { buildEffectPermutationGraph, EFFECT_PERMUTATION_GRAPH_VERSION, EFFECT_PERMUTATION_GRAPH_FORMAT, EFFECT_PERMUTATION_GRAPH_CHUNK } from '../../../format/effect/effectPermutationGraph.js';
6
+ import { buildCompleteEffectReflection, EFFECT_REFLECTION_CHUNK, EFFECT_REFLECTION_BLOB_CHUNK } from '../../../format/effect/effectReflectionPackage.js';
7
+ import { buildPackage, inspectWithValues, emitGlslWithOptions } from './helpers.js';
8
+ import { sha256Utf8, sha256Bytes } from '../../../format/effect/sha256.js';
9
+
10
+ const PACKAGE_VERSION = "0.2.0";
11
+
12
+ /**
13
+ * Builds a complete CEWG package from compiled Tr2 effect bytes.
14
+ *
15
+ * This browser-safe path owns whole-effect selection, stage translation,
16
+ * package assembly, and structural qualification. Filesystem and native-tool
17
+ * concerns remain in Node callers.
18
+ *
19
+ * @param {Uint8Array|ArrayBuffer|ArrayBufferView} input Compiled effect bytes.
20
+ * @param {object} [options] Selection, provenance, and emitter policy.
21
+ * @returns {object} Package bytes plus inspection and qualification records.
22
+ */
23
+ function buildEffectPackage(input, options = {}) {
24
+ const values = normalizeOptions(input, options);
25
+ const effectRes = CjsHlslFormat.read(values.sourceBytes, {
26
+ emit: CjsHlslFormat.OUTPUT_RAW,
27
+ source: values.source
28
+ });
29
+ if (!effectRes.IsGood()) {
30
+ throw effectRes.loadError || new Error("Tr2EffectRes failed to load input");
31
+ }
32
+ const sourceIdentity = normalizeSourceIdentity(values);
33
+ // One INFO version means one contract, and that contract requires complete
34
+ // source reflection, which only version-15 input can supply.
35
+ if (effectRes.m_version !== 15) {
36
+ throw new Error("Effect package requires a version-15 compiled effect, got version " + (effectRes.m_version ?? "unknown"));
37
+ }
38
+ const permutationGraph = buildEffectPermutationGraph(effectRes);
39
+ const reflectionPackage = effectRes.m_version === 15 ? buildCompleteEffectReflection(effectRes, permutationGraph, {
40
+ sourceIdentity,
41
+ sourcePath: values.source
42
+ }) : null;
43
+ const variants = buildExportVariants(effectRes, values.allPermutations);
44
+ const bodyMap = new Map();
45
+ const stageMap = new Map();
46
+ const shaderMap = new Map();
47
+ for (const variant of variants) {
48
+ if (bodyMap.has(variant.bodyKey)) {
49
+ continue;
50
+ }
51
+ const shader = effectRes.GetShader(toShaderOptions(variant.options));
52
+ if (!shader) {
53
+ bodyMap.set(variant.bodyKey, {
54
+ key: variant.bodyKey,
55
+ bodyOffset: variant.bodyOffset,
56
+ bodySize: variant.bodySize,
57
+ firstVariantKey: variant.key,
58
+ error: "Tr2EffectRes.GetShader returned null",
59
+ manifest: null,
60
+ stages: []
61
+ });
62
+ continue;
63
+ }
64
+ const effectDescription = shader.GetEffectDescription();
65
+ const manifest = HlslEffectBindingManifest.fromEffectDescription(effectDescription);
66
+ const collection = collectStages(effectDescription, values.selection);
67
+ const body = {
68
+ key: variant.bodyKey,
69
+ bodyOffset: variant.bodyOffset,
70
+ bodySize: variant.bodySize,
71
+ firstVariantKey: variant.key,
72
+ error: collection.errors.length ? collection.errors.join("; ") : null,
73
+ manifest: manifest.toJSON(),
74
+ stages: []
75
+ };
76
+ for (const stage of collection.stages) {
77
+ const stageKey = `${variant.bodyKey}.${stage.key}`;
78
+ const shaderKey = `shader_${stageKey}`;
79
+ const contract = buildStageContract(stage);
80
+ const stageRecord = {
81
+ key: stageKey,
82
+ bodyKey: variant.bodyKey,
83
+ localKey: stage.key,
84
+ techniqueName: stage.techniqueName,
85
+ passIndex: stage.passIndex,
86
+ stageType: stage.stageType,
87
+ stageName: stage.stageName,
88
+ shaderHandle: stage.shaderHandle,
89
+ shaderSize: stage.bytecode.shaderSize,
90
+ stringTableOffset: stage.bytecode.stringTableOffset,
91
+ shaderKey,
92
+ contract
93
+ };
94
+ stageMap.set(stageKey, stageRecord);
95
+ body.stages.push(stageKey);
96
+ shaderMap.set(shaderKey, {
97
+ key: shaderKey,
98
+ firstStageKey: stageKey,
99
+ firstBodyKey: variant.bodyKey,
100
+ stageName: stage.stageName,
101
+ shaderSize: stage.bytecode.shaderSize,
102
+ stringTableOffset: stage.bytecode.stringTableOffset,
103
+ bytes: stage.bytecode.bytes,
104
+ contracts: [{
105
+ stageKey,
106
+ techniqueName: stage.techniqueName,
107
+ passIndex: stage.passIndex,
108
+ stageName: stage.stageName,
109
+ contract
110
+ }]
111
+ });
112
+ }
113
+ bodyMap.set(variant.bodyKey, body);
114
+ }
115
+ translateStages(shaderMap, stageMap, values);
116
+ const bodies = Array.from(bodyMap.values());
117
+ const stages = Array.from(stageMap.values());
118
+ const translatedShaders = Array.from(shaderMap.values()).map(record => {
119
+ const {
120
+ bytes,
121
+ emit,
122
+ ...output
123
+ } = record;
124
+ output.primaryContract = mergeShaderContracts(output.contracts);
125
+ return output;
126
+ });
127
+ const failedShaders = translatedShaders.filter(record => !record.hlsl2webgl?.ok && !record.excluded);
128
+ const excludedShaders = translatedShaders.filter(record => record.excluded);
129
+ const failedBodies = bodies.filter(body => body.error);
130
+ const rasterCompleteness = inspectRasterCompleteness(stages, translatedShaders);
131
+ const availableShaderCount = translatedShaders.filter(record => record.hlsl2webgl?.ok && record.source).length;
132
+ const info = {
133
+ format: "CEWG",
134
+ formatVersion: EFFECT_INFO_VERSION,
135
+ packageKind: values.allPermutations ? "tr2-effect-webgl-permutations" : "tr2-effect-webgl",
136
+ targetBackend: "webgl",
137
+ backendPackage: "@carbonenginejs/format-webgl",
138
+ backendPackageVersion: PACKAGE_VERSION,
139
+ generatedAt: values.generatedAt,
140
+ sourcePath: values.source,
141
+ outputPath: values.outputPath,
142
+ sourceByteLength: sourceIdentity.byteLength,
143
+ sourceMd5: sourceIdentity.md5,
144
+ sourceSha256: sourceIdentity.sha256,
145
+ sourceIdentity,
146
+ translator: "dxbc-js-emitter",
147
+ translatorVersion: PACKAGE_VERSION,
148
+ language: "es300",
149
+ flags: null,
150
+ selection: values.selection,
151
+ permutationMode: values.allPermutations ? "all" : "selected",
152
+ defaultPermutationIndex: defaultPermutationIndex(effectRes.m_permutations),
153
+ sourceEffectVersion: effectRes.m_version,
154
+ ...(reflectionPackage ? {
155
+ sourceBodyCoverage: "all-unique",
156
+ backendBodyCoverage: values.allPermutations ? "all" : "selected",
157
+ backendProgramCoverage: selectionCoversWholeEffect(values.selection) ? "all-stages" : "filtered"
158
+ } : {}),
159
+ permutationCount: variants.length,
160
+ uniqueBodyCount: bodies.length,
161
+ sourcePermutationCount: permutationGraph.variants.length,
162
+ sourceUniqueBodyCount: permutationGraph.bodies.length,
163
+ permutationGraph: {
164
+ chunk: EFFECT_PERMUTATION_GRAPH_CHUNK,
165
+ format: EFFECT_PERMUTATION_GRAPH_FORMAT,
166
+ formatVersion: EFFECT_PERMUTATION_GRAPH_VERSION,
167
+ sha256: sha256Utf8(`${JSON.stringify(permutationGraph)}\n`),
168
+ permutationCount: permutationGraph.variants.length,
169
+ uniqueBodyCount: permutationGraph.bodies.length
170
+ },
171
+ ...(reflectionPackage ? {
172
+ effectReflection: reflectionPackage.pointer
173
+ } : {}),
174
+ bodyStageCount: stages.length,
175
+ uniqueShaderCount: translatedShaders.length,
176
+ translatedShaderCount: translatedShaders.length - failedShaders.length - excludedShaders.length,
177
+ excludedShaderCount: excludedShaders.length,
178
+ failedShaderCount: failedShaders.length,
179
+ failedBodyCount: failedBodies.length,
180
+ expectedRasterPassCount: rasterCompleteness.expectedPassCount,
181
+ completeRasterPassCount: rasterCompleteness.completePassCount,
182
+ incompleteRasterPassCount: rasterCompleteness.incompletePasses.length,
183
+ availableShaderCount,
184
+ allowFailures: values.allowFailures,
185
+ completeness: {
186
+ packageValid: true,
187
+ sourceComplete: reflectionPackage !== null,
188
+ backendComplete: false,
189
+ runtimeComplete: false
190
+ }
191
+ };
192
+ const metadata = {
193
+ generatedAt: values.generatedAt,
194
+ sourcePath: values.source,
195
+ effectResource: effectRes.toJSON(),
196
+ permutations: effectRes.GetPermutationDescription(),
197
+ variants,
198
+ bodies: bodies.map(body => ({
199
+ key: body.key,
200
+ bodyOffset: body.bodyOffset,
201
+ bodySize: body.bodySize,
202
+ firstVariantKey: body.firstVariantKey,
203
+ error: body.error,
204
+ manifest: body.manifest
205
+ }))
206
+ };
207
+ const glsl = {
208
+ format: "CEWG_GLSL_SET",
209
+ formatVersion: 1,
210
+ language: "es300",
211
+ permutationMode: info.permutationMode,
212
+ selection: values.selection,
213
+ variants: variants.map(variant => ({
214
+ key: variant.key,
215
+ permutationIndex: variant.permutationIndex,
216
+ bodyKey: variant.bodyKey
217
+ })),
218
+ bodies: bodies.map(body => ({
219
+ key: body.key,
220
+ error: body.error,
221
+ stages: body.stages
222
+ })),
223
+ stages,
224
+ shaders: translatedShaders
225
+ };
226
+ const qualification = qualifyEffectPackage({
227
+ info,
228
+ metadata,
229
+ glsl,
230
+ failedShaders,
231
+ excludedShaders,
232
+ failedBodies,
233
+ rasterCompleteness,
234
+ availableShaderCount
235
+ });
236
+ if (!qualification.ok && !values.allowFailures) {
237
+ throw new Error(`CEWG target is incomplete; output was not built. ${qualification.errors.join("; ")}`);
238
+ }
239
+ const chunks = [["INFO", info], ["META", metadata], [EFFECT_PERMUTATION_GRAPH_CHUNK, permutationGraph], ...(reflectionPackage ? [[EFFECT_REFLECTION_CHUNK, reflectionPackage.reflection], [EFFECT_REFLECTION_BLOB_CHUNK, reflectionPackage.blobBytes]] : []), ["GLSL", glsl]];
240
+ if (values.includeSourceEffect) {
241
+ chunks.push(["TR2E", values.sourceBytes]);
242
+ }
243
+ const bytes = buildPackage(chunks);
244
+ const inspection = inspectWithValues(bytes, {
245
+ source: values.source
246
+ });
247
+ return Object.freeze({
248
+ bytes,
249
+ info: Object.freeze(info),
250
+ metadata: Object.freeze(metadata),
251
+ permutationGraph,
252
+ reflection: reflectionPackage?.reflection ?? null,
253
+ reflectionBlobs: reflectionPackage?.blobBytes ?? null,
254
+ glsl: Object.freeze(glsl),
255
+ inspection: Object.freeze(inspection),
256
+ qualification: Object.freeze(qualification)
257
+ });
258
+ }
259
+ function normalizeOptions(input, options) {
260
+ if (!options || typeof options !== "object" || Array.isArray(options)) {
261
+ throw new TypeError("CEWG effect options must be an object");
262
+ }
263
+ const sourceBytes = toBytes(input);
264
+ const source = String(options.source ?? "memory").trim() || "memory";
265
+ const selection = Object.freeze({
266
+ technique: options.technique === undefined || options.technique === null ? null : String(options.technique),
267
+ pass: options.pass === undefined || options.pass === null ? null : Number(options.pass),
268
+ stage: options.stage === undefined || options.stage === null ? null : String(options.stage).toLowerCase()
269
+ });
270
+ if (selection.pass !== null && (!Number.isSafeInteger(selection.pass) || selection.pass < 0)) {
271
+ throw new TypeError("CEWG effect pass must be a non-negative integer or null");
272
+ }
273
+ if (selection.stage !== null && !["vertex", "pixel", "compute"].includes(selection.stage)) {
274
+ throw new TypeError(`Unsupported CEWG effect stage: ${selection.stage}`);
275
+ }
276
+ if (options.emitterOptions !== undefined && (!options.emitterOptions || typeof options.emitterOptions !== "object" || Array.isArray(options.emitterOptions))) {
277
+ throw new TypeError("CEWG emitterOptions must be an object");
278
+ }
279
+ return {
280
+ sourceBytes,
281
+ source,
282
+ outputPath: normalizeOptionalString(options.outputPath, "CEWG outputPath"),
283
+ sourceIdentity: options.sourceIdentity ?? null,
284
+ generatedAt: options.generatedAt === undefined || options.generatedAt === null ? null : new Date(options.generatedAt).toISOString(),
285
+ allPermutations: options.allPermutations !== false,
286
+ allowFailures: options.allowFailures === true,
287
+ includeSourceEffect: options.includeSourceEffect === true,
288
+ selection,
289
+ emitterOptions: {
290
+ ...(options.emitterOptions ?? {})
291
+ }
292
+ };
293
+ }
294
+ function normalizeOptionalString(value, name) {
295
+ if (value === undefined || value === null) {
296
+ return null;
297
+ }
298
+ const result = String(value).trim();
299
+ if (!result) {
300
+ throw new TypeError(`${name} must be a non-empty string or null`);
301
+ }
302
+ return result;
303
+ }
304
+ function selectionCoversWholeEffect(selection) {
305
+ return selection.technique === null && selection.pass === null && selection.stage === null;
306
+ }
307
+ function toBytes(input) {
308
+ if (input instanceof Uint8Array) {
309
+ return input;
310
+ }
311
+ if (input instanceof ArrayBuffer) {
312
+ return new Uint8Array(input);
313
+ }
314
+ if (ArrayBuffer.isView(input)) {
315
+ return new Uint8Array(input.buffer, input.byteOffset, input.byteLength);
316
+ }
317
+ throw new TypeError("CEWG effect input must be Uint8Array, ArrayBuffer, or ArrayBufferView bytes");
318
+ }
319
+ function defaultPermutationIndex(permutations) {
320
+ let multiplier = 1;
321
+ let index = 0;
322
+ for (const permutation of permutations) {
323
+ index += (permutation.defaultOption || 0) * multiplier;
324
+ multiplier *= permutation.options.length || 1;
325
+ }
326
+ return index;
327
+ }
328
+ function bodyKey(record) {
329
+ return `body_${record.offset}_${record.size}`;
330
+ }
331
+ function decodePermutationOptions(permutations, permutationIndex) {
332
+ let remaining = permutationIndex;
333
+ return permutations.map(permutation => {
334
+ const optionCount = permutation.options.length || 1;
335
+ const optionIndex = optionCount ? remaining % optionCount : 0;
336
+ remaining = Math.floor(remaining / optionCount);
337
+ return {
338
+ name: permutation.name,
339
+ value: permutation.options[optionIndex] || "",
340
+ optionIndex,
341
+ defaultOption: permutation.defaultOption
342
+ };
343
+ });
344
+ }
345
+ function toShaderOptions(options) {
346
+ return options.map(option => ({
347
+ name: option.name,
348
+ value: option.value
349
+ }));
350
+ }
351
+ function buildExportVariants(effectRes, allPermutations) {
352
+ if (allPermutations) {
353
+ return effectRes.m_offsets.map((record, variantIndex) => {
354
+ const permutationIndex = Number.isInteger(record.index) ? record.index : variantIndex;
355
+ return {
356
+ key: `variant_${permutationIndex}`,
357
+ variantIndex,
358
+ permutationIndex,
359
+ tableIndex: variantIndex,
360
+ bodyKey: bodyKey(record),
361
+ bodyOffset: record.offset,
362
+ bodySize: record.size,
363
+ options: decodePermutationOptions(effectRes.m_permutations, permutationIndex),
364
+ tableIndexMatchesPermutationIndex: variantIndex === permutationIndex
365
+ };
366
+ });
367
+ }
368
+ const permutationIndex = defaultPermutationIndex(effectRes.m_permutations);
369
+ const record = effectRes.m_offsets[permutationIndex];
370
+ if (!record) {
371
+ throw new Error(`Default permutation index ${permutationIndex} is not present`);
372
+ }
373
+ return [{
374
+ key: `variant_${permutationIndex}`,
375
+ variantIndex: permutationIndex,
376
+ permutationIndex,
377
+ tableIndex: permutationIndex,
378
+ bodyKey: bodyKey(record),
379
+ bodyOffset: record.offset,
380
+ bodySize: record.size,
381
+ options: decodePermutationOptions(effectRes.m_permutations, permutationIndex),
382
+ tableIndexMatchesPermutationIndex: Number.isInteger(record.index) ? record.index === permutationIndex : true
383
+ }];
384
+ }
385
+ function collectStages(effectDescription, selection) {
386
+ const stages = [];
387
+ const errors = [];
388
+ for (const technique of effectDescription.techniques ?? []) {
389
+ if (selection.technique && technique.name !== selection.technique) {
390
+ continue;
391
+ }
392
+ if (!selection.stage && !Number.isInteger(selection.pass) && technique.passes.length === 0) {
393
+ errors.push(`${technique.name} declares no passes`);
394
+ }
395
+ for (let passIndex = 0; passIndex < technique.passes.length; passIndex++) {
396
+ if (Number.isInteger(selection.pass) && passIndex !== selection.pass) {
397
+ continue;
398
+ }
399
+ const pass = technique.passes[passIndex];
400
+ let declaredStageCount = 0;
401
+ for (let stageType = 0; stageType < HlslRenderContextEnum.SHADER_TYPE_COUNT; stageType++) {
402
+ const stageInput = pass.stageInputs[stageType];
403
+ if (!stageInput?.m_exists) {
404
+ continue;
405
+ }
406
+ declaredStageCount++;
407
+ const stageName = hlslShaderStageName(stageType);
408
+ if (selection.stage && stageName !== selection.stage) {
409
+ continue;
410
+ }
411
+ if (!stageInput.cjsShaderBytecode) {
412
+ errors.push(`${technique.name}.pass${passIndex}.${stageName} declares shader handle ` + `${stageInput.m_shader ?? "unknown"} but has no shader bytecode`);
413
+ continue;
414
+ }
415
+ stages.push({
416
+ key: `${technique.name}.pass${passIndex}.${stageName}`,
417
+ techniqueName: technique.name,
418
+ passIndex,
419
+ stageType,
420
+ stageName,
421
+ shaderHandle: stageInput.m_shader,
422
+ bytecode: stageInput.cjsShaderBytecode,
423
+ pipelineInputs: cloneJson(stageInput.signature?.pipelineInputs ?? []),
424
+ registers: cloneJson(stageInput.signature?.registers ?? []),
425
+ resources: mapToJson(stageInput.resources),
426
+ samplers: mapToJson(stageInput.samplers),
427
+ uavs: mapToJson(stageInput.uavs),
428
+ constants: cloneJson(stageInput.constants ?? [])
429
+ });
430
+ }
431
+ if (!selection.stage && declaredStageCount === 0) {
432
+ errors.push(`${technique.name}.pass${passIndex} declares no shader stages`);
433
+ }
434
+ }
435
+ }
436
+ return {
437
+ stages,
438
+ errors
439
+ };
440
+ }
441
+ function translateStages(shaderMap, stageMap, values) {
442
+ const emitInto = (record, pairVaryings) => {
443
+ try {
444
+ const result = emitGlslWithOptions(record.bytes, {
445
+ ...values.emitterOptions,
446
+ source: `${values.source}#${record.firstStageKey}`,
447
+ ...(pairVaryings?.length ? {
448
+ pairVaryings
449
+ } : {})
450
+ });
451
+ const stageInterface = normalizeBitangentStageInterface(result, record);
452
+ record.emit = {
453
+ ...result,
454
+ source: stageInterface.source,
455
+ inputs: stageInterface.inputs
456
+ };
457
+ record.source = stageInterface.source;
458
+ record.bindings = result.bindings;
459
+ record.stageInputs = stageInterface.inputs;
460
+ record.stageOutputs = result.outputs;
461
+ record.emitWarnings = result.warnings;
462
+ record.translator = "dxbc-js-emitter";
463
+ record.hlsl2webgl = {
464
+ ok: true,
465
+ mode: "js-emitter"
466
+ };
467
+ if (result.stageName === "compute") {
468
+ record.computeFragment = result.computeFragment;
469
+ }
470
+ const issue = validateStageSourceShape(record);
471
+ if (issue) {
472
+ record.hlsl2webgl = {
473
+ ok: false,
474
+ validationError: issue
475
+ };
476
+ record.source = null;
477
+ }
478
+ } catch (error) {
479
+ const message = error?.message || String(error);
480
+ record.hlsl2webgl = {
481
+ ok: false,
482
+ error: message,
483
+ details: error?.details ?? null
484
+ };
485
+ if (/not supported|No GLSL lowering|unimplementable/iu.test(message)) {
486
+ record.excluded = {
487
+ reason: message,
488
+ ...(error?.details?.opcodeName ? {
489
+ opcodeName: error.details.opcodeName
490
+ } : {}),
491
+ ...(error?.details?.dimensionName ? {
492
+ dimensionName: error.details.dimensionName
493
+ } : {})
494
+ };
495
+ }
496
+ }
497
+ };
498
+ for (const record of shaderMap.values()) {
499
+ if (record.stageName !== "vertex") {
500
+ emitInto(record, null);
501
+ }
502
+ }
503
+ const pixelVaryingsByPass = new Map();
504
+ for (const stage of stageMap.values()) {
505
+ if (stage.stageName !== "pixel") {
506
+ continue;
507
+ }
508
+ const record = shaderMap.get(stage.shaderKey);
509
+ if (!record?.emit) {
510
+ continue;
511
+ }
512
+ pixelVaryingsByPass.set(`${stage.bodyKey}|${stage.techniqueName}|${stage.passIndex}`, record.emit.inputs.filter(input => typeof input.name === "string" && input.name.startsWith("vs_r")).map(input => input.register).sort((left, right) => left - right));
513
+ }
514
+ for (const stage of stageMap.values()) {
515
+ if (stage.stageName !== "vertex") {
516
+ continue;
517
+ }
518
+ const record = shaderMap.get(stage.shaderKey);
519
+ const varyings = pixelVaryingsByPass.get(`${stage.bodyKey}|${stage.techniqueName}|${stage.passIndex}`) ?? [];
520
+ if (record) {
521
+ record.pairVaryings = varyings;
522
+ emitInto(record, varyings);
523
+ }
524
+ }
525
+ }
526
+ function cloneJson(value) {
527
+ if (value === undefined || value === null) {
528
+ return value;
529
+ }
530
+ return JSON.parse(JSON.stringify(value));
531
+ }
532
+ function mapToJson(map) {
533
+ if (!(map instanceof Map)) {
534
+ return [];
535
+ }
536
+ return Array.from(map.entries()).map(([registerIndex, value]) => ({
537
+ registerIndex,
538
+ ...cloneJson(value)
539
+ }));
540
+ }
541
+ function buildStageContract(stage) {
542
+ const pipelineInputs = cloneJson(stage.pipelineInputs ?? []);
543
+ const inputSemantics = pipelineInputs.map(input => ({
544
+ semantic: `${input.usageName || `USAGE_${input.usage}`}${input.usageIndex || ""}`,
545
+ usage: input.usage,
546
+ usageName: input.usageName,
547
+ usageIndex: input.usageIndex,
548
+ registerIndex: input.registerIndex,
549
+ usedMask: input.usedMask,
550
+ type: input.type,
551
+ dimension: input.dimension
552
+ }));
553
+ const inputNames = new Set(inputSemantics.map(input => input.usageName));
554
+ const hasNormal = inputNames.has("NORMAL");
555
+ const hasTangent = inputNames.has("TANGENT");
556
+ const hasBinormal = inputNames.has("BINORMAL") || inputNames.has("BITANGENT");
557
+ const hasBlendIndices = inputNames.has("BLENDINDICES") || inputNames.has("BLENDINDICE");
558
+ let tangentContract = "none";
559
+ if (hasNormal && hasTangent && hasBinormal) {
560
+ tangentContract = "split_tbn";
561
+ } else if (!hasNormal && hasTangent) {
562
+ tangentContract = "packed_tangent_or_tangent_only";
563
+ } else if (hasNormal || hasTangent || hasBinormal) {
564
+ tangentContract = "partial_tbn";
565
+ }
566
+ const resources = cloneJson(stage.resources ?? []);
567
+ const samplers = cloneJson(stage.samplers ?? []);
568
+ const uavs = cloneJson(stage.uavs ?? []);
569
+ const constants = cloneJson(stage.constants ?? []);
570
+ const resourceNames = resources.map(entry => entry.name).filter(Boolean);
571
+ return {
572
+ stageName: stage.stageName,
573
+ stageType: stage.stageType,
574
+ vertex: stage.stageName === "vertex" ? {
575
+ inputs: inputSemantics,
576
+ tangentContract,
577
+ requiresSplitTbn: tangentContract === "split_tbn",
578
+ requiresPackedTangent: tangentContract === "packed_tangent_or_tangent_only",
579
+ requiresSkinning: hasBlendIndices || resourceNames.includes("BoneTransforms"),
580
+ hasBlendIndices
581
+ } : null,
582
+ texturePacking: classifyTexturePacking(resourceNames),
583
+ constantBuffers: (stage.registers ?? []).filter(entry => entry.registerType === 0).map(entry => ({
584
+ registerIndex: entry.registerIndex,
585
+ registerSpace: entry.registerSpace,
586
+ registerCount: entry.registerCount,
587
+ arrayCount: entry.arrayCount,
588
+ dynamic: Boolean(entry.dynamic)
589
+ })),
590
+ resources,
591
+ samplers,
592
+ uavs,
593
+ constants
594
+ };
595
+ }
596
+ function classifyTexturePacking(names) {
597
+ const values = new Set(names);
598
+ if (["NoMap", "PmdgMap", "ArMap"].some(name => values.has(name))) {
599
+ return "packed_textures";
600
+ }
601
+ if (["NormalMap", "RoughnessMap", "MaterialMap", "AlbedoMap", "AoMap", "PaintMaskMap"].some(name => values.has(name))) {
602
+ return "unpacked_textures";
603
+ }
604
+ return "unknown";
605
+ }
606
+ function mergeShaderContracts(contracts) {
607
+ const first = contracts?.[0]?.contract ?? null;
608
+ if (!first) {
609
+ return null;
610
+ }
611
+ return {
612
+ stageName: first.stageName,
613
+ stageType: first.stageType,
614
+ vertex: first.vertex ? cloneJson(first.vertex) : null,
615
+ texturePacking: first.texturePacking,
616
+ constantBuffers: cloneJson(first.constantBuffers ?? []),
617
+ resourceNames: (first.resources ?? []).map(entry => entry.name).filter(Boolean),
618
+ samplerNames: (first.samplers ?? []).map(entry => entry.name).filter(Boolean),
619
+ sharedByStageCount: contracts.length
620
+ };
621
+ }
622
+ function normalizeBitangentStageInterface(result, shaderRecord) {
623
+ if (shaderRecord?.stageName !== "vertex") {
624
+ return {
625
+ source: result.source,
626
+ inputs: result.inputs
627
+ };
628
+ }
629
+ const bitangentRegisters = new Set((shaderRecord.contracts ?? []).flatMap(entry => entry.contract?.vertex?.inputs ?? []).filter(input => input.usageName === "BITANGENT").map(input => input.registerIndex));
630
+ let source = result.source;
631
+ const inputs = result.inputs.map(input => {
632
+ if (!bitangentRegisters.has(input.register) || input.semanticName !== "BINORMAL") {
633
+ return input;
634
+ }
635
+ const name = `in_BITANGENT${input.semanticIndex}`;
636
+ source = source.replaceAll(input.name, name);
637
+ return {
638
+ ...input,
639
+ name,
640
+ semanticName: "BITANGENT"
641
+ };
642
+ });
643
+ return {
644
+ source,
645
+ inputs
646
+ };
647
+ }
648
+ function validateStageSourceShape(record) {
649
+ const source = record?.source ?? "";
650
+ if (!source) {
651
+ return null;
652
+ }
653
+ const hasVertexOutput = /\bgl_Position\b/u.test(source);
654
+ const hasVertexInterface = /\bin\s+(?:lowp|mediump|highp)?\s*\w+\s+attr\d+\b/u.test(source) || /\bout\s+(?:lowp|mediump|highp)?\s*\w+\s+vs_TEXCOORD\d+\b/u.test(source) || /\bin_[A-Z]+[0-9]+\b/u.test(source);
655
+ const hasFragmentOutput = /\bout\s+(?:lowp|mediump|highp)?\s*vec4\s+SV_Target\d+\b/u.test(source) || /\bgl_FragColor\b/u.test(source);
656
+ if (record.stageName === "vertex" && !hasVertexOutput) {
657
+ return "vertex stage source does not write gl_Position";
658
+ }
659
+ if (record.stageName === "pixel" && (hasVertexOutput || hasVertexInterface) && !hasFragmentOutput) {
660
+ return "pixel stage source looks like vertex GLSL";
661
+ }
662
+ if (record.stageName === "compute" && !/\bcewgUav\d+(_s\d+)?\b/u.test(source)) {
663
+ return "compute stage source does not write any cewgUav output";
664
+ }
665
+ return null;
666
+ }
667
+ function inspectRasterCompleteness(stages, shaders) {
668
+ const shaderMap = new Map(shaders.map(shader => [shader.key, shader]));
669
+ const groups = new Map();
670
+ for (const stage of stages) {
671
+ if (!["vertex", "pixel"].includes(stage.stageName)) {
672
+ continue;
673
+ }
674
+ const key = `${stage.bodyKey}:${stage.techniqueName}:${stage.passIndex}`;
675
+ const group = groups.get(key) ?? {
676
+ key,
677
+ bodyKey: stage.bodyKey,
678
+ techniqueName: stage.techniqueName,
679
+ passIndex: stage.passIndex,
680
+ vertex: null,
681
+ pixel: null,
682
+ duplicateStages: []
683
+ };
684
+ if (group[stage.stageName]) {
685
+ group.duplicateStages.push(stage.stageName);
686
+ }
687
+ group[stage.stageName] = stage;
688
+ groups.set(key, group);
689
+ }
690
+ const incompletePasses = [];
691
+ let completePassCount = 0;
692
+ for (const group of groups.values()) {
693
+ const missingStages = [];
694
+ const unavailableStages = [];
695
+ for (const stageName of ["vertex", "pixel"]) {
696
+ const stage = group[stageName];
697
+ if (!stage) {
698
+ missingStages.push(stageName);
699
+ continue;
700
+ }
701
+ const shader = shaderMap.get(stage.shaderKey);
702
+ if (!shader?.hlsl2webgl?.ok || !shader.source) {
703
+ unavailableStages.push({
704
+ stageName,
705
+ stageKey: stage.key,
706
+ shaderKey: stage.shaderKey,
707
+ reason: shader?.hlsl2webgl?.validationError || shader?.hlsl2webgl?.error || shader?.excluded?.reason || "translated source is unavailable"
708
+ });
709
+ }
710
+ }
711
+ if (!missingStages.length && !unavailableStages.length && !group.duplicateStages.length) {
712
+ completePassCount++;
713
+ } else {
714
+ incompletePasses.push({
715
+ ...group,
716
+ missingStages,
717
+ unavailableStages,
718
+ duplicateStages: [...new Set(group.duplicateStages)].sort()
719
+ });
720
+ }
721
+ }
722
+ return {
723
+ expectedPassCount: groups.size,
724
+ completePassCount,
725
+ incompletePasses
726
+ };
727
+ }
728
+ function normalizeSourceIdentity(values) {
729
+ const identity = values.sourceIdentity;
730
+ if (identity !== null && (!identity || typeof identity !== "object" || Array.isArray(identity))) {
731
+ throw new TypeError("CEWG sourceIdentity must be an object");
732
+ }
733
+ const sha256 = sha256Bytes(values.sourceBytes);
734
+ if (identity?.sha256 !== undefined && identity?.sha256 !== null && identity.sha256 !== sha256) {
735
+ throw new Error("CEWG sourceIdentity.sha256 does not match the exact effect input bytes");
736
+ }
737
+ return Object.freeze({
738
+ filePath: identity?.filePath ?? values.source,
739
+ logicalPath: identity?.logicalPath ?? values.source,
740
+ game: identity?.game ?? null,
741
+ client: identity?.client ?? null,
742
+ build: identity?.build === undefined || identity?.build === null ? null : String(identity.build),
743
+ byteLength: values.sourceBytes.byteLength,
744
+ md5: identity?.md5 ?? null,
745
+ sha256
746
+ });
747
+ }
748
+ function qualifyEffectPackage({
749
+ info,
750
+ metadata,
751
+ glsl,
752
+ failedShaders,
753
+ excludedShaders,
754
+ failedBodies,
755
+ rasterCompleteness,
756
+ availableShaderCount
757
+ }) {
758
+ const errors = [];
759
+ if (info.format !== "CEWG" || glsl.format !== "CEWG_GLSL_SET") {
760
+ errors.push("invalid CEWG package envelope");
761
+ }
762
+ if (!Array.isArray(metadata.variants) || !Array.isArray(glsl.shaders)) {
763
+ errors.push("missing CEWG graph arrays");
764
+ }
765
+ if (failedShaders.length) {
766
+ errors.push(`${failedShaders.length} shader translation(s) failed`);
767
+ }
768
+ if (excludedShaders.length) {
769
+ errors.push(`${excludedShaders.length} shader translation(s) are unsupported`);
770
+ }
771
+ if (failedBodies.length) {
772
+ errors.push(`${failedBodies.length} effect body/bodies failed`);
773
+ }
774
+ if (rasterCompleteness.incompletePasses.length) {
775
+ errors.push(`${rasterCompleteness.incompletePasses.length} raster pass(es) are incomplete`);
776
+ }
777
+ if (!availableShaderCount) {
778
+ errors.push("no translated shaders are available");
779
+ }
780
+ return {
781
+ ok: errors.length === 0,
782
+ level: errors.length ? "diagnostic" : "structural",
783
+ errors: Object.freeze(errors),
784
+ incompletePasses: Object.freeze(rasterCompleteness.incompletePasses)
785
+ };
786
+ }
787
+
788
+ export { buildEffectPackage };
789
+ //# sourceMappingURL=effectPackage.js.map