@woosh/meep-engine 3.14.1 → 3.14.2
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 +31 -24
- package/package.json +1 -1
- package/src/avif/native/DECISIONS.md +544 -536
- package/src/avif/native/heif/parse_avif_file.d.ts.map +1 -1
- package/src/avif/native/heif/parse_avif_file.js +384 -383
- package/src/avif/native/heif/parse_image_grid.d.ts.map +1 -1
- package/src/avif/native/heif/parse_image_grid.js +49 -48
- package/src/basis/BasisBitReader.d.ts +77 -0
- package/src/basis/BasisBitReader.d.ts.map +1 -0
- package/src/basis/BasisBitReader.js +231 -0
- package/src/basis/BasisHuffmanTable.d.ts +53 -0
- package/src/basis/BasisHuffmanTable.d.ts.map +1 -0
- package/src/basis/BasisHuffmanTable.js +263 -0
- package/src/basis/basis_read_huffman_table.d.ts +20 -0
- package/src/basis/basis_read_huffman_table.d.ts.map +1 -0
- package/src/basis/basis_read_huffman_table.js +187 -0
- package/src/basis/etc1s/Etc1sSelectorHistory.d.ts +50 -0
- package/src/basis/etc1s/Etc1sSelectorHistory.d.ts.map +1 -0
- package/src/basis/etc1s/Etc1sSelectorHistory.js +89 -0
- package/src/basis/etc1s/etc1s_block_colors.d.ts +14 -0
- package/src/basis/etc1s/etc1s_block_colors.d.ts.map +1 -0
- package/src/basis/etc1s/etc1s_block_colors.js +75 -0
- package/src/basis/etc1s/etc1s_decode_slice.d.ts +57 -0
- package/src/basis/etc1s/etc1s_decode_slice.d.ts.map +1 -0
- package/src/basis/etc1s/etc1s_decode_slice.js +258 -0
- package/src/basis/etc1s/etc1s_read_endpoint_codebook.d.ts +48 -0
- package/src/basis/etc1s/etc1s_read_endpoint_codebook.d.ts.map +1 -0
- package/src/basis/etc1s/etc1s_read_endpoint_codebook.js +111 -0
- package/src/basis/etc1s/etc1s_read_selector_codebook.d.ts +42 -0
- package/src/basis/etc1s/etc1s_read_selector_codebook.d.ts.map +1 -0
- package/src/basis/etc1s/etc1s_read_selector_codebook.js +127 -0
- package/src/basis/etc1s/etc1s_read_slice_tables.d.ts +54 -0
- package/src/basis/etc1s/etc1s_read_slice_tables.d.ts.map +1 -0
- package/src/basis/etc1s/etc1s_read_slice_tables.js +47 -0
- package/src/basis/transcode/build_range_plan.js +54 -0
- package/src/basis/transcode/etc1s_to_bc1.d.ts +24 -0
- package/src/basis/transcode/etc1s_to_bc1.d.ts.map +1 -0
- package/src/basis/transcode/etc1s_to_bc1.js +205 -0
- package/src/basis/transcode/etc1s_to_bc7.d.ts +30 -0
- package/src/basis/transcode/etc1s_to_bc7.d.ts.map +1 -0
- package/src/basis/transcode/etc1s_to_bc7.js +496 -0
- package/src/basis/transcode/fit_endpoints.d.ts +59 -0
- package/src/basis/transcode/fit_endpoints.d.ts.map +1 -0
- package/src/basis/transcode/fit_endpoints.js +226 -0
- package/src/{avif/native/isobmff → core/binary}/ByteCursor.d.ts +19 -6
- package/src/core/binary/ByteCursor.d.ts.map +1 -0
- package/src/{avif/native/isobmff → core/binary}/ByteCursor.js +41 -14
- package/src/engine/EngineHarness.js +1 -1
- package/src/engine/asset/codec/Codec.d.ts.map +1 -0
- package/src/engine/asset/codec/CodecWithFallback.d.ts.map +1 -0
- package/src/engine/asset/{loaders/image/codec → codec}/CodecWithFallback.js +2 -2
- package/src/engine/asset/loaders/image/IMAGE_CODEC_REVIEW_2026_08_28.md +4 -4
- package/src/engine/asset/loaders/image/ImageRGBADataLoader.d.ts +1 -1
- package/src/engine/asset/loaders/image/ImageRGBADataLoader.d.ts.map +1 -1
- package/src/engine/asset/loaders/image/ImageRGBADataLoader.js +1 -1
- package/src/engine/asset/loaders/image/codec/NativeImageDecoder.d.ts +1 -1
- package/src/engine/asset/loaders/image/codec/NativeImageDecoder.d.ts.map +1 -1
- package/src/engine/asset/loaders/image/codec/NativeImageDecoder.js +1 -1
- package/src/engine/asset/loaders/image/codec/ThreadedImageDecoder.d.ts +1 -1
- package/src/engine/asset/loaders/image/codec/ThreadedImageDecoder.d.ts.map +1 -1
- package/src/engine/asset/loaders/image/codec/ThreadedImageDecoder.js +1 -1
- package/src/engine/graphics/texture/atlas/TextureAtlas.d.ts.map +1 -1
- package/src/engine/graphics/texture/atlas/TextureAtlas.js +13 -0
- package/src/engine/physics/broadphase/generate_pairs.d.ts.map +1 -1
- package/src/engine/physics/broadphase/generate_pairs.js +7 -1
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/ktx2/KTX2_IDENTIFIER.d.ts +14 -0
- package/src/ktx2/KTX2_IDENTIFIER.d.ts.map +1 -0
- package/src/ktx2/KTX2_IDENTIFIER.js +15 -0
- package/src/ktx2/KhrDfModel.d.ts +35 -0
- package/src/ktx2/KhrDfModel.d.ts.map +1 -0
- package/src/ktx2/KhrDfModel.js +49 -0
- package/src/ktx2/SupercompressionScheme.d.ts +16 -0
- package/src/ktx2/SupercompressionScheme.d.ts.map +1 -0
- package/src/ktx2/SupercompressionScheme.js +23 -0
- package/src/ktx2/ktx2_read.d.ts +71 -0
- package/src/ktx2/ktx2_read.d.ts.map +1 -0
- package/src/ktx2/ktx2_read.js +581 -0
- package/src/ktx2/ktx2_read_basis_lz_global_data.d.ts +27 -0
- package/src/ktx2/ktx2_read_basis_lz_global_data.d.ts.map +1 -0
- package/src/ktx2/ktx2_read_basis_lz_global_data.js +189 -0
- package/src/ktx2/vk_format_to_texture_format.d.ts +55 -0
- package/src/ktx2/vk_format_to_texture_format.d.ts.map +1 -0
- package/src/ktx2/vk_format_to_texture_format.js +290 -0
- package/src/shade/descriptor/GPUTextureUsage.d.ts +23 -0
- package/src/shade/descriptor/GPUTextureUsage.d.ts.map +1 -0
- package/src/shade/descriptor/GPUTextureUsage.js +24 -0
- package/src/shade/descriptor/WebGPUExtensionType.d.ts +3 -0
- package/src/shade/descriptor/WebGPUExtensionType.js +26 -0
- package/src/shade/descriptor/texture/TextureDescriptor.d.ts +2 -6
- package/src/shade/descriptor/texture/TextureDescriptor.d.ts.map +1 -1
- package/src/shade/descriptor/texture/TextureDescriptor.js +24 -40
- package/src/shade/descriptor/texture/format/TextureFormat.d.ts +125 -0
- package/src/shade/descriptor/texture/format/TextureFormat.d.ts.map +1 -0
- package/src/shade/descriptor/texture/format/TextureFormat.js +146 -0
- package/src/shade/descriptor/texture/format/gpu_texture_format_info.d.ts +60 -0
- package/src/shade/descriptor/texture/format/gpu_texture_format_info.d.ts.map +1 -1
- package/src/shade/descriptor/texture/format/gpu_texture_format_info.js +102 -0
- package/src/shade/device/graph/TextureResourceDescriptor.d.ts.map +1 -1
- package/src/shade/device/graph/TextureResourceDescriptor.js +160 -155
- package/src/shade/device/mock/SoftwareGPUQueue.d.ts +11 -4
- package/src/shade/device/mock/SoftwareGPUQueue.d.ts.map +1 -1
- package/src/shade/device/mock/SoftwareGPUQueue.js +31 -37
- package/src/shade/device/mock/SoftwareGPUTexture.d.ts.map +1 -1
- package/src/shade/device/mock/SoftwareGPUTexture.js +8 -4
- package/src/shade/device/timing/profile/frame_graph_extract_topology.d.ts.map +1 -1
- package/src/shade/device/timing/profile/frame_graph_extract_topology.js +164 -174
- package/src/shade/playground/ground_seam/README.md +235 -0
- package/src/shade/playground/ground_seam/capture_scene_color.d.ts +45 -0
- package/src/shade/playground/ground_seam/capture_scene_color.d.ts.map +1 -0
- package/src/shade/playground/ground_seam/capture_scene_color.js +242 -0
- package/src/shade/playground/ground_seam/depth_step_across_seam.d.ts +11 -0
- package/src/shade/playground/ground_seam/depth_step_across_seam.d.ts.map +1 -0
- package/src/shade/playground/ground_seam/depth_step_across_seam.js +185 -0
- package/src/shade/playground/ground_seam/index.html +195 -0
- package/src/shade/playground/ground_seam/main.d.ts +2 -0
- package/src/shade/playground/ground_seam/main.d.ts.map +1 -0
- package/src/shade/playground/ground_seam/main.js +879 -0
- package/src/shade/playground/ground_seam/make_grid_texture.d.ts +29 -0
- package/src/shade/playground/ground_seam/make_grid_texture.d.ts.map +1 -0
- package/src/shade/playground/ground_seam/make_grid_texture.js +105 -0
- package/src/shade/playground/ground_seam/make_ground.d.ts +70 -0
- package/src/shade/playground/ground_seam/make_ground.d.ts.map +1 -0
- package/src/shade/playground/ground_seam/make_ground.js +161 -0
- package/src/shade/playground/ground_seam/measure_flicker.d.ts +71 -0
- package/src/shade/playground/ground_seam/measure_flicker.d.ts.map +1 -0
- package/src/shade/playground/ground_seam/measure_flicker.js +531 -0
- package/src/shade/renderer/Renderer.d.ts.map +1 -1
- package/src/shade/renderer/Renderer.js +2519 -2511
- package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts.map +1 -1
- package/src/shade/renderer/hiz/HierarchicalZBuffer.js +275 -274
- package/src/shade/renderer/light/GPULightCollection.d.ts.map +1 -1
- package/src/shade/renderer/light/GPULightCollection.js +323 -314
- package/src/shade/renderer/lightmap/GPULightMap.js +336 -336
- package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts.map +1 -1
- package/src/shade/renderer/material/resident/GPUResidentMaterialContext.js +12 -2
- package/src/shade/renderer/material/standard/fragment_gbuffer.d.ts.map +1 -1
- package/src/shade/renderer/material/standard/fragment_gbuffer.js +3 -1
- package/src/shade/renderer/material/standard/fragment_gbuffer_vt.js +169 -169
- package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.d.ts.map +1 -1
- package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.js +3 -1
- package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
- package/src/shade/renderer/rasterize/native/oit/chunk_forward_shade_standard_fragment_brick4.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/oit/chunk_forward_shade_standard_fragment_brick4.js +3 -1
- package/src/shade/renderer/rasterize/native/oit/chunk_forward_shade_standard_fragment_ibl.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/oit/chunk_forward_shade_standard_fragment_ibl.js +3 -1
- package/src/shade/renderer/shader/chunk/geometry/normal/chunk_decode_tangent_normal.d.ts +28 -0
- package/src/shade/renderer/shader/chunk/geometry/normal/chunk_decode_tangent_normal.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/geometry/normal/chunk_decode_tangent_normal.js +39 -0
- package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_barycentric_full.d.ts +45 -0
- package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_barycentric_full.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_barycentric_full.js +94 -61
- package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_barycentric_solve.d.ts +24 -0
- package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_barycentric_solve.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_barycentric_solve.js +43 -0
- package/src/shade/renderer/texture/COMPRESSED_TEXTURE_PLAN_2026_09_01.md +1462 -0
- package/src/shade/renderer/texture/TextureManager.d.ts.map +1 -1
- package/src/shade/renderer/texture/TextureManager.js +20 -8
- package/src/shade/renderer/texture/TextureRole.d.ts +19 -0
- package/src/shade/renderer/texture/TextureRole.d.ts.map +1 -0
- package/src/shade/renderer/texture/TextureRole.js +26 -0
- package/src/shade/renderer/texture/TextureVariantSet.d.ts +71 -0
- package/src/shade/renderer/texture/TextureVariantSet.d.ts.map +1 -0
- package/src/shade/renderer/texture/TextureVariantSet.js +105 -0
- package/src/shade/renderer/texture/download_texture_data.d.ts.map +1 -1
- package/src/shade/renderer/texture/download_texture_data.js +22 -0
- package/src/shade/renderer/texture/format/gpu_texture_compression_support.d.ts +15 -0
- package/src/shade/renderer/texture/format/gpu_texture_compression_support.d.ts.map +1 -0
- package/src/shade/renderer/texture/format/gpu_texture_compression_support.js +50 -0
- package/src/shade/renderer/texture/format/gpu_texture_format_can_generate_mipmaps.d.ts +27 -0
- package/src/shade/renderer/texture/format/gpu_texture_format_can_generate_mipmaps.d.ts.map +1 -0
- package/src/shade/renderer/texture/format/gpu_texture_format_can_generate_mipmaps.js +65 -0
- package/src/shade/renderer/texture/format/infer_format_from_parameters.d.ts +11 -0
- package/src/shade/renderer/texture/format/infer_format_from_parameters.d.ts.map +1 -0
- package/src/shade/renderer/texture/format/infer_format_from_parameters.js +88 -0
- package/src/shade/renderer/texture/format/texture_format_from_shade_image.d.ts +24 -0
- package/src/shade/renderer/texture/format/texture_format_from_shade_image.d.ts.map +1 -0
- package/src/shade/renderer/texture/format/texture_format_from_shade_image.js +71 -0
- package/src/shade/renderer/texture/format/texture_format_preference.d.ts +22 -0
- package/src/shade/renderer/texture/format/texture_format_preference.d.ts.map +1 -0
- package/src/shade/renderer/texture/format/texture_format_preference.js +89 -0
- package/src/shade/renderer/texture/format/texture_variant_select.d.ts +24 -0
- package/src/shade/renderer/texture/format/texture_variant_select.d.ts.map +1 -0
- package/src/shade/renderer/texture/format/texture_variant_select.js +38 -0
- package/src/shade/renderer/texture/shade_texture_might_have_alpha.d.ts +9 -1
- package/src/shade/renderer/texture/shade_texture_might_have_alpha.d.ts.map +1 -1
- package/src/shade/renderer/texture/shade_texture_might_have_alpha.js +73 -8
- package/src/shade/renderer/texture/source/AlphaMode.d.ts +27 -0
- package/src/shade/renderer/texture/source/AlphaMode.d.ts.map +1 -0
- package/src/shade/renderer/texture/source/AlphaMode.js +52 -0
- package/src/shade/renderer/texture/source/ShadeImage.d.ts +33 -0
- package/src/shade/renderer/texture/source/ShadeImage.d.ts.map +1 -1
- package/src/shade/renderer/texture/source/ShadeImage.js +74 -0
- package/src/shade/renderer/texture/source/ShadeTexelData.d.ts +78 -0
- package/src/shade/renderer/texture/source/ShadeTexelData.d.ts.map +1 -0
- package/src/shade/renderer/texture/source/ShadeTexelData.js +158 -0
- package/src/shade/renderer/texture/texture_descriptor_from_texture_shade.d.ts +0 -10
- package/src/shade/renderer/texture/texture_descriptor_from_texture_shade.d.ts.map +1 -1
- package/src/shade/renderer/texture/texture_descriptor_from_texture_shade.js +73 -175
- package/src/shade/renderer/texture/texture_write_level.d.ts +32 -0
- package/src/shade/renderer/texture/texture_write_level.d.ts.map +1 -0
- package/src/shade/renderer/texture/texture_write_level.js +77 -0
- package/src/shade/renderer/texture/texture_write_to_gpu.d.ts +8 -1
- package/src/shade/renderer/texture/texture_write_to_gpu.d.ts.map +1 -1
- package/src/shade/renderer/texture/texture_write_to_gpu.js +62 -37
- package/src/shade/renderer/texture/virtual/source/VTSourceImage.d.ts +8 -0
- package/src/shade/renderer/texture/virtual/source/VTSourceImage.d.ts.map +1 -1
- package/src/shade/renderer/texture/virtual/source/VTSourceImage.js +8 -0
- package/src/shade/util/texture_mip_extent.d.ts +49 -0
- package/src/shade/util/texture_mip_extent.d.ts.map +1 -0
- package/src/shade/util/texture_mip_extent.js +87 -0
- package/src/avif/native/isobmff/ByteCursor.d.ts.map +0 -1
- package/src/engine/asset/loaders/image/codec/Codec.d.ts.map +0 -1
- package/src/engine/asset/loaders/image/codec/CodecWithFallback.d.ts.map +0 -1
- package/src/shade/util/compute_max_mip_count.d.ts +0 -8
- package/src/shade/util/compute_max_mip_count.d.ts.map +0 -1
- package/src/shade/util/compute_max_mip_count.js +0 -27
- /package/src/engine/asset/{loaders/image/codec → codec}/Codec.d.ts +0 -0
- /package/src/engine/asset/{loaders/image/codec → codec}/Codec.js +0 -0
- /package/src/engine/asset/{loaders/image/codec → codec}/CodecWithFallback.d.ts +0 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Texels that are already in a GPU format, with their mip levels.
|
|
3
|
+
*
|
|
4
|
+
* The general case of image data, not a special one: an uncompressed image is this with a 1×1 block.
|
|
5
|
+
* What separates it from the {@link Sampler2D} and `ArrayBuffer` sources beside it is that the format
|
|
6
|
+
* is *stated* rather than inferred from a channel count and a data type — which is the only way to
|
|
7
|
+
* describe block-compressed texels, since a BC7 block has no per-texel anything to inspect.
|
|
8
|
+
*
|
|
9
|
+
* Rows are tightly packed rows of *blocks*, with no padding between rows or between levels, which is
|
|
10
|
+
* exactly what {@link gpu_texture_format_row_bytes} and {@link gpu_texture_format_row_count}
|
|
11
|
+
* describe and what `queue.writeTexture` takes directly.
|
|
12
|
+
*
|
|
13
|
+
* `depth` halves per level, matching {@link ShadeTexture.from}, which reads a depth above 1 as a 3D
|
|
14
|
+
* texture. Array textures are not modelled here because they are not modelled there either.
|
|
15
|
+
*/
|
|
16
|
+
export class ShadeTexelData {
|
|
17
|
+
/**
|
|
18
|
+
* Bytes one level of a tightly packed payload occupies.
|
|
19
|
+
*
|
|
20
|
+
* @param {GPUTextureFormat} format
|
|
21
|
+
* @param {number} width base level, texels
|
|
22
|
+
* @param {number} height base level, texels
|
|
23
|
+
* @param {number} depth base level
|
|
24
|
+
* @param {number} level
|
|
25
|
+
* @returns {number}
|
|
26
|
+
*/
|
|
27
|
+
static level_byte_length(format: GPUTextureFormat, width: number, height: number, depth: number, level: number): number;
|
|
28
|
+
/**
|
|
29
|
+
* @param {GPUTextureFormat} format
|
|
30
|
+
* @param {number} width
|
|
31
|
+
* @param {number} height
|
|
32
|
+
* @param {number} depth
|
|
33
|
+
* @param {(Uint8Array|undefined)[]} levels
|
|
34
|
+
*/
|
|
35
|
+
constructor(format: GPUTextureFormat, width: number, height: number, depth: number, levels: (Uint8Array | undefined)[]);
|
|
36
|
+
/**
|
|
37
|
+
* @type {GPUTextureFormat}
|
|
38
|
+
* @readonly
|
|
39
|
+
*/
|
|
40
|
+
readonly format: GPUTextureFormat;
|
|
41
|
+
/**
|
|
42
|
+
* Texels of the base level.
|
|
43
|
+
* @type {number}
|
|
44
|
+
* @readonly
|
|
45
|
+
*/
|
|
46
|
+
readonly width: number;
|
|
47
|
+
/**
|
|
48
|
+
* @type {number}
|
|
49
|
+
* @readonly
|
|
50
|
+
*/
|
|
51
|
+
readonly height: number;
|
|
52
|
+
/**
|
|
53
|
+
* @type {number}
|
|
54
|
+
* @readonly
|
|
55
|
+
*/
|
|
56
|
+
readonly depth: number;
|
|
57
|
+
/**
|
|
58
|
+
* One entry per mip, index 0 = base.
|
|
59
|
+
*
|
|
60
|
+
* An entry may be `undefined` — a level that has not arrived yet. A texture streams in level by
|
|
61
|
+
* level, so "the chain has 12 levels and 4 of them are here" is an ordinary state, distinct from
|
|
62
|
+
* a payload that declares a chain it does not have (which is rejected below).
|
|
63
|
+
*
|
|
64
|
+
* @type {(Uint8Array|undefined)[]}
|
|
65
|
+
* @readonly
|
|
66
|
+
*/
|
|
67
|
+
readonly levels: (Uint8Array | undefined)[];
|
|
68
|
+
/**
|
|
69
|
+
* @returns {number} how many levels this payload declares, arrived or not
|
|
70
|
+
*/
|
|
71
|
+
get level_count(): number;
|
|
72
|
+
/**
|
|
73
|
+
* @readonly
|
|
74
|
+
* @type {boolean}
|
|
75
|
+
*/
|
|
76
|
+
readonly isShadeTexelData: boolean;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=ShadeTexelData.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ShadeTexelData.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/texture/source/ShadeTexelData.js"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;;GAcG;AACH;IAyGI;;;;;;;;;OASG;IACH,0DANW,MAAM,UACN,MAAM,SACN,MAAM,SACN,MAAM,GACJ,MAAM,CAQlB;IAnFD;;;;;;OAMG;IACH,6CALW,MAAM,UACN,MAAM,SACN,MAAM,UACN,CAAC,UAAU,GAAC,SAAS,CAAC,EAAE,EA4DlC;IAtGD;;;OAGG;IACH,kCAAO;IAEP;;;;OAIG;IACH,gBAHU,MAAM,CAGV;IAEN;;;OAGG;IACH,iBAHU,MAAM,CAGT;IAEP;;;OAGG;IACH,gBAHU,MAAM,CAGV;IAEN;;;;;;;;;OASG;IACH,iBAHU,CAAC,UAAU,GAAC,SAAS,CAAC,EAAE,CAG3B;IAuFP;;OAEG;IACH,0BAEC;IAGL;;;OAGG;IACH,2BAFU,OAAO,CAEwB;CANxC"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { assert } from "../../../../core/assert.js";
|
|
2
|
+
import {
|
|
3
|
+
gpu_texture_format_info,
|
|
4
|
+
gpu_texture_format_level_bytes
|
|
5
|
+
} from "../../../descriptor/texture/format/gpu_texture_format_info.js";
|
|
6
|
+
import { texture_mip_extent, texture_mip_level_count } from "../../../util/texture_mip_extent.js";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Texels that are already in a GPU format, with their mip levels.
|
|
10
|
+
*
|
|
11
|
+
* The general case of image data, not a special one: an uncompressed image is this with a 1×1 block.
|
|
12
|
+
* What separates it from the {@link Sampler2D} and `ArrayBuffer` sources beside it is that the format
|
|
13
|
+
* is *stated* rather than inferred from a channel count and a data type — which is the only way to
|
|
14
|
+
* describe block-compressed texels, since a BC7 block has no per-texel anything to inspect.
|
|
15
|
+
*
|
|
16
|
+
* Rows are tightly packed rows of *blocks*, with no padding between rows or between levels, which is
|
|
17
|
+
* exactly what {@link gpu_texture_format_row_bytes} and {@link gpu_texture_format_row_count}
|
|
18
|
+
* describe and what `queue.writeTexture` takes directly.
|
|
19
|
+
*
|
|
20
|
+
* `depth` halves per level, matching {@link ShadeTexture.from}, which reads a depth above 1 as a 3D
|
|
21
|
+
* texture. Array textures are not modelled here because they are not modelled there either.
|
|
22
|
+
*/
|
|
23
|
+
export class ShadeTexelData {
|
|
24
|
+
/**
|
|
25
|
+
* @type {GPUTextureFormat}
|
|
26
|
+
* @readonly
|
|
27
|
+
*/
|
|
28
|
+
format;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Texels of the base level.
|
|
32
|
+
* @type {number}
|
|
33
|
+
* @readonly
|
|
34
|
+
*/
|
|
35
|
+
width;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @type {number}
|
|
39
|
+
* @readonly
|
|
40
|
+
*/
|
|
41
|
+
height;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @type {number}
|
|
45
|
+
* @readonly
|
|
46
|
+
*/
|
|
47
|
+
depth;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* One entry per mip, index 0 = base.
|
|
51
|
+
*
|
|
52
|
+
* An entry may be `undefined` — a level that has not arrived yet. A texture streams in level by
|
|
53
|
+
* level, so "the chain has 12 levels and 4 of them are here" is an ordinary state, distinct from
|
|
54
|
+
* a payload that declares a chain it does not have (which is rejected below).
|
|
55
|
+
*
|
|
56
|
+
* @type {(Uint8Array|undefined)[]}
|
|
57
|
+
* @readonly
|
|
58
|
+
*/
|
|
59
|
+
levels;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @param {GPUTextureFormat} format
|
|
63
|
+
* @param {number} width
|
|
64
|
+
* @param {number} height
|
|
65
|
+
* @param {number} depth
|
|
66
|
+
* @param {(Uint8Array|undefined)[]} levels
|
|
67
|
+
*/
|
|
68
|
+
constructor(format, width, height, depth, levels) {
|
|
69
|
+
// throws for a name that is not a GPUTextureFormat, which is the first thing worth knowing
|
|
70
|
+
// about a payload claiming to be in one
|
|
71
|
+
gpu_texture_format_info(format);
|
|
72
|
+
|
|
73
|
+
assert.isNonNegativeInteger(width, 'width');
|
|
74
|
+
assert.isNonNegativeInteger(height, 'height');
|
|
75
|
+
assert.isNonNegativeInteger(depth, 'depth');
|
|
76
|
+
|
|
77
|
+
assert.greaterThan(width, 0, 'width');
|
|
78
|
+
assert.greaterThan(height, 0, 'height');
|
|
79
|
+
assert.greaterThan(depth, 0, 'depth');
|
|
80
|
+
|
|
81
|
+
assert.isArray(levels, 'levels');
|
|
82
|
+
assert.greaterThan(levels.length, 0, 'levels.length');
|
|
83
|
+
|
|
84
|
+
/*
|
|
85
|
+
One level, or the whole chain. Nothing in between.
|
|
86
|
+
|
|
87
|
+
A partial chain would leave the mip generator asked to start from some level other than 0,
|
|
88
|
+
which it cannot do, and would make "how many levels does this texture have" a question with
|
|
89
|
+
two answers. A chain whose levels have not all *arrived* is a different thing and is legal —
|
|
90
|
+
that is a hole in `levels`, not a short `levels`.
|
|
91
|
+
*/
|
|
92
|
+
// "3d" for the same reason `level_byte_length` uses it: a payload's depth is a volume, and
|
|
93
|
+
// a volume deeper than it is wide has a chain longer than its width alone implies
|
|
94
|
+
const full_chain = texture_mip_level_count(width, height, depth, "3d");
|
|
95
|
+
|
|
96
|
+
if (levels.length !== 1 && levels.length !== full_chain) {
|
|
97
|
+
throw new Error(
|
|
98
|
+
`levels.length must be 1 or ${full_chain} (the full chain for`
|
|
99
|
+
+ ` ${width}x${height}x${depth}), got ${levels.length}`
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
for (let level = 0; level < levels.length; level++) {
|
|
104
|
+
const bytes = levels[level];
|
|
105
|
+
|
|
106
|
+
if (bytes === undefined) {
|
|
107
|
+
// not arrived yet
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const expected = ShadeTexelData.level_byte_length(format, width, height, depth, level);
|
|
112
|
+
|
|
113
|
+
if (bytes.byteLength !== expected) {
|
|
114
|
+
throw new Error(
|
|
115
|
+
`level ${level} of a ${width}x${height}x${depth} '${format}' payload should be`
|
|
116
|
+
+ ` ${expected} bytes, got ${bytes.byteLength}`
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
this.format = format;
|
|
122
|
+
this.width = width;
|
|
123
|
+
this.height = height;
|
|
124
|
+
this.depth = depth;
|
|
125
|
+
this.levels = levels;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Bytes one level of a tightly packed payload occupies.
|
|
130
|
+
*
|
|
131
|
+
* @param {GPUTextureFormat} format
|
|
132
|
+
* @param {number} width base level, texels
|
|
133
|
+
* @param {number} height base level, texels
|
|
134
|
+
* @param {number} depth base level
|
|
135
|
+
* @param {number} level
|
|
136
|
+
* @returns {number}
|
|
137
|
+
*/
|
|
138
|
+
static level_byte_length(format, width, height, depth, level) {
|
|
139
|
+
// "3d": a payload's depth is a volume, matching ShadeTexture.from, which reads a depth above
|
|
140
|
+
// one as a 3D texture
|
|
141
|
+
const extent = texture_mip_extent(width, height, depth, "3d", level);
|
|
142
|
+
|
|
143
|
+
return gpu_texture_format_level_bytes(format, extent[0], extent[1], extent[2]);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* @returns {number} how many levels this payload declares, arrived or not
|
|
148
|
+
*/
|
|
149
|
+
get level_count() {
|
|
150
|
+
return this.levels.length;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* @readonly
|
|
156
|
+
* @type {boolean}
|
|
157
|
+
*/
|
|
158
|
+
ShadeTexelData.prototype.isShadeTexelData = true;
|
|
@@ -1,18 +1,8 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @param {number} channel_count
|
|
3
|
-
* @param {BinaryDataType} data_type
|
|
4
|
-
* @param {boolean} normalized
|
|
5
|
-
* @param {ColorSpace} color_space
|
|
6
|
-
* @returns {GPUTextureFormat}
|
|
7
|
-
*/
|
|
8
|
-
export function infer_format_from_parameters(channel_count: number, data_type: BinaryDataType, normalized: boolean, color_space: ColorSpace): GPUTextureFormat;
|
|
9
1
|
/**
|
|
10
2
|
*
|
|
11
3
|
* @param {ShadeTexture} shade
|
|
12
4
|
* @returns {TextureDescriptor}
|
|
13
5
|
*/
|
|
14
6
|
export function texture_descriptor_from_texture_shade(shade: ShadeTexture): TextureDescriptor;
|
|
15
|
-
import { BinaryDataType } from "../../../core/binary/type/BinaryDataType.js";
|
|
16
|
-
import { ColorSpace } from "./ColorSpace.js";
|
|
17
7
|
import { TextureDescriptor } from "../../descriptor/texture/TextureDescriptor.js";
|
|
18
8
|
//# sourceMappingURL=texture_descriptor_from_texture_shade.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"texture_descriptor_from_texture_shade.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/texture/texture_descriptor_from_texture_shade.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"texture_descriptor_from_texture_shade.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/texture/texture_descriptor_from_texture_shade.js"],"names":[],"mappings":"AAOA;;;;GAIG;AACH,4EAFa,iBAAiB,CA+D7B;kCAzEiC,+CAA+C"}
|
|
@@ -1,176 +1,74 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
* @
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|| data_type === BinaryDataType.Float16
|
|
75
|
-
) {
|
|
76
|
-
ending = "float";
|
|
77
|
-
} else {
|
|
78
|
-
throw new Error(`Unsupported data type '${data_type}'`);
|
|
79
|
-
}
|
|
80
|
-
} else if (color_space === ColorSpace.SRGB) {
|
|
81
|
-
if (data_type === BinaryDataType.Uint8) {
|
|
82
|
-
ending = "unorm-srgb";
|
|
83
|
-
} else {
|
|
84
|
-
throw new Error(`Unsupported data type '${data_type}'`);
|
|
85
|
-
}
|
|
86
|
-
} else {
|
|
87
|
-
throw new Error(`Unsupported color space '${color_space}'`);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
return `${prefix}${bit_size}${ending}`;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
*
|
|
96
|
-
* @param {ShadeImage} image
|
|
97
|
-
* @returns {GPUTextureFormat}
|
|
98
|
-
*/
|
|
99
|
-
function inferFormatFromImage(image) {
|
|
100
|
-
const source = image.source;
|
|
101
|
-
|
|
102
|
-
const color_space = image.color_space;
|
|
103
|
-
if (source.isSampler2D === true) {
|
|
104
|
-
// is a sampler
|
|
105
|
-
|
|
106
|
-
return infer_format_from_parameters(
|
|
107
|
-
image.channel_count, image.data_type, image.normalized, image.color_space
|
|
108
|
-
);
|
|
109
|
-
|
|
110
|
-
} else if (isImageBitmap(source)) {
|
|
111
|
-
if (image.data_type === BinaryDataType.Float16) {
|
|
112
|
-
return "rgba16float";
|
|
113
|
-
} else if (color_space === ColorSpace.SRGB) {
|
|
114
|
-
/*
|
|
115
|
-
Forces conversion from sRGB to linear in the shader
|
|
116
|
-
@see https://www.w3.org/TR/webgpu/#texture-formats
|
|
117
|
-
*/
|
|
118
|
-
return "rgba8unorm-srgb"
|
|
119
|
-
} else {
|
|
120
|
-
return "rgba8unorm"
|
|
121
|
-
}
|
|
122
|
-
} else if (source instanceof ArrayBuffer) {
|
|
123
|
-
return infer_format_from_parameters(
|
|
124
|
-
image.channel_count,
|
|
125
|
-
image.data_type,
|
|
126
|
-
image.normalized,
|
|
127
|
-
image.color_space,
|
|
128
|
-
);
|
|
129
|
-
} else {
|
|
130
|
-
throw new Error(`Unsupported image data`);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
*
|
|
136
|
-
* @param {ShadeTexture} shade
|
|
137
|
-
* @returns {TextureDescriptor}
|
|
138
|
-
*/
|
|
139
|
-
export function texture_descriptor_from_texture_shade(shade) {
|
|
140
|
-
|
|
141
|
-
const image = shade.image;
|
|
142
|
-
|
|
143
|
-
let usage = GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.COPY_SRC;
|
|
144
|
-
|
|
145
|
-
let mipLevelCount = 1;
|
|
146
|
-
|
|
147
|
-
if ((shade.flags & ShadeTextureFlags.GenerateMipMaps) !== 0) {
|
|
148
|
-
// need to bind texture for writing for mipmaps
|
|
149
|
-
usage |= GPUTextureUsage.RENDER_ATTACHMENT;
|
|
150
|
-
|
|
151
|
-
mipLevelCount = compute_max_mip_count(image.width, image.height);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* @type {GPUTextureFormat}
|
|
156
|
-
*/
|
|
157
|
-
const format = inferFormatFromImage(image);
|
|
158
|
-
|
|
159
|
-
let dimension = "1d";
|
|
160
|
-
|
|
161
|
-
if (shade.dimensions === 2) {
|
|
162
|
-
dimension = "2d";
|
|
163
|
-
} else if (shade.dimensions === 3) {
|
|
164
|
-
dimension = "3d";
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
return TextureDescriptor.from({
|
|
168
|
-
label: shade.label,
|
|
169
|
-
size: [image.width, image.height, image.depth],
|
|
170
|
-
format,
|
|
171
|
-
usage: usage,
|
|
172
|
-
mipLevelCount,
|
|
173
|
-
dimension,
|
|
174
|
-
});
|
|
175
|
-
|
|
1
|
+
import { TextureDescriptor } from "../../descriptor/texture/TextureDescriptor.js";
|
|
2
|
+
import { gpu_texture_format_can_generate_mipmaps } from "./format/gpu_texture_format_can_generate_mipmaps.js";
|
|
3
|
+
import { texture_format_from_shade_image } from "./format/texture_format_from_shade_image.js";
|
|
4
|
+
import { texture_mip_level_count } from "../../util/texture_mip_extent.js";
|
|
5
|
+
|
|
6
|
+
import { ShadeTextureFlags } from "./ShadeTextureFlags.js";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
*
|
|
10
|
+
* @param {ShadeTexture} shade
|
|
11
|
+
* @returns {TextureDescriptor}
|
|
12
|
+
*/
|
|
13
|
+
export function texture_descriptor_from_texture_shade(shade) {
|
|
14
|
+
|
|
15
|
+
const image = shade.image;
|
|
16
|
+
|
|
17
|
+
let usage = GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.COPY_SRC;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @type {GPUTextureFormat}
|
|
21
|
+
*/
|
|
22
|
+
const format = texture_format_from_shade_image(image);
|
|
23
|
+
|
|
24
|
+
/*
|
|
25
|
+
Two independent things, which used to be one.
|
|
26
|
+
|
|
27
|
+
Where the levels come from is a property of the image: it supplies `level_count` of them, and
|
|
28
|
+
that is how many the texture gets. Whether to run the mip generator is an instruction the caller
|
|
29
|
+
gives, and it is honoured or it throws — never quietly reinterpreted from what the image happens
|
|
30
|
+
to carry. Set the flag on an image that already has a chain and the chain is regenerated, which
|
|
31
|
+
is a real use: a container whose mips were built with a filter you do not want.
|
|
32
|
+
*/
|
|
33
|
+
const generate = (shade.flags & ShadeTextureFlags.GenerateMipMaps) !== 0;
|
|
34
|
+
|
|
35
|
+
let dimension = "1d";
|
|
36
|
+
|
|
37
|
+
if (shade.dimensions === 2) {
|
|
38
|
+
dimension = "2d";
|
|
39
|
+
} else if (shade.dimensions === 3) {
|
|
40
|
+
dimension = "3d";
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
let mipLevelCount;
|
|
44
|
+
|
|
45
|
+
if (generate) {
|
|
46
|
+
if (!gpu_texture_format_can_generate_mipmaps(format)) {
|
|
47
|
+
throw new Error(
|
|
48
|
+
`${shade.label || 'texture'}: mipmap generation was requested for '${format}',`
|
|
49
|
+
+ ` which cannot be a render attachment. Mips for this format come from whatever`
|
|
50
|
+
+ ` encoded it — supply them in the payload and clear`
|
|
51
|
+
+ ` ShadeTextureFlags.GenerateMipMaps.`
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// the generator renders between levels, so the texture has to be bindable for writing
|
|
56
|
+
usage |= GPUTextureUsage.RENDER_ATTACHMENT;
|
|
57
|
+
|
|
58
|
+
// through the dimension: a volume's chain runs down its depth too, so a 4x4x16 asking for
|
|
59
|
+
// generated mips wants five levels and not the three its width alone implies
|
|
60
|
+
mipLevelCount = texture_mip_level_count(image.width, image.height, image.depth, dimension);
|
|
61
|
+
} else {
|
|
62
|
+
mipLevelCount = image.level_count;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return TextureDescriptor.from({
|
|
66
|
+
label: shade.label,
|
|
67
|
+
size: [image.width, image.height, image.depth],
|
|
68
|
+
format,
|
|
69
|
+
usage: usage,
|
|
70
|
+
mipLevelCount,
|
|
71
|
+
dimension,
|
|
72
|
+
});
|
|
73
|
+
|
|
176
74
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Write one mip level of a texture from tightly packed texels.
|
|
3
|
+
*
|
|
4
|
+
* **The level, not the image, is the unit.** meep streams: a texture is not a thing that arrives, it
|
|
5
|
+
* is a thing that keeps arriving. The descriptor is built from a header before any texels exist, the
|
|
6
|
+
* texture is allocated once at full size, and levels land as they are delivered — so the primitive
|
|
7
|
+
* has to be "put these bytes in that level", with whole-image upload written on top rather than the
|
|
8
|
+
* other way around.
|
|
9
|
+
*
|
|
10
|
+
* **Layout comes from the format, not from arithmetic.** `channels × bytes_per_channel × width` is
|
|
11
|
+
* right only for the 1×1-block formats, and is wrong in a way that is easy to miss: the 1×1 mip of a
|
|
12
|
+
* BC7 texture is a whole 16-byte block, not a sixteenth of one.
|
|
13
|
+
* {@link gpu_texture_format_row_bytes} rounds up to whole blocks and this asks it rather than
|
|
14
|
+
* repeating it.
|
|
15
|
+
*
|
|
16
|
+
* Everything but the bytes is read off the texture — format, size, dimension. Passing them
|
|
17
|
+
* separately would be one more pair of things that can disagree, and the texture is the authority on
|
|
18
|
+
* all three because it is the thing being written into. The extent at a level, including the rule
|
|
19
|
+
* that only a 3D texture's depth halves, comes from {@link texture_mip_extent}.
|
|
20
|
+
*
|
|
21
|
+
* `queue.writeTexture` has **no** `bytesPerRow` alignment requirement, unlike `copyBufferToTexture`
|
|
22
|
+
* and its multiple of 256. That is what makes a tightly packed payload uploadable with no staging
|
|
23
|
+
* buffer and no padding, and it is why this is the path for texels that are already in host memory.
|
|
24
|
+
*
|
|
25
|
+
* @param {GPUQueue} queue
|
|
26
|
+
* @param {GPUTexture} texture
|
|
27
|
+
* @param {number} level mip level to write, 0 = base
|
|
28
|
+
* @param {BufferSource} bytes rows of blocks, tightly packed, no padding between rows or layers
|
|
29
|
+
* @returns {void}
|
|
30
|
+
*/
|
|
31
|
+
export function texture_write_level(queue: GPUQueue, texture: GPUTexture, level: number, bytes: BufferSource): void;
|
|
32
|
+
//# sourceMappingURL=texture_write_level.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"texture_write_level.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/texture/texture_write_level.js"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,iFAJW,MAAM,SACN,YAAY,GACV,IAAI,CAwChB"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { assert } from "../../../core/assert.js";
|
|
2
|
+
import {
|
|
3
|
+
gpu_texture_format_level_bytes,
|
|
4
|
+
gpu_texture_format_row_bytes,
|
|
5
|
+
gpu_texture_format_row_count
|
|
6
|
+
} from "../../descriptor/texture/format/gpu_texture_format_info.js";
|
|
7
|
+
import { texture_mip_extent } from "../../util/texture_mip_extent.js";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Write one mip level of a texture from tightly packed texels.
|
|
11
|
+
*
|
|
12
|
+
* **The level, not the image, is the unit.** meep streams: a texture is not a thing that arrives, it
|
|
13
|
+
* is a thing that keeps arriving. The descriptor is built from a header before any texels exist, the
|
|
14
|
+
* texture is allocated once at full size, and levels land as they are delivered — so the primitive
|
|
15
|
+
* has to be "put these bytes in that level", with whole-image upload written on top rather than the
|
|
16
|
+
* other way around.
|
|
17
|
+
*
|
|
18
|
+
* **Layout comes from the format, not from arithmetic.** `channels × bytes_per_channel × width` is
|
|
19
|
+
* right only for the 1×1-block formats, and is wrong in a way that is easy to miss: the 1×1 mip of a
|
|
20
|
+
* BC7 texture is a whole 16-byte block, not a sixteenth of one.
|
|
21
|
+
* {@link gpu_texture_format_row_bytes} rounds up to whole blocks and this asks it rather than
|
|
22
|
+
* repeating it.
|
|
23
|
+
*
|
|
24
|
+
* Everything but the bytes is read off the texture — format, size, dimension. Passing them
|
|
25
|
+
* separately would be one more pair of things that can disagree, and the texture is the authority on
|
|
26
|
+
* all three because it is the thing being written into. The extent at a level, including the rule
|
|
27
|
+
* that only a 3D texture's depth halves, comes from {@link texture_mip_extent}.
|
|
28
|
+
*
|
|
29
|
+
* `queue.writeTexture` has **no** `bytesPerRow` alignment requirement, unlike `copyBufferToTexture`
|
|
30
|
+
* and its multiple of 256. That is what makes a tightly packed payload uploadable with no staging
|
|
31
|
+
* buffer and no padding, and it is why this is the path for texels that are already in host memory.
|
|
32
|
+
*
|
|
33
|
+
* @param {GPUQueue} queue
|
|
34
|
+
* @param {GPUTexture} texture
|
|
35
|
+
* @param {number} level mip level to write, 0 = base
|
|
36
|
+
* @param {BufferSource} bytes rows of blocks, tightly packed, no padding between rows or layers
|
|
37
|
+
* @returns {void}
|
|
38
|
+
*/
|
|
39
|
+
export function texture_write_level(queue, texture, level, bytes) {
|
|
40
|
+
assert.defined(queue, 'queue');
|
|
41
|
+
assert.defined(texture, 'texture');
|
|
42
|
+
assert.defined(bytes, 'bytes');
|
|
43
|
+
|
|
44
|
+
assert.isNonNegativeInteger(level, 'level');
|
|
45
|
+
assert.lessThan(level, texture.mipLevelCount, 'level');
|
|
46
|
+
|
|
47
|
+
const format = texture.format;
|
|
48
|
+
|
|
49
|
+
const extent = texture_mip_extent(
|
|
50
|
+
texture.width, texture.height, texture.depthOrArrayLayers, texture.dimension, level
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
const bytes_per_row = gpu_texture_format_row_bytes(format, extent[0]);
|
|
54
|
+
const rows_per_image = gpu_texture_format_row_count(format, extent[1]);
|
|
55
|
+
|
|
56
|
+
assert.equal(
|
|
57
|
+
bytes.byteLength,
|
|
58
|
+
gpu_texture_format_level_bytes(format, extent[0], extent[1], extent[2]),
|
|
59
|
+
`byte length for level ${level} of a ${extent.join('x')} '${format}' texture`
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
queue.writeTexture(
|
|
63
|
+
{
|
|
64
|
+
texture,
|
|
65
|
+
mipLevel: level,
|
|
66
|
+
origin: { x: 0, y: 0, z: 0 },
|
|
67
|
+
},
|
|
68
|
+
bytes,
|
|
69
|
+
{
|
|
70
|
+
offset: 0,
|
|
71
|
+
bytesPerRow: bytes_per_row,
|
|
72
|
+
// required once the copy is more than one layer deep, and harmless before that
|
|
73
|
+
rowsPerImage: rows_per_image,
|
|
74
|
+
},
|
|
75
|
+
extent
|
|
76
|
+
);
|
|
77
|
+
}
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* Upload an image's texels into a texture.
|
|
3
|
+
*
|
|
4
|
+
* `level_count` says how many of the image's levels to write, from the base up, and is required
|
|
5
|
+
* rather than defaulted: the one caller that wants fewer than all of them — {@link TextureManager},
|
|
6
|
+
* about to run the mip generator — is the caller least able to have that decision made for it.
|
|
7
|
+
* Uploading levels the generator is about to overwrite is bytes across the bus for nothing.
|
|
2
8
|
*
|
|
3
9
|
* @param {ShadeImage} image
|
|
4
10
|
* @param {GPUTexture} texture
|
|
5
11
|
* @param {GPUQueue} queue
|
|
12
|
+
* @param {number} level_count how many levels to write; `image.level_count` for all of them
|
|
6
13
|
*/
|
|
7
|
-
export function texture_write_to_gpu(image: ShadeImage, texture: GPUTexture, queue: GPUQueue): void;
|
|
14
|
+
export function texture_write_to_gpu(image: ShadeImage, texture: GPUTexture, queue: GPUQueue, level_count: number): void;
|
|
8
15
|
//# sourceMappingURL=texture_write_to_gpu.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"texture_write_to_gpu.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/texture/texture_write_to_gpu.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"texture_write_to_gpu.d.ts","sourceRoot":"","sources":["../../../../../src/shade/renderer/texture/texture_write_to_gpu.js"],"names":[],"mappings":"AAyKA;;;;;;;;;;;;GAYG;AACH,2GAFW,MAAM,QAqGhB"}
|