@carbonenginejs/runtime-resource 0.12.2 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -0
- package/dist/CjsResMan.js +393 -29
- package/dist/CjsResMan.js.map +1 -1
- package/dist/format/carbonEffect/CjsCarbonEffectReader.js +165 -118
- package/dist/format/carbonEffect/CjsCarbonEffectReader.js.map +1 -1
- package/dist/format/carbonEffect/buildCarbonEffectContainer.js +182 -0
- package/dist/format/carbonEffect/buildCarbonEffectContainer.js.map +1 -0
- package/dist/format/carbonEffect/carbonEffectBackendBlock.js +7 -113
- package/dist/format/carbonEffect/carbonEffectBackendBlock.js.map +1 -1
- package/dist/format/carbonEffect/carbonEffectRecords.js +258 -66
- package/dist/format/carbonEffect/carbonEffectRecords.js.map +1 -1
- package/dist/format/carbonEffect/carbonEffectResourceTransform.js +197 -0
- package/dist/format/carbonEffect/carbonEffectResourceTransform.js.map +1 -0
- package/dist/format/effect/effectBodyInventory.js +146 -0
- package/dist/format/effect/effectBodyInventory.js.map +1 -0
- package/dist/format/effect/effectPermutationGraph.js +13 -13
- package/dist/format/effect/effectPermutationGraph.js.map +1 -1
- package/dist/format/index.js +4 -4
- package/dist/formats/black/CjsBlackFormat.js +19 -1
- package/dist/formats/black/CjsBlackFormat.js.map +1 -1
- package/dist/formats/bnk/CjsBnkFormat.js +28 -9
- package/dist/formats/bnk/CjsBnkFormat.js.map +1 -1
- package/dist/formats/bnk/core/busNodes.js +252 -0
- package/dist/formats/bnk/core/busNodes.js.map +1 -0
- package/dist/formats/bnk/core/effectNodes.js +147 -0
- package/dist/formats/bnk/core/effectNodes.js.map +1 -0
- package/dist/formats/bnk/core/eventAction.js +135 -24
- package/dist/formats/bnk/core/eventAction.js.map +1 -1
- package/dist/formats/bnk/core/globalSettings.js +215 -0
- package/dist/formats/bnk/core/globalSettings.js.map +1 -0
- package/dist/formats/bnk/core/helpers.js +37 -5
- package/dist/formats/bnk/core/helpers.js.map +1 -1
- package/dist/formats/bnk/core/musicNodes.js +43 -19
- package/dist/formats/bnk/core/musicNodes.js.map +1 -1
- package/dist/formats/bnk/core/nodeBase.js +28 -7
- package/dist/formats/bnk/core/nodeBase.js.map +1 -1
- package/dist/formats/dds/core/helpers.js +40 -1
- package/dist/formats/dds/core/helpers.js.map +1 -1
- package/dist/formats/dxbc/CjsDxbcFormat.js +45 -0
- package/dist/formats/dxbc/CjsDxbcFormat.js.map +1 -1
- package/dist/formats/dxbc/core/disassemble.js +240 -0
- package/dist/formats/dxbc/core/disassemble.js.map +1 -0
- package/dist/formats/gltf/CjsGltfFormat.js +1 -39
- package/dist/formats/gltf/CjsGltfFormat.js.map +1 -1
- package/dist/formats/gltf/core/helpers.js +1 -21
- package/dist/formats/gltf/core/helpers.js.map +1 -1
- package/dist/formats/hlsl/CjsHlslFormat.js +0 -21
- package/dist/formats/hlsl/CjsHlslFormat.js.map +1 -1
- package/dist/formats/hlsl/core/carbonDescriptionToRuntime.js +118 -49
- package/dist/formats/hlsl/core/carbonDescriptionToRuntime.js.map +1 -1
- package/dist/formats/hlsl/core/detailMapFamily.js +128 -0
- package/dist/formats/hlsl/core/detailMapFamily.js.map +1 -0
- package/dist/formats/hlsl/core/localLightFamily.js +133 -0
- package/dist/formats/hlsl/core/localLightFamily.js.map +1 -0
- package/dist/formats/hlsl/core/tr2/resources/HlslEffectRes.js +79 -73
- package/dist/formats/hlsl/core/tr2/resources/HlslEffectRes.js.map +1 -1
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectBindingManifest.js +8 -1
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectBindingManifest.js.map +1 -1
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectDescription.js +11 -691
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectDescription.js.map +1 -1
- package/dist/formats/index.js +4 -2
- package/dist/formats/index.js.map +1 -1
- package/dist/formats/obj/CjsObjFormat.js +1 -22
- package/dist/formats/obj/CjsObjFormat.js.map +1 -1
- package/dist/formats/obj/core/helpers.js +1 -21
- package/dist/formats/obj/core/helpers.js.map +1 -1
- package/dist/formats/pickle/CjsPickleFormat.js +214 -0
- package/dist/formats/pickle/CjsPickleFormat.js.map +1 -0
- package/dist/formats/pickle/core/CjsPickleProtocol0Reader.js +551 -0
- package/dist/formats/pickle/core/CjsPickleProtocol0Reader.js.map +1 -0
- package/dist/formats/pickle/index.js +2 -0
- package/dist/formats/pickle/index.js.map +1 -0
- package/dist/formats/red/core/redGraph.js +11 -8
- package/dist/formats/red/core/redGraph.js.map +1 -1
- package/dist/formats/stl/CjsStlFormat.js +1 -46
- package/dist/formats/stl/CjsStlFormat.js.map +1 -1
- package/dist/formats/stl/core/helpers.js +1 -21
- package/dist/formats/stl/core/helpers.js.map +1 -1
- package/dist/formats/webgl/CjsWebglFormat.js +33 -55
- package/dist/formats/webgl/CjsWebglFormat.js.map +1 -1
- package/dist/formats/webgl/core/buildGlslEffectContainer.js +70 -0
- package/dist/formats/webgl/core/buildGlslEffectContainer.js.map +1 -0
- package/dist/formats/webgl/core/effectPackage.js +216 -108
- package/dist/formats/webgl/core/effectPackage.js.map +1 -1
- package/dist/formats/webgl/core/errors.js +1 -1
- package/dist/formats/webgl/core/errors.js.map +1 -1
- package/dist/formats/webgl/core/glsl/DxbcGlslEmitter.js +166 -24
- package/dist/formats/webgl/core/glsl/DxbcGlslEmitter.js.map +1 -1
- package/dist/formats/webgl/core/glsl/DxbcGlslOperandFormatter.js +63 -5
- package/dist/formats/webgl/core/glsl/DxbcGlslOperandFormatter.js.map +1 -1
- package/dist/formats/webgl/core/glsl/packedLightFixups.js +98 -0
- package/dist/formats/webgl/core/glsl/packedLightFixups.js.map +1 -0
- package/dist/formats/webgl/core/glslBackendBlock.js +552 -0
- package/dist/formats/webgl/core/glslBackendBlock.js.map +1 -0
- package/dist/formats/webgl/core/glslBackendBodySet.js +243 -0
- package/dist/formats/webgl/core/glslBackendBodySet.js.map +1 -0
- package/dist/formats/webgl/core/{cewgCompleteness.js → glslEffectCompleteness.js} +12 -8
- package/dist/formats/webgl/core/glslEffectCompleteness.js.map +1 -0
- package/dist/formats/webgl/core/helpers.js +33 -172
- package/dist/formats/webgl/core/helpers.js.map +1 -1
- package/dist/formats/webgl/core/inspectGlslEffectContainer.js +122 -0
- package/dist/formats/webgl/core/inspectGlslEffectContainer.js.map +1 -0
- package/dist/formats/webgl/core/readGlslEffectContainer.js +249 -0
- package/dist/formats/webgl/core/readGlslEffectContainer.js.map +1 -0
- package/dist/formats/webgpu/CjsWebgpuFormat.js +15 -15
- package/dist/formats/webgpu/CjsWebgpuFormat.js.map +1 -1
- package/dist/formats/webgpu/core/buildCarbonEffectContainer.js +37 -145
- package/dist/formats/webgpu/core/buildCarbonEffectContainer.js.map +1 -1
- package/dist/formats/webgpu/core/{cewgpu/CewgpuContainer.js → carbonWebgpu/CarbonWebgpuContainer.js} +13 -27
- package/dist/formats/webgpu/core/carbonWebgpu/CarbonWebgpuContainer.js.map +1 -0
- package/dist/formats/webgpu/core/{cewgpu → carbonWebgpu}/containerViews.js +1 -1
- package/dist/formats/webgpu/core/carbonWebgpu/containerViews.js.map +1 -0
- package/dist/formats/webgpu/core/{cewgpu → carbonWebgpu}/validateContainer.js +4 -4
- package/dist/formats/webgpu/core/carbonWebgpu/validateContainer.js.map +1 -0
- package/dist/formats/webgpu/core/effectBackendBodySet.js +18 -18
- package/dist/formats/webgpu/core/effectBackendBodySet.js.map +1 -1
- package/dist/formats/webgpu/core/errors.js +1 -1
- package/dist/formats/webgpu/core/errors.js.map +1 -1
- package/dist/formats/webgpu/core/helpers.js +22 -22
- package/dist/formats/webgpu/core/helpers.js.map +1 -1
- package/dist/formats/webgpu/core/packageEffect.js +11 -15
- package/dist/formats/webgpu/core/packageEffect.js.map +1 -1
- package/dist/formats/webgpu/core/packageEffectSelection.js +1 -1
- package/dist/formats/webgpu/core/packageEffectSelection.js.map +1 -1
- package/dist/formats/webgpu/core/wgsl/buildResourceTransformPlan.js +23 -23
- package/dist/formats/webgpu/core/wgsl/buildResourceTransformPlan.js.map +1 -1
- package/dist/formats/webgpu/core/wgsl/buildWgslSet.js +6 -6
- package/dist/formats/webgpu/core/wgsl/buildWgslSet.js.map +1 -1
- package/dist/formats/yaml/CjsYamlFormat.js +3 -3
- package/dist/formats/yaml/CjsYamlFormat.js.map +1 -1
- package/dist/formats/yaml/core/CjsYamlReader.js +4 -6
- package/dist/formats/yaml/core/CjsYamlReader.js.map +1 -1
- package/dist/formats/yaml/core/helpers.js +27 -1
- package/dist/formats/yaml/core/helpers.js.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/resource/CjsLoadingObject.js +19 -0
- package/dist/resource/CjsLoadingObject.js.map +1 -0
- package/dist/resource/CjsResource.js +4 -0
- package/dist/resource/CjsResource.js.map +1 -1
- package/dist/resource/ResourceHandlerMode.js +14 -0
- package/dist/resource/ResourceHandlerMode.js.map +1 -0
- package/dist/resource/index.js +2 -0
- package/dist/resource/index.js.map +1 -1
- package/dist/resource/shader/Tr2EffectRes.js +118 -213
- package/dist/resource/shader/Tr2EffectRes.js.map +1 -1
- package/dist/resource/shader/Tr2Shader.js +37 -15
- package/dist/resource/shader/Tr2Shader.js.map +1 -1
- package/dist/resource/shader/reflection/Tr2EffectConstant.js +37 -29
- package/dist/resource/shader/reflection/Tr2EffectConstant.js.map +1 -1
- package/dist/resource/shader/reflection/Tr2EffectDescription.js +39 -34
- package/dist/resource/shader/reflection/Tr2EffectDescription.js.map +1 -1
- package/dist/resource/shader/reflection/Tr2EffectLibrary.js +51 -30
- package/dist/resource/shader/reflection/Tr2EffectLibrary.js.map +1 -1
- package/dist/resource/shader/reflection/Tr2EffectParameterAnnotation.js +45 -25
- package/dist/resource/shader/reflection/Tr2EffectParameterAnnotation.js.map +1 -1
- package/dist/resource/shader/reflection/Tr2EffectResource.js +51 -17
- package/dist/resource/shader/reflection/Tr2EffectResource.js.map +1 -1
- package/dist/resource/shader/reflection/Tr2EffectStageInput.js +219 -88
- package/dist/resource/shader/reflection/Tr2EffectStageInput.js.map +1 -1
- package/dist/resource/shader/reflection/Tr2EffectTechnique.js +28 -18
- package/dist/resource/shader/reflection/Tr2EffectTechnique.js.map +1 -1
- package/dist/resource/shader/reflection/Tr2Pass.js +96 -39
- package/dist/resource/shader/reflection/Tr2Pass.js.map +1 -1
- package/dist/resource/shader/reflection/carbonRecordFields.js +159 -0
- package/dist/resource/shader/reflection/carbonRecordFields.js.map +1 -0
- package/dist/resource/shader/reflection/shaderStage.js +22 -0
- package/dist/resource/shader/reflection/shaderStage.js.map +1 -0
- package/dist/resource/shader/sampler/Tr2SamplerSetup.js +68 -10
- package/dist/resource/shader/sampler/Tr2SamplerSetup.js.map +1 -1
- package/dist/worker/CjsResManMainThreadLoader.js +9 -7
- package/dist/worker/CjsResManMainThreadLoader.js.map +1 -1
- package/dist/worker/CjsResManWorker.js +5 -4
- package/dist/worker/CjsResManWorker.js.map +1 -1
- package/dist/worker/CjsResManWorkerLoader.js +9 -6
- package/dist/worker/CjsResManWorkerLoader.js.map +1 -1
- package/docs/README.md +2 -2
- package/docs/architecture.md +12 -3
- package/docs/concepts/resource-lifecycle.md +9 -8
- package/docs/concepts/shader-resource-model.md +14 -17
- package/docs/concepts/writing-an-engine-adapter.md +1 -1
- package/docs/formats/README.md +4 -2
- package/docs/formats/carbon-effect-container.md +127 -26
- package/docs/formats/dxbc/architecture.md +1 -1
- package/docs/formats/dxbc/reference/api.md +28 -0
- package/docs/formats/hlsl/README.md +3 -3
- package/docs/formats/hlsl/architecture.md +8 -9
- package/docs/formats/hlsl/guides/hydrating-json-output.md +3 -5
- package/docs/formats/hlsl/guides/reading-effects.md +5 -1
- package/docs/formats/hlsl/reference/advanced-analysis.md +20 -25
- package/docs/formats/hlsl/reference/api.md +0 -7
- package/docs/formats/hlsl/reference/json-graph.md +1 -4
- package/docs/formats/pickle.md +82 -0
- package/docs/formats/webgl/README.md +71 -13
- package/docs/formats/webgl/architecture.md +16 -17
- package/docs/formats/webgl/carbon-constant-layouts.md +3 -3
- package/docs/formats/webgl/decl-io.md +3 -3
- package/docs/formats/webgl/memory-structured.md +27 -8
- package/docs/formats/webgl/texture-sample.md +1 -1
- package/docs/formats/webgpu/README.md +3 -3
- package/docs/formats/webgpu/architecture.md +5 -6
- package/docs/formats/webgpu/formats/{cewgpu.md → carbon-webgpu.md} +10 -11
- package/docs/formats/webgpu/guides/effect-packaging.md +6 -8
- package/docs/formats/webgpu/reference/api.md +11 -12
- package/docs/formats/webgpu/reference/wgsl-compatibility.md +11 -8
- package/docs/formats/wwise.md +63 -2
- package/docs/reference/classes/core.md +10 -0
- package/docs/reference/classes/formats.md +40 -48
- package/docs/reference/classes/resources.md +2 -2
- package/docs/reference/queues.md +88 -4
- package/docs/reference/workers.md +7 -0
- package/package.json +61 -61
- package/dist/format/carbonEffect/carbonDescriptionFromPortable.js +0 -372
- package/dist/format/carbonEffect/carbonDescriptionFromPortable.js.map +0 -1
- package/dist/format/effect/effectReflectionPackage.js +0 -636
- package/dist/format/effect/effectReflectionPackage.js.map +0 -1
- package/dist/formats/hlsl/core/HlslReader.js +0 -16
- package/dist/formats/hlsl/core/HlslReader.js.map +0 -1
- package/dist/formats/hlsl/core/portableReflection.js +0 -848
- package/dist/formats/hlsl/core/portableReflection.js.map +0 -1
- package/dist/formats/hlsl/portable.js +0 -2
- package/dist/formats/hlsl/portable.js.map +0 -1
- package/dist/formats/webgl/core/cewg/CewgPackage.js +0 -340
- package/dist/formats/webgl/core/cewg/CewgPackage.js.map +0 -1
- package/dist/formats/webgl/core/cewg/CewgPackageBuilder.js +0 -104
- package/dist/formats/webgl/core/cewg/CewgPackageBuilder.js.map +0 -1
- package/dist/formats/webgl/core/cewg/binary.js +0 -19
- package/dist/formats/webgl/core/cewg/binary.js.map +0 -1
- package/dist/formats/webgl/core/cewgCompleteness.js.map +0 -1
- package/dist/formats/webgl/core/effectPackageValidation.js +0 -331
- package/dist/formats/webgl/core/effectPackageValidation.js.map +0 -1
- package/dist/formats/webgpu/core/cewgpu/CewgpuContainer.js.map +0 -1
- package/dist/formats/webgpu/core/cewgpu/containerViews.js.map +0 -1
- package/dist/formats/webgpu/core/cewgpu/validateContainer.js.map +0 -1
- package/dist/resource/shader/portable.js +0 -33
- package/dist/resource/shader/portable.js.map +0 -1
- package/docs/formats/hlsl/reference/portable-reflection.md +0 -141
- package/docs/formats/webgl/effect-reflection.md +0 -127
|
@@ -45,6 +45,8 @@ const NON_COMPARISON_TEXTURE_OPCODES = new Set(["sample", "sample_l", "sample_b"
|
|
|
45
45
|
* Filtered-sample coordinate mask per resource dimension
|
|
46
46
|
* (HLSLcc `TranslateTexCoord`, toGLSLInstruction.cpp:985-1031).
|
|
47
47
|
*/
|
|
48
|
+
/** GLSL symbol for the merged detail-map array. */
|
|
49
|
+
const DETAIL_MAP_ARRAY_SYMBOL = "sDetailArrayMap";
|
|
48
50
|
const COORD_MASK_BY_DIMENSION = {
|
|
49
51
|
2: "x",
|
|
50
52
|
3: "xy",
|
|
@@ -100,8 +102,24 @@ class DxbcGlslEmitter {
|
|
|
100
102
|
// LightProfileArray) when `--stub-light-resources` is set, so the
|
|
101
103
|
// fragment sampler count drops under MAX_TEXTURE_IMAGE_UNITS.
|
|
102
104
|
stubResourceRegisters: [],
|
|
105
|
+
// Resource (t#) registers whose declaration is dropped and whose
|
|
106
|
+
// samples lower to `vec4(1.0)` rather than `vec4(0.0)`.
|
|
107
|
+
//
|
|
108
|
+
// Separate from `stubResourceRegisters` because the two are not
|
|
109
|
+
// interchangeable: a stubbed sampler reads as zero, which is right
|
|
110
|
+
// for a term that is added and wrong for one that is multiplied.
|
|
111
|
+
// `LightProfileArray` is multiplied into a light's attenuation, so
|
|
112
|
+
// stubbing it would drive every profiled light to black, whereas
|
|
113
|
+
// 1.0 is exactly what the shader's own no-profile path yields.
|
|
114
|
+
neutralResourceRegisters: [],
|
|
103
115
|
lightConstantBuffer: null,
|
|
104
116
|
lightPackedTexture: null,
|
|
117
|
+
// Resource (t#) registers to merge into one `sampler2DArray`, in
|
|
118
|
+
// layer order. Empty by default; the packager fills it from the
|
|
119
|
+
// backend-neutral detail-map recogniser. Merging three 2D textures
|
|
120
|
+
// into one array binding frees two texture units on shaders that
|
|
121
|
+
// sit exactly on WebGL2's 16-unit limit.
|
|
122
|
+
detailMapArrayRegisters: [],
|
|
105
123
|
...options.profile
|
|
106
124
|
};
|
|
107
125
|
}
|
|
@@ -207,6 +225,15 @@ class DxbcGlslEmitter {
|
|
|
207
225
|
// declarations/bindings are dropped and every read of them lowers
|
|
208
226
|
// to `uintBitsToFloat(0u)` (structured) / `vec4(0.0)` (sampled).
|
|
209
227
|
stubbedResources: new Set(this.profile.stubResourceRegisters || []),
|
|
228
|
+
// Resource (t#) registers dropped to a compile-time *one*: same
|
|
229
|
+
// declaration handling as `stubbedResources`, but reads lower to
|
|
230
|
+
// `vec4(1.0)` so a multiplied term degrades to neutral instead of
|
|
231
|
+
// to black. See `neutralResourceRegisters` on the profile.
|
|
232
|
+
neutralResources: new Set(this.profile.neutralResourceRegisters || []),
|
|
233
|
+
// Resource register -> array layer for the merged detail maps, and
|
|
234
|
+
// whether the one shared array declaration has been emitted yet.
|
|
235
|
+
detailMapArrayLayers: new Map((this.profile.detailMapArrayRegisters || []).map((register, layer) => [register, layer])),
|
|
236
|
+
detailMapArrayDeclared: false,
|
|
210
237
|
inputMasks: new Map(),
|
|
211
238
|
outputMasks: new Map(),
|
|
212
239
|
bindings: [],
|
|
@@ -263,7 +290,7 @@ class DxbcGlslEmitter {
|
|
|
263
290
|
constantBuffer: slot => state.constantBufferNames.get(slot) || `cb${slot}`,
|
|
264
291
|
constantBufferMember: this.profile.constantBufferStyle === "std140" ? "data" : "",
|
|
265
292
|
resource: index => state.resourceNames.get(index) || `t${index}`,
|
|
266
|
-
uav: index => state.uavNames.get(index) || `
|
|
293
|
+
uav: index => state.uavNames.get(index) || `cjsUav${index}`,
|
|
267
294
|
immediateConstantBuffer: state.icbName
|
|
268
295
|
}
|
|
269
296
|
});
|
|
@@ -409,7 +436,7 @@ class DxbcGlslEmitter {
|
|
|
409
436
|
dataRegister,
|
|
410
437
|
profileRegister: Number.isInteger(Number(profile.profileRegister)) ? Number(profile.profileRegister) : null,
|
|
411
438
|
registerIndex: Number.isInteger(Number(profile.registerIndex)) ? Number(profile.registerIndex) : indexRegister,
|
|
412
|
-
name: profile.name || "
|
|
439
|
+
name: profile.name || "cjsLocalLightTexture",
|
|
413
440
|
dataTexelBase: Number.isInteger(Number(profile.dataTexelBase)) ? Number(profile.dataTexelBase) : 131072
|
|
414
441
|
};
|
|
415
442
|
}
|
|
@@ -433,7 +460,7 @@ class DxbcGlslEmitter {
|
|
|
433
460
|
strideBytes: 0,
|
|
434
461
|
format: "RGBA32UI",
|
|
435
462
|
width: this.profile.dataTextureWidth,
|
|
436
|
-
|
|
463
|
+
cjsSemantic: "packedLocalLights",
|
|
437
464
|
lightIndexRegister: profile.indexRegister,
|
|
438
465
|
lightDataRegister: profile.dataRegister,
|
|
439
466
|
lightProfileRegister: profile.profileRegister,
|
|
@@ -453,14 +480,14 @@ class DxbcGlslEmitter {
|
|
|
453
480
|
state.lightConstantBufferDeclared = true;
|
|
454
481
|
const rows = 1 + profile.capacity * 3;
|
|
455
482
|
state.constantBufferNames.set(profile.registerIndex, profile.name);
|
|
456
|
-
state.declarationLines.push(`uniform vec4 ${profile.name}[${rows}];`, `uint
|
|
483
|
+
state.declarationLines.push(`uniform vec4 ${profile.name}[${rows}];`, `uint cjsLocalLightCount() { return floatBitsToUint(${profile.name}[0].x); }`, "uint cjsLocalLightIndexLoad(int element) {", " uint count = cjsLocalLightCount();", " if (count == 0u) return 0u;", ` const int listBase = ${profile.listBase};`, " if (element < listBase) return uint(listBase);", " int local = element - listBase;", " int node = local >> 1;", " if (node < 0 || uint(node) >= count) return 0u;", " if ((local & 1) == 0) return uint(node + 1);", " uint next = uint(node + 1);", " return next < count ? uint(listBase + int(next) * 2) : 0u;", "}", "vec4 cjsLocalLightRow(int lightIndex, int row) {", " int i = lightIndex - 1;", " if (i < 0 || uint(i) >= cjsLocalLightCount() || row < 0 || row >= 3) return vec4(0.0);", ` return ${profile.name}[1 + i * 3 + row];`, "}");
|
|
457
484
|
state.bindings.push({
|
|
458
485
|
kind: "constantBuffer",
|
|
459
486
|
registerIndex: profile.registerIndex,
|
|
460
487
|
name: profile.name,
|
|
461
488
|
sizeInVec4: rows,
|
|
462
489
|
style: "array",
|
|
463
|
-
|
|
490
|
+
cjsSemantic: "localLights",
|
|
464
491
|
capacityLights: profile.capacity,
|
|
465
492
|
lightIndexRegister: profile.indexRegister,
|
|
466
493
|
lightDataRegister: profile.dataRegister,
|
|
@@ -723,6 +750,18 @@ class DxbcGlslEmitter {
|
|
|
723
750
|
// this register lowers to vec4(0.0) in _textureSample.
|
|
724
751
|
break;
|
|
725
752
|
}
|
|
753
|
+
if (state.neutralResources.has(register)) {
|
|
754
|
+
// Same as the stub above, but its samples lower to
|
|
755
|
+
// vec4(1.0). Dropping the declaration is what frees the
|
|
756
|
+
// sampler unit; the substitution is what keeps the result
|
|
757
|
+
// correct for a multiplied term.
|
|
758
|
+
//
|
|
759
|
+
// Nothing is recorded as a binding, because nothing is
|
|
760
|
+
// bound. The pass's resource-transform section carries the
|
|
761
|
+
// statement that this resource was dropped deliberately;
|
|
762
|
+
// see `localLightProfileNeutralTransformFor`.
|
|
763
|
+
break;
|
|
764
|
+
}
|
|
726
765
|
if (declaration.resourceDimension === 1) {
|
|
727
766
|
// Buffer<> texel buffers (post-processing) become float data textures
|
|
728
767
|
// read via width-wrapped texelFetch; no samplerBuffer in WebGL2.
|
|
@@ -748,6 +787,10 @@ class DxbcGlslEmitter {
|
|
|
748
787
|
dimensionName: declaration.resourceDimensionName
|
|
749
788
|
});
|
|
750
789
|
}
|
|
790
|
+
if (state.detailMapArrayLayers.has(register)) {
|
|
791
|
+
this._declareDetailArrayMap(state, register, declaration, comparisonSamplers);
|
|
792
|
+
break;
|
|
793
|
+
}
|
|
751
794
|
const name = this.profile.samplerName(register, state.stageName);
|
|
752
795
|
state.resourceDimensions.set(register, declaration.resourceDimension);
|
|
753
796
|
state.resourceNames.set(register, name);
|
|
@@ -840,7 +883,7 @@ class DxbcGlslEmitter {
|
|
|
840
883
|
} else {
|
|
841
884
|
// Vertex-stage structured buffers (BoneTransforms) become dedicated
|
|
842
885
|
// std140 UBOs sized to the profile capacity (Carbon max 69 joints).
|
|
843
|
-
const name = `
|
|
886
|
+
const name = `CjsSb${register}`;
|
|
844
887
|
const capacity = this.profile.vertexStructuredCapacity;
|
|
845
888
|
const rows = capacity * Math.ceil(strideDwords / 4);
|
|
846
889
|
state.structuredBuffers.set(register, {
|
|
@@ -882,7 +925,7 @@ class DxbcGlslEmitter {
|
|
|
882
925
|
// framebufferTextureLayer.
|
|
883
926
|
const sliceNames = new Map();
|
|
884
927
|
for (const slice of plan.slices) {
|
|
885
|
-
const name = `
|
|
928
|
+
const name = `cjsUav${register}_s${slice}`;
|
|
886
929
|
const location = this._allocateUavOutputLocation(state, register);
|
|
887
930
|
sliceNames.set(slice, name);
|
|
888
931
|
state.declarationLines.push(`layout(location = ${location}) out highp vec4 ${name};`);
|
|
@@ -898,7 +941,7 @@ class DxbcGlslEmitter {
|
|
|
898
941
|
state.uavSliceNames.set(register, sliceNames);
|
|
899
942
|
break;
|
|
900
943
|
}
|
|
901
|
-
const name = `
|
|
944
|
+
const name = `cjsUav${register}`;
|
|
902
945
|
const location = this._allocateUavOutputLocation(state, register);
|
|
903
946
|
state.uavNames.set(register, name);
|
|
904
947
|
state.declarationLines.push(`layout(location = ${location}) out highp vec4 ${name};`);
|
|
@@ -1103,7 +1146,7 @@ class DxbcGlslEmitter {
|
|
|
1103
1146
|
|
|
1104
1147
|
/**
|
|
1105
1148
|
* Emits the shared `gl_FragCoord`-derived thread-id prelude for map-style
|
|
1106
|
-
* compute shaders: a `
|
|
1149
|
+
* compute shaders: a `cjsDispatchOrigin` uniform (so a dispatch can be
|
|
1107
1150
|
* tiled across more than one draw/viewport), then only the intermediate
|
|
1108
1151
|
* and final locals this shader actually declared inputs for.
|
|
1109
1152
|
*
|
|
@@ -1114,29 +1157,29 @@ class DxbcGlslEmitter {
|
|
|
1114
1157
|
if (!used.threadId && !used.groupId && !used.tig && !used.flattened) {
|
|
1115
1158
|
return;
|
|
1116
1159
|
}
|
|
1117
|
-
state.dispatchOriginUniform = "
|
|
1118
|
-
state.declarationLines.push("uniform ivec3
|
|
1160
|
+
state.dispatchOriginUniform = "cjsDispatchOrigin";
|
|
1161
|
+
state.declarationLines.push("uniform ivec3 cjsDispatchOrigin;");
|
|
1119
1162
|
state.bindings.push({
|
|
1120
1163
|
kind: "dispatchUniform",
|
|
1121
|
-
name: "
|
|
1164
|
+
name: "cjsDispatchOrigin"
|
|
1122
1165
|
});
|
|
1123
|
-
state.earlyMainLines.push("ivec3
|
|
1166
|
+
state.earlyMainLines.push("ivec3 cjsThreadId = ivec3(ivec2(gl_FragCoord.xy), 0) + cjsDispatchOrigin;");
|
|
1124
1167
|
if (used.threadId) {
|
|
1125
|
-
state.earlyMainLines.push("vec4 vThreadID = intBitsToFloat(ivec4(
|
|
1168
|
+
state.earlyMainLines.push("vec4 vThreadID = intBitsToFloat(ivec4(cjsThreadId, 0));");
|
|
1126
1169
|
}
|
|
1127
1170
|
if (used.groupId || used.tig || used.flattened) {
|
|
1128
1171
|
const [nx, ny, nz] = this._threadGroupSizeOrThrow(state);
|
|
1129
|
-
state.earlyMainLines.push(`ivec3
|
|
1172
|
+
state.earlyMainLines.push(`ivec3 cjsGroupId = cjsThreadId / ivec3(${nx}, ${ny}, ${nz});`);
|
|
1130
1173
|
if (used.groupId) {
|
|
1131
|
-
state.earlyMainLines.push("vec4 vThreadGroupID = intBitsToFloat(ivec4(
|
|
1174
|
+
state.earlyMainLines.push("vec4 vThreadGroupID = intBitsToFloat(ivec4(cjsGroupId, 0));");
|
|
1132
1175
|
}
|
|
1133
1176
|
if (used.tig || used.flattened) {
|
|
1134
|
-
state.earlyMainLines.push(`ivec3
|
|
1177
|
+
state.earlyMainLines.push(`ivec3 cjsTig = cjsThreadId - cjsGroupId * ivec3(${nx}, ${ny}, ${nz});`);
|
|
1135
1178
|
if (used.tig) {
|
|
1136
|
-
state.earlyMainLines.push("vec4 vThreadIDInGroup = intBitsToFloat(ivec4(
|
|
1179
|
+
state.earlyMainLines.push("vec4 vThreadIDInGroup = intBitsToFloat(ivec4(cjsTig, 0));");
|
|
1137
1180
|
}
|
|
1138
1181
|
if (used.flattened) {
|
|
1139
|
-
state.earlyMainLines.push(`vec4 vThreadIDInGroupFlattened = intBitsToFloat(ivec4(
|
|
1182
|
+
state.earlyMainLines.push(`vec4 vThreadIDInGroupFlattened = intBitsToFloat(ivec4(cjsTig.z*${nx}*${ny} + cjsTig.y*${nx} + cjsTig.x, 0, 0, 0));`);
|
|
1140
1183
|
}
|
|
1141
1184
|
}
|
|
1142
1185
|
}
|
|
@@ -1689,6 +1732,82 @@ class DxbcGlslEmitter {
|
|
|
1689
1732
|
}
|
|
1690
1733
|
}
|
|
1691
1734
|
|
|
1735
|
+
/**
|
|
1736
|
+
* Declares the merged detail-map array, once, on the first member seen.
|
|
1737
|
+
*
|
|
1738
|
+
* Each member keeps its own entry in `resourceNames` pointing at the shared
|
|
1739
|
+
* array, so every existing reference site resolves to it without knowing a
|
|
1740
|
+
* merge happened. The declared dimension deliberately stays 2D: the layer is
|
|
1741
|
+
* appended to the coordinate at each sample site rather than read out of the
|
|
1742
|
+
* shader's own operand, which has no third component to give.
|
|
1743
|
+
*
|
|
1744
|
+
* @param {object} state Mutable emission state.
|
|
1745
|
+
* @param {number} register Resource register being declared.
|
|
1746
|
+
* @param {object} declaration Decoded resource declaration.
|
|
1747
|
+
* @param {Set<number>|null} comparisonSamplers Comparison samplers, when any.
|
|
1748
|
+
* @private
|
|
1749
|
+
*/
|
|
1750
|
+
_declareDetailArrayMap(state, register, declaration, comparisonSamplers) {
|
|
1751
|
+
// A comparison-sampled or non-2D detail map is not the family the
|
|
1752
|
+
// recogniser promised, so refuse rather than emit a wrong declaration.
|
|
1753
|
+
if (comparisonSamplers || declaration.resourceDimension !== 3) {
|
|
1754
|
+
throw new WebglReadError("Detail-map array merging requires plain 2D textures without comparison sampling", {
|
|
1755
|
+
source: state.sourceName,
|
|
1756
|
+
register,
|
|
1757
|
+
dimensionName: declaration.resourceDimensionName
|
|
1758
|
+
});
|
|
1759
|
+
}
|
|
1760
|
+
state.resourceDimensions.set(register, declaration.resourceDimension);
|
|
1761
|
+
state.resourceNames.set(register, DETAIL_MAP_ARRAY_SYMBOL);
|
|
1762
|
+
if (state.detailMapArrayDeclared) return;
|
|
1763
|
+
state.detailMapArrayDeclared = true;
|
|
1764
|
+
state.declarationLines.push(`uniform mediump sampler2DArray ${DETAIL_MAP_ARRAY_SYMBOL};`);
|
|
1765
|
+
state.bindings.push({
|
|
1766
|
+
kind: "resource",
|
|
1767
|
+
registerIndex: register,
|
|
1768
|
+
name: DETAIL_MAP_ARRAY_SYMBOL,
|
|
1769
|
+
samplerType: "sampler2DArray",
|
|
1770
|
+
dimensionName: "texture2darray",
|
|
1771
|
+
arrayLayerCount: state.detailMapArrayLayers.size,
|
|
1772
|
+
mergedFrom: [...state.detailMapArrayLayers.keys()]
|
|
1773
|
+
});
|
|
1774
|
+
}
|
|
1775
|
+
|
|
1776
|
+
/**
|
|
1777
|
+
* Returns the array layer a texture operand maps to, when it was merged.
|
|
1778
|
+
*
|
|
1779
|
+
* @param {object} state Mutable emission state.
|
|
1780
|
+
* @param {object} texOperand Texture resource operand.
|
|
1781
|
+
* @returns {number|null} Layer index, or null when the register was not merged.
|
|
1782
|
+
* @private
|
|
1783
|
+
*/
|
|
1784
|
+
_detailMapArrayLayer(state, texOperand) {
|
|
1785
|
+
const layer = state.detailMapArrayLayers.get(texOperand.registerIndex);
|
|
1786
|
+
return layer === undefined ? null : layer;
|
|
1787
|
+
}
|
|
1788
|
+
|
|
1789
|
+
/**
|
|
1790
|
+
* Refuses an operation that cannot be redirected at an array layer.
|
|
1791
|
+
*
|
|
1792
|
+
* Recognising the detail family proves the resources are mergeable; it does
|
|
1793
|
+
* not prove every *use* is. A texel fetch or a size query against a merged
|
|
1794
|
+
* register would silently mean something different once the register became
|
|
1795
|
+
* one layer of an array, so those fail the build instead.
|
|
1796
|
+
*
|
|
1797
|
+
* @param {object} state Mutable emission state.
|
|
1798
|
+
* @param {object} instruction Decoded DXBC instruction.
|
|
1799
|
+
* @param {object} texOperand Texture resource operand.
|
|
1800
|
+
* @private
|
|
1801
|
+
*/
|
|
1802
|
+
_rejectDetailArrayMapUse(state, instruction, texOperand) {
|
|
1803
|
+
if (!state.detailMapArrayLayers.has(texOperand.registerIndex)) return;
|
|
1804
|
+
throw new WebglReadError(`Detail map merged into an array is used by ${instruction.opcodeName}, ` + "which this emitter cannot redirect at an array layer", {
|
|
1805
|
+
source: state.sourceName,
|
|
1806
|
+
register: texOperand.registerIndex,
|
|
1807
|
+
opcodeName: instruction.opcodeName
|
|
1808
|
+
});
|
|
1809
|
+
}
|
|
1810
|
+
|
|
1692
1811
|
/**
|
|
1693
1812
|
* Resolves and validates the declared dimension of a texture operand.
|
|
1694
1813
|
*
|
|
@@ -1763,9 +1882,24 @@ class DxbcGlslEmitter {
|
|
|
1763
1882
|
});
|
|
1764
1883
|
return;
|
|
1765
1884
|
}
|
|
1885
|
+
if (state.neutralResources.has(texOperand.registerIndex)) {
|
|
1886
|
+
// Neutralised sampler (LightProfileArray): its declaration was
|
|
1887
|
+
// dropped, and the value it fed is a multiplier, so lower to one.
|
|
1888
|
+
// The shader's own no-profile path leaves attenuation untouched,
|
|
1889
|
+
// which is what multiplying by 1.0 reproduces exactly.
|
|
1890
|
+
const oneSwizzle = [...mask].map(component => texOperand.swizzle ? texOperand.swizzle["xyzw".indexOf(component)] : component).join("");
|
|
1891
|
+
this._assign(state, instruction, `vec4(1.0).${oneSwizzle}`, {
|
|
1892
|
+
saturate: instruction.saturate
|
|
1893
|
+
});
|
|
1894
|
+
return;
|
|
1895
|
+
}
|
|
1766
1896
|
const dimension = this._resourceDimension(state, instruction, texOperand);
|
|
1767
1897
|
const coordMask = COORD_MASK_BY_DIMENSION[dimension];
|
|
1768
|
-
const
|
|
1898
|
+
const detailLayer = this._detailMapArrayLayer(state, texOperand);
|
|
1899
|
+
const baseCoord = this._vecArg(state, coordOperand, coordMask);
|
|
1900
|
+
// A merged detail map keeps its 2D coordinate and gains the layer as a
|
|
1901
|
+
// literal third component; the register it came from is the layer.
|
|
1902
|
+
const coord = detailLayer === null ? baseCoord : `vec3(${baseCoord}, ${detailLayer}.0)`;
|
|
1769
1903
|
const texName = state.formatter.registerReference(texOperand);
|
|
1770
1904
|
const returnSwizzle = [...mask].map(component => texOperand.swizzle ? texOperand.swizzle["xyzw".indexOf(component)] : component).join("");
|
|
1771
1905
|
if (comparisonRefOperandIndex !== null) {
|
|
@@ -1832,6 +1966,7 @@ class DxbcGlslEmitter {
|
|
|
1832
1966
|
} = this._destMask(state, instruction);
|
|
1833
1967
|
const coordOperand = instruction.operands[1];
|
|
1834
1968
|
const texOperand = instruction.operands[2];
|
|
1969
|
+
this._rejectDetailArrayMapUse(state, instruction, texOperand);
|
|
1835
1970
|
const dimension = this._resourceDimension(state, instruction, texOperand);
|
|
1836
1971
|
const texName = state.formatter.registerReference(texOperand);
|
|
1837
1972
|
const returnSwizzle = [...mask].map(component => texOperand.swizzle ? texOperand.swizzle["xyzw".indexOf(component)] : component).join("");
|
|
@@ -2491,7 +2626,7 @@ DxbcGlslEmitter.prototype._ldStructured = function _ldStructured(state, instruct
|
|
|
2491
2626
|
const texel = `(${info.dataTexelBase} + ((${dword}) >> 2))`;
|
|
2492
2627
|
value = `uintBitsToFloat(texelFetch(${info.name}, ivec2((${texel}) & ${widthMask}, (${texel}) >> ${widthShift}), 0)[(${dword}) & 3])`;
|
|
2493
2628
|
} else if (info.kind === "lightIndexCb") {
|
|
2494
|
-
value = `uintBitsToFloat(
|
|
2629
|
+
value = `uintBitsToFloat(cjsLocalLightIndexLoad(${element}))`;
|
|
2495
2630
|
} else if (info.kind === "lightDataCb") {
|
|
2496
2631
|
if (!aligned) {
|
|
2497
2632
|
throw new WebglReadError("local-light constant-buffer lowering requires aligned light rows", {
|
|
@@ -2499,7 +2634,7 @@ DxbcGlslEmitter.prototype._ldStructured = function _ldStructured(state, instruct
|
|
|
2499
2634
|
offset: instruction.offset
|
|
2500
2635
|
});
|
|
2501
2636
|
}
|
|
2502
|
-
value = `
|
|
2637
|
+
value = `cjsLocalLightRow(${element}, ${offsetDwords / 4}).${channel}`;
|
|
2503
2638
|
} else if (info.kind === "ubo") {
|
|
2504
2639
|
if (aligned) {
|
|
2505
2640
|
const row = `(${element}) * ${info.strideDwords / 4}${offsetDwords ? ` + ${offsetDwords / 4}` : ""}`;
|
|
@@ -2535,6 +2670,7 @@ DxbcGlslEmitter.prototype._resinfo = function _resinfo(state, instruction) {
|
|
|
2535
2670
|
as: "int"
|
|
2536
2671
|
});
|
|
2537
2672
|
const texOperand = instruction.operands[2];
|
|
2673
|
+
this._rejectDetailArrayMapUse(state, instruction, texOperand);
|
|
2538
2674
|
const dimension = this._resourceDimension(state, instruction, texOperand);
|
|
2539
2675
|
const axisCount = dimension === 5 || dimension === 8 ? 3 : 2;
|
|
2540
2676
|
const returnType = instruction.resinfoReturnTypeName || "float";
|
|
@@ -2604,8 +2740,14 @@ DxbcGlslEmitter.prototype._gather4 = function _gather4(state, instruction) {
|
|
|
2604
2740
|
offset: instruction.offset
|
|
2605
2741
|
});
|
|
2606
2742
|
}
|
|
2607
|
-
|
|
2608
|
-
|
|
2743
|
+
// A merged detail map is declared 2D but sampled through an array, so the
|
|
2744
|
+
// array helper and the layered coordinate are selected by the merge rather
|
|
2745
|
+
// than by the declared dimension.
|
|
2746
|
+
const detailLayer = this._detailMapArrayLayer(state, texOperand);
|
|
2747
|
+
const asArray = dimension === 8 || detailLayer !== null;
|
|
2748
|
+
const helper = this.helpers.require(asArray ? "hlslcc_textureGather4ArrayEmulated" : "hlslcc_textureGather4Emulated");
|
|
2749
|
+
const baseCoord = this._vecArg(state, coordOperand, dimension === 8 ? "xyz" : "xy");
|
|
2750
|
+
const coord = detailLayer === null ? baseCoord : `vec3(${baseCoord}, ${detailLayer}.0)`;
|
|
2609
2751
|
const texName = state.formatter.registerReference(texOperand);
|
|
2610
2752
|
const channelLetter = this._gather4Channel(samplerOperand);
|
|
2611
2753
|
const channelIndex = "xyzw".indexOf(channelLetter);
|