@woosh/meep-engine 3.14.0 → 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.
Files changed (220) hide show
  1. package/README.md +33 -64
  2. package/package.json +1 -1
  3. package/src/avif/native/DECISIONS.md +544 -536
  4. package/src/avif/native/heif/parse_avif_file.d.ts.map +1 -1
  5. package/src/avif/native/heif/parse_avif_file.js +384 -383
  6. package/src/avif/native/heif/parse_image_grid.d.ts.map +1 -1
  7. package/src/avif/native/heif/parse_image_grid.js +49 -48
  8. package/src/basis/BasisBitReader.d.ts +77 -0
  9. package/src/basis/BasisBitReader.d.ts.map +1 -0
  10. package/src/basis/BasisBitReader.js +231 -0
  11. package/src/basis/BasisHuffmanTable.d.ts +53 -0
  12. package/src/basis/BasisHuffmanTable.d.ts.map +1 -0
  13. package/src/basis/BasisHuffmanTable.js +263 -0
  14. package/src/basis/basis_read_huffman_table.d.ts +20 -0
  15. package/src/basis/basis_read_huffman_table.d.ts.map +1 -0
  16. package/src/basis/basis_read_huffman_table.js +187 -0
  17. package/src/basis/etc1s/Etc1sSelectorHistory.d.ts +50 -0
  18. package/src/basis/etc1s/Etc1sSelectorHistory.d.ts.map +1 -0
  19. package/src/basis/etc1s/Etc1sSelectorHistory.js +89 -0
  20. package/src/basis/etc1s/etc1s_block_colors.d.ts +14 -0
  21. package/src/basis/etc1s/etc1s_block_colors.d.ts.map +1 -0
  22. package/src/basis/etc1s/etc1s_block_colors.js +75 -0
  23. package/src/basis/etc1s/etc1s_decode_slice.d.ts +57 -0
  24. package/src/basis/etc1s/etc1s_decode_slice.d.ts.map +1 -0
  25. package/src/basis/etc1s/etc1s_decode_slice.js +258 -0
  26. package/src/basis/etc1s/etc1s_read_endpoint_codebook.d.ts +48 -0
  27. package/src/basis/etc1s/etc1s_read_endpoint_codebook.d.ts.map +1 -0
  28. package/src/basis/etc1s/etc1s_read_endpoint_codebook.js +111 -0
  29. package/src/basis/etc1s/etc1s_read_selector_codebook.d.ts +42 -0
  30. package/src/basis/etc1s/etc1s_read_selector_codebook.d.ts.map +1 -0
  31. package/src/basis/etc1s/etc1s_read_selector_codebook.js +127 -0
  32. package/src/basis/etc1s/etc1s_read_slice_tables.d.ts +54 -0
  33. package/src/basis/etc1s/etc1s_read_slice_tables.d.ts.map +1 -0
  34. package/src/basis/etc1s/etc1s_read_slice_tables.js +47 -0
  35. package/src/basis/transcode/build_range_plan.js +54 -0
  36. package/src/basis/transcode/etc1s_to_bc1.d.ts +24 -0
  37. package/src/basis/transcode/etc1s_to_bc1.d.ts.map +1 -0
  38. package/src/basis/transcode/etc1s_to_bc1.js +205 -0
  39. package/src/basis/transcode/etc1s_to_bc7.d.ts +30 -0
  40. package/src/basis/transcode/etc1s_to_bc7.d.ts.map +1 -0
  41. package/src/basis/transcode/etc1s_to_bc7.js +496 -0
  42. package/src/basis/transcode/fit_endpoints.d.ts +59 -0
  43. package/src/basis/transcode/fit_endpoints.d.ts.map +1 -0
  44. package/src/basis/transcode/fit_endpoints.js +226 -0
  45. package/src/{avif/native/isobmff → core/binary}/ByteCursor.d.ts +19 -6
  46. package/src/core/binary/ByteCursor.d.ts.map +1 -0
  47. package/src/{avif/native/isobmff → core/binary}/ByteCursor.js +41 -14
  48. package/src/engine/EngineHarness.js +1 -1
  49. package/src/engine/asset/codec/Codec.d.ts.map +1 -0
  50. package/src/engine/asset/codec/CodecWithFallback.d.ts.map +1 -0
  51. package/src/engine/asset/{loaders/image/codec → codec}/CodecWithFallback.js +2 -2
  52. package/src/engine/asset/loaders/image/IMAGE_CODEC_REVIEW_2026_08_28.md +4 -4
  53. package/src/engine/asset/loaders/image/ImageRGBADataLoader.d.ts +1 -1
  54. package/src/engine/asset/loaders/image/ImageRGBADataLoader.d.ts.map +1 -1
  55. package/src/engine/asset/loaders/image/ImageRGBADataLoader.js +1 -1
  56. package/src/engine/asset/loaders/image/codec/NativeImageDecoder.d.ts +1 -1
  57. package/src/engine/asset/loaders/image/codec/NativeImageDecoder.d.ts.map +1 -1
  58. package/src/engine/asset/loaders/image/codec/NativeImageDecoder.js +1 -1
  59. package/src/engine/asset/loaders/image/codec/ThreadedImageDecoder.d.ts +1 -1
  60. package/src/engine/asset/loaders/image/codec/ThreadedImageDecoder.d.ts.map +1 -1
  61. package/src/engine/asset/loaders/image/codec/ThreadedImageDecoder.js +1 -1
  62. package/src/engine/graphics/texture/atlas/TextureAtlas.d.ts.map +1 -1
  63. package/src/engine/graphics/texture/atlas/TextureAtlas.js +13 -0
  64. package/src/engine/physics/broadphase/generate_pairs.d.ts.map +1 -1
  65. package/src/engine/physics/broadphase/generate_pairs.js +7 -1
  66. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  67. package/src/ktx2/KTX2_IDENTIFIER.d.ts +14 -0
  68. package/src/ktx2/KTX2_IDENTIFIER.d.ts.map +1 -0
  69. package/src/ktx2/KTX2_IDENTIFIER.js +15 -0
  70. package/src/ktx2/KhrDfModel.d.ts +35 -0
  71. package/src/ktx2/KhrDfModel.d.ts.map +1 -0
  72. package/src/ktx2/KhrDfModel.js +49 -0
  73. package/src/ktx2/SupercompressionScheme.d.ts +16 -0
  74. package/src/ktx2/SupercompressionScheme.d.ts.map +1 -0
  75. package/src/ktx2/SupercompressionScheme.js +23 -0
  76. package/src/ktx2/ktx2_read.d.ts +71 -0
  77. package/src/ktx2/ktx2_read.d.ts.map +1 -0
  78. package/src/ktx2/ktx2_read.js +581 -0
  79. package/src/ktx2/ktx2_read_basis_lz_global_data.d.ts +27 -0
  80. package/src/ktx2/ktx2_read_basis_lz_global_data.d.ts.map +1 -0
  81. package/src/ktx2/ktx2_read_basis_lz_global_data.js +189 -0
  82. package/src/ktx2/vk_format_to_texture_format.d.ts +55 -0
  83. package/src/ktx2/vk_format_to_texture_format.d.ts.map +1 -0
  84. package/src/ktx2/vk_format_to_texture_format.js +290 -0
  85. package/src/shade/descriptor/GPUTextureUsage.d.ts +23 -0
  86. package/src/shade/descriptor/GPUTextureUsage.d.ts.map +1 -0
  87. package/src/shade/descriptor/GPUTextureUsage.js +24 -0
  88. package/src/shade/descriptor/WebGPUExtensionType.d.ts +3 -0
  89. package/src/shade/descriptor/WebGPUExtensionType.js +26 -0
  90. package/src/shade/descriptor/texture/TextureDescriptor.d.ts +2 -6
  91. package/src/shade/descriptor/texture/TextureDescriptor.d.ts.map +1 -1
  92. package/src/shade/descriptor/texture/TextureDescriptor.js +24 -40
  93. package/src/shade/descriptor/texture/format/TextureFormat.d.ts +125 -0
  94. package/src/shade/descriptor/texture/format/TextureFormat.d.ts.map +1 -0
  95. package/src/shade/descriptor/texture/format/TextureFormat.js +146 -0
  96. package/src/shade/descriptor/texture/format/gpu_texture_format_info.d.ts +60 -0
  97. package/src/shade/descriptor/texture/format/gpu_texture_format_info.d.ts.map +1 -1
  98. package/src/shade/descriptor/texture/format/gpu_texture_format_info.js +102 -0
  99. package/src/shade/device/graph/TextureResourceDescriptor.d.ts.map +1 -1
  100. package/src/shade/device/graph/TextureResourceDescriptor.js +160 -155
  101. package/src/shade/device/mock/SoftwareGPUQueue.d.ts +11 -4
  102. package/src/shade/device/mock/SoftwareGPUQueue.d.ts.map +1 -1
  103. package/src/shade/device/mock/SoftwareGPUQueue.js +31 -37
  104. package/src/shade/device/mock/SoftwareGPUTexture.d.ts.map +1 -1
  105. package/src/shade/device/mock/SoftwareGPUTexture.js +8 -4
  106. package/src/shade/device/timing/profile/frame_graph_extract_topology.d.ts.map +1 -1
  107. package/src/shade/device/timing/profile/frame_graph_extract_topology.js +164 -174
  108. package/src/shade/playground/ground_seam/README.md +235 -0
  109. package/src/shade/playground/ground_seam/capture_scene_color.d.ts +45 -0
  110. package/src/shade/playground/ground_seam/capture_scene_color.d.ts.map +1 -0
  111. package/src/shade/playground/ground_seam/capture_scene_color.js +242 -0
  112. package/src/shade/playground/ground_seam/depth_step_across_seam.d.ts +11 -0
  113. package/src/shade/playground/ground_seam/depth_step_across_seam.d.ts.map +1 -0
  114. package/src/shade/playground/ground_seam/depth_step_across_seam.js +185 -0
  115. package/src/shade/playground/ground_seam/index.html +195 -0
  116. package/src/shade/playground/ground_seam/main.d.ts +2 -0
  117. package/src/shade/playground/ground_seam/main.d.ts.map +1 -0
  118. package/src/shade/playground/ground_seam/main.js +879 -0
  119. package/src/shade/playground/ground_seam/make_grid_texture.d.ts +29 -0
  120. package/src/shade/playground/ground_seam/make_grid_texture.d.ts.map +1 -0
  121. package/src/shade/playground/ground_seam/make_grid_texture.js +105 -0
  122. package/src/shade/playground/ground_seam/make_ground.d.ts +70 -0
  123. package/src/shade/playground/ground_seam/make_ground.d.ts.map +1 -0
  124. package/src/shade/playground/ground_seam/make_ground.js +161 -0
  125. package/src/shade/playground/ground_seam/measure_flicker.d.ts +71 -0
  126. package/src/shade/playground/ground_seam/measure_flicker.d.ts.map +1 -0
  127. package/src/shade/playground/ground_seam/measure_flicker.js +531 -0
  128. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  129. package/src/shade/renderer/Renderer.js +2519 -2511
  130. package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts.map +1 -1
  131. package/src/shade/renderer/hiz/HierarchicalZBuffer.js +275 -274
  132. package/src/shade/renderer/light/GPULightCollection.d.ts.map +1 -1
  133. package/src/shade/renderer/light/GPULightCollection.js +323 -314
  134. package/src/shade/renderer/lightmap/GPULightMap.js +336 -336
  135. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts.map +1 -1
  136. package/src/shade/renderer/material/resident/GPUResidentMaterialContext.js +12 -2
  137. package/src/shade/renderer/material/standard/fragment_gbuffer.d.ts.map +1 -1
  138. package/src/shade/renderer/material/standard/fragment_gbuffer.js +3 -1
  139. package/src/shade/renderer/material/standard/fragment_gbuffer_vt.js +169 -169
  140. package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.d.ts.map +1 -1
  141. package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.js +3 -1
  142. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  143. package/src/shade/renderer/rasterize/native/oit/chunk_forward_shade_standard_fragment_brick4.d.ts.map +1 -1
  144. package/src/shade/renderer/rasterize/native/oit/chunk_forward_shade_standard_fragment_brick4.js +3 -1
  145. package/src/shade/renderer/rasterize/native/oit/chunk_forward_shade_standard_fragment_ibl.d.ts.map +1 -1
  146. package/src/shade/renderer/rasterize/native/oit/chunk_forward_shade_standard_fragment_ibl.js +3 -1
  147. package/src/shade/renderer/shader/chunk/geometry/normal/chunk_decode_tangent_normal.d.ts +28 -0
  148. package/src/shade/renderer/shader/chunk/geometry/normal/chunk_decode_tangent_normal.d.ts.map +1 -0
  149. package/src/shade/renderer/shader/chunk/geometry/normal/chunk_decode_tangent_normal.js +39 -0
  150. package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_barycentric_full.d.ts +45 -0
  151. package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_barycentric_full.d.ts.map +1 -1
  152. package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_barycentric_full.js +94 -61
  153. package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_barycentric_solve.d.ts +24 -0
  154. package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_barycentric_solve.d.ts.map +1 -0
  155. package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_barycentric_solve.js +43 -0
  156. package/src/shade/renderer/texture/COMPRESSED_TEXTURE_PLAN_2026_09_01.md +1462 -0
  157. package/src/shade/renderer/texture/TextureManager.d.ts.map +1 -1
  158. package/src/shade/renderer/texture/TextureManager.js +20 -8
  159. package/src/shade/renderer/texture/TextureRole.d.ts +19 -0
  160. package/src/shade/renderer/texture/TextureRole.d.ts.map +1 -0
  161. package/src/shade/renderer/texture/TextureRole.js +26 -0
  162. package/src/shade/renderer/texture/TextureVariantSet.d.ts +71 -0
  163. package/src/shade/renderer/texture/TextureVariantSet.d.ts.map +1 -0
  164. package/src/shade/renderer/texture/TextureVariantSet.js +105 -0
  165. package/src/shade/renderer/texture/download_texture_data.d.ts.map +1 -1
  166. package/src/shade/renderer/texture/download_texture_data.js +22 -0
  167. package/src/shade/renderer/texture/format/gpu_texture_compression_support.d.ts +15 -0
  168. package/src/shade/renderer/texture/format/gpu_texture_compression_support.d.ts.map +1 -0
  169. package/src/shade/renderer/texture/format/gpu_texture_compression_support.js +50 -0
  170. package/src/shade/renderer/texture/format/gpu_texture_format_can_generate_mipmaps.d.ts +27 -0
  171. package/src/shade/renderer/texture/format/gpu_texture_format_can_generate_mipmaps.d.ts.map +1 -0
  172. package/src/shade/renderer/texture/format/gpu_texture_format_can_generate_mipmaps.js +65 -0
  173. package/src/shade/renderer/texture/format/infer_format_from_parameters.d.ts +11 -0
  174. package/src/shade/renderer/texture/format/infer_format_from_parameters.d.ts.map +1 -0
  175. package/src/shade/renderer/texture/format/infer_format_from_parameters.js +88 -0
  176. package/src/shade/renderer/texture/format/texture_format_from_shade_image.d.ts +24 -0
  177. package/src/shade/renderer/texture/format/texture_format_from_shade_image.d.ts.map +1 -0
  178. package/src/shade/renderer/texture/format/texture_format_from_shade_image.js +71 -0
  179. package/src/shade/renderer/texture/format/texture_format_preference.d.ts +22 -0
  180. package/src/shade/renderer/texture/format/texture_format_preference.d.ts.map +1 -0
  181. package/src/shade/renderer/texture/format/texture_format_preference.js +89 -0
  182. package/src/shade/renderer/texture/format/texture_variant_select.d.ts +24 -0
  183. package/src/shade/renderer/texture/format/texture_variant_select.d.ts.map +1 -0
  184. package/src/shade/renderer/texture/format/texture_variant_select.js +38 -0
  185. package/src/shade/renderer/texture/shade_texture_might_have_alpha.d.ts +9 -1
  186. package/src/shade/renderer/texture/shade_texture_might_have_alpha.d.ts.map +1 -1
  187. package/src/shade/renderer/texture/shade_texture_might_have_alpha.js +73 -8
  188. package/src/shade/renderer/texture/source/AlphaMode.d.ts +27 -0
  189. package/src/shade/renderer/texture/source/AlphaMode.d.ts.map +1 -0
  190. package/src/shade/renderer/texture/source/AlphaMode.js +52 -0
  191. package/src/shade/renderer/texture/source/ShadeImage.d.ts +33 -0
  192. package/src/shade/renderer/texture/source/ShadeImage.d.ts.map +1 -1
  193. package/src/shade/renderer/texture/source/ShadeImage.js +74 -0
  194. package/src/shade/renderer/texture/source/ShadeTexelData.d.ts +78 -0
  195. package/src/shade/renderer/texture/source/ShadeTexelData.d.ts.map +1 -0
  196. package/src/shade/renderer/texture/source/ShadeTexelData.js +158 -0
  197. package/src/shade/renderer/texture/texture_descriptor_from_texture_shade.d.ts +0 -10
  198. package/src/shade/renderer/texture/texture_descriptor_from_texture_shade.d.ts.map +1 -1
  199. package/src/shade/renderer/texture/texture_descriptor_from_texture_shade.js +73 -175
  200. package/src/shade/renderer/texture/texture_write_level.d.ts +32 -0
  201. package/src/shade/renderer/texture/texture_write_level.d.ts.map +1 -0
  202. package/src/shade/renderer/texture/texture_write_level.js +77 -0
  203. package/src/shade/renderer/texture/texture_write_to_gpu.d.ts +8 -1
  204. package/src/shade/renderer/texture/texture_write_to_gpu.d.ts.map +1 -1
  205. package/src/shade/renderer/texture/texture_write_to_gpu.js +62 -37
  206. package/src/shade/renderer/texture/virtual/source/VTSourceImage.d.ts +8 -0
  207. package/src/shade/renderer/texture/virtual/source/VTSourceImage.d.ts.map +1 -1
  208. package/src/shade/renderer/texture/virtual/source/VTSourceImage.js +8 -0
  209. package/src/shade/util/texture_mip_extent.d.ts +49 -0
  210. package/src/shade/util/texture_mip_extent.d.ts.map +1 -0
  211. package/src/shade/util/texture_mip_extent.js +87 -0
  212. package/src/avif/native/isobmff/ByteCursor.d.ts.map +0 -1
  213. package/src/engine/asset/loaders/image/codec/Codec.d.ts.map +0 -1
  214. package/src/engine/asset/loaders/image/codec/CodecWithFallback.d.ts.map +0 -1
  215. package/src/shade/util/compute_max_mip_count.d.ts +0 -8
  216. package/src/shade/util/compute_max_mip_count.d.ts.map +0 -1
  217. package/src/shade/util/compute_max_mip_count.js +0 -27
  218. /package/src/engine/asset/{loaders/image/codec → codec}/Codec.d.ts +0 -0
  219. /package/src/engine/asset/{loaders/image/codec → codec}/Codec.js +0 -0
  220. /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":"AASA;;;;;;GAMG;AACH,4DANW,MAAM,aACN,cAAc,cACd,OAAO,eACP,UAAU,oBA6EpB;AA2CD;;;;GAIG;AACH,4EAFa,iBAAiB,CAuC7B;+BA/K8B,6CAA6C;2BAIjD,iBAAiB;kCADV,+CAA+C"}
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 { BinaryDataType } from "../../../core/binary/type/BinaryDataType.js";
2
- import { dataTypeByteSize } from "../../../core/binary/type/DataTypeByteSizes.js";
3
- import { isImageBitmap } from "../../../engine/graphics/texture/isImageBitmap.js";
4
- import { TextureDescriptor } from "../../descriptor/texture/TextureDescriptor.js";
5
- import { ColorSpace } from "./ColorSpace.js";
6
- import { compute_max_mip_count } from "../../util/compute_max_mip_count.js";
7
-
8
- import { ShadeTextureFlags } from "./ShadeTextureFlags.js";
9
-
10
- /**
11
- * @param {number} channel_count
12
- * @param {BinaryDataType} data_type
13
- * @param {boolean} normalized
14
- * @param {ColorSpace} color_space
15
- * @returns {GPUTextureFormat}
16
- */
17
- export function infer_format_from_parameters(
18
- channel_count,
19
- data_type,
20
- normalized,
21
- color_space
22
- ) {
23
-
24
- // Some channel counts are unsupported, specifically RGB, so we have to go up 1 to RGBA
25
- const valid_channel_counts = [1, 2, 4];
26
-
27
- let valid_channel_count = channel_count;
28
-
29
- if (valid_channel_counts.includes(channel_count) === false) {
30
- for (let i = 0; i < valid_channel_counts.length; i++) {
31
- let vs = valid_channel_counts[i];
32
-
33
- if (channel_count < vs) {
34
- valid_channel_count = vs;
35
- break;
36
- }
37
- }
38
- }
39
-
40
- const prefix = 'rgba'.slice(0, valid_channel_count);
41
-
42
- const byte_size = dataTypeByteSize(data_type);
43
-
44
- const bit_size = byte_size * 8;
45
-
46
- let ending;
47
- if (color_space === ColorSpace.LinearSRGB) {
48
- if (data_type === BinaryDataType.Uint8) {
49
- ending = "unorm";
50
- } else if (data_type === BinaryDataType.Float32) {
51
- ending = "float";
52
- } else if (data_type === BinaryDataType.Float16 || data_type === BinaryDataType.Uint16) {
53
- // Half-float HDR data (e.g. octahedral environment maps). parse_rgbe stores f16 bit
54
- // patterns in a Uint16Array, so the same half-float payload can be classified as either
55
- // Float16 or Uint16 depending on the runtime both map to the 16-bit float format.
56
- ending = "float";
57
- } else {
58
- throw new Error(`Unsupported data type '${data_type}'`);
59
- }
60
- } else if (color_space === ColorSpace.None) {
61
- if (
62
- data_type === BinaryDataType.Uint8
63
- || data_type === BinaryDataType.Uint16
64
- || data_type === BinaryDataType.Uint32
65
- ) {
66
- if (normalized) {
67
- ending = "unorm";
68
- } else {
69
- ending = "uint";
70
- }
71
-
72
- } else if (
73
- data_type === BinaryDataType.Float32
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":"AAsLA;;;;;GAKG;AACH,oGAoEC"}
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"}