@forgeax/engine-assets-runtime 0.1.19 → 0.1.20
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/dist/.tsbuildinfo +1 -1
- package/dist/__tests__/texture-pack-loader.unit.test.d.ts +2 -0
- package/dist/__tests__/texture-pack-loader.unit.test.d.ts.map +1 -0
- package/dist/decode-image-bytes.d.ts +2 -2
- package/dist/decode-image-bytes.d.ts.map +1 -1
- package/dist/errors/asset.d.ts +20 -0
- package/dist/errors/asset.d.ts.map +1 -1
- package/dist/index.mjs +259 -231
- package/dist/index.mjs.map +1 -1
- package/dist/loaders/pack-artifact.d.ts +25 -1
- package/dist/loaders/pack-artifact.d.ts.map +1 -1
- package/dist/registry/validate-material.d.ts +25 -0
- package/dist/registry/validate-material.d.ts.map +1 -1
- package/package.json +14 -14
- package/src/__tests__/decode-image-bytes.browser.test.ts +5 -8
- package/src/__tests__/pack-basis-load.integration.test.ts +66 -7
- package/src/__tests__/texture-pack-loader.unit.test.ts +145 -0
- package/src/decode-image-bytes.ts +6 -11
- package/src/errors/asset.ts +33 -0
- package/src/loaders/pack-artifact.ts +218 -17
- package/src/registry/validate-material.ts +54 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"texture-pack-loader.unit.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/texture-pack-loader.unit.test.ts"],"names":[],"mappings":""}
|
|
@@ -25,8 +25,8 @@ import type { ImageError, Result, TextureAsset } from '@forgeax/engine-types';
|
|
|
25
25
|
* @param opts - Optional decode overrides:
|
|
26
26
|
* - `colorSpace`: `'srgb'` (default) or `'linear'`. Derives POD `format`:
|
|
27
27
|
* `srgb -> 'rgba8unorm-srgb'`, `linear -> 'rgba8unorm'`.
|
|
28
|
-
* - `mipmap`: `true` (default) or `false`. When true,
|
|
29
|
-
*
|
|
28
|
+
* - `mipmap`: `true` (default) or `false`. When true, the producer requests
|
|
29
|
+
* generated mips; when false, it keeps one authored level.
|
|
30
30
|
* @returns `ok(TextureAsset)` on success; `err(ImageError)` on failure.
|
|
31
31
|
*
|
|
32
32
|
* @example
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decode-image-bytes.d.ts","sourceRoot":"","sources":["../src/decode-image-bytes.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"decode-image-bytes.d.ts","sourceRoot":"","sources":["../src/decode-image-bytes.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAY9E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,UAAU,GAAG,WAAW,EAC/B,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE;IAAE,UAAU,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GAC9D,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC,CA8B3C"}
|
package/dist/errors/asset.d.ts
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
import type { MeshBinHeaderV4 } from '@forgeax/engine-pack';
|
|
2
2
|
import { AssetError, type AssetMeshBinContractFacts, type AssetMeshBinContractViolationReason } from '@forgeax/engine-types';
|
|
3
|
+
export type TexturePackVerificationCause = 'byte-length' | 'digest-mismatch' | 'packing-order-mismatch' | 'shape-mismatch';
|
|
4
|
+
export interface TexturePackVerificationDetail {
|
|
5
|
+
readonly guid: string;
|
|
6
|
+
readonly sourceKey: string;
|
|
7
|
+
readonly generation: number;
|
|
8
|
+
readonly stage: 'producer' | 'loader';
|
|
9
|
+
readonly cause: TexturePackVerificationCause;
|
|
10
|
+
readonly expectedBytes?: number;
|
|
11
|
+
readonly actualBytes?: number;
|
|
12
|
+
readonly expectedDigest?: string;
|
|
13
|
+
readonly actualDigest?: string;
|
|
14
|
+
}
|
|
15
|
+
/** Structured failure for the producer/loader texture contract. */
|
|
16
|
+
export declare class TexturePackVerificationError extends Error {
|
|
17
|
+
readonly code: "texture-pack-verification-failed";
|
|
18
|
+
readonly expected: string;
|
|
19
|
+
readonly hint = "repair the producer output and retry the same texture GUID generation";
|
|
20
|
+
readonly detail: TexturePackVerificationDetail;
|
|
21
|
+
constructor(detail: TexturePackVerificationDetail, expected: string);
|
|
22
|
+
}
|
|
3
23
|
export declare class MeshBinAssetError extends AssetError {
|
|
4
24
|
readonly subject: "mesh-bin";
|
|
5
25
|
readonly sourceKey: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"asset.d.ts","sourceRoot":"","sources":["../../src/errors/asset.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"asset.d.ts","sourceRoot":"","sources":["../../src/errors/asset.ts"],"names":[],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -695,217 +695,6 @@ function unpackMeshBinV4(bytes, sourceKey) {
|
|
|
695
695
|
};
|
|
696
696
|
return ok(mesh);
|
|
697
697
|
}
|
|
698
|
-
var deviceCache = /* @__PURE__ */ new WeakMap();
|
|
699
|
-
var MIPMAP_WGSL = `
|
|
700
|
-
struct VsOut {
|
|
701
|
-
@builtin(position) clip : vec4<f32>,
|
|
702
|
-
@location(0) uv : vec2<f32>,
|
|
703
|
-
};
|
|
704
|
-
|
|
705
|
-
@vertex
|
|
706
|
-
fn vs_main(@builtin(vertex_index) vid : u32) -> VsOut {
|
|
707
|
-
// 3 vertices forming an oversized triangle: (-1,-1), (-1,3), (3,-1)
|
|
708
|
-
var positions = array<vec2<f32>, 3>(
|
|
709
|
-
vec2<f32>(-1.0, -1.0),
|
|
710
|
-
vec2<f32>(-1.0, 3.0),
|
|
711
|
-
vec2<f32>( 3.0, -1.0),
|
|
712
|
-
);
|
|
713
|
-
let pos = positions[vid];
|
|
714
|
-
var out : VsOut;
|
|
715
|
-
out.clip = vec4<f32>(pos, 0.0, 1.0);
|
|
716
|
-
// NDC -> UV with Y-flip fused into a single MAD.
|
|
717
|
-
out.uv = pos * vec2<f32>(0.5, -0.5) + vec2<f32>(0.5);
|
|
718
|
-
return out;
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
@group(0) @binding(0) var src_sampler : sampler;
|
|
722
|
-
@group(0) @binding(1) var src_texture : texture_2d<f32>;
|
|
723
|
-
|
|
724
|
-
@fragment
|
|
725
|
-
fn fs_main(in : VsOut) -> @location(0) vec4<f32> {
|
|
726
|
-
return textureSample(src_texture, src_sampler, in.uv);
|
|
727
|
-
}
|
|
728
|
-
`;
|
|
729
|
-
function numMipLevels(size) {
|
|
730
|
-
const max = Math.max(size.width, size.height);
|
|
731
|
-
if (max <= 1) return 1;
|
|
732
|
-
return Math.floor(Math.log2(max)) + 1;
|
|
733
|
-
}
|
|
734
|
-
function mipmapCacheSize(device) {
|
|
735
|
-
const cache = deviceCache.get(device);
|
|
736
|
-
return cache?.pipelines.size ?? 0;
|
|
737
|
-
}
|
|
738
|
-
async function getOrCreateMipmapPipeline(device, format, asyncCreateShaderModule) {
|
|
739
|
-
const cache = await ensureDeviceCache(device, asyncCreateShaderModule);
|
|
740
|
-
if (!cache.ok) return cache;
|
|
741
|
-
const existing = cache.value.pipelines.get(format);
|
|
742
|
-
if (existing !== void 0) {
|
|
743
|
-
return ok$1(existing);
|
|
744
|
-
}
|
|
745
|
-
const layoutRes = device.createPipelineLayout({
|
|
746
|
-
label: "mipmap-pl",
|
|
747
|
-
bindGroupLayouts: [cache.value.layout]
|
|
748
|
-
});
|
|
749
|
-
if (!layoutRes.ok) return layoutRes;
|
|
750
|
-
const pipelineRes = device.createRenderPipeline({
|
|
751
|
-
label: `mipmap-pipeline-${format}`,
|
|
752
|
-
layout: layoutRes.value,
|
|
753
|
-
vertex: { module: cache.value.module, entryPoint: "vs_main" },
|
|
754
|
-
fragment: {
|
|
755
|
-
module: cache.value.module,
|
|
756
|
-
entryPoint: "fs_main",
|
|
757
|
-
targets: [{ format }]
|
|
758
|
-
},
|
|
759
|
-
primitive: { topology: "triangle-list" }
|
|
760
|
-
});
|
|
761
|
-
if (!pipelineRes.ok) return pipelineRes;
|
|
762
|
-
cache.value.pipelines.set(format, pipelineRes.value);
|
|
763
|
-
return pipelineRes;
|
|
764
|
-
}
|
|
765
|
-
async function ensureDeviceCache(device, asyncCreateShaderModule) {
|
|
766
|
-
const existing = deviceCache.get(device);
|
|
767
|
-
if (existing !== void 0) return ok$1(existing);
|
|
768
|
-
const moduleRes = await asyncCreateShaderModule(device, {
|
|
769
|
-
code: MIPMAP_WGSL,
|
|
770
|
-
label: "mipmap-wgsl"
|
|
771
|
-
});
|
|
772
|
-
if (!moduleRes.ok) return moduleRes;
|
|
773
|
-
const samplerRes = device.createSampler({
|
|
774
|
-
magFilter: "linear",
|
|
775
|
-
minFilter: "linear",
|
|
776
|
-
mipmapFilter: "linear"
|
|
777
|
-
});
|
|
778
|
-
if (!samplerRes.ok) return samplerRes;
|
|
779
|
-
const FRAGMENT_STAGE = 2;
|
|
780
|
-
const layoutRes = device.createBindGroupLayout({
|
|
781
|
-
label: "mipmap-bgl",
|
|
782
|
-
entries: [
|
|
783
|
-
{ binding: 0, visibility: FRAGMENT_STAGE, sampler: { type: "filtering" } },
|
|
784
|
-
{
|
|
785
|
-
binding: 1,
|
|
786
|
-
visibility: FRAGMENT_STAGE,
|
|
787
|
-
texture: { sampleType: "float", viewDimension: "2d" }
|
|
788
|
-
}
|
|
789
|
-
]
|
|
790
|
-
});
|
|
791
|
-
if (!layoutRes.ok) return layoutRes;
|
|
792
|
-
const cache = {
|
|
793
|
-
sampler: samplerRes.value,
|
|
794
|
-
module: moduleRes.value,
|
|
795
|
-
layout: layoutRes.value,
|
|
796
|
-
pipelines: /* @__PURE__ */ new Map()
|
|
797
|
-
};
|
|
798
|
-
deviceCache.set(device, cache);
|
|
799
|
-
return ok$1(cache);
|
|
800
|
-
}
|
|
801
|
-
function recordMipmapBlit(device, texture, levels, pipeline, cache) {
|
|
802
|
-
const encoderRes = device.createCommandEncoder({ label: "mipmap-encoder" });
|
|
803
|
-
if (!encoderRes.ok) return encoderRes;
|
|
804
|
-
const encoder = encoderRes.value;
|
|
805
|
-
for (let i = 1; i < levels; i++) {
|
|
806
|
-
const srcViewRes = device.createTextureView(texture, {
|
|
807
|
-
baseMipLevel: i - 1,
|
|
808
|
-
mipLevelCount: 1,
|
|
809
|
-
dimension: "2d"
|
|
810
|
-
});
|
|
811
|
-
if (!srcViewRes.ok) return srcViewRes;
|
|
812
|
-
const dstViewRes = device.createTextureView(texture, {
|
|
813
|
-
baseMipLevel: i,
|
|
814
|
-
mipLevelCount: 1,
|
|
815
|
-
dimension: "2d"
|
|
816
|
-
});
|
|
817
|
-
if (!dstViewRes.ok) return dstViewRes;
|
|
818
|
-
const bindGroupRes = device.createBindGroup({
|
|
819
|
-
label: `mipmap-bg-${i}`,
|
|
820
|
-
layout: cache.layout,
|
|
821
|
-
entries: [
|
|
822
|
-
{ binding: 0, resource: { kind: "sampler", value: cache.sampler } },
|
|
823
|
-
{ binding: 1, resource: { kind: "textureView", value: srcViewRes.value } }
|
|
824
|
-
]
|
|
825
|
-
});
|
|
826
|
-
if (!bindGroupRes.ok) return bindGroupRes;
|
|
827
|
-
const pass = encoder.beginRenderPass({
|
|
828
|
-
label: `mipmap-pass-${i}`,
|
|
829
|
-
colorAttachments: [
|
|
830
|
-
{
|
|
831
|
-
view: dstViewRes.value,
|
|
832
|
-
clearValue: { r: 0, g: 0, b: 0, a: 1 },
|
|
833
|
-
loadOp: "clear",
|
|
834
|
-
storeOp: "store"
|
|
835
|
-
}
|
|
836
|
-
]
|
|
837
|
-
});
|
|
838
|
-
pass.setPipeline(pipeline);
|
|
839
|
-
pass.setBindGroup(0, bindGroupRes.value);
|
|
840
|
-
pass.draw(3, 1, 0, 0);
|
|
841
|
-
pass.end();
|
|
842
|
-
}
|
|
843
|
-
const finishRes = encoder.finish();
|
|
844
|
-
if (!finishRes.ok) return finishRes;
|
|
845
|
-
return device.queue.submit([finishRes.value]);
|
|
846
|
-
}
|
|
847
|
-
function blitMipmapsSync(device, texture, descriptor) {
|
|
848
|
-
const levels = descriptor.levels ?? numMipLevels(descriptor);
|
|
849
|
-
if (levels <= 1) return ok$1(void 0);
|
|
850
|
-
const cache = deviceCache.get(device);
|
|
851
|
-
if (cache === void 0) {
|
|
852
|
-
return err(
|
|
853
|
-
new RhiError({
|
|
854
|
-
code: "rhi-not-available",
|
|
855
|
-
expected: "mipmap pipeline cache prewarmed for this device before blitMipmapsSync",
|
|
856
|
-
hint: "call prewarmMipmapPipeline(device, formats) at renderer.ready before the synchronous record-stage mipmap blit"
|
|
857
|
-
})
|
|
858
|
-
);
|
|
859
|
-
}
|
|
860
|
-
const pipeline = cache.pipelines.get(descriptor.format);
|
|
861
|
-
if (pipeline === void 0) {
|
|
862
|
-
return err(
|
|
863
|
-
new RhiError({
|
|
864
|
-
code: "rhi-not-available",
|
|
865
|
-
expected: `mipmap pipeline for format ${descriptor.format} prewarmed`,
|
|
866
|
-
hint: `format ${descriptor.format} was not prewarmed; add it to the prewarmMipmapPipeline format list at renderer.ready`
|
|
867
|
-
})
|
|
868
|
-
);
|
|
869
|
-
}
|
|
870
|
-
return recordMipmapBlit(device, texture, levels, pipeline, cache);
|
|
871
|
-
}
|
|
872
|
-
function encodeMipmapLevel(device, pass, sourceView, format) {
|
|
873
|
-
const cache = deviceCache.get(device);
|
|
874
|
-
if (cache === void 0) {
|
|
875
|
-
return err(
|
|
876
|
-
new RhiError({
|
|
877
|
-
code: "rhi-not-available",
|
|
878
|
-
expected: "mipmap pipeline cache prewarmed for the graph device before encoding",
|
|
879
|
-
hint: "call prewarmMipmapPipeline(device, formats) at renderer.ready"
|
|
880
|
-
})
|
|
881
|
-
);
|
|
882
|
-
}
|
|
883
|
-
const pipeline = cache.pipelines.get(format);
|
|
884
|
-
if (pipeline === void 0) {
|
|
885
|
-
return err(
|
|
886
|
-
new RhiError({
|
|
887
|
-
code: "rhi-not-available",
|
|
888
|
-
expected: `mipmap pipeline for format ${format} prewarmed`,
|
|
889
|
-
hint: `format ${format} was not prewarmed; add it to the renderer prewarm list`
|
|
890
|
-
})
|
|
891
|
-
);
|
|
892
|
-
}
|
|
893
|
-
const bindGroup = device.createBindGroup({
|
|
894
|
-
label: "mipmap-graph-bind-group",
|
|
895
|
-
layout: cache.layout,
|
|
896
|
-
entries: [
|
|
897
|
-
{ binding: 0, resource: { kind: "sampler", value: cache.sampler } },
|
|
898
|
-
{ binding: 1, resource: { kind: "textureView", value: sourceView } }
|
|
899
|
-
]
|
|
900
|
-
});
|
|
901
|
-
if (!bindGroup.ok) return bindGroup;
|
|
902
|
-
pass.setPipeline(pipeline);
|
|
903
|
-
pass.setBindGroup(0, bindGroup.value);
|
|
904
|
-
pass.draw(3, 1, 0, 0);
|
|
905
|
-
return ok$1(void 0);
|
|
906
|
-
}
|
|
907
|
-
|
|
908
|
-
// src/loaders/pack-artifact.ts
|
|
909
698
|
function firstArtifact(input) {
|
|
910
699
|
return input.artifacts.body ?? Object.values(input.artifacts)[0];
|
|
911
700
|
}
|
|
@@ -916,6 +705,34 @@ function payloadNumber(payload, key2, fallback) {
|
|
|
916
705
|
function payloadColorSpace(payload) {
|
|
917
706
|
return payload.colorSpace === "linear" ? "linear" : "srgb";
|
|
918
707
|
}
|
|
708
|
+
function payloadTextureShape(payload) {
|
|
709
|
+
const shape = payload.shape;
|
|
710
|
+
if (!record(shape) || typeof shape.viewDimension !== "string" || !record(shape.extent)) {
|
|
711
|
+
return void 0;
|
|
712
|
+
}
|
|
713
|
+
const { width, height, layers, depth } = shape.extent;
|
|
714
|
+
if (!positiveInteger(width) || !positiveInteger(height)) return void 0;
|
|
715
|
+
if (shape.viewDimension === "2d" && layers === void 0 && depth === void 0) {
|
|
716
|
+
return { viewDimension: "2d", extent: { width, height } };
|
|
717
|
+
}
|
|
718
|
+
if (shape.viewDimension === "2d-array" && positiveInteger(layers) && depth === void 0) {
|
|
719
|
+
return { viewDimension: "2d-array", extent: { width, height, layers } };
|
|
720
|
+
}
|
|
721
|
+
if (shape.viewDimension === "3d" && positiveInteger(depth) && layers === void 0) {
|
|
722
|
+
return { viewDimension: "3d", extent: { width, height, depth } };
|
|
723
|
+
}
|
|
724
|
+
return void 0;
|
|
725
|
+
}
|
|
726
|
+
function payloadTextureMips(payload) {
|
|
727
|
+
const mips = payload.mips;
|
|
728
|
+
if (!record(mips) || typeof mips.kind !== "string") return void 0;
|
|
729
|
+
if (mips.kind === "none") return { kind: "none" };
|
|
730
|
+
if (mips.kind === "generate") return { kind: "generate" };
|
|
731
|
+
if (mips.kind === "packed" && positiveInteger(mips.levelCount)) {
|
|
732
|
+
return { kind: "packed", levelCount: mips.levelCount };
|
|
733
|
+
}
|
|
734
|
+
return void 0;
|
|
735
|
+
}
|
|
919
736
|
function invalidPackAsset(input, expected) {
|
|
920
737
|
return {
|
|
921
738
|
ok: false,
|
|
@@ -1070,8 +887,6 @@ async function loadTexturePack(input, ctx) {
|
|
|
1070
887
|
if (artifact === void 0)
|
|
1071
888
|
return invalidPackAsset(input, "texture asset-local image artifact");
|
|
1072
889
|
const payload = input.payload;
|
|
1073
|
-
const width = payloadNumber(payload, "width", 0);
|
|
1074
|
-
const height = payloadNumber(payload, "height", 0);
|
|
1075
890
|
const colorSpace = payloadColorSpace(payload);
|
|
1076
891
|
const codec = artifact.descriptor.assetCodec;
|
|
1077
892
|
const profile = codecProfile(codec);
|
|
@@ -1119,13 +934,14 @@ async function loadTexturePack(input, ctx) {
|
|
|
1119
934
|
ok: true,
|
|
1120
935
|
value: {
|
|
1121
936
|
kind: "texture",
|
|
1122
|
-
|
|
1123
|
-
|
|
937
|
+
shape: {
|
|
938
|
+
viewDimension: "2d",
|
|
939
|
+
extent: { width: transcoded.value.width, height: transcoded.value.height }
|
|
940
|
+
},
|
|
1124
941
|
format: target,
|
|
1125
942
|
data,
|
|
1126
943
|
colorSpace,
|
|
1127
|
-
|
|
1128
|
-
mipLevelCount: Math.max(1, transcoded.value.mips.length)
|
|
944
|
+
mips: { kind: "packed", levelCount: Math.max(1, transcoded.value.mips.length) }
|
|
1129
945
|
}
|
|
1130
946
|
};
|
|
1131
947
|
} catch (error) {
|
|
@@ -1203,13 +1019,14 @@ async function loadTexturePack(input, ctx) {
|
|
|
1203
1019
|
ok: true,
|
|
1204
1020
|
value: {
|
|
1205
1021
|
kind: "texture",
|
|
1206
|
-
|
|
1207
|
-
|
|
1022
|
+
shape: {
|
|
1023
|
+
viewDimension: "2d",
|
|
1024
|
+
extent: { width: transcoded.value.width, height: transcoded.value.height }
|
|
1025
|
+
},
|
|
1208
1026
|
format: target,
|
|
1209
1027
|
data,
|
|
1210
1028
|
colorSpace,
|
|
1211
|
-
|
|
1212
|
-
mipLevelCount: Math.max(1, transcoded.value.mips.length)
|
|
1029
|
+
mips: { kind: "packed", levelCount: Math.max(1, transcoded.value.mips.length) }
|
|
1213
1030
|
}
|
|
1214
1031
|
};
|
|
1215
1032
|
} catch (error) {
|
|
@@ -1234,18 +1051,23 @@ async function loadTexturePack(input, ctx) {
|
|
|
1234
1051
|
};
|
|
1235
1052
|
}
|
|
1236
1053
|
}
|
|
1237
|
-
const
|
|
1054
|
+
const shape = payloadTextureShape(payload);
|
|
1055
|
+
const mips = payloadTextureMips(payload);
|
|
1056
|
+
if (shape === void 0 || mips === void 0) {
|
|
1057
|
+
return invalidPackAsset(
|
|
1058
|
+
input,
|
|
1059
|
+
"texture payload with a valid shape and mip policy"
|
|
1060
|
+
);
|
|
1061
|
+
}
|
|
1238
1062
|
return {
|
|
1239
1063
|
ok: true,
|
|
1240
1064
|
value: {
|
|
1241
1065
|
kind: "texture",
|
|
1242
|
-
|
|
1243
|
-
height,
|
|
1066
|
+
shape,
|
|
1244
1067
|
format: payload.format ?? (colorSpace === "srgb" ? "rgba8unorm-srgb" : "rgba8unorm"),
|
|
1245
1068
|
data: artifact.bytes,
|
|
1246
1069
|
colorSpace,
|
|
1247
|
-
|
|
1248
|
-
mipLevelCount: mipmap ? numMipLevels({ width, height }) : 1
|
|
1070
|
+
mips
|
|
1249
1071
|
}
|
|
1250
1072
|
};
|
|
1251
1073
|
}
|
|
@@ -6899,16 +6721,13 @@ async function decodeImageBytes(bytes, mime, opts = {}) {
|
|
|
6899
6721
|
}
|
|
6900
6722
|
const dec = decoded.value;
|
|
6901
6723
|
const format = colorSpace === "srgb" ? "rgba8unorm-srgb" : "rgba8unorm";
|
|
6902
|
-
const mipLevelCount = mipmap ? numMipLevels({ width: dec.width, height: dec.height }) : 1;
|
|
6903
6724
|
const pod = {
|
|
6904
6725
|
kind: "texture",
|
|
6905
|
-
width: dec.width,
|
|
6906
|
-
height: dec.height,
|
|
6726
|
+
shape: { viewDimension: "2d", extent: { width: dec.width, height: dec.height } },
|
|
6907
6727
|
format,
|
|
6908
6728
|
data: dec.bytes,
|
|
6909
6729
|
colorSpace,
|
|
6910
|
-
mipmap
|
|
6911
|
-
mipLevelCount
|
|
6730
|
+
mips: mipmap ? { kind: "generate" } : { kind: "none" }
|
|
6912
6731
|
};
|
|
6913
6732
|
return ok(pod);
|
|
6914
6733
|
}
|
|
@@ -8318,6 +8137,215 @@ function inspectMaterialRuntime(ready) {
|
|
|
8318
8137
|
status: "Ready"
|
|
8319
8138
|
};
|
|
8320
8139
|
}
|
|
8140
|
+
var deviceCache = /* @__PURE__ */ new WeakMap();
|
|
8141
|
+
var MIPMAP_WGSL = `
|
|
8142
|
+
struct VsOut {
|
|
8143
|
+
@builtin(position) clip : vec4<f32>,
|
|
8144
|
+
@location(0) uv : vec2<f32>,
|
|
8145
|
+
};
|
|
8146
|
+
|
|
8147
|
+
@vertex
|
|
8148
|
+
fn vs_main(@builtin(vertex_index) vid : u32) -> VsOut {
|
|
8149
|
+
// 3 vertices forming an oversized triangle: (-1,-1), (-1,3), (3,-1)
|
|
8150
|
+
var positions = array<vec2<f32>, 3>(
|
|
8151
|
+
vec2<f32>(-1.0, -1.0),
|
|
8152
|
+
vec2<f32>(-1.0, 3.0),
|
|
8153
|
+
vec2<f32>( 3.0, -1.0),
|
|
8154
|
+
);
|
|
8155
|
+
let pos = positions[vid];
|
|
8156
|
+
var out : VsOut;
|
|
8157
|
+
out.clip = vec4<f32>(pos, 0.0, 1.0);
|
|
8158
|
+
// NDC -> UV with Y-flip fused into a single MAD.
|
|
8159
|
+
out.uv = pos * vec2<f32>(0.5, -0.5) + vec2<f32>(0.5);
|
|
8160
|
+
return out;
|
|
8161
|
+
}
|
|
8162
|
+
|
|
8163
|
+
@group(0) @binding(0) var src_sampler : sampler;
|
|
8164
|
+
@group(0) @binding(1) var src_texture : texture_2d<f32>;
|
|
8165
|
+
|
|
8166
|
+
@fragment
|
|
8167
|
+
fn fs_main(in : VsOut) -> @location(0) vec4<f32> {
|
|
8168
|
+
return textureSample(src_texture, src_sampler, in.uv);
|
|
8169
|
+
}
|
|
8170
|
+
`;
|
|
8171
|
+
function numMipLevels(size) {
|
|
8172
|
+
const max = Math.max(size.width, size.height);
|
|
8173
|
+
if (max <= 1) return 1;
|
|
8174
|
+
return Math.floor(Math.log2(max)) + 1;
|
|
8175
|
+
}
|
|
8176
|
+
function mipmapCacheSize(device) {
|
|
8177
|
+
const cache = deviceCache.get(device);
|
|
8178
|
+
return cache?.pipelines.size ?? 0;
|
|
8179
|
+
}
|
|
8180
|
+
async function getOrCreateMipmapPipeline(device, format, asyncCreateShaderModule) {
|
|
8181
|
+
const cache = await ensureDeviceCache(device, asyncCreateShaderModule);
|
|
8182
|
+
if (!cache.ok) return cache;
|
|
8183
|
+
const existing = cache.value.pipelines.get(format);
|
|
8184
|
+
if (existing !== void 0) {
|
|
8185
|
+
return ok$1(existing);
|
|
8186
|
+
}
|
|
8187
|
+
const layoutRes = device.createPipelineLayout({
|
|
8188
|
+
label: "mipmap-pl",
|
|
8189
|
+
bindGroupLayouts: [cache.value.layout]
|
|
8190
|
+
});
|
|
8191
|
+
if (!layoutRes.ok) return layoutRes;
|
|
8192
|
+
const pipelineRes = device.createRenderPipeline({
|
|
8193
|
+
label: `mipmap-pipeline-${format}`,
|
|
8194
|
+
layout: layoutRes.value,
|
|
8195
|
+
vertex: { module: cache.value.module, entryPoint: "vs_main" },
|
|
8196
|
+
fragment: {
|
|
8197
|
+
module: cache.value.module,
|
|
8198
|
+
entryPoint: "fs_main",
|
|
8199
|
+
targets: [{ format }]
|
|
8200
|
+
},
|
|
8201
|
+
primitive: { topology: "triangle-list" }
|
|
8202
|
+
});
|
|
8203
|
+
if (!pipelineRes.ok) return pipelineRes;
|
|
8204
|
+
cache.value.pipelines.set(format, pipelineRes.value);
|
|
8205
|
+
return pipelineRes;
|
|
8206
|
+
}
|
|
8207
|
+
async function ensureDeviceCache(device, asyncCreateShaderModule) {
|
|
8208
|
+
const existing = deviceCache.get(device);
|
|
8209
|
+
if (existing !== void 0) return ok$1(existing);
|
|
8210
|
+
const moduleRes = await asyncCreateShaderModule(device, {
|
|
8211
|
+
code: MIPMAP_WGSL,
|
|
8212
|
+
label: "mipmap-wgsl"
|
|
8213
|
+
});
|
|
8214
|
+
if (!moduleRes.ok) return moduleRes;
|
|
8215
|
+
const samplerRes = device.createSampler({
|
|
8216
|
+
magFilter: "linear",
|
|
8217
|
+
minFilter: "linear",
|
|
8218
|
+
mipmapFilter: "linear"
|
|
8219
|
+
});
|
|
8220
|
+
if (!samplerRes.ok) return samplerRes;
|
|
8221
|
+
const FRAGMENT_STAGE = 2;
|
|
8222
|
+
const layoutRes = device.createBindGroupLayout({
|
|
8223
|
+
label: "mipmap-bgl",
|
|
8224
|
+
entries: [
|
|
8225
|
+
{ binding: 0, visibility: FRAGMENT_STAGE, sampler: { type: "filtering" } },
|
|
8226
|
+
{
|
|
8227
|
+
binding: 1,
|
|
8228
|
+
visibility: FRAGMENT_STAGE,
|
|
8229
|
+
texture: { sampleType: "float", viewDimension: "2d" }
|
|
8230
|
+
}
|
|
8231
|
+
]
|
|
8232
|
+
});
|
|
8233
|
+
if (!layoutRes.ok) return layoutRes;
|
|
8234
|
+
const cache = {
|
|
8235
|
+
sampler: samplerRes.value,
|
|
8236
|
+
module: moduleRes.value,
|
|
8237
|
+
layout: layoutRes.value,
|
|
8238
|
+
pipelines: /* @__PURE__ */ new Map()
|
|
8239
|
+
};
|
|
8240
|
+
deviceCache.set(device, cache);
|
|
8241
|
+
return ok$1(cache);
|
|
8242
|
+
}
|
|
8243
|
+
function recordMipmapBlit(device, texture, levels, pipeline, cache) {
|
|
8244
|
+
const encoderRes = device.createCommandEncoder({ label: "mipmap-encoder" });
|
|
8245
|
+
if (!encoderRes.ok) return encoderRes;
|
|
8246
|
+
const encoder = encoderRes.value;
|
|
8247
|
+
for (let i = 1; i < levels; i++) {
|
|
8248
|
+
const srcViewRes = device.createTextureView(texture, {
|
|
8249
|
+
baseMipLevel: i - 1,
|
|
8250
|
+
mipLevelCount: 1,
|
|
8251
|
+
dimension: "2d"
|
|
8252
|
+
});
|
|
8253
|
+
if (!srcViewRes.ok) return srcViewRes;
|
|
8254
|
+
const dstViewRes = device.createTextureView(texture, {
|
|
8255
|
+
baseMipLevel: i,
|
|
8256
|
+
mipLevelCount: 1,
|
|
8257
|
+
dimension: "2d"
|
|
8258
|
+
});
|
|
8259
|
+
if (!dstViewRes.ok) return dstViewRes;
|
|
8260
|
+
const bindGroupRes = device.createBindGroup({
|
|
8261
|
+
label: `mipmap-bg-${i}`,
|
|
8262
|
+
layout: cache.layout,
|
|
8263
|
+
entries: [
|
|
8264
|
+
{ binding: 0, resource: { kind: "sampler", value: cache.sampler } },
|
|
8265
|
+
{ binding: 1, resource: { kind: "textureView", value: srcViewRes.value } }
|
|
8266
|
+
]
|
|
8267
|
+
});
|
|
8268
|
+
if (!bindGroupRes.ok) return bindGroupRes;
|
|
8269
|
+
const pass = encoder.beginRenderPass({
|
|
8270
|
+
label: `mipmap-pass-${i}`,
|
|
8271
|
+
colorAttachments: [
|
|
8272
|
+
{
|
|
8273
|
+
view: dstViewRes.value,
|
|
8274
|
+
clearValue: { r: 0, g: 0, b: 0, a: 1 },
|
|
8275
|
+
loadOp: "clear",
|
|
8276
|
+
storeOp: "store"
|
|
8277
|
+
}
|
|
8278
|
+
]
|
|
8279
|
+
});
|
|
8280
|
+
pass.setPipeline(pipeline);
|
|
8281
|
+
pass.setBindGroup(0, bindGroupRes.value);
|
|
8282
|
+
pass.draw(3, 1, 0, 0);
|
|
8283
|
+
pass.end();
|
|
8284
|
+
}
|
|
8285
|
+
const finishRes = encoder.finish();
|
|
8286
|
+
if (!finishRes.ok) return finishRes;
|
|
8287
|
+
return device.queue.submit([finishRes.value]);
|
|
8288
|
+
}
|
|
8289
|
+
function blitMipmapsSync(device, texture, descriptor) {
|
|
8290
|
+
const levels = descriptor.levels ?? numMipLevels(descriptor);
|
|
8291
|
+
if (levels <= 1) return ok$1(void 0);
|
|
8292
|
+
const cache = deviceCache.get(device);
|
|
8293
|
+
if (cache === void 0) {
|
|
8294
|
+
return err(
|
|
8295
|
+
new RhiError({
|
|
8296
|
+
code: "rhi-not-available",
|
|
8297
|
+
expected: "mipmap pipeline cache prewarmed for this device before blitMipmapsSync",
|
|
8298
|
+
hint: "call prewarmMipmapPipeline(device, formats) at renderer.ready before the synchronous record-stage mipmap blit"
|
|
8299
|
+
})
|
|
8300
|
+
);
|
|
8301
|
+
}
|
|
8302
|
+
const pipeline = cache.pipelines.get(descriptor.format);
|
|
8303
|
+
if (pipeline === void 0) {
|
|
8304
|
+
return err(
|
|
8305
|
+
new RhiError({
|
|
8306
|
+
code: "rhi-not-available",
|
|
8307
|
+
expected: `mipmap pipeline for format ${descriptor.format} prewarmed`,
|
|
8308
|
+
hint: `format ${descriptor.format} was not prewarmed; add it to the prewarmMipmapPipeline format list at renderer.ready`
|
|
8309
|
+
})
|
|
8310
|
+
);
|
|
8311
|
+
}
|
|
8312
|
+
return recordMipmapBlit(device, texture, levels, pipeline, cache);
|
|
8313
|
+
}
|
|
8314
|
+
function encodeMipmapLevel(device, pass, sourceView, format) {
|
|
8315
|
+
const cache = deviceCache.get(device);
|
|
8316
|
+
if (cache === void 0) {
|
|
8317
|
+
return err(
|
|
8318
|
+
new RhiError({
|
|
8319
|
+
code: "rhi-not-available",
|
|
8320
|
+
expected: "mipmap pipeline cache prewarmed for the graph device before encoding",
|
|
8321
|
+
hint: "call prewarmMipmapPipeline(device, formats) at renderer.ready"
|
|
8322
|
+
})
|
|
8323
|
+
);
|
|
8324
|
+
}
|
|
8325
|
+
const pipeline = cache.pipelines.get(format);
|
|
8326
|
+
if (pipeline === void 0) {
|
|
8327
|
+
return err(
|
|
8328
|
+
new RhiError({
|
|
8329
|
+
code: "rhi-not-available",
|
|
8330
|
+
expected: `mipmap pipeline for format ${format} prewarmed`,
|
|
8331
|
+
hint: `format ${format} was not prewarmed; add it to the renderer prewarm list`
|
|
8332
|
+
})
|
|
8333
|
+
);
|
|
8334
|
+
}
|
|
8335
|
+
const bindGroup = device.createBindGroup({
|
|
8336
|
+
label: "mipmap-graph-bind-group",
|
|
8337
|
+
layout: cache.layout,
|
|
8338
|
+
entries: [
|
|
8339
|
+
{ binding: 0, resource: { kind: "sampler", value: cache.sampler } },
|
|
8340
|
+
{ binding: 1, resource: { kind: "textureView", value: sourceView } }
|
|
8341
|
+
]
|
|
8342
|
+
});
|
|
8343
|
+
if (!bindGroup.ok) return bindGroup;
|
|
8344
|
+
pass.setPipeline(pipeline);
|
|
8345
|
+
pass.setBindGroup(0, bindGroup.value);
|
|
8346
|
+
pass.draw(3, 1, 0, 0);
|
|
8347
|
+
return ok$1(void 0);
|
|
8348
|
+
}
|
|
8321
8349
|
|
|
8322
8350
|
// src/plugin.ts
|
|
8323
8351
|
function assetsPlugin(assets) {
|