@next2d/webgpu 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (349) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +574 -0
  3. package/package.json +30 -0
  4. package/src/AtlasManager.d.ts +23 -0
  5. package/src/AtlasManager.js +123 -0
  6. package/src/AttachmentManager/service/AttachmentManagerCreateAttachmentObjectService.d.ts +13 -0
  7. package/src/AttachmentManager/service/AttachmentManagerCreateAttachmentObjectService.js +24 -0
  8. package/src/AttachmentManager/service/AttachmentManagerCreateColorBufferService.d.ts +15 -0
  9. package/src/AttachmentManager/service/AttachmentManagerCreateColorBufferService.js +31 -0
  10. package/src/AttachmentManager/service/AttachmentManagerCreateRenderPassDescriptorService.d.ts +5 -0
  11. package/src/AttachmentManager/service/AttachmentManagerCreateRenderPassDescriptorService.js +42 -0
  12. package/src/AttachmentManager/service/AttachmentManagerCreateStencilBufferService.d.ts +16 -0
  13. package/src/AttachmentManager/service/AttachmentManagerCreateStencilBufferService.js +28 -0
  14. package/src/AttachmentManager/service/AttachmentManagerCreateTextureObjectService.d.ts +17 -0
  15. package/src/AttachmentManager/service/AttachmentManagerCreateTextureObjectService.js +33 -0
  16. package/src/AttachmentManager/service/AttachmentManagerGetColorBufferService.d.ts +16 -0
  17. package/src/AttachmentManager/service/AttachmentManagerGetColorBufferService.js +28 -0
  18. package/src/AttachmentManager/service/AttachmentManagerGetStencilBufferService.d.ts +17 -0
  19. package/src/AttachmentManager/service/AttachmentManagerGetStencilBufferService.js +27 -0
  20. package/src/AttachmentManager/service/AttachmentManagerGetTextureService.d.ts +18 -0
  21. package/src/AttachmentManager/service/AttachmentManagerGetTextureService.js +27 -0
  22. package/src/AttachmentManager/service/AttachmentManagerReleaseTextureService.d.ts +12 -0
  23. package/src/AttachmentManager/service/AttachmentManagerReleaseTextureService.js +17 -0
  24. package/src/AttachmentManager/usecase/AttachmentManagerGetAttachmentObjectUseCase.d.ts +26 -0
  25. package/src/AttachmentManager/usecase/AttachmentManagerGetAttachmentObjectUseCase.js +43 -0
  26. package/src/AttachmentManager/usecase/AttachmentManagerReleaseAttachmentUseCase.d.ts +18 -0
  27. package/src/AttachmentManager/usecase/AttachmentManagerReleaseAttachmentUseCase.js +33 -0
  28. package/src/AttachmentManager.d.ts +19 -0
  29. package/src/AttachmentManager.js +105 -0
  30. package/src/BezierConverter/BezierConverter.d.ts +16 -0
  31. package/src/BezierConverter/BezierConverter.js +15 -0
  32. package/src/BezierConverter/service/BezierConverterCalculateFlatnessService.d.ts +15 -0
  33. package/src/BezierConverter/service/BezierConverterCalculateFlatnessService.js +37 -0
  34. package/src/BezierConverter/service/BezierConverterSplitCubicService.d.ts +15 -0
  35. package/src/BezierConverter/service/BezierConverterSplitCubicService.js +47 -0
  36. package/src/BezierConverter/usecase/BezierConverterAdaptiveCubicToQuadUseCase.d.ts +29 -0
  37. package/src/BezierConverter/usecase/BezierConverterAdaptiveCubicToQuadUseCase.js +80 -0
  38. package/src/Blend/BlendInstancedManager.d.ts +35 -0
  39. package/src/Blend/BlendInstancedManager.js +147 -0
  40. package/src/Blend/service/BlendAddService.d.ts +1 -0
  41. package/src/Blend/service/BlendAddService.js +8 -0
  42. package/src/Blend/service/BlendAlphaService.d.ts +1 -0
  43. package/src/Blend/service/BlendAlphaService.js +8 -0
  44. package/src/Blend/service/BlendEraseService.d.ts +1 -0
  45. package/src/Blend/service/BlendEraseService.js +8 -0
  46. package/src/Blend/service/BlendGetStateService.d.ts +12 -0
  47. package/src/Blend/service/BlendGetStateService.js +13 -0
  48. package/src/Blend/service/BlendOneZeroService.d.ts +1 -0
  49. package/src/Blend/service/BlendOneZeroService.js +8 -0
  50. package/src/Blend/service/BlendResetService.d.ts +1 -0
  51. package/src/Blend/service/BlendResetService.js +8 -0
  52. package/src/Blend/service/BlendScreenService.d.ts +1 -0
  53. package/src/Blend/service/BlendScreenService.js +8 -0
  54. package/src/Blend/service/BlendSetModeService.d.ts +2 -0
  55. package/src/Blend/service/BlendSetModeService.js +4 -0
  56. package/src/Blend/usecase/BlendApplyComplexBlendUseCase.d.ts +6 -0
  57. package/src/Blend/usecase/BlendApplyComplexBlendUseCase.js +79 -0
  58. package/src/Blend/usecase/BlendOperationUseCase.d.ts +11 -0
  59. package/src/Blend/usecase/BlendOperationUseCase.js +31 -0
  60. package/src/Blend.d.ts +8 -0
  61. package/src/Blend.js +91 -0
  62. package/src/BufferManager/service/BufferManagerCreateIndirectBufferService.d.ts +15 -0
  63. package/src/BufferManager/service/BufferManagerCreateIndirectBufferService.js +37 -0
  64. package/src/BufferManager/service/BufferManagerCreateRectVerticesService.d.ts +13 -0
  65. package/src/BufferManager/service/BufferManagerCreateRectVerticesService.js +23 -0
  66. package/src/BufferManager/service/BufferManagerCreateStorageBufferService.d.ts +17 -0
  67. package/src/BufferManager/service/BufferManagerCreateStorageBufferService.js +23 -0
  68. package/src/BufferManager/service/BufferManagerReleaseUniformBufferService.d.ts +12 -0
  69. package/src/BufferManager/service/BufferManagerReleaseUniformBufferService.js +32 -0
  70. package/src/BufferManager/service/BufferManagerReleaseVertexBufferService.d.ts +12 -0
  71. package/src/BufferManager/service/BufferManagerReleaseVertexBufferService.js +32 -0
  72. package/src/BufferManager/service/BufferManagerUpdateIndirectBufferService.d.ts +12 -0
  73. package/src/BufferManager/service/BufferManagerUpdateIndirectBufferService.js +20 -0
  74. package/src/BufferManager/service/BufferManagerUpperPowerOfTwoService.d.ts +10 -0
  75. package/src/BufferManager/service/BufferManagerUpperPowerOfTwoService.js +18 -0
  76. package/src/BufferManager/usecase/BufferManagerAcquireStorageBufferUseCase.d.ts +15 -0
  77. package/src/BufferManager/usecase/BufferManagerAcquireStorageBufferUseCase.js +51 -0
  78. package/src/BufferManager/usecase/BufferManagerAcquireUniformBufferUseCase.d.ts +13 -0
  79. package/src/BufferManager/usecase/BufferManagerAcquireUniformBufferUseCase.js +26 -0
  80. package/src/BufferManager/usecase/BufferManagerAcquireVertexBufferUseCase.d.ts +14 -0
  81. package/src/BufferManager/usecase/BufferManagerAcquireVertexBufferUseCase.js +46 -0
  82. package/src/BufferManager/usecase/BufferManagerCleanupStorageBuffersUseCase.d.ts +12 -0
  83. package/src/BufferManager/usecase/BufferManagerCleanupStorageBuffersUseCase.js +20 -0
  84. package/src/BufferManager/usecase/BufferManagerReleaseStorageBufferUseCase.d.ts +9 -0
  85. package/src/BufferManager/usecase/BufferManagerReleaseStorageBufferUseCase.js +15 -0
  86. package/src/BufferManager.d.ts +93 -0
  87. package/src/BufferManager.js +487 -0
  88. package/src/Compute/ComputePipelineManager.d.ts +61 -0
  89. package/src/Compute/ComputePipelineManager.js +313 -0
  90. package/src/Compute/service/ComputeExecuteBlurService.d.ts +21 -0
  91. package/src/Compute/service/ComputeExecuteBlurService.js +81 -0
  92. package/src/Context/service/ContextComputeBitmapMatrixService.d.ts +1 -0
  93. package/src/Context/service/ContextComputeBitmapMatrixService.js +74 -0
  94. package/src/Context/service/ContextComputeGradientMatrixService.d.ts +4 -0
  95. package/src/Context/service/ContextComputeGradientMatrixService.js +88 -0
  96. package/src/Context/service/ContextFillSimpleService.d.ts +2 -0
  97. package/src/Context/service/ContextFillSimpleService.js +28 -0
  98. package/src/Context/service/ContextFillWithStencilMainService.d.ts +2 -0
  99. package/src/Context/service/ContextFillWithStencilMainService.js +19 -0
  100. package/src/Context/service/ContextFillWithStencilService.d.ts +2 -0
  101. package/src/Context/service/ContextFillWithStencilService.js +19 -0
  102. package/src/Context/usecase/ContextApplyFilterUseCase.d.ts +5 -0
  103. package/src/Context/usecase/ContextApplyFilterUseCase.js +668 -0
  104. package/src/Context/usecase/ContextBitmapFillUseCase.d.ts +4 -0
  105. package/src/Context/usecase/ContextBitmapFillUseCase.js +210 -0
  106. package/src/Context/usecase/ContextBitmapStrokeUseCase.d.ts +4 -0
  107. package/src/Context/usecase/ContextBitmapStrokeUseCase.js +119 -0
  108. package/src/Context/usecase/ContextClipUseCase.d.ts +5 -0
  109. package/src/Context/usecase/ContextClipUseCase.js +101 -0
  110. package/src/Context/usecase/ContextContainerEndLayerUseCase.d.ts +5 -0
  111. package/src/Context/usecase/ContextContainerEndLayerUseCase.js +476 -0
  112. package/src/Context/usecase/ContextDrawArraysInstancedUseCase.d.ts +6 -0
  113. package/src/Context/usecase/ContextDrawArraysInstancedUseCase.js +135 -0
  114. package/src/Context/usecase/ContextDrawIndirectUseCase.d.ts +6 -0
  115. package/src/Context/usecase/ContextDrawIndirectUseCase.js +154 -0
  116. package/src/Context/usecase/ContextGradientFillUseCase.d.ts +4 -0
  117. package/src/Context/usecase/ContextGradientFillUseCase.js +230 -0
  118. package/src/Context/usecase/ContextGradientStrokeUseCase.d.ts +4 -0
  119. package/src/Context/usecase/ContextGradientStrokeUseCase.js +138 -0
  120. package/src/Context/usecase/ContextProcessComplexBlendQueueUseCase.d.ts +6 -0
  121. package/src/Context/usecase/ContextProcessComplexBlendQueueUseCase.js +213 -0
  122. package/src/Context.d.ts +430 -0
  123. package/src/Context.js +2453 -0
  124. package/src/FillTexturePool.d.ts +6 -0
  125. package/src/FillTexturePool.js +72 -0
  126. package/src/Filter/BevelFilter/FilterApplyBevelFilterUseCase.d.ts +10 -0
  127. package/src/Filter/BevelFilter/FilterApplyBevelFilterUseCase.js +214 -0
  128. package/src/Filter/BevelFilterShader.d.ts +2 -0
  129. package/src/Filter/BevelFilterShader.js +107 -0
  130. package/src/Filter/BitmapFilterShader.d.ts +2 -0
  131. package/src/Filter/BitmapFilterShader.js +207 -0
  132. package/src/Filter/BlurFilter/FilterApplyBlurFilterUseCase.d.ts +16 -0
  133. package/src/Filter/BlurFilter/FilterApplyBlurFilterUseCase.js +243 -0
  134. package/src/Filter/BlurFilter/service/BlurFilterComputeShaderService.d.ts +40 -0
  135. package/src/Filter/BlurFilter/service/BlurFilterComputeShaderService.js +51 -0
  136. package/src/Filter/BlurFilter/usecase/FilterApplyBlurComputeUseCase.d.ts +25 -0
  137. package/src/Filter/BlurFilter/usecase/FilterApplyBlurComputeUseCase.js +180 -0
  138. package/src/Filter/BlurFilterShader.d.ts +5 -0
  139. package/src/Filter/BlurFilterShader.js +109 -0
  140. package/src/Filter/BlurFilterUseCase.d.ts +36 -0
  141. package/src/Filter/BlurFilterUseCase.js +85 -0
  142. package/src/Filter/ColorMatrixFilter/FilterApplyColorMatrixFilterUseCase.d.ts +12 -0
  143. package/src/Filter/ColorMatrixFilter/FilterApplyColorMatrixFilterUseCase.js +90 -0
  144. package/src/Filter/ColorMatrixFilterShader.d.ts +4 -0
  145. package/src/Filter/ColorMatrixFilterShader.js +51 -0
  146. package/src/Filter/ConvolutionFilter/FilterApplyConvolutionFilterUseCase.d.ts +6 -0
  147. package/src/Filter/ConvolutionFilter/FilterApplyConvolutionFilterUseCase.js +144 -0
  148. package/src/Filter/ConvolutionFilterShader.d.ts +2 -0
  149. package/src/Filter/ConvolutionFilterShader.js +115 -0
  150. package/src/Filter/DisplacementMapFilter/FilterApplyDisplacementMapFilterUseCase.d.ts +6 -0
  151. package/src/Filter/DisplacementMapFilter/FilterApplyDisplacementMapFilterUseCase.js +172 -0
  152. package/src/Filter/DisplacementMapFilterShader.d.ts +2 -0
  153. package/src/Filter/DisplacementMapFilterShader.js +114 -0
  154. package/src/Filter/DropShadowFilter/FilterApplyDropShadowFilterUseCase.d.ts +24 -0
  155. package/src/Filter/DropShadowFilter/FilterApplyDropShadowFilterUseCase.js +179 -0
  156. package/src/Filter/DropShadowFilterShader.d.ts +4 -0
  157. package/src/Filter/DropShadowFilterShader.js +93 -0
  158. package/src/Filter/FilterGradientLUTCache.d.ts +29 -0
  159. package/src/Filter/FilterGradientLUTCache.js +84 -0
  160. package/src/Filter/FilterOffset.d.ts +8 -0
  161. package/src/Filter/FilterOffset.js +10 -0
  162. package/src/Filter/GlowFilter/FilterApplyGlowFilterUseCase.d.ts +24 -0
  163. package/src/Filter/GlowFilter/FilterApplyGlowFilterUseCase.js +143 -0
  164. package/src/Filter/GlowFilterShader.d.ts +4 -0
  165. package/src/Filter/GlowFilterShader.js +66 -0
  166. package/src/Filter/GradientBevelFilter/FilterApplyGradientBevelFilterUseCase.d.ts +29 -0
  167. package/src/Filter/GradientBevelFilter/FilterApplyGradientBevelFilterUseCase.js +216 -0
  168. package/src/Filter/GradientGlowFilter/FilterApplyGradientGlowFilterUseCase.d.ts +29 -0
  169. package/src/Filter/GradientGlowFilter/FilterApplyGradientGlowFilterUseCase.js +164 -0
  170. package/src/FrameBufferManager/service/FrameBufferManagerCreateRenderPassDescriptorService.d.ts +4 -0
  171. package/src/FrameBufferManager/service/FrameBufferManagerCreateRenderPassDescriptorService.js +23 -0
  172. package/src/FrameBufferManager/service/FrameBufferManagerCreateStencilRenderPassDescriptorService.d.ts +4 -0
  173. package/src/FrameBufferManager/service/FrameBufferManagerCreateStencilRenderPassDescriptorService.js +28 -0
  174. package/src/FrameBufferManager/service/FrameBufferManagerFlushPendingReleasesService.d.ts +11 -0
  175. package/src/FrameBufferManager/service/FrameBufferManagerFlushPendingReleasesService.js +19 -0
  176. package/src/FrameBufferManager/usecase/FrameBufferManagerCreateAttachmentUseCase.d.ts +23 -0
  177. package/src/FrameBufferManager/usecase/FrameBufferManagerCreateAttachmentUseCase.js +125 -0
  178. package/src/FrameBufferManager/usecase/FrameBufferManagerReleaseTemporaryAttachmentUseCase.d.ts +14 -0
  179. package/src/FrameBufferManager/usecase/FrameBufferManagerReleaseTemporaryAttachmentUseCase.js +23 -0
  180. package/src/FrameBufferManager.d.ts +24 -0
  181. package/src/FrameBufferManager.js +161 -0
  182. package/src/Gradient/GradientLUTCache.d.ts +61 -0
  183. package/src/Gradient/GradientLUTCache.js +153 -0
  184. package/src/Gradient/GradientLUTGenerator.d.ts +30 -0
  185. package/src/Gradient/GradientLUTGenerator.js +202 -0
  186. package/src/Grid.d.ts +18 -0
  187. package/src/Grid.js +21 -0
  188. package/src/Mask/service/MaskBeginMaskService.d.ts +9 -0
  189. package/src/Mask/service/MaskBeginMaskService.js +22 -0
  190. package/src/Mask/service/MaskEndMaskService.d.ts +15 -0
  191. package/src/Mask/service/MaskEndMaskService.js +36 -0
  192. package/src/Mask/service/MaskSetMaskBoundsService.d.ts +13 -0
  193. package/src/Mask/service/MaskSetMaskBoundsService.js +36 -0
  194. package/src/Mask/service/MaskUnionMaskService.d.ts +4 -0
  195. package/src/Mask/service/MaskUnionMaskService.js +74 -0
  196. package/src/Mask/usecase/MaskBindUseCase.d.ts +10 -0
  197. package/src/Mask/usecase/MaskBindUseCase.js +20 -0
  198. package/src/Mask/usecase/MaskLeaveMaskUseCase.d.ts +13 -0
  199. package/src/Mask/usecase/MaskLeaveMaskUseCase.js +51 -0
  200. package/src/Mask.d.ts +12 -0
  201. package/src/Mask.js +41 -0
  202. package/src/Mesh/service/MeshFillGenerateService.d.ts +19 -0
  203. package/src/Mesh/service/MeshFillGenerateService.js +76 -0
  204. package/src/Mesh/service/MeshLerpService.d.ts +13 -0
  205. package/src/Mesh/service/MeshLerpService.js +17 -0
  206. package/src/Mesh/service/MeshStrokeFillGenerateService.d.ts +19 -0
  207. package/src/Mesh/service/MeshStrokeFillGenerateService.js +76 -0
  208. package/src/Mesh/usecase/MeshBitmapStrokeGenerateUseCase.d.ts +13 -0
  209. package/src/Mesh/usecase/MeshBitmapStrokeGenerateUseCase.js +65 -0
  210. package/src/Mesh/usecase/MeshFillGenerateUseCase.d.ts +12 -0
  211. package/src/Mesh/usecase/MeshFillGenerateUseCase.js +48 -0
  212. package/src/Mesh/usecase/MeshGradientStrokeGenerateUseCase.d.ts +13 -0
  213. package/src/Mesh/usecase/MeshGradientStrokeGenerateUseCase.js +65 -0
  214. package/src/Mesh/usecase/MeshSplitQuadraticBezierUseCase.d.ts +14 -0
  215. package/src/Mesh/usecase/MeshSplitQuadraticBezierUseCase.js +28 -0
  216. package/src/Mesh/usecase/MeshStrokeFillGenerateUseCase.d.ts +18 -0
  217. package/src/Mesh/usecase/MeshStrokeFillGenerateUseCase.js +54 -0
  218. package/src/Mesh/usecase/MeshStrokeGenerateUseCase.d.ts +25 -0
  219. package/src/Mesh/usecase/MeshStrokeGenerateUseCase.js +608 -0
  220. package/src/PathCommand.d.ts +123 -0
  221. package/src/PathCommand.js +317 -0
  222. package/src/SamplerCache/service/SamplerCacheCreateCommonSamplersService.d.ts +11 -0
  223. package/src/SamplerCache/service/SamplerCacheCreateCommonSamplersService.js +35 -0
  224. package/src/SamplerCache/service/SamplerCacheGenerateKeyService.d.ts +13 -0
  225. package/src/SamplerCache/service/SamplerCacheGenerateKeyService.js +15 -0
  226. package/src/SamplerCache/service/SamplerCacheGetOrCreateService.d.ts +15 -0
  227. package/src/SamplerCache/service/SamplerCacheGetOrCreateService.js +30 -0
  228. package/src/SamplerCache.d.ts +18 -0
  229. package/src/SamplerCache.js +61 -0
  230. package/src/Shader/BlendModeShader.d.ts +51 -0
  231. package/src/Shader/BlendModeShader.js +71 -0
  232. package/src/Shader/GradientLUTGenerator/service/GradientLUTCalculateResolutionService.d.ts +12 -0
  233. package/src/Shader/GradientLUTGenerator/service/GradientLUTCalculateResolutionService.js +28 -0
  234. package/src/Shader/GradientLUTGenerator/service/GradientLUTGeneratePixelsService.d.ts +13 -0
  235. package/src/Shader/GradientLUTGenerator/service/GradientLUTGeneratePixelsService.js +61 -0
  236. package/src/Shader/GradientLUTGenerator/service/GradientLUTInterpolateColorService.d.ts +19 -0
  237. package/src/Shader/GradientLUTGenerator/service/GradientLUTInterpolateColorService.js +37 -0
  238. package/src/Shader/GradientLUTGenerator/service/GradientLUTParseStopsService.d.ts +11 -0
  239. package/src/Shader/GradientLUTGenerator/service/GradientLUTParseStopsService.js +24 -0
  240. package/src/Shader/GradientLUTGenerator/usecase/GradientLUTGenerateDataUseCase.d.ts +14 -0
  241. package/src/Shader/GradientLUTGenerator/usecase/GradientLUTGenerateDataUseCase.js +24 -0
  242. package/src/Shader/PipelineManager.d.ts +57 -0
  243. package/src/Shader/PipelineManager.js +2868 -0
  244. package/src/Shader/ShaderInstancedManager.d.ts +8 -0
  245. package/src/Shader/ShaderInstancedManager.js +18 -0
  246. package/src/Shader/ShaderSource.d.ts +60 -0
  247. package/src/Shader/ShaderSource.js +518 -0
  248. package/src/Shader/wgsl/common/SharedWgsl.d.ts +5 -0
  249. package/src/Shader/wgsl/common/SharedWgsl.js +37 -0
  250. package/src/Shader/wgsl/fragment/BasicFragment.d.ts +2 -0
  251. package/src/Shader/wgsl/fragment/BasicFragment.js +28 -0
  252. package/src/Shader/wgsl/fragment/BitmapFragment.d.ts +1 -0
  253. package/src/Shader/wgsl/fragment/BitmapFragment.js +43 -0
  254. package/src/Shader/wgsl/fragment/BlendFragment.d.ts +8 -0
  255. package/src/Shader/wgsl/fragment/BlendFragment.js +63 -0
  256. package/src/Shader/wgsl/fragment/EffectFragment.d.ts +6 -0
  257. package/src/Shader/wgsl/fragment/EffectFragment.js +324 -0
  258. package/src/Shader/wgsl/fragment/FillFragment.d.ts +1 -0
  259. package/src/Shader/wgsl/fragment/FillFragment.js +28 -0
  260. package/src/Shader/wgsl/fragment/FilterFragment.d.ts +10 -0
  261. package/src/Shader/wgsl/fragment/FilterFragment.js +212 -0
  262. package/src/Shader/wgsl/fragment/GradientFragment.d.ts +3 -0
  263. package/src/Shader/wgsl/fragment/GradientFragment.js +118 -0
  264. package/src/Shader/wgsl/fragment/InstancedFragment.d.ts +1 -0
  265. package/src/Shader/wgsl/fragment/InstancedFragment.js +20 -0
  266. package/src/Shader/wgsl/fragment/MaskFragment.d.ts +1 -0
  267. package/src/Shader/wgsl/fragment/MaskFragment.js +17 -0
  268. package/src/Shader/wgsl/fragment/StencilFragment.d.ts +2 -0
  269. package/src/Shader/wgsl/fragment/StencilFragment.js +33 -0
  270. package/src/Shader/wgsl/vertex/BasicVertex.d.ts +1 -0
  271. package/src/Shader/wgsl/vertex/BasicVertex.js +37 -0
  272. package/src/Shader/wgsl/vertex/BitmapVertex.d.ts +1 -0
  273. package/src/Shader/wgsl/vertex/BitmapVertex.js +43 -0
  274. package/src/Shader/wgsl/vertex/FillVertex.d.ts +1 -0
  275. package/src/Shader/wgsl/vertex/FillVertex.js +35 -0
  276. package/src/Shader/wgsl/vertex/FilterVertex.d.ts +12 -0
  277. package/src/Shader/wgsl/vertex/FilterVertex.js +193 -0
  278. package/src/Shader/wgsl/vertex/GradientVertex.d.ts +1 -0
  279. package/src/Shader/wgsl/vertex/GradientVertex.js +44 -0
  280. package/src/Shader/wgsl/vertex/InstancedVertex.d.ts +1 -0
  281. package/src/Shader/wgsl/vertex/InstancedVertex.js +48 -0
  282. package/src/Shader/wgsl/vertex/MaskVertex.d.ts +1 -0
  283. package/src/Shader/wgsl/vertex/MaskVertex.js +36 -0
  284. package/src/Shader/wgsl/vertex/StencilVertex.d.ts +2 -0
  285. package/src/Shader/wgsl/vertex/StencilVertex.js +66 -0
  286. package/src/TextureManager/service/TextureManagerInitializeSamplersService.d.ts +11 -0
  287. package/src/TextureManager/service/TextureManagerInitializeSamplersService.js +48 -0
  288. package/src/TextureManager/usecase/TextureManagerCreateTextureFromImageBitmapUseCase.d.ts +13 -0
  289. package/src/TextureManager/usecase/TextureManagerCreateTextureFromImageBitmapUseCase.js +30 -0
  290. package/src/TextureManager/usecase/TextureManagerCreateTextureFromPixelsUseCase.d.ts +15 -0
  291. package/src/TextureManager/usecase/TextureManagerCreateTextureFromPixelsUseCase.js +26 -0
  292. package/src/TextureManager.d.ts +15 -0
  293. package/src/TextureManager.js +87 -0
  294. package/src/TexturePool/service/TexturePoolCleanupService.d.ts +14 -0
  295. package/src/TexturePool/service/TexturePoolCleanupService.js +28 -0
  296. package/src/TexturePool/service/TexturePoolEvictOldestService.d.ts +11 -0
  297. package/src/TexturePool/service/TexturePoolEvictOldestService.js +24 -0
  298. package/src/TexturePool/service/TexturePoolReleaseService.d.ts +13 -0
  299. package/src/TexturePool/service/TexturePoolReleaseService.js +22 -0
  300. package/src/TexturePool/usecase/TexturePoolAcquireUseCase.d.ts +19 -0
  301. package/src/TexturePool/usecase/TexturePoolAcquireUseCase.js +90 -0
  302. package/src/TexturePool.d.ts +69 -0
  303. package/src/TexturePool.js +151 -0
  304. package/src/WebGPUUtil.d.ts +102 -0
  305. package/src/WebGPUUtil.js +157 -0
  306. package/src/index.d.ts +1 -0
  307. package/src/index.js +1 -0
  308. package/src/interface/IAttachmentObject.d.ts +41 -0
  309. package/src/interface/IAttachmentObject.js +1 -0
  310. package/src/interface/IBlendMode.d.ts +1 -0
  311. package/src/interface/IBlendMode.js +1 -0
  312. package/src/interface/IBlendState.d.ts +8 -0
  313. package/src/interface/IBlendState.js +1 -0
  314. package/src/interface/IBounds.d.ts +6 -0
  315. package/src/interface/IBounds.js +1 -0
  316. package/src/interface/ICachedBindGroup.d.ts +8 -0
  317. package/src/interface/ICachedBindGroup.js +1 -0
  318. package/src/interface/IColorBufferObject.d.ts +17 -0
  319. package/src/interface/IColorBufferObject.js +1 -0
  320. package/src/interface/IComplexBlendItem.d.ts +19 -0
  321. package/src/interface/IComplexBlendItem.js +1 -0
  322. package/src/interface/IFilterConfig.d.ts +29 -0
  323. package/src/interface/IFilterConfig.js +1 -0
  324. package/src/interface/IGradientLUTData.d.ts +8 -0
  325. package/src/interface/IGradientLUTData.js +1 -0
  326. package/src/interface/IGradientStop.d.ts +11 -0
  327. package/src/interface/IGradientStop.js +1 -0
  328. package/src/interface/ILocalFilterConfig.d.ts +21 -0
  329. package/src/interface/ILocalFilterConfig.js +1 -0
  330. package/src/interface/IMeshResult.d.ts +8 -0
  331. package/src/interface/IMeshResult.js +1 -0
  332. package/src/interface/IPath.d.ts +8 -0
  333. package/src/interface/IPath.js +1 -0
  334. package/src/interface/IPoint.d.ts +4 -0
  335. package/src/interface/IPoint.js +1 -0
  336. package/src/interface/IPooledBuffer.d.ts +8 -0
  337. package/src/interface/IPooledBuffer.js +1 -0
  338. package/src/interface/IPooledTexture.d.ts +17 -0
  339. package/src/interface/IPooledTexture.js +1 -0
  340. package/src/interface/IQuadraticSegment.d.ts +9 -0
  341. package/src/interface/IQuadraticSegment.js +1 -0
  342. package/src/interface/IRectangleInfo.d.ts +13 -0
  343. package/src/interface/IRectangleInfo.js +1 -0
  344. package/src/interface/IStencilBufferObject.d.ts +16 -0
  345. package/src/interface/IStencilBufferObject.js +1 -0
  346. package/src/interface/IStorageBufferConfig.d.ts +40 -0
  347. package/src/interface/IStorageBufferConfig.js +1 -0
  348. package/src/interface/ITextureObject.d.ts +16 -0
  349. package/src/interface/ITextureObject.js +1 -0
@@ -0,0 +1,2868 @@
1
+ import { ShaderSource } from "./ShaderSource";
2
+ import { $samples } from "../WebGPUUtil";
3
+ const VERTEX_BUFFER_LAYOUT_4F = {
4
+ "arrayStride": 4 * 4,
5
+ "attributes": [
6
+ { "shaderLocation": 0, "offset": 0, "format": "float32x2" },
7
+ { "shaderLocation": 1, "offset": 2 * 4, "format": "float32x2" }
8
+ ]
9
+ };
10
+ const BLEND_PREMULTIPLIED_ALPHA = {
11
+ "color": {
12
+ "srcFactor": "one",
13
+ "dstFactor": "one-minus-src-alpha",
14
+ "operation": "add"
15
+ },
16
+ "alpha": {
17
+ "srcFactor": "one",
18
+ "dstFactor": "one-minus-src-alpha",
19
+ "operation": "add"
20
+ }
21
+ };
22
+ export class PipelineManager {
23
+ constructor(device, format) {
24
+ Object.defineProperty(this, "device", {
25
+ enumerable: true,
26
+ configurable: true,
27
+ writable: true,
28
+ value: void 0
29
+ });
30
+ Object.defineProperty(this, "format", {
31
+ enumerable: true,
32
+ configurable: true,
33
+ writable: true,
34
+ value: void 0
35
+ });
36
+ Object.defineProperty(this, "pipelines", {
37
+ enumerable: true,
38
+ configurable: true,
39
+ writable: true,
40
+ value: void 0
41
+ });
42
+ Object.defineProperty(this, "bindGroupLayouts", {
43
+ enumerable: true,
44
+ configurable: true,
45
+ writable: true,
46
+ value: void 0
47
+ });
48
+ Object.defineProperty(this, "sampleCount", {
49
+ enumerable: true,
50
+ configurable: true,
51
+ writable: true,
52
+ value: void 0
53
+ });
54
+ Object.defineProperty(this, "shaderModuleCache", {
55
+ enumerable: true,
56
+ configurable: true,
57
+ writable: true,
58
+ value: new Map()
59
+ });
60
+ Object.defineProperty(this, "filterBindGroupLayouts", {
61
+ enumerable: true,
62
+ configurable: true,
63
+ writable: true,
64
+ value: new Map()
65
+ });
66
+ Object.defineProperty(this, "lazyInitGroups", {
67
+ enumerable: true,
68
+ configurable: true,
69
+ writable: true,
70
+ value: new Set()
71
+ });
72
+ Object.defineProperty(this, "lazyGroupMap", {
73
+ enumerable: true,
74
+ configurable: true,
75
+ writable: true,
76
+ value: new Map([
77
+ ...Array.from({ "length": 16 }, (_, i) => [`blur_filter_${i + 1}`, "blur_filter"]),
78
+ ["blur_filter", "blur_filter"],
79
+ ["texture_copy", "texture_copy"], ["texture_copy_rgba8", "texture_copy"], ["color_transform", "texture_copy"], ["y_flip_color_transform", "texture_copy"],
80
+ ["texture_erase", "texture_copy"], ["blur_texture_copy", "texture_copy"],
81
+ ["filter_blend", "texture_copy"], ["texture_copy_bgra", "texture_copy"],
82
+ ["filter_output", "texture_copy"], ["filter_output_add", "texture_copy"],
83
+ ["filter_output_screen", "texture_copy"], ["filter_output_alpha", "texture_copy"],
84
+ ["filter_output_erase", "texture_copy"], ["texture_copy_bgra_msaa", "texture_copy"],
85
+ ["filter_output_msaa", "texture_copy"], ["filter_output_add_msaa", "texture_copy"],
86
+ ["filter_output_screen_msaa", "texture_copy"], ["filter_output_alpha_msaa", "texture_copy"],
87
+ ["filter_output_erase_msaa", "texture_copy"],
88
+ ["positioned_texture", "texture_copy"], ["positioned_texture_rgba", "texture_copy"],
89
+ ["bitmap_render_msaa", "texture_copy"], ["bitmap_render", "texture_copy"],
90
+ ["texture_scale", "texture_copy"], ["texture_scale_blend", "texture_copy"],
91
+ ["bitmap_sync", "bitmap_sync"],
92
+ ["color_matrix_filter", "filter"], ["bevel_base", "filter"],
93
+ ["glow_filter", "filter"], ["drop_shadow_filter", "filter"],
94
+ ["bevel_filter", "filter"], ["gradient_glow_filter", "filter"],
95
+ ["gradient_bevel_filter", "filter"],
96
+ ["complex_blend", "complex_blend"],
97
+ ["complex_blend_copy", "complex_blend"],
98
+ ["complex_blend_scale", "complex_blend"], ["complex_blend_output", "complex_blend"],
99
+ ["complex_blend_output_msaa", "complex_blend"],
100
+ ["filter_complex_blend_output", "complex_blend"],
101
+ ["filter_complex_blend_output_msaa", "complex_blend"]
102
+ ])
103
+ });
104
+ Object.defineProperty(this, "gradientPipelineLayout", {
105
+ enumerable: true,
106
+ configurable: true,
107
+ writable: true,
108
+ value: null
109
+ });
110
+ Object.defineProperty(this, "gradientVertexShaderModule", {
111
+ enumerable: true,
112
+ configurable: true,
113
+ writable: true,
114
+ value: null
115
+ });
116
+ Object.defineProperty(this, "gradientFragmentShaderModule", {
117
+ enumerable: true,
118
+ configurable: true,
119
+ writable: true,
120
+ value: null
121
+ });
122
+ Object.defineProperty(this, "gradientStencilFragmentShaderModule", {
123
+ enumerable: true,
124
+ configurable: true,
125
+ writable: true,
126
+ value: null
127
+ });
128
+ this.device = device;
129
+ this.format = format;
130
+ this.pipelines = new Map();
131
+ this.bindGroupLayouts = new Map();
132
+ this.sampleCount = $samples;
133
+ this.initialize();
134
+ }
135
+ getOrCreateShaderModule(key, code) {
136
+ let module = this.shaderModuleCache.get(key);
137
+ if (!module) {
138
+ module = this.device.createShaderModule({ code });
139
+ this.shaderModuleCache.set(key, module);
140
+ }
141
+ return module;
142
+ }
143
+ initialize() {
144
+ this.createFillPipeline();
145
+ this.createStencilFillPipelines();
146
+ this.createClipPipeline();
147
+ this.createMaskUnionPipelines();
148
+ this.createMaskPipeline();
149
+ this.createBasicPipeline();
150
+ this.createTexturePipeline();
151
+ this.createInstancedPipeline();
152
+ this.createGradientPipeline();
153
+ this.createBitmapFillPipeline();
154
+ this.createBlendPipeline();
155
+ this.createNodeClearPipeline();
156
+ }
157
+ ensureLazyGroup(name) {
158
+ const group = this.lazyGroupMap.get(name);
159
+ if (!group || this.lazyInitGroups.has(group)) {
160
+ return;
161
+ }
162
+ this.lazyInitGroups.add(group);
163
+ switch (group) {
164
+ case "blur_filter":
165
+ this.createBlurFilterPipeline();
166
+ break;
167
+ case "texture_copy":
168
+ this.createTextureCopyPipeline();
169
+ break;
170
+ case "bitmap_sync":
171
+ this.createBitmapSyncPipeline();
172
+ break;
173
+ case "filter":
174
+ this.createColorMatrixFilterPipeline();
175
+ break;
176
+ case "complex_blend":
177
+ this.createComplexBlendPipelines();
178
+ break;
179
+ }
180
+ }
181
+ preloadLazyGroups() {
182
+ const groups = ["blur_filter", "texture_copy", "bitmap_sync", "filter", "complex_blend"];
183
+ for (const group of groups) {
184
+ this.ensureLazyGroup(group);
185
+ }
186
+ }
187
+ createFillPipeline() {
188
+ // Dynamic Offset対応のBindGroupLayout(fill + stencil共有)
189
+ const dynamicBindGroupLayout = this.device.createBindGroupLayout({
190
+ "entries": [
191
+ {
192
+ "binding": 0,
193
+ "visibility": GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
194
+ "buffer": { "type": "uniform", "hasDynamicOffset": true }
195
+ }
196
+ ]
197
+ });
198
+ this.bindGroupLayouts.set("fill_dynamic", dynamicBindGroupLayout);
199
+ const pipelineLayout = this.device.createPipelineLayout({
200
+ "bindGroupLayouts": [dynamicBindGroupLayout]
201
+ });
202
+ const vertexShaderModule = this.getOrCreateShaderModule("fillVertex", ShaderSource.getFillVertexShader());
203
+ const fragmentShaderModule = this.getOrCreateShaderModule("fillFragment", ShaderSource.getFillFragmentShader());
204
+ const vertexBufferLayout = VERTEX_BUFFER_LAYOUT_4F;
205
+ const blendState = BLEND_PREMULTIPLIED_ALPHA;
206
+ const pipelineRGBA = this.device.createRenderPipeline({
207
+ "layout": pipelineLayout,
208
+ "vertex": {
209
+ "module": vertexShaderModule,
210
+ "entryPoint": "main",
211
+ "buffers": [vertexBufferLayout]
212
+ },
213
+ "fragment": {
214
+ "module": fragmentShaderModule,
215
+ "entryPoint": "main",
216
+ "targets": [{
217
+ "format": "rgba8unorm",
218
+ "blend": blendState
219
+ }]
220
+ },
221
+ "primitive": {
222
+ "topology": "triangle-list",
223
+ "cullMode": "none"
224
+ },
225
+ "depthStencil": {
226
+ "format": "stencil8",
227
+ "stencilFront": {
228
+ "compare": "always",
229
+ "failOp": "keep",
230
+ "depthFailOp": "keep",
231
+ "passOp": "keep"
232
+ },
233
+ "stencilBack": {
234
+ "compare": "always",
235
+ "failOp": "keep",
236
+ "depthFailOp": "keep",
237
+ "passOp": "keep"
238
+ },
239
+ "stencilReadMask": 0x00,
240
+ "stencilWriteMask": 0x00
241
+ },
242
+ "multisample": {
243
+ "count": this.sampleCount,
244
+ "alphaToCoverageEnabled": true
245
+ }
246
+ });
247
+ const pipelineBGRA = this.device.createRenderPipeline({
248
+ "layout": pipelineLayout,
249
+ "vertex": {
250
+ "module": vertexShaderModule,
251
+ "entryPoint": "main",
252
+ "buffers": [vertexBufferLayout],
253
+ "constants": { "yFlipSign": -1.0 }
254
+ },
255
+ "fragment": {
256
+ "module": fragmentShaderModule,
257
+ "entryPoint": "main",
258
+ "targets": [{
259
+ "format": this.format,
260
+ "blend": blendState
261
+ }]
262
+ },
263
+ "primitive": {
264
+ "topology": "triangle-list",
265
+ "cullMode": "none"
266
+ },
267
+ "multisample": {
268
+ "count": this.sampleCount,
269
+ "alphaToCoverageEnabled": true
270
+ }
271
+ });
272
+ this.pipelines.set("fill", pipelineRGBA);
273
+ this.pipelines.set("fill_bgra", pipelineBGRA);
274
+ const pipelineBGRAStencil = this.device.createRenderPipeline({
275
+ "layout": pipelineLayout,
276
+ "vertex": {
277
+ "module": vertexShaderModule,
278
+ "entryPoint": "main",
279
+ "buffers": [vertexBufferLayout],
280
+ "constants": { "yFlipSign": -1.0 }
281
+ },
282
+ "fragment": {
283
+ "module": fragmentShaderModule,
284
+ "entryPoint": "main",
285
+ "targets": [{
286
+ "format": this.format,
287
+ "blend": blendState
288
+ }]
289
+ },
290
+ "primitive": {
291
+ "topology": "triangle-list",
292
+ "cullMode": "none"
293
+ },
294
+ "depthStencil": {
295
+ "format": "stencil8",
296
+ "stencilFront": {
297
+ "compare": "equal",
298
+ "failOp": "keep",
299
+ "depthFailOp": "keep",
300
+ "passOp": "keep"
301
+ },
302
+ "stencilBack": {
303
+ "compare": "equal",
304
+ "failOp": "keep",
305
+ "depthFailOp": "keep",
306
+ "passOp": "keep"
307
+ },
308
+ "stencilReadMask": 0xFF,
309
+ "stencilWriteMask": 0x00
310
+ },
311
+ "multisample": {
312
+ "count": this.sampleCount,
313
+ "alphaToCoverageEnabled": true
314
+ }
315
+ });
316
+ this.pipelines.set("fill_bgra_stencil", pipelineBGRAStencil);
317
+ }
318
+ createStencilFillPipelines() {
319
+ const vertexBufferLayout = VERTEX_BUFFER_LAYOUT_4F;
320
+ // fill_dynamicレイアウトを共有(hasDynamicOffset: true)
321
+ const dynamicLayout = this.bindGroupLayouts.get("fill_dynamic");
322
+ const stencilPipelineLayout = this.device.createPipelineLayout({
323
+ "bindGroupLayouts": [dynamicLayout]
324
+ });
325
+ const stencilWritePipeline = this.device.createRenderPipeline({
326
+ "layout": stencilPipelineLayout,
327
+ "vertex": {
328
+ "module": this.getOrCreateShaderModule("stencilWriteVertex", ShaderSource.getStencilWriteVertexShader()),
329
+ "entryPoint": "main",
330
+ "buffers": [vertexBufferLayout]
331
+ },
332
+ "fragment": {
333
+ "module": this.getOrCreateShaderModule("stencilWriteFragment", ShaderSource.getStencilWriteFragmentShader()),
334
+ "entryPoint": "main",
335
+ "targets": [{
336
+ "format": "rgba8unorm",
337
+ "writeMask": 0
338
+ }]
339
+ },
340
+ "primitive": {
341
+ "topology": "triangle-list",
342
+ "cullMode": "none",
343
+ "frontFace": "ccw"
344
+ },
345
+ "depthStencil": {
346
+ "format": "stencil8",
347
+ "stencilFront": {
348
+ "compare": "always",
349
+ "failOp": "keep",
350
+ "depthFailOp": "keep",
351
+ "passOp": "increment-wrap"
352
+ },
353
+ "stencilBack": {
354
+ "compare": "always",
355
+ "failOp": "keep",
356
+ "depthFailOp": "keep",
357
+ "passOp": "decrement-wrap"
358
+ },
359
+ "stencilReadMask": 0xFF,
360
+ "stencilWriteMask": 0xFF
361
+ },
362
+ "multisample": {
363
+ "count": this.sampleCount,
364
+ "alphaToCoverageEnabled": true
365
+ }
366
+ });
367
+ this.pipelines.set("stencil_write", stencilWritePipeline);
368
+ const stencilFillPipeline = this.device.createRenderPipeline({
369
+ "layout": stencilPipelineLayout,
370
+ "vertex": {
371
+ "module": this.getOrCreateShaderModule("stencilFillVertex", ShaderSource.getStencilFillVertexShader()),
372
+ "entryPoint": "main",
373
+ "buffers": [vertexBufferLayout]
374
+ },
375
+ "fragment": {
376
+ "module": this.getOrCreateShaderModule("stencilFillFragment", ShaderSource.getStencilFillFragmentShader()),
377
+ "entryPoint": "main",
378
+ "targets": [{
379
+ "format": "rgba8unorm",
380
+ "blend": {
381
+ "color": {
382
+ "srcFactor": "one",
383
+ "dstFactor": "one-minus-src-alpha",
384
+ "operation": "add"
385
+ },
386
+ "alpha": {
387
+ "srcFactor": "one",
388
+ "dstFactor": "one-minus-src-alpha",
389
+ "operation": "add"
390
+ }
391
+ }
392
+ }]
393
+ },
394
+ "primitive": {
395
+ "topology": "triangle-list",
396
+ "cullMode": "none"
397
+ },
398
+ "depthStencil": {
399
+ "format": "stencil8",
400
+ "stencilFront": {
401
+ "compare": "not-equal",
402
+ "failOp": "keep",
403
+ "depthFailOp": "zero",
404
+ "passOp": "zero"
405
+ },
406
+ "stencilBack": {
407
+ "compare": "not-equal",
408
+ "failOp": "keep",
409
+ "depthFailOp": "zero",
410
+ "passOp": "zero"
411
+ },
412
+ "stencilReadMask": 0xFF,
413
+ "stencilWriteMask": 0xFF
414
+ },
415
+ "multisample": {
416
+ "count": this.sampleCount
417
+ }
418
+ });
419
+ this.pipelines.set("stencil_fill", stencilFillPipeline);
420
+ const stencilWritePipelineAtlas = this.device.createRenderPipeline({
421
+ "layout": stencilPipelineLayout,
422
+ "vertex": {
423
+ "module": this.getOrCreateShaderModule("stencilWriteVertex", ShaderSource.getStencilWriteVertexShader()),
424
+ "entryPoint": "main",
425
+ "buffers": [vertexBufferLayout]
426
+ },
427
+ "fragment": {
428
+ "module": this.getOrCreateShaderModule("stencilWriteFragment", ShaderSource.getStencilWriteFragmentShader()),
429
+ "entryPoint": "main",
430
+ "targets": [{
431
+ "format": "rgba8unorm",
432
+ "writeMask": 0
433
+ }]
434
+ },
435
+ "primitive": {
436
+ "topology": "triangle-list",
437
+ "cullMode": "none",
438
+ "frontFace": "ccw"
439
+ },
440
+ "depthStencil": {
441
+ "format": "stencil8",
442
+ "stencilFront": {
443
+ "compare": "always",
444
+ "failOp": "keep",
445
+ "depthFailOp": "keep",
446
+ "passOp": "increment-wrap"
447
+ },
448
+ "stencilBack": {
449
+ "compare": "always",
450
+ "failOp": "keep",
451
+ "depthFailOp": "keep",
452
+ "passOp": "decrement-wrap"
453
+ },
454
+ "stencilReadMask": 0xFF,
455
+ "stencilWriteMask": 0xFF
456
+ },
457
+ "multisample": {
458
+ "count": this.sampleCount,
459
+ "alphaToCoverageEnabled": true
460
+ }
461
+ });
462
+ this.pipelines.set("stencil_write_atlas", stencilWritePipelineAtlas);
463
+ const stencilWritePipelineMain = this.device.createRenderPipeline({
464
+ "layout": stencilPipelineLayout,
465
+ "vertex": {
466
+ "module": this.getOrCreateShaderModule("stencilWriteVertex", ShaderSource.getStencilWriteVertexShader()),
467
+ "entryPoint": "main",
468
+ "buffers": [vertexBufferLayout],
469
+ "constants": { "yFlipSign": -1.0 }
470
+ },
471
+ "fragment": {
472
+ "module": this.getOrCreateShaderModule("stencilWriteFragment", ShaderSource.getStencilWriteFragmentShader()),
473
+ "entryPoint": "main",
474
+ "targets": [{
475
+ "format": this.format,
476
+ "writeMask": 0
477
+ }]
478
+ },
479
+ "primitive": {
480
+ "topology": "triangle-list",
481
+ "cullMode": "none",
482
+ "frontFace": "ccw"
483
+ },
484
+ "depthStencil": {
485
+ "format": "stencil8",
486
+ "stencilFront": {
487
+ "compare": "always",
488
+ "failOp": "keep",
489
+ "depthFailOp": "keep",
490
+ "passOp": "increment-wrap"
491
+ },
492
+ "stencilBack": {
493
+ "compare": "always",
494
+ "failOp": "keep",
495
+ "depthFailOp": "keep",
496
+ "passOp": "decrement-wrap"
497
+ },
498
+ "stencilReadMask": 0xFF,
499
+ "stencilWriteMask": 0xFF
500
+ },
501
+ "multisample": {
502
+ "count": this.sampleCount,
503
+ "alphaToCoverageEnabled": true
504
+ }
505
+ });
506
+ this.pipelines.set("stencil_write_main", stencilWritePipelineMain);
507
+ const stencilFillPipelineAtlas = this.device.createRenderPipeline({
508
+ "layout": stencilPipelineLayout,
509
+ "vertex": {
510
+ "module": this.getOrCreateShaderModule("stencilFillVertex", ShaderSource.getStencilFillVertexShader()),
511
+ "entryPoint": "main",
512
+ "buffers": [vertexBufferLayout]
513
+ },
514
+ "fragment": {
515
+ "module": this.getOrCreateShaderModule("stencilFillFragment", ShaderSource.getStencilFillFragmentShader()),
516
+ "entryPoint": "main",
517
+ "targets": [{
518
+ "format": "rgba8unorm",
519
+ "blend": {
520
+ "color": {
521
+ "srcFactor": "one",
522
+ "dstFactor": "one-minus-src-alpha",
523
+ "operation": "add"
524
+ },
525
+ "alpha": {
526
+ "srcFactor": "one",
527
+ "dstFactor": "one",
528
+ "operation": "max"
529
+ }
530
+ }
531
+ }]
532
+ },
533
+ "primitive": {
534
+ "topology": "triangle-list",
535
+ "cullMode": "none"
536
+ },
537
+ "depthStencil": {
538
+ "format": "stencil8",
539
+ "stencilFront": {
540
+ "compare": "not-equal",
541
+ "failOp": "keep",
542
+ "depthFailOp": "zero",
543
+ "passOp": "zero"
544
+ },
545
+ "stencilBack": {
546
+ "compare": "not-equal",
547
+ "failOp": "keep",
548
+ "depthFailOp": "zero",
549
+ "passOp": "zero"
550
+ },
551
+ "stencilReadMask": 0xFF,
552
+ "stencilWriteMask": 0xFF
553
+ },
554
+ "multisample": {
555
+ "count": this.sampleCount
556
+ }
557
+ });
558
+ this.pipelines.set("stencil_fill_atlas", stencilFillPipelineAtlas);
559
+ const stencilFillPipelineMain = this.device.createRenderPipeline({
560
+ "layout": stencilPipelineLayout,
561
+ "vertex": {
562
+ "module": this.getOrCreateShaderModule("stencilFillVertex", ShaderSource.getStencilFillVertexShader()),
563
+ "entryPoint": "main",
564
+ "buffers": [vertexBufferLayout],
565
+ "constants": { "yFlipSign": -1.0 }
566
+ },
567
+ "fragment": {
568
+ "module": this.getOrCreateShaderModule("stencilFillFragment", ShaderSource.getStencilFillFragmentShader()),
569
+ "entryPoint": "main",
570
+ "targets": [{
571
+ "format": this.format,
572
+ "blend": {
573
+ "color": {
574
+ "srcFactor": "one",
575
+ "dstFactor": "one-minus-src-alpha",
576
+ "operation": "add"
577
+ },
578
+ "alpha": {
579
+ "srcFactor": "one",
580
+ "dstFactor": "one",
581
+ "operation": "max"
582
+ }
583
+ }
584
+ }]
585
+ },
586
+ "primitive": {
587
+ "topology": "triangle-list",
588
+ "cullMode": "none"
589
+ },
590
+ "depthStencil": {
591
+ "format": "stencil8",
592
+ "stencilFront": {
593
+ "compare": "not-equal",
594
+ "failOp": "keep",
595
+ "depthFailOp": "zero",
596
+ "passOp": "zero"
597
+ },
598
+ "stencilBack": {
599
+ "compare": "not-equal",
600
+ "failOp": "keep",
601
+ "depthFailOp": "zero",
602
+ "passOp": "zero"
603
+ },
604
+ "stencilReadMask": 0xFF,
605
+ "stencilWriteMask": 0xFF
606
+ },
607
+ "multisample": {
608
+ "count": this.sampleCount
609
+ }
610
+ });
611
+ this.pipelines.set("stencil_fill_main", stencilFillPipelineMain);
612
+ const stencilFillMaskedPipeline = this.device.createRenderPipeline({
613
+ "layout": stencilPipelineLayout,
614
+ "vertex": {
615
+ "module": this.getOrCreateShaderModule("stencilFillVertex", ShaderSource.getStencilFillVertexShader()),
616
+ "entryPoint": "main",
617
+ "buffers": [vertexBufferLayout]
618
+ },
619
+ "fragment": {
620
+ "module": this.getOrCreateShaderModule("stencilFillFragment", ShaderSource.getStencilFillFragmentShader()),
621
+ "entryPoint": "main",
622
+ "targets": [{
623
+ "format": "rgba8unorm",
624
+ "blend": {
625
+ "color": {
626
+ "srcFactor": "one",
627
+ "dstFactor": "one-minus-src-alpha",
628
+ "operation": "add"
629
+ },
630
+ "alpha": {
631
+ "srcFactor": "one",
632
+ "dstFactor": "one-minus-src-alpha",
633
+ "operation": "add"
634
+ }
635
+ }
636
+ }]
637
+ },
638
+ "primitive": {
639
+ "topology": "triangle-list",
640
+ "cullMode": "none"
641
+ },
642
+ "depthStencil": {
643
+ "format": "stencil8",
644
+ "stencilFront": {
645
+ "compare": "greater",
646
+ "failOp": "keep",
647
+ "depthFailOp": "replace",
648
+ "passOp": "replace"
649
+ },
650
+ "stencilBack": {
651
+ "compare": "greater",
652
+ "failOp": "keep",
653
+ "depthFailOp": "replace",
654
+ "passOp": "replace"
655
+ },
656
+ "stencilReadMask": 0xFF,
657
+ "stencilWriteMask": 0xFF
658
+ },
659
+ "multisample": {
660
+ "count": this.sampleCount
661
+ }
662
+ });
663
+ this.pipelines.set("stencil_fill_masked", stencilFillMaskedPipeline);
664
+ }
665
+ createClipPipeline() {
666
+ const vertexBufferLayout = VERTEX_BUFFER_LAYOUT_4F;
667
+ const dynamicLayout = this.bindGroupLayouts.get("fill_dynamic");
668
+ const clipPipelineLayout = this.device.createPipelineLayout({
669
+ "bindGroupLayouts": [dynamicLayout]
670
+ });
671
+ const clipWritePipeline = this.device.createRenderPipeline({
672
+ "layout": clipPipelineLayout,
673
+ "vertex": {
674
+ "module": this.getOrCreateShaderModule("stencilWriteVertex", ShaderSource.getStencilWriteVertexShader()),
675
+ "entryPoint": "main",
676
+ "buffers": [vertexBufferLayout]
677
+ },
678
+ "fragment": {
679
+ "module": this.getOrCreateShaderModule("stencilWriteFragment", ShaderSource.getStencilWriteFragmentShader()),
680
+ "entryPoint": "main",
681
+ "targets": [{
682
+ "format": "rgba8unorm",
683
+ "writeMask": 0
684
+ }]
685
+ },
686
+ "primitive": {
687
+ "topology": "triangle-list",
688
+ "cullMode": "none"
689
+ },
690
+ "depthStencil": {
691
+ "format": "stencil8",
692
+ "stencilFront": {
693
+ "compare": "always",
694
+ "failOp": "zero",
695
+ "depthFailOp": "invert",
696
+ "passOp": "invert"
697
+ },
698
+ "stencilBack": {
699
+ "compare": "always",
700
+ "failOp": "zero",
701
+ "depthFailOp": "invert",
702
+ "passOp": "invert"
703
+ },
704
+ "stencilReadMask": 0xFF,
705
+ "stencilWriteMask": 0xFF
706
+ },
707
+ "multisample": {
708
+ "count": this.sampleCount
709
+ }
710
+ });
711
+ this.pipelines.set("clip_write", clipWritePipeline);
712
+ const vertexShaderModule = this.getOrCreateShaderModule("stencilWriteVertex", ShaderSource.getStencilWriteVertexShader());
713
+ const fragmentShaderModule = this.getOrCreateShaderModule("stencilWriteFragment", ShaderSource.getStencilWriteFragmentShader());
714
+ for (let level = 1; level <= 8; level++) {
715
+ const stencilWriteMask = 1 << level - 1;
716
+ const clipWriteMainPipeline = this.device.createRenderPipeline({
717
+ "layout": clipPipelineLayout,
718
+ "vertex": {
719
+ "module": vertexShaderModule,
720
+ "entryPoint": "main",
721
+ "buffers": [vertexBufferLayout],
722
+ "constants": { "yFlipSign": -1.0 }
723
+ },
724
+ "fragment": {
725
+ "module": fragmentShaderModule,
726
+ "entryPoint": "main",
727
+ "targets": [{
728
+ "format": this.format,
729
+ "writeMask": 0
730
+ }]
731
+ },
732
+ "primitive": {
733
+ "topology": "triangle-list",
734
+ "cullMode": "none"
735
+ },
736
+ "depthStencil": {
737
+ "format": "stencil8",
738
+ "stencilFront": {
739
+ "compare": "always",
740
+ "failOp": "zero",
741
+ "depthFailOp": "invert",
742
+ "passOp": "invert"
743
+ },
744
+ "stencilBack": {
745
+ "compare": "always",
746
+ "failOp": "zero",
747
+ "depthFailOp": "invert",
748
+ "passOp": "invert"
749
+ },
750
+ "stencilReadMask": 0xFF,
751
+ "stencilWriteMask": stencilWriteMask
752
+ },
753
+ "multisample": {
754
+ "count": this.sampleCount,
755
+ "alphaToCoverageEnabled": true
756
+ }
757
+ });
758
+ this.pipelines.set(`clip_write_main_${level}`, clipWriteMainPipeline);
759
+ }
760
+ this.pipelines.set("clip_write_main", this.pipelines.get("clip_write_main_1"));
761
+ for (let level = 1; level <= 8; level++) {
762
+ const stencilWriteMask = 1 << level - 1;
763
+ const clipClearMainPipeline = this.device.createRenderPipeline({
764
+ "layout": clipPipelineLayout,
765
+ "vertex": {
766
+ "module": vertexShaderModule,
767
+ "entryPoint": "main",
768
+ "buffers": [vertexBufferLayout],
769
+ "constants": { "yFlipSign": -1.0 }
770
+ },
771
+ "fragment": {
772
+ "module": fragmentShaderModule,
773
+ "entryPoint": "main",
774
+ "targets": [{
775
+ "format": this.format,
776
+ "writeMask": 0
777
+ }]
778
+ },
779
+ "primitive": {
780
+ "topology": "triangle-list",
781
+ "cullMode": "none"
782
+ },
783
+ "depthStencil": {
784
+ "format": "stencil8",
785
+ "stencilFront": {
786
+ "compare": "always",
787
+ "failOp": "replace",
788
+ "depthFailOp": "replace",
789
+ "passOp": "replace"
790
+ },
791
+ "stencilBack": {
792
+ "compare": "always",
793
+ "failOp": "replace",
794
+ "depthFailOp": "replace",
795
+ "passOp": "replace"
796
+ },
797
+ "stencilReadMask": 0xFF,
798
+ "stencilWriteMask": stencilWriteMask
799
+ },
800
+ "multisample": {
801
+ "count": this.sampleCount
802
+ }
803
+ });
804
+ this.pipelines.set(`clip_clear_main_${level}`, clipClearMainPipeline);
805
+ }
806
+ }
807
+ createMaskUnionPipelines() {
808
+ const vertexBufferLayout = VERTEX_BUFFER_LAYOUT_4F;
809
+ const dynamicLayout = this.bindGroupLayouts.get("fill_dynamic");
810
+ const maskUnionPipelineLayout = this.device.createPipelineLayout({
811
+ "bindGroupLayouts": [dynamicLayout]
812
+ });
813
+ const vertexShaderModule = this.getOrCreateShaderModule("stencilWriteVertex", ShaderSource.getStencilWriteVertexShader());
814
+ const fragmentShaderModule = this.getOrCreateShaderModule("stencilWriteFragment", ShaderSource.getStencilWriteFragmentShader());
815
+ for (let level = 1; level <= 8; level++) {
816
+ const mask = 1 << level - 1;
817
+ const upperBitsMask = ~mask & 0xFF;
818
+ const mergePipeline = this.device.createRenderPipeline({
819
+ "layout": maskUnionPipelineLayout,
820
+ "vertex": {
821
+ "module": vertexShaderModule,
822
+ "entryPoint": "main",
823
+ "buffers": [vertexBufferLayout],
824
+ "constants": { "yFlipSign": -1.0 }
825
+ },
826
+ "fragment": {
827
+ "module": fragmentShaderModule,
828
+ "entryPoint": "main",
829
+ "targets": [{
830
+ "format": this.format,
831
+ "writeMask": 0
832
+ }]
833
+ },
834
+ "primitive": {
835
+ "topology": "triangle-list",
836
+ "cullMode": "none"
837
+ },
838
+ "depthStencil": {
839
+ "format": "stencil8",
840
+ "stencilFront": {
841
+ "compare": "less-equal",
842
+ "failOp": "zero",
843
+ "depthFailOp": "replace",
844
+ "passOp": "replace"
845
+ },
846
+ "stencilBack": {
847
+ "compare": "less-equal",
848
+ "failOp": "zero",
849
+ "depthFailOp": "replace",
850
+ "passOp": "replace"
851
+ },
852
+ "stencilReadMask": 0xFF,
853
+ "stencilWriteMask": upperBitsMask
854
+ }
855
+ });
856
+ this.pipelines.set(`mask_union_merge_${level}`, mergePipeline);
857
+ const clearPipeline = this.device.createRenderPipeline({
858
+ "layout": maskUnionPipelineLayout,
859
+ "vertex": {
860
+ "module": vertexShaderModule,
861
+ "entryPoint": "main",
862
+ "buffers": [vertexBufferLayout],
863
+ "constants": { "yFlipSign": -1.0 }
864
+ },
865
+ "fragment": {
866
+ "module": fragmentShaderModule,
867
+ "entryPoint": "main",
868
+ "targets": [{
869
+ "format": this.format,
870
+ "writeMask": 0
871
+ }]
872
+ },
873
+ "primitive": {
874
+ "topology": "triangle-list",
875
+ "cullMode": "none"
876
+ },
877
+ "depthStencil": {
878
+ "format": "stencil8",
879
+ "stencilFront": {
880
+ "compare": "always",
881
+ "failOp": "replace",
882
+ "depthFailOp": "replace",
883
+ "passOp": "replace"
884
+ },
885
+ "stencilBack": {
886
+ "compare": "always",
887
+ "failOp": "replace",
888
+ "depthFailOp": "replace",
889
+ "passOp": "replace"
890
+ },
891
+ "stencilReadMask": 0xFF,
892
+ "stencilWriteMask": 1 << level
893
+ }
894
+ });
895
+ this.pipelines.set(`mask_union_clear_${level}`, clearPipeline);
896
+ }
897
+ }
898
+ createMaskPipeline() {
899
+ const bindGroupLayout = this.device.createBindGroupLayout({
900
+ "entries": [
901
+ {
902
+ "binding": 0,
903
+ "visibility": GPUShaderStage.VERTEX,
904
+ "buffer": { "type": "uniform" }
905
+ }
906
+ ]
907
+ });
908
+ this.bindGroupLayouts.set("mask", bindGroupLayout);
909
+ const pipelineLayout = this.device.createPipelineLayout({
910
+ "bindGroupLayouts": [bindGroupLayout]
911
+ });
912
+ const vertexShaderModule = this.getOrCreateShaderModule("maskVertex", ShaderSource.getMaskVertexShader());
913
+ const fragmentShaderModule = this.getOrCreateShaderModule("maskFragment", ShaderSource.getMaskFragmentShader());
914
+ const pipeline = this.device.createRenderPipeline({
915
+ "layout": pipelineLayout,
916
+ "vertex": {
917
+ "module": vertexShaderModule,
918
+ "entryPoint": "main",
919
+ "buffers": [{
920
+ "arrayStride": 4 * 4,
921
+ "attributes": [
922
+ {
923
+ "shaderLocation": 0,
924
+ "offset": 0,
925
+ "format": "float32x2"
926
+ },
927
+ {
928
+ "shaderLocation": 1,
929
+ "offset": 2 * 4,
930
+ "format": "float32x2"
931
+ }
932
+ ]
933
+ }]
934
+ },
935
+ "fragment": {
936
+ "module": fragmentShaderModule,
937
+ "entryPoint": "main",
938
+ "targets": [{
939
+ "format": this.format,
940
+ "blend": {
941
+ "color": {
942
+ "srcFactor": "one",
943
+ "dstFactor": "one-minus-src-alpha",
944
+ "operation": "add"
945
+ },
946
+ "alpha": {
947
+ "srcFactor": "one",
948
+ "dstFactor": "one-minus-src-alpha",
949
+ "operation": "add"
950
+ }
951
+ }
952
+ }]
953
+ },
954
+ "primitive": {
955
+ "topology": "triangle-list",
956
+ "cullMode": "none"
957
+ }
958
+ });
959
+ this.pipelines.set("mask", pipeline);
960
+ }
961
+ createBasicPipeline() {
962
+ const bindGroupLayout = this.device.createBindGroupLayout({
963
+ "entries": [{
964
+ "binding": 0,
965
+ "visibility": GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
966
+ "buffer": { "type": "uniform" }
967
+ }]
968
+ });
969
+ this.bindGroupLayouts.set("basic", bindGroupLayout);
970
+ const pipelineLayout = this.device.createPipelineLayout({
971
+ "bindGroupLayouts": [bindGroupLayout]
972
+ });
973
+ const vertexShaderModule = this.getOrCreateShaderModule("basicVertex", ShaderSource.getBasicVertexShader());
974
+ const fragmentShaderModule = this.getOrCreateShaderModule("basicFragment", ShaderSource.getBasicFragmentShader());
975
+ const vertexBufferLayout = {
976
+ "arrayStride": 4 * 4,
977
+ "attributes": [
978
+ {
979
+ "shaderLocation": 0,
980
+ "offset": 0,
981
+ "format": "float32x2"
982
+ },
983
+ {
984
+ "shaderLocation": 1,
985
+ "offset": 2 * 4,
986
+ "format": "float32x2"
987
+ }
988
+ ]
989
+ };
990
+ const blendState = BLEND_PREMULTIPLIED_ALPHA;
991
+ const pipelineRGBA = this.device.createRenderPipeline({
992
+ "layout": pipelineLayout,
993
+ "vertex": {
994
+ "module": vertexShaderModule,
995
+ "entryPoint": "main",
996
+ "buffers": [vertexBufferLayout]
997
+ },
998
+ "fragment": {
999
+ "module": fragmentShaderModule,
1000
+ "entryPoint": "main",
1001
+ "targets": [{
1002
+ "format": "rgba8unorm",
1003
+ "blend": blendState
1004
+ }]
1005
+ },
1006
+ "primitive": {
1007
+ "topology": "triangle-list",
1008
+ "cullMode": "none"
1009
+ },
1010
+ "multisample": {
1011
+ "count": this.sampleCount
1012
+ }
1013
+ });
1014
+ const pipelineBGRA = this.device.createRenderPipeline({
1015
+ "layout": pipelineLayout,
1016
+ "vertex": {
1017
+ "module": vertexShaderModule,
1018
+ "entryPoint": "main",
1019
+ "buffers": [vertexBufferLayout],
1020
+ "constants": { "yFlipSign": -1.0 }
1021
+ },
1022
+ "fragment": {
1023
+ "module": fragmentShaderModule,
1024
+ "entryPoint": "main",
1025
+ "targets": [{
1026
+ "format": this.format,
1027
+ "blend": blendState
1028
+ }]
1029
+ },
1030
+ "primitive": {
1031
+ "topology": "triangle-list",
1032
+ "cullMode": "none"
1033
+ }
1034
+ });
1035
+ this.pipelines.set("basic", pipelineRGBA);
1036
+ this.pipelines.set("basic_bgra", pipelineBGRA);
1037
+ }
1038
+ createTexturePipeline() {
1039
+ const bindGroupLayout = this.device.createBindGroupLayout({
1040
+ "entries": [
1041
+ {
1042
+ "binding": 0,
1043
+ "visibility": GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
1044
+ "buffer": { "type": "uniform" }
1045
+ },
1046
+ {
1047
+ "binding": 1,
1048
+ "visibility": GPUShaderStage.FRAGMENT,
1049
+ "sampler": {}
1050
+ },
1051
+ {
1052
+ "binding": 2,
1053
+ "visibility": GPUShaderStage.FRAGMENT,
1054
+ "texture": {}
1055
+ }
1056
+ ]
1057
+ });
1058
+ this.bindGroupLayouts.set("texture", bindGroupLayout);
1059
+ const pipelineLayout = this.device.createPipelineLayout({
1060
+ "bindGroupLayouts": [bindGroupLayout]
1061
+ });
1062
+ const vertexShaderModule = this.getOrCreateShaderModule("basicVertex", ShaderSource.getBasicVertexShader());
1063
+ const fragmentShaderModule = this.getOrCreateShaderModule("textureFragment", ShaderSource.getTextureFragmentShader());
1064
+ const pipeline = this.device.createRenderPipeline({
1065
+ "layout": pipelineLayout,
1066
+ "vertex": {
1067
+ "module": vertexShaderModule,
1068
+ "entryPoint": "main",
1069
+ "buffers": [{
1070
+ "arrayStride": 4 * 4,
1071
+ "attributes": [
1072
+ {
1073
+ "shaderLocation": 0,
1074
+ "offset": 0,
1075
+ "format": "float32x2"
1076
+ },
1077
+ {
1078
+ "shaderLocation": 1,
1079
+ "offset": 2 * 4,
1080
+ "format": "float32x2"
1081
+ }
1082
+ ]
1083
+ }]
1084
+ },
1085
+ "fragment": {
1086
+ "module": fragmentShaderModule,
1087
+ "entryPoint": "main",
1088
+ "targets": [{
1089
+ "format": this.format,
1090
+ "blend": {
1091
+ "color": {
1092
+ "srcFactor": "one",
1093
+ "dstFactor": "one-minus-src-alpha",
1094
+ "operation": "add"
1095
+ },
1096
+ "alpha": {
1097
+ "srcFactor": "one",
1098
+ "dstFactor": "one-minus-src-alpha",
1099
+ "operation": "add"
1100
+ }
1101
+ }
1102
+ }]
1103
+ },
1104
+ "primitive": {
1105
+ "topology": "triangle-list",
1106
+ "cullMode": "none"
1107
+ }
1108
+ });
1109
+ this.pipelines.set("texture", pipeline);
1110
+ }
1111
+ createInstancedPipeline() {
1112
+ const bindGroupLayout = this.device.createBindGroupLayout({
1113
+ "entries": [
1114
+ {
1115
+ "binding": 0,
1116
+ "visibility": GPUShaderStage.FRAGMENT,
1117
+ "sampler": {}
1118
+ },
1119
+ {
1120
+ "binding": 1,
1121
+ "visibility": GPUShaderStage.FRAGMENT,
1122
+ "texture": {}
1123
+ }
1124
+ ]
1125
+ });
1126
+ this.bindGroupLayouts.set("instanced", bindGroupLayout);
1127
+ const pipelineLayout = this.device.createPipelineLayout({
1128
+ "bindGroupLayouts": [bindGroupLayout]
1129
+ });
1130
+ const vertexShaderModule = this.getOrCreateShaderModule("instancedVertex", ShaderSource.getInstancedVertexShader());
1131
+ const fragmentShaderModule = this.getOrCreateShaderModule("instancedFragment", ShaderSource.getInstancedFragmentShader());
1132
+ const instanceBufferLayout = {
1133
+ "arrayStride": 96,
1134
+ "stepMode": "instance",
1135
+ "attributes": [
1136
+ {
1137
+ "shaderLocation": 2,
1138
+ "offset": 0,
1139
+ "format": "float32x4"
1140
+ },
1141
+ {
1142
+ "shaderLocation": 3,
1143
+ "offset": 16,
1144
+ "format": "float32x4"
1145
+ },
1146
+ {
1147
+ "shaderLocation": 4,
1148
+ "offset": 32,
1149
+ "format": "float32x4"
1150
+ },
1151
+ {
1152
+ "shaderLocation": 5,
1153
+ "offset": 48,
1154
+ "format": "float32x4"
1155
+ },
1156
+ {
1157
+ "shaderLocation": 6,
1158
+ "offset": 64,
1159
+ "format": "float32x4"
1160
+ },
1161
+ {
1162
+ "shaderLocation": 7,
1163
+ "offset": 80,
1164
+ "format": "float32x4"
1165
+ }
1166
+ ]
1167
+ };
1168
+ const pipeline = this.device.createRenderPipeline({
1169
+ "layout": pipelineLayout,
1170
+ "vertex": {
1171
+ "module": vertexShaderModule,
1172
+ "entryPoint": "main",
1173
+ "buffers": [
1174
+ {
1175
+ "arrayStride": 4 * 4,
1176
+ "stepMode": "vertex",
1177
+ "attributes": [
1178
+ {
1179
+ "shaderLocation": 0,
1180
+ "offset": 0,
1181
+ "format": "float32x2"
1182
+ },
1183
+ {
1184
+ "shaderLocation": 1,
1185
+ "offset": 2 * 4,
1186
+ "format": "float32x2"
1187
+ }
1188
+ ]
1189
+ },
1190
+ instanceBufferLayout
1191
+ ]
1192
+ },
1193
+ "fragment": {
1194
+ "module": fragmentShaderModule,
1195
+ "entryPoint": "main",
1196
+ "targets": [{
1197
+ "format": this.format,
1198
+ "blend": {
1199
+ "color": {
1200
+ "srcFactor": "one",
1201
+ "dstFactor": "one-minus-src-alpha",
1202
+ "operation": "add"
1203
+ },
1204
+ "alpha": {
1205
+ "srcFactor": "one",
1206
+ "dstFactor": "one-minus-src-alpha",
1207
+ "operation": "add"
1208
+ }
1209
+ }
1210
+ }]
1211
+ },
1212
+ "primitive": {
1213
+ "topology": "triangle-list",
1214
+ "cullMode": "none"
1215
+ },
1216
+ "multisample": {
1217
+ "count": this.sampleCount
1218
+ }
1219
+ });
1220
+ this.pipelines.set("instanced", pipeline);
1221
+ const vertexBuffers = [
1222
+ {
1223
+ "arrayStride": 4 * 4,
1224
+ "stepMode": "vertex",
1225
+ "attributes": [
1226
+ { "shaderLocation": 0, "offset": 0, "format": "float32x2" },
1227
+ { "shaderLocation": 1, "offset": 2 * 4, "format": "float32x2" }
1228
+ ]
1229
+ },
1230
+ instanceBufferLayout
1231
+ ];
1232
+ const blendVariants = [
1233
+ ["instanced_add", { "color": { "srcFactor": "one", "dstFactor": "one", "operation": "add" }, "alpha": { "srcFactor": "one", "dstFactor": "one-minus-src-alpha", "operation": "add" } }],
1234
+ ["instanced_screen", { "color": { "srcFactor": "one-minus-dst", "dstFactor": "one", "operation": "add" }, "alpha": { "srcFactor": "one", "dstFactor": "one-minus-src-alpha", "operation": "add" } }],
1235
+ ["instanced_alpha", { "color": { "srcFactor": "zero", "dstFactor": "src-alpha", "operation": "add" }, "alpha": { "srcFactor": "zero", "dstFactor": "src-alpha", "operation": "add" } }],
1236
+ ["instanced_erase", { "color": { "srcFactor": "zero", "dstFactor": "one-minus-src-alpha", "operation": "add" }, "alpha": { "srcFactor": "zero", "dstFactor": "one-minus-src-alpha", "operation": "add" } }],
1237
+ ["instanced_copy", { "color": { "srcFactor": "one", "dstFactor": "zero", "operation": "add" }, "alpha": { "srcFactor": "one", "dstFactor": "zero", "operation": "add" } }]
1238
+ ];
1239
+ for (const [name, blend] of blendVariants) {
1240
+ const variantPipeline = this.device.createRenderPipeline({
1241
+ "layout": pipelineLayout,
1242
+ "vertex": {
1243
+ "module": vertexShaderModule,
1244
+ "entryPoint": "main",
1245
+ "buffers": vertexBuffers
1246
+ },
1247
+ "fragment": {
1248
+ "module": fragmentShaderModule,
1249
+ "entryPoint": "main",
1250
+ "targets": [{ "format": this.format, "blend": blend }]
1251
+ },
1252
+ "primitive": { "topology": "triangle-list", "cullMode": "none" },
1253
+ "multisample": { "count": this.sampleCount }
1254
+ });
1255
+ this.pipelines.set(name, variantPipeline);
1256
+ }
1257
+ const maskedPipeline = this.device.createRenderPipeline({
1258
+ "layout": pipelineLayout,
1259
+ "vertex": {
1260
+ "module": vertexShaderModule,
1261
+ "entryPoint": "main",
1262
+ "buffers": [
1263
+ {
1264
+ "arrayStride": 4 * 4,
1265
+ "stepMode": "vertex",
1266
+ "attributes": [
1267
+ { "shaderLocation": 0, "offset": 0, "format": "float32x2" },
1268
+ { "shaderLocation": 1, "offset": 2 * 4, "format": "float32x2" }
1269
+ ]
1270
+ },
1271
+ instanceBufferLayout
1272
+ ]
1273
+ },
1274
+ "fragment": {
1275
+ "module": fragmentShaderModule,
1276
+ "entryPoint": "main",
1277
+ "targets": [{
1278
+ "format": this.format,
1279
+ "blend": {
1280
+ "color": {
1281
+ "srcFactor": "one",
1282
+ "dstFactor": "one-minus-src-alpha",
1283
+ "operation": "add"
1284
+ },
1285
+ "alpha": {
1286
+ "srcFactor": "one",
1287
+ "dstFactor": "one-minus-src-alpha",
1288
+ "operation": "add"
1289
+ }
1290
+ }
1291
+ }]
1292
+ },
1293
+ "primitive": {
1294
+ "topology": "triangle-list",
1295
+ "cullMode": "none"
1296
+ },
1297
+ "depthStencil": {
1298
+ "format": "stencil8",
1299
+ "stencilFront": {
1300
+ "compare": "equal",
1301
+ "failOp": "keep",
1302
+ "depthFailOp": "keep",
1303
+ "passOp": "keep"
1304
+ },
1305
+ "stencilBack": {
1306
+ "compare": "equal",
1307
+ "failOp": "keep",
1308
+ "depthFailOp": "keep",
1309
+ "passOp": "keep"
1310
+ },
1311
+ "stencilReadMask": 0xFF,
1312
+ "stencilWriteMask": 0x00
1313
+ },
1314
+ "multisample": {
1315
+ "count": this.sampleCount
1316
+ }
1317
+ });
1318
+ this.pipelines.set("instanced_masked", maskedPipeline);
1319
+ }
1320
+ createGradientPipeline() {
1321
+ const bindGroupLayout = this.device.createBindGroupLayout({
1322
+ "entries": [
1323
+ {
1324
+ "binding": 0,
1325
+ "visibility": GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
1326
+ "buffer": { "type": "uniform" }
1327
+ },
1328
+ {
1329
+ "binding": 1,
1330
+ "visibility": GPUShaderStage.FRAGMENT,
1331
+ "sampler": {}
1332
+ },
1333
+ {
1334
+ "binding": 2,
1335
+ "visibility": GPUShaderStage.FRAGMENT,
1336
+ "texture": {}
1337
+ }
1338
+ ]
1339
+ });
1340
+ this.bindGroupLayouts.set("gradient_fill", bindGroupLayout);
1341
+ const pipelineLayout = this.device.createPipelineLayout({
1342
+ "bindGroupLayouts": [bindGroupLayout]
1343
+ });
1344
+ this.gradientPipelineLayout = pipelineLayout;
1345
+ const vertexShaderModule = this.getOrCreateShaderModule("gradientFillVertex", ShaderSource.getGradientFillVertexShader());
1346
+ this.gradientVertexShaderModule = vertexShaderModule;
1347
+ const fragmentShaderModule = this.getOrCreateShaderModule("gradientFillFragment", ShaderSource.getGradientFillFragmentShader());
1348
+ this.gradientFragmentShaderModule = fragmentShaderModule;
1349
+ const stencilFragmentShaderModule = this.getOrCreateShaderModule("gradientFillStencilFragment", ShaderSource.getGradientFillStencilFragmentShader());
1350
+ this.gradientStencilFragmentShaderModule = stencilFragmentShaderModule;
1351
+ const vertexBufferLayout = VERTEX_BUFFER_LAYOUT_4F;
1352
+ const blendState = BLEND_PREMULTIPLIED_ALPHA;
1353
+ const pipelineRGBA = this.device.createRenderPipeline({
1354
+ "label": "gradient_fill_no_stencil_pipeline",
1355
+ "layout": pipelineLayout,
1356
+ "vertex": {
1357
+ "module": vertexShaderModule,
1358
+ "entryPoint": "main",
1359
+ "buffers": [vertexBufferLayout]
1360
+ },
1361
+ "fragment": {
1362
+ "module": fragmentShaderModule,
1363
+ "entryPoint": "main",
1364
+ "targets": [{
1365
+ "format": "rgba8unorm",
1366
+ "blend": blendState
1367
+ }]
1368
+ },
1369
+ "primitive": {
1370
+ "topology": "triangle-list",
1371
+ "cullMode": "none"
1372
+ },
1373
+ "multisample": {
1374
+ "count": this.sampleCount
1375
+ }
1376
+ });
1377
+ const pipelineBGRA = this.device.createRenderPipeline({
1378
+ "layout": pipelineLayout,
1379
+ "vertex": {
1380
+ "module": vertexShaderModule,
1381
+ "entryPoint": "main",
1382
+ "buffers": [vertexBufferLayout],
1383
+ "constants": { "yFlipSign": -1.0 }
1384
+ },
1385
+ "fragment": {
1386
+ "module": fragmentShaderModule,
1387
+ "entryPoint": "main",
1388
+ "targets": [{
1389
+ "format": this.format,
1390
+ "blend": blendState
1391
+ }]
1392
+ },
1393
+ "primitive": {
1394
+ "topology": "triangle-list",
1395
+ "cullMode": "none"
1396
+ },
1397
+ "multisample": {
1398
+ "count": this.sampleCount
1399
+ }
1400
+ });
1401
+ this.pipelines.set("gradient_fill", pipelineRGBA);
1402
+ this.pipelines.set("gradient_fill_no_stencil", pipelineRGBA);
1403
+ this.pipelines.set("gradient_fill_bgra", pipelineBGRA);
1404
+ const strokeStencilState = {
1405
+ "format": "stencil8",
1406
+ "stencilFront": {
1407
+ "compare": "always",
1408
+ "failOp": "keep",
1409
+ "depthFailOp": "keep",
1410
+ "passOp": "keep"
1411
+ },
1412
+ "stencilBack": {
1413
+ "compare": "always",
1414
+ "failOp": "keep",
1415
+ "depthFailOp": "keep",
1416
+ "passOp": "keep"
1417
+ },
1418
+ "stencilReadMask": 0x00,
1419
+ "stencilWriteMask": 0x00
1420
+ };
1421
+ const pipelineGradientStrokeAtlas = this.device.createRenderPipeline({
1422
+ "label": "gradient_stroke_atlas_pipeline",
1423
+ "layout": pipelineLayout,
1424
+ "vertex": {
1425
+ "module": vertexShaderModule,
1426
+ "entryPoint": "main",
1427
+ "buffers": [vertexBufferLayout]
1428
+ },
1429
+ "fragment": {
1430
+ "module": fragmentShaderModule,
1431
+ "entryPoint": "main",
1432
+ "targets": [{
1433
+ "format": "rgba8unorm",
1434
+ "blend": blendState
1435
+ }]
1436
+ },
1437
+ "primitive": {
1438
+ "topology": "triangle-list",
1439
+ "cullMode": "none"
1440
+ },
1441
+ "depthStencil": strokeStencilState,
1442
+ "multisample": {
1443
+ "count": this.sampleCount
1444
+ }
1445
+ });
1446
+ this.pipelines.set("gradient_stroke_atlas", pipelineGradientStrokeAtlas);
1447
+ const pipelineGradientStrokeBGRA = this.device.createRenderPipeline({
1448
+ "label": "gradient_stroke_bgra_pipeline",
1449
+ "layout": pipelineLayout,
1450
+ "vertex": {
1451
+ "module": vertexShaderModule,
1452
+ "entryPoint": "main",
1453
+ "buffers": [vertexBufferLayout],
1454
+ "constants": { "yFlipSign": -1.0 }
1455
+ },
1456
+ "fragment": {
1457
+ "module": fragmentShaderModule,
1458
+ "entryPoint": "main",
1459
+ "targets": [{
1460
+ "format": this.format,
1461
+ "blend": blendState
1462
+ }]
1463
+ },
1464
+ "primitive": {
1465
+ "topology": "triangle-list",
1466
+ "cullMode": "none"
1467
+ },
1468
+ "depthStencil": strokeStencilState,
1469
+ "multisample": {
1470
+ "count": this.sampleCount
1471
+ }
1472
+ });
1473
+ this.pipelines.set("gradient_stroke_bgra", pipelineGradientStrokeBGRA);
1474
+ const pipelineBGRA_noMSAA = this.device.createRenderPipeline({
1475
+ "layout": pipelineLayout,
1476
+ "vertex": {
1477
+ "module": vertexShaderModule,
1478
+ "entryPoint": "main",
1479
+ "buffers": [vertexBufferLayout],
1480
+ "constants": { "yFlipSign": -1.0 }
1481
+ },
1482
+ "fragment": {
1483
+ "module": fragmentShaderModule,
1484
+ "entryPoint": "main",
1485
+ "targets": [{
1486
+ "format": this.format,
1487
+ "blend": blendState
1488
+ }]
1489
+ },
1490
+ "primitive": {
1491
+ "topology": "triangle-list",
1492
+ "cullMode": "none"
1493
+ },
1494
+ "multisample": {
1495
+ "count": 1
1496
+ }
1497
+ });
1498
+ this.pipelines.set("gradient_fill_bgra_no_msaa", pipelineBGRA_noMSAA);
1499
+ const pipelineRGBAStencil = this.device.createRenderPipeline({
1500
+ "layout": pipelineLayout,
1501
+ "vertex": {
1502
+ "module": vertexShaderModule,
1503
+ "entryPoint": "main",
1504
+ "buffers": [vertexBufferLayout]
1505
+ },
1506
+ "fragment": {
1507
+ "module": fragmentShaderModule,
1508
+ "entryPoint": "main",
1509
+ "targets": [{
1510
+ "format": "rgba8unorm",
1511
+ "blend": blendState
1512
+ }]
1513
+ },
1514
+ "primitive": {
1515
+ "topology": "triangle-list",
1516
+ "cullMode": "none"
1517
+ },
1518
+ "depthStencil": {
1519
+ "format": "stencil8",
1520
+ "stencilFront": {
1521
+ "compare": "not-equal",
1522
+ "failOp": "keep",
1523
+ "depthFailOp": "zero",
1524
+ "passOp": "zero"
1525
+ },
1526
+ "stencilBack": {
1527
+ "compare": "not-equal",
1528
+ "failOp": "keep",
1529
+ "depthFailOp": "zero",
1530
+ "passOp": "zero"
1531
+ },
1532
+ "stencilReadMask": 0xFF,
1533
+ "stencilWriteMask": 0xFF
1534
+ },
1535
+ "multisample": {
1536
+ "count": this.sampleCount
1537
+ }
1538
+ });
1539
+ this.pipelines.set("gradient_fill_stencil", pipelineRGBAStencil);
1540
+ const pipelineRGBAStencilAtlas = this.device.createRenderPipeline({
1541
+ "layout": pipelineLayout,
1542
+ "vertex": {
1543
+ "module": vertexShaderModule,
1544
+ "entryPoint": "main",
1545
+ "buffers": [vertexBufferLayout]
1546
+ },
1547
+ "fragment": {
1548
+ "module": stencilFragmentShaderModule,
1549
+ "entryPoint": "main",
1550
+ "targets": [{
1551
+ "format": "rgba8unorm",
1552
+ "blend": blendState
1553
+ }]
1554
+ },
1555
+ "primitive": {
1556
+ "topology": "triangle-list",
1557
+ "cullMode": "none"
1558
+ },
1559
+ "depthStencil": {
1560
+ "format": "stencil8",
1561
+ "stencilFront": {
1562
+ "compare": "not-equal",
1563
+ "failOp": "keep",
1564
+ "depthFailOp": "zero",
1565
+ "passOp": "zero"
1566
+ },
1567
+ "stencilBack": {
1568
+ "compare": "not-equal",
1569
+ "failOp": "keep",
1570
+ "depthFailOp": "zero",
1571
+ "passOp": "zero"
1572
+ },
1573
+ "stencilReadMask": 0xFF,
1574
+ "stencilWriteMask": 0xFF
1575
+ },
1576
+ "multisample": {
1577
+ "count": this.sampleCount
1578
+ }
1579
+ });
1580
+ this.pipelines.set("gradient_fill_stencil_atlas", pipelineRGBAStencilAtlas);
1581
+ const pipelineStencilMain = this.device.createRenderPipeline({
1582
+ "layout": pipelineLayout,
1583
+ "vertex": {
1584
+ "module": vertexShaderModule,
1585
+ "entryPoint": "main",
1586
+ "buffers": [vertexBufferLayout],
1587
+ "constants": { "yFlipSign": -1.0 }
1588
+ },
1589
+ "fragment": {
1590
+ "module": stencilFragmentShaderModule,
1591
+ "entryPoint": "main",
1592
+ "targets": [{
1593
+ "format": this.format,
1594
+ "blend": blendState
1595
+ }]
1596
+ },
1597
+ "primitive": {
1598
+ "topology": "triangle-list",
1599
+ "cullMode": "none"
1600
+ },
1601
+ "depthStencil": {
1602
+ "format": "stencil8",
1603
+ "stencilFront": {
1604
+ "compare": "not-equal",
1605
+ "failOp": "keep",
1606
+ "depthFailOp": "zero",
1607
+ "passOp": "zero"
1608
+ },
1609
+ "stencilBack": {
1610
+ "compare": "not-equal",
1611
+ "failOp": "keep",
1612
+ "depthFailOp": "zero",
1613
+ "passOp": "zero"
1614
+ },
1615
+ "stencilReadMask": 0xFF,
1616
+ "stencilWriteMask": 0xFF
1617
+ },
1618
+ "multisample": {
1619
+ "count": 1
1620
+ }
1621
+ });
1622
+ this.pipelines.set("gradient_fill_stencil_main", pipelineStencilMain);
1623
+ const pipelineBGRAStencil = this.device.createRenderPipeline({
1624
+ "layout": pipelineLayout,
1625
+ "vertex": {
1626
+ "module": vertexShaderModule,
1627
+ "entryPoint": "main",
1628
+ "buffers": [vertexBufferLayout],
1629
+ "constants": { "yFlipSign": -1.0 }
1630
+ },
1631
+ "fragment": {
1632
+ "module": fragmentShaderModule,
1633
+ "entryPoint": "main",
1634
+ "targets": [{
1635
+ "format": this.format,
1636
+ "blend": blendState
1637
+ }]
1638
+ },
1639
+ "primitive": {
1640
+ "topology": "triangle-list",
1641
+ "cullMode": "none"
1642
+ },
1643
+ "depthStencil": {
1644
+ "format": "stencil8",
1645
+ "stencilFront": {
1646
+ "compare": "equal",
1647
+ "failOp": "keep",
1648
+ "depthFailOp": "keep",
1649
+ "passOp": "keep"
1650
+ },
1651
+ "stencilBack": {
1652
+ "compare": "equal",
1653
+ "failOp": "keep",
1654
+ "depthFailOp": "keep",
1655
+ "passOp": "keep"
1656
+ },
1657
+ "stencilReadMask": 0xFF,
1658
+ "stencilWriteMask": 0x00
1659
+ },
1660
+ "multisample": {
1661
+ "count": this.sampleCount
1662
+ }
1663
+ });
1664
+ this.pipelines.set("gradient_fill_bgra_stencil", pipelineBGRAStencil);
1665
+ }
1666
+ createBitmapFillPipeline() {
1667
+ const bindGroupLayout = this.device.createBindGroupLayout({
1668
+ "entries": [
1669
+ {
1670
+ "binding": 0,
1671
+ "visibility": GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
1672
+ "buffer": { "type": "uniform" }
1673
+ },
1674
+ {
1675
+ "binding": 1,
1676
+ "visibility": GPUShaderStage.FRAGMENT,
1677
+ "sampler": {}
1678
+ },
1679
+ {
1680
+ "binding": 2,
1681
+ "visibility": GPUShaderStage.FRAGMENT,
1682
+ "texture": {}
1683
+ }
1684
+ ]
1685
+ });
1686
+ this.bindGroupLayouts.set("bitmap_fill", bindGroupLayout);
1687
+ const pipelineLayout = this.device.createPipelineLayout({
1688
+ "bindGroupLayouts": [bindGroupLayout]
1689
+ });
1690
+ const vertexShaderModule = this.getOrCreateShaderModule("bitmapFillVertex", ShaderSource.getBitmapFillVertexShader());
1691
+ const fragmentShaderModule = this.getOrCreateShaderModule("bitmapFillFragment", ShaderSource.getBitmapFillFragmentShader());
1692
+ const vertexBufferLayout = VERTEX_BUFFER_LAYOUT_4F;
1693
+ const blendState = BLEND_PREMULTIPLIED_ALPHA;
1694
+ const pipelineRGBA = this.device.createRenderPipeline({
1695
+ "layout": pipelineLayout,
1696
+ "vertex": {
1697
+ "module": vertexShaderModule,
1698
+ "entryPoint": "main",
1699
+ "buffers": [vertexBufferLayout]
1700
+ },
1701
+ "fragment": {
1702
+ "module": fragmentShaderModule,
1703
+ "entryPoint": "main",
1704
+ "targets": [{
1705
+ "format": "rgba8unorm",
1706
+ "blend": blendState
1707
+ }]
1708
+ },
1709
+ "primitive": {
1710
+ "topology": "triangle-list",
1711
+ "cullMode": "none"
1712
+ },
1713
+ "multisample": {
1714
+ "count": this.sampleCount
1715
+ }
1716
+ });
1717
+ const pipelineBGRA = this.device.createRenderPipeline({
1718
+ "layout": pipelineLayout,
1719
+ "vertex": {
1720
+ "module": vertexShaderModule,
1721
+ "entryPoint": "main",
1722
+ "buffers": [vertexBufferLayout],
1723
+ "constants": { "yFlipSign": -1.0 }
1724
+ },
1725
+ "fragment": {
1726
+ "module": fragmentShaderModule,
1727
+ "entryPoint": "main",
1728
+ "targets": [{
1729
+ "format": this.format,
1730
+ "blend": blendState
1731
+ }]
1732
+ },
1733
+ "primitive": {
1734
+ "topology": "triangle-list",
1735
+ "cullMode": "none"
1736
+ }
1737
+ });
1738
+ this.pipelines.set("bitmap_fill", pipelineRGBA);
1739
+ this.pipelines.set("bitmap_fill_bgra", pipelineBGRA);
1740
+ const bitmapStrokeStencilState = {
1741
+ "format": "stencil8",
1742
+ "stencilFront": {
1743
+ "compare": "always",
1744
+ "failOp": "keep",
1745
+ "depthFailOp": "keep",
1746
+ "passOp": "keep"
1747
+ },
1748
+ "stencilBack": {
1749
+ "compare": "always",
1750
+ "failOp": "keep",
1751
+ "depthFailOp": "keep",
1752
+ "passOp": "keep"
1753
+ },
1754
+ "stencilReadMask": 0x00,
1755
+ "stencilWriteMask": 0x00
1756
+ };
1757
+ const pipelineBitmapStrokeAtlas = this.device.createRenderPipeline({
1758
+ "label": "bitmap_stroke_atlas_pipeline",
1759
+ "layout": pipelineLayout,
1760
+ "vertex": {
1761
+ "module": vertexShaderModule,
1762
+ "entryPoint": "main",
1763
+ "buffers": [vertexBufferLayout]
1764
+ },
1765
+ "fragment": {
1766
+ "module": fragmentShaderModule,
1767
+ "entryPoint": "main",
1768
+ "targets": [{
1769
+ "format": "rgba8unorm",
1770
+ "blend": blendState
1771
+ }]
1772
+ },
1773
+ "primitive": {
1774
+ "topology": "triangle-list",
1775
+ "cullMode": "none"
1776
+ },
1777
+ "depthStencil": bitmapStrokeStencilState,
1778
+ "multisample": {
1779
+ "count": this.sampleCount
1780
+ }
1781
+ });
1782
+ this.pipelines.set("bitmap_stroke_atlas", pipelineBitmapStrokeAtlas);
1783
+ const pipelineBitmapStrokeBGRA = this.device.createRenderPipeline({
1784
+ "label": "bitmap_stroke_bgra_pipeline",
1785
+ "layout": pipelineLayout,
1786
+ "vertex": {
1787
+ "module": vertexShaderModule,
1788
+ "entryPoint": "main",
1789
+ "buffers": [vertexBufferLayout],
1790
+ "constants": { "yFlipSign": -1.0 }
1791
+ },
1792
+ "fragment": {
1793
+ "module": fragmentShaderModule,
1794
+ "entryPoint": "main",
1795
+ "targets": [{
1796
+ "format": this.format,
1797
+ "blend": blendState
1798
+ }]
1799
+ },
1800
+ "primitive": {
1801
+ "topology": "triangle-list",
1802
+ "cullMode": "none"
1803
+ },
1804
+ "depthStencil": bitmapStrokeStencilState,
1805
+ "multisample": {
1806
+ "count": this.sampleCount
1807
+ }
1808
+ });
1809
+ this.pipelines.set("bitmap_stroke_bgra", pipelineBitmapStrokeBGRA);
1810
+ const pipelineRGBAStencil = this.device.createRenderPipeline({
1811
+ "layout": pipelineLayout,
1812
+ "vertex": {
1813
+ "module": vertexShaderModule,
1814
+ "entryPoint": "main",
1815
+ "buffers": [vertexBufferLayout]
1816
+ },
1817
+ "fragment": {
1818
+ "module": fragmentShaderModule,
1819
+ "entryPoint": "main",
1820
+ "targets": [{
1821
+ "format": "rgba8unorm",
1822
+ "blend": blendState
1823
+ }]
1824
+ },
1825
+ "primitive": {
1826
+ "topology": "triangle-list",
1827
+ "cullMode": "none"
1828
+ },
1829
+ "depthStencil": {
1830
+ "format": "stencil8",
1831
+ "stencilFront": {
1832
+ "compare": "not-equal",
1833
+ "failOp": "keep",
1834
+ "depthFailOp": "zero",
1835
+ "passOp": "zero"
1836
+ },
1837
+ "stencilBack": {
1838
+ "compare": "not-equal",
1839
+ "failOp": "keep",
1840
+ "depthFailOp": "zero",
1841
+ "passOp": "zero"
1842
+ },
1843
+ "stencilReadMask": 0xFF,
1844
+ "stencilWriteMask": 0xFF
1845
+ },
1846
+ "multisample": {
1847
+ "count": this.sampleCount
1848
+ }
1849
+ });
1850
+ this.pipelines.set("bitmap_fill_stencil", pipelineRGBAStencil);
1851
+ const pipelineBGRAStencil = this.device.createRenderPipeline({
1852
+ "layout": pipelineLayout,
1853
+ "vertex": {
1854
+ "module": vertexShaderModule,
1855
+ "entryPoint": "main",
1856
+ "buffers": [vertexBufferLayout],
1857
+ "constants": { "yFlipSign": -1.0 }
1858
+ },
1859
+ "fragment": {
1860
+ "module": fragmentShaderModule,
1861
+ "entryPoint": "main",
1862
+ "targets": [{
1863
+ "format": this.format,
1864
+ "blend": blendState
1865
+ }]
1866
+ },
1867
+ "primitive": {
1868
+ "topology": "triangle-list",
1869
+ "cullMode": "none"
1870
+ },
1871
+ "depthStencil": {
1872
+ "format": "stencil8",
1873
+ "stencilFront": {
1874
+ "compare": "equal",
1875
+ "failOp": "keep",
1876
+ "depthFailOp": "keep",
1877
+ "passOp": "keep"
1878
+ },
1879
+ "stencilBack": {
1880
+ "compare": "equal",
1881
+ "failOp": "keep",
1882
+ "depthFailOp": "keep",
1883
+ "passOp": "keep"
1884
+ },
1885
+ "stencilReadMask": 0xFF,
1886
+ "stencilWriteMask": 0x00
1887
+ }
1888
+ });
1889
+ this.pipelines.set("bitmap_fill_bgra_stencil", pipelineBGRAStencil);
1890
+ }
1891
+ createBlendPipeline() {
1892
+ const bindGroupLayout = this.device.createBindGroupLayout({
1893
+ "entries": [
1894
+ {
1895
+ "binding": 0,
1896
+ "visibility": GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
1897
+ "buffer": { "type": "uniform" }
1898
+ },
1899
+ {
1900
+ "binding": 1,
1901
+ "visibility": GPUShaderStage.FRAGMENT,
1902
+ "buffer": { "type": "uniform" }
1903
+ },
1904
+ {
1905
+ "binding": 2,
1906
+ "visibility": GPUShaderStage.FRAGMENT,
1907
+ "sampler": {}
1908
+ },
1909
+ {
1910
+ "binding": 3,
1911
+ "visibility": GPUShaderStage.FRAGMENT,
1912
+ "texture": {}
1913
+ },
1914
+ {
1915
+ "binding": 4,
1916
+ "visibility": GPUShaderStage.FRAGMENT,
1917
+ "sampler": {}
1918
+ },
1919
+ {
1920
+ "binding": 5,
1921
+ "visibility": GPUShaderStage.FRAGMENT,
1922
+ "texture": {}
1923
+ }
1924
+ ]
1925
+ });
1926
+ this.bindGroupLayouts.set("blend", bindGroupLayout);
1927
+ const pipelineLayout = this.device.createPipelineLayout({
1928
+ "bindGroupLayouts": [bindGroupLayout]
1929
+ });
1930
+ const vertexShaderModule = this.getOrCreateShaderModule("basicVertex", ShaderSource.getBasicVertexShader());
1931
+ const fragmentShaderModule = this.getOrCreateShaderModule("blendFragment", ShaderSource.getBlendFragmentShader());
1932
+ const pipeline = this.device.createRenderPipeline({
1933
+ "layout": pipelineLayout,
1934
+ "vertex": {
1935
+ "module": vertexShaderModule,
1936
+ "entryPoint": "main",
1937
+ "buffers": [{
1938
+ "arrayStride": 4 * 4,
1939
+ "attributes": [
1940
+ {
1941
+ "shaderLocation": 0,
1942
+ "offset": 0,
1943
+ "format": "float32x2"
1944
+ },
1945
+ {
1946
+ "shaderLocation": 1,
1947
+ "offset": 2 * 4,
1948
+ "format": "float32x2"
1949
+ }
1950
+ ]
1951
+ }]
1952
+ },
1953
+ "fragment": {
1954
+ "module": fragmentShaderModule,
1955
+ "entryPoint": "main",
1956
+ "targets": [{
1957
+ "format": this.format,
1958
+ "blend": {
1959
+ "color": {
1960
+ "srcFactor": "one",
1961
+ "dstFactor": "one-minus-src-alpha",
1962
+ "operation": "add"
1963
+ },
1964
+ "alpha": {
1965
+ "srcFactor": "one",
1966
+ "dstFactor": "one-minus-src-alpha",
1967
+ "operation": "add"
1968
+ }
1969
+ }
1970
+ }]
1971
+ },
1972
+ "primitive": {
1973
+ "topology": "triangle-list",
1974
+ "cullMode": "none"
1975
+ }
1976
+ });
1977
+ this.pipelines.set("blend", pipeline);
1978
+ }
1979
+ createBlurFilterPipeline() {
1980
+ const bindGroupLayout = this.device.createBindGroupLayout({
1981
+ "entries": [
1982
+ {
1983
+ "binding": 0,
1984
+ "visibility": GPUShaderStage.FRAGMENT,
1985
+ "buffer": { "type": "uniform" }
1986
+ },
1987
+ {
1988
+ "binding": 1,
1989
+ "visibility": GPUShaderStage.FRAGMENT,
1990
+ "sampler": {}
1991
+ },
1992
+ {
1993
+ "binding": 2,
1994
+ "visibility": GPUShaderStage.FRAGMENT,
1995
+ "texture": {}
1996
+ }
1997
+ ]
1998
+ });
1999
+ this.bindGroupLayouts.set("blur_filter", bindGroupLayout);
2000
+ const vertexShaderModule = this.getOrCreateShaderModule("blurFilterVertex", ShaderSource.getBlurFilterVertexShader());
2001
+ const pipelineLayout = this.device.createPipelineLayout({
2002
+ "bindGroupLayouts": [bindGroupLayout]
2003
+ });
2004
+ for (let halfBlur = 1; halfBlur <= 16; halfBlur++) {
2005
+ const fragmentShaderModule = this.getOrCreateShaderModule(`blurFilterFragment_${halfBlur}`, ShaderSource.getBlurFilterFragmentShader(halfBlur));
2006
+ const pipeline = this.device.createRenderPipeline({
2007
+ "layout": pipelineLayout,
2008
+ "vertex": {
2009
+ "module": vertexShaderModule,
2010
+ "entryPoint": "main",
2011
+ "buffers": []
2012
+ },
2013
+ "fragment": {
2014
+ "module": fragmentShaderModule,
2015
+ "entryPoint": "main",
2016
+ "targets": [{
2017
+ "format": "rgba8unorm",
2018
+ "blend": {
2019
+ "color": {
2020
+ "srcFactor": "one",
2021
+ "dstFactor": "zero",
2022
+ "operation": "add"
2023
+ },
2024
+ "alpha": {
2025
+ "srcFactor": "one",
2026
+ "dstFactor": "zero",
2027
+ "operation": "add"
2028
+ }
2029
+ }
2030
+ }]
2031
+ },
2032
+ "primitive": {
2033
+ "topology": "triangle-list",
2034
+ "cullMode": "none"
2035
+ }
2036
+ });
2037
+ this.pipelines.set(`blur_filter_${halfBlur}`, pipeline);
2038
+ }
2039
+ }
2040
+ createTextureCopyPipeline() {
2041
+ const bindGroupLayout = this.device.createBindGroupLayout({
2042
+ "entries": [
2043
+ {
2044
+ "binding": 0,
2045
+ "visibility": GPUShaderStage.FRAGMENT,
2046
+ "buffer": { "type": "uniform" }
2047
+ },
2048
+ {
2049
+ "binding": 1,
2050
+ "visibility": GPUShaderStage.FRAGMENT,
2051
+ "sampler": {}
2052
+ },
2053
+ {
2054
+ "binding": 2,
2055
+ "visibility": GPUShaderStage.FRAGMENT,
2056
+ "texture": {}
2057
+ }
2058
+ ]
2059
+ });
2060
+ this.bindGroupLayouts.set("texture_copy", bindGroupLayout);
2061
+ const pipelineLayout = this.device.createPipelineLayout({
2062
+ "bindGroupLayouts": [bindGroupLayout]
2063
+ });
2064
+ const vertexShaderModule = this.getOrCreateShaderModule("blurFilterVertex", ShaderSource.getBlurFilterVertexShader());
2065
+ const fragmentShaderModule = this.getOrCreateShaderModule("textureCopyFragment", ShaderSource.getTextureCopyFragmentShader());
2066
+ const BLEND_REPLACE = {
2067
+ "color": { "srcFactor": "one", "dstFactor": "zero", "operation": "add" },
2068
+ "alpha": { "srcFactor": "one", "dstFactor": "zero", "operation": "add" }
2069
+ };
2070
+ const BLEND_ALPHA = {
2071
+ "color": { "srcFactor": "one", "dstFactor": "one-minus-src-alpha", "operation": "add" },
2072
+ "alpha": { "srcFactor": "one", "dstFactor": "one-minus-src-alpha", "operation": "add" }
2073
+ };
2074
+ const BLEND_ERASE = {
2075
+ "color": { "srcFactor": "zero", "dstFactor": "one-minus-src-alpha", "operation": "add" },
2076
+ "alpha": { "srcFactor": "zero", "dstFactor": "one-minus-src-alpha", "operation": "add" }
2077
+ };
2078
+ this.pipelines.set("texture_copy", this.createFullscreenQuadPipeline(pipelineLayout, vertexShaderModule, fragmentShaderModule, this.format, BLEND_REPLACE));
2079
+ this.pipelines.set("texture_copy_rgba8", this.createFullscreenQuadPipeline(pipelineLayout, vertexShaderModule, fragmentShaderModule, "rgba8unorm", BLEND_REPLACE));
2080
+ const colorTransformFragmentModule = this.getOrCreateShaderModule("colorTransformFragment", ShaderSource.getColorTransformFragmentShader());
2081
+ this.pipelines.set("color_transform", this.createFullscreenQuadPipeline(pipelineLayout, vertexShaderModule, colorTransformFragmentModule, "rgba8unorm", BLEND_REPLACE));
2082
+ const yFlipCTFragmentModule = this.getOrCreateShaderModule("yFlipColorTransformFragment", ShaderSource.getYFlipColorTransformFragmentShader());
2083
+ this.pipelines.set("y_flip_color_transform", this.createFullscreenQuadPipeline(pipelineLayout, vertexShaderModule, yFlipCTFragmentModule, "rgba8unorm", BLEND_REPLACE));
2084
+ const blurCopyFragmentModule = this.getOrCreateShaderModule("blurTextureCopyFragment", ShaderSource.getBlurTextureCopyFragmentShader());
2085
+ this.pipelines.set("texture_erase", this.createFullscreenQuadPipeline(pipelineLayout, vertexShaderModule, blurCopyFragmentModule, "rgba8unorm", BLEND_ERASE));
2086
+ this.pipelines.set("blur_texture_copy", this.createFullscreenQuadPipeline(pipelineLayout, vertexShaderModule, blurCopyFragmentModule, "rgba8unorm", BLEND_REPLACE));
2087
+ this.pipelines.set("filter_blend", this.createFullscreenQuadPipeline(pipelineLayout, vertexShaderModule, fragmentShaderModule, this.format, BLEND_ALPHA));
2088
+ this.pipelines.set("texture_copy_bgra", this.createFullscreenQuadPipeline(pipelineLayout, vertexShaderModule, fragmentShaderModule, this.format, BLEND_REPLACE));
2089
+ const filterOutputShaderModule = this.getOrCreateShaderModule("filterOutputFragment", ShaderSource.getFilterOutputFragmentShader());
2090
+ this.pipelines.set("filter_output", this.createFullscreenQuadPipeline(pipelineLayout, vertexShaderModule, filterOutputShaderModule, this.format, BLEND_ALPHA));
2091
+ const filterOutputBlendVariants = [
2092
+ ["filter_output_add", { "color": { "srcFactor": "one", "dstFactor": "one", "operation": "add" }, "alpha": { "srcFactor": "one", "dstFactor": "one", "operation": "add" } }],
2093
+ ["filter_output_screen", { "color": { "srcFactor": "one", "dstFactor": "one-minus-src", "operation": "add" }, "alpha": { "srcFactor": "one", "dstFactor": "one-minus-src-alpha", "operation": "add" } }],
2094
+ ["filter_output_alpha", { "color": { "srcFactor": "zero", "dstFactor": "src-alpha", "operation": "add" }, "alpha": { "srcFactor": "zero", "dstFactor": "src-alpha", "operation": "add" } }],
2095
+ ["filter_output_erase", { "color": { "srcFactor": "zero", "dstFactor": "one-minus-src-alpha", "operation": "add" }, "alpha": { "srcFactor": "zero", "dstFactor": "one-minus-src-alpha", "operation": "add" } }]
2096
+ ];
2097
+ for (const [name, blend] of filterOutputBlendVariants) {
2098
+ this.pipelines.set(name, this.createFullscreenQuadPipeline(pipelineLayout, vertexShaderModule, filterOutputShaderModule, this.format, blend));
2099
+ }
2100
+ if (this.sampleCount > 1) {
2101
+ const copyBlend = { "color": { "srcFactor": "one", "dstFactor": "zero", "operation": "add" }, "alpha": { "srcFactor": "one", "dstFactor": "zero", "operation": "add" } };
2102
+ this.pipelines.set("texture_copy_bgra_msaa", this.createFullscreenQuadPipeline(pipelineLayout, vertexShaderModule, fragmentShaderModule, this.format, copyBlend, this.sampleCount));
2103
+ const normalBlend = { "color": { "srcFactor": "one", "dstFactor": "one-minus-src-alpha", "operation": "add" }, "alpha": { "srcFactor": "one", "dstFactor": "one-minus-src-alpha", "operation": "add" } };
2104
+ this.pipelines.set("filter_output_msaa", this.createFullscreenQuadPipeline(pipelineLayout, vertexShaderModule, filterOutputShaderModule, this.format, normalBlend, this.sampleCount));
2105
+ for (const [name, blend] of filterOutputBlendVariants) {
2106
+ this.pipelines.set(`${name}_msaa`, this.createFullscreenQuadPipeline(pipelineLayout, vertexShaderModule, filterOutputShaderModule, this.format, blend, this.sampleCount));
2107
+ }
2108
+ }
2109
+ this.createPositionedTexturePipeline();
2110
+ this.createTextureScalePipeline();
2111
+ }
2112
+ createPositionedTexturePipeline() {
2113
+ const bindGroupLayout = this.device.createBindGroupLayout({
2114
+ "entries": [
2115
+ {
2116
+ "binding": 0,
2117
+ "visibility": GPUShaderStage.VERTEX,
2118
+ "buffer": { "type": "uniform" }
2119
+ },
2120
+ {
2121
+ "binding": 1,
2122
+ "visibility": GPUShaderStage.FRAGMENT,
2123
+ "sampler": {}
2124
+ },
2125
+ {
2126
+ "binding": 2,
2127
+ "visibility": GPUShaderStage.FRAGMENT,
2128
+ "texture": {}
2129
+ }
2130
+ ]
2131
+ });
2132
+ this.bindGroupLayouts.set("positioned_texture", bindGroupLayout);
2133
+ const pipelineLayout = this.device.createPipelineLayout({
2134
+ "bindGroupLayouts": [bindGroupLayout]
2135
+ });
2136
+ const vertexShaderModule = this.getOrCreateShaderModule("positionedTextureVertex", ShaderSource.getPositionedTextureVertexShader());
2137
+ const fragmentShaderModule = this.getOrCreateShaderModule("positionedTextureFragment", ShaderSource.getPositionedTextureFragmentShader());
2138
+ const pipeline = this.device.createRenderPipeline({
2139
+ "layout": pipelineLayout,
2140
+ "vertex": {
2141
+ "module": vertexShaderModule,
2142
+ "entryPoint": "main",
2143
+ "buffers": []
2144
+ },
2145
+ "fragment": {
2146
+ "module": fragmentShaderModule,
2147
+ "entryPoint": "main",
2148
+ "targets": [{
2149
+ "format": this.format,
2150
+ "blend": {
2151
+ "color": {
2152
+ "srcFactor": "one",
2153
+ "dstFactor": "one-minus-src-alpha",
2154
+ "operation": "add"
2155
+ },
2156
+ "alpha": {
2157
+ "srcFactor": "one",
2158
+ "dstFactor": "one-minus-src-alpha",
2159
+ "operation": "add"
2160
+ }
2161
+ }
2162
+ }]
2163
+ },
2164
+ "primitive": {
2165
+ "topology": "triangle-list",
2166
+ "cullMode": "none"
2167
+ }
2168
+ });
2169
+ this.pipelines.set("positioned_texture", pipeline);
2170
+ const pipelineRGBA = this.device.createRenderPipeline({
2171
+ "layout": pipelineLayout,
2172
+ "vertex": {
2173
+ "module": vertexShaderModule,
2174
+ "entryPoint": "main",
2175
+ "buffers": []
2176
+ },
2177
+ "fragment": {
2178
+ "module": fragmentShaderModule,
2179
+ "entryPoint": "main",
2180
+ "targets": [{
2181
+ "format": "rgba8unorm",
2182
+ "blend": {
2183
+ "color": {
2184
+ "srcFactor": "one",
2185
+ "dstFactor": "one-minus-src-alpha",
2186
+ "operation": "add"
2187
+ },
2188
+ "alpha": {
2189
+ "srcFactor": "one",
2190
+ "dstFactor": "one-minus-src-alpha",
2191
+ "operation": "add"
2192
+ }
2193
+ }
2194
+ }]
2195
+ },
2196
+ "primitive": {
2197
+ "topology": "triangle-list",
2198
+ "cullMode": "none"
2199
+ }
2200
+ });
2201
+ this.pipelines.set("positioned_texture_rgba", pipelineRGBA);
2202
+ const pipelineMsaa = this.device.createRenderPipeline({
2203
+ "layout": pipelineLayout,
2204
+ "vertex": {
2205
+ "module": vertexShaderModule,
2206
+ "entryPoint": "main",
2207
+ "buffers": []
2208
+ },
2209
+ "fragment": {
2210
+ "module": fragmentShaderModule,
2211
+ "entryPoint": "main",
2212
+ "targets": [{
2213
+ "format": "rgba8unorm",
2214
+ "blend": {
2215
+ "color": {
2216
+ "srcFactor": "one",
2217
+ "dstFactor": "zero",
2218
+ "operation": "add"
2219
+ },
2220
+ "alpha": {
2221
+ "srcFactor": "one",
2222
+ "dstFactor": "zero",
2223
+ "operation": "add"
2224
+ }
2225
+ }
2226
+ }]
2227
+ },
2228
+ "primitive": {
2229
+ "topology": "triangle-list",
2230
+ "cullMode": "none"
2231
+ },
2232
+ "multisample": {
2233
+ "count": 4
2234
+ },
2235
+ "depthStencil": {
2236
+ "format": "stencil8",
2237
+ "stencilFront": {
2238
+ "compare": "always",
2239
+ "failOp": "keep",
2240
+ "depthFailOp": "keep",
2241
+ "passOp": "keep"
2242
+ },
2243
+ "stencilBack": {
2244
+ "compare": "always",
2245
+ "failOp": "keep",
2246
+ "depthFailOp": "keep",
2247
+ "passOp": "keep"
2248
+ }
2249
+ }
2250
+ });
2251
+ this.pipelines.set("bitmap_render_msaa", pipelineMsaa);
2252
+ const pipelineNonMsaa = this.device.createRenderPipeline({
2253
+ "layout": pipelineLayout,
2254
+ "vertex": {
2255
+ "module": vertexShaderModule,
2256
+ "entryPoint": "main",
2257
+ "buffers": []
2258
+ },
2259
+ "fragment": {
2260
+ "module": fragmentShaderModule,
2261
+ "entryPoint": "main",
2262
+ "targets": [{
2263
+ "format": "rgba8unorm",
2264
+ "blend": {
2265
+ "color": {
2266
+ "srcFactor": "one",
2267
+ "dstFactor": "zero",
2268
+ "operation": "add"
2269
+ },
2270
+ "alpha": {
2271
+ "srcFactor": "one",
2272
+ "dstFactor": "zero",
2273
+ "operation": "add"
2274
+ }
2275
+ }
2276
+ }]
2277
+ },
2278
+ "primitive": {
2279
+ "topology": "triangle-list",
2280
+ "cullMode": "none"
2281
+ },
2282
+ "depthStencil": {
2283
+ "format": "stencil8",
2284
+ "stencilFront": {
2285
+ "compare": "always",
2286
+ "failOp": "keep",
2287
+ "depthFailOp": "keep",
2288
+ "passOp": "keep"
2289
+ },
2290
+ "stencilBack": {
2291
+ "compare": "always",
2292
+ "failOp": "keep",
2293
+ "depthFailOp": "keep",
2294
+ "passOp": "keep"
2295
+ }
2296
+ }
2297
+ });
2298
+ this.pipelines.set("bitmap_render", pipelineNonMsaa);
2299
+ }
2300
+ createTextureScalePipeline() {
2301
+ const bindGroupLayout = this.device.createBindGroupLayout({
2302
+ "entries": [
2303
+ {
2304
+ "binding": 0,
2305
+ "visibility": GPUShaderStage.VERTEX,
2306
+ "buffer": { "type": "uniform" }
2307
+ },
2308
+ {
2309
+ "binding": 1,
2310
+ "visibility": GPUShaderStage.FRAGMENT,
2311
+ "sampler": {}
2312
+ },
2313
+ {
2314
+ "binding": 2,
2315
+ "visibility": GPUShaderStage.FRAGMENT,
2316
+ "texture": {}
2317
+ }
2318
+ ]
2319
+ });
2320
+ this.bindGroupLayouts.set("texture_scale", bindGroupLayout);
2321
+ const pipelineLayout = this.device.createPipelineLayout({
2322
+ "bindGroupLayouts": [bindGroupLayout]
2323
+ });
2324
+ const vertexShaderModule = this.getOrCreateShaderModule("textureScaleVertex", ShaderSource.getTextureScaleVertexShader());
2325
+ const fragmentShaderModule = this.getOrCreateShaderModule("positionedTextureFragment", ShaderSource.getPositionedTextureFragmentShader());
2326
+ const pipeline = this.device.createRenderPipeline({
2327
+ "layout": pipelineLayout,
2328
+ "vertex": {
2329
+ "module": vertexShaderModule,
2330
+ "entryPoint": "main",
2331
+ "buffers": []
2332
+ },
2333
+ "fragment": {
2334
+ "module": fragmentShaderModule,
2335
+ "entryPoint": "main",
2336
+ "targets": [{
2337
+ "format": "rgba8unorm",
2338
+ "blend": {
2339
+ "color": {
2340
+ "srcFactor": "one",
2341
+ "dstFactor": "zero",
2342
+ "operation": "add"
2343
+ },
2344
+ "alpha": {
2345
+ "srcFactor": "one",
2346
+ "dstFactor": "zero",
2347
+ "operation": "add"
2348
+ }
2349
+ }
2350
+ }]
2351
+ },
2352
+ "primitive": {
2353
+ "topology": "triangle-list",
2354
+ "cullMode": "none"
2355
+ }
2356
+ });
2357
+ this.pipelines.set("texture_scale", pipeline);
2358
+ const blendVertexShaderModule = this.getOrCreateShaderModule("textureScaleBlendVertex", ShaderSource.getTextureScaleBlendVertexShader());
2359
+ const blendPipeline = this.device.createRenderPipeline({
2360
+ "layout": pipelineLayout,
2361
+ "vertex": {
2362
+ "module": blendVertexShaderModule,
2363
+ "entryPoint": "main",
2364
+ "buffers": []
2365
+ },
2366
+ "fragment": {
2367
+ "module": fragmentShaderModule,
2368
+ "entryPoint": "main",
2369
+ "targets": [{
2370
+ "format": "rgba8unorm",
2371
+ "blend": {
2372
+ "color": {
2373
+ "srcFactor": "one",
2374
+ "dstFactor": "zero",
2375
+ "operation": "add"
2376
+ },
2377
+ "alpha": {
2378
+ "srcFactor": "one",
2379
+ "dstFactor": "zero",
2380
+ "operation": "add"
2381
+ }
2382
+ }
2383
+ }]
2384
+ },
2385
+ "primitive": {
2386
+ "topology": "triangle-list",
2387
+ "cullMode": "none"
2388
+ }
2389
+ });
2390
+ this.pipelines.set("texture_scale_blend", blendPipeline);
2391
+ }
2392
+ createBitmapSyncPipeline() {
2393
+ const bindGroupLayout = this.device.createBindGroupLayout({
2394
+ "entries": [
2395
+ {
2396
+ "binding": 0,
2397
+ "visibility": GPUShaderStage.VERTEX,
2398
+ "buffer": { "type": "uniform" }
2399
+ },
2400
+ {
2401
+ "binding": 1,
2402
+ "visibility": GPUShaderStage.FRAGMENT,
2403
+ "sampler": { "type": "filtering" }
2404
+ },
2405
+ {
2406
+ "binding": 2,
2407
+ "visibility": GPUShaderStage.FRAGMENT,
2408
+ "texture": { "sampleType": "float" }
2409
+ }
2410
+ ]
2411
+ });
2412
+ this.bindGroupLayouts.set("bitmap_sync", bindGroupLayout);
2413
+ const pipelineLayout = this.device.createPipelineLayout({
2414
+ "bindGroupLayouts": [bindGroupLayout]
2415
+ });
2416
+ const vertexShaderModule = this.getOrCreateShaderModule("bitmapSyncVertex", ShaderSource.getBitmapSyncVertexShader());
2417
+ const fragmentShaderModule = this.getOrCreateShaderModule("bitmapSyncFragment", ShaderSource.getBitmapSyncFragmentShader());
2418
+ const pipeline = this.device.createRenderPipeline({
2419
+ "layout": pipelineLayout,
2420
+ "vertex": {
2421
+ "module": vertexShaderModule,
2422
+ "entryPoint": "main",
2423
+ "buffers": []
2424
+ },
2425
+ "fragment": {
2426
+ "module": fragmentShaderModule,
2427
+ "entryPoint": "main",
2428
+ "targets": [{
2429
+ "format": "rgba8unorm",
2430
+ "blend": {
2431
+ "color": {
2432
+ "srcFactor": "one",
2433
+ "dstFactor": "zero",
2434
+ "operation": "add"
2435
+ },
2436
+ "alpha": {
2437
+ "srcFactor": "one",
2438
+ "dstFactor": "zero",
2439
+ "operation": "add"
2440
+ }
2441
+ }
2442
+ }]
2443
+ },
2444
+ "primitive": {
2445
+ "topology": "triangle-list",
2446
+ "cullMode": "none"
2447
+ },
2448
+ "multisample": {
2449
+ "count": 4
2450
+ }
2451
+ });
2452
+ this.pipelines.set("bitmap_sync", pipeline);
2453
+ }
2454
+ createColorMatrixFilterPipeline() {
2455
+ const BLEND_REPLACE = {
2456
+ "color": { "srcFactor": "one", "dstFactor": "zero", "operation": "add" },
2457
+ "alpha": { "srcFactor": "one", "dstFactor": "zero", "operation": "add" }
2458
+ };
2459
+ const BLEND_ALPHA = {
2460
+ "color": { "srcFactor": "one", "dstFactor": "one-minus-src-alpha", "operation": "add" },
2461
+ "alpha": { "srcFactor": "one", "dstFactor": "one-minus-src-alpha", "operation": "add" }
2462
+ };
2463
+ this.createFilterPipelineWithLayout("color_matrix_filter", ShaderSource.getColorMatrixFilterFragmentShader(), 1, BLEND_REPLACE);
2464
+ this.createFilterPipelineWithLayout("bevel_base", ShaderSource.getBevelBaseFragmentShader(), 1, BLEND_REPLACE);
2465
+ this.createFilterPipelineWithLayout("glow_filter", ShaderSource.getGlowFilterFragmentShader(), 2, BLEND_ALPHA);
2466
+ this.createFilterPipelineWithLayout("drop_shadow_filter", ShaderSource.getDropShadowFilterFragmentShader(), 2, BLEND_ALPHA);
2467
+ this.createFilterPipelineWithLayout("bevel_filter", ShaderSource.getBevelFilterFragmentShader(), 2, BLEND_ALPHA);
2468
+ this.createFilterPipelineWithLayout("gradient_glow_filter", ShaderSource.getGradientGlowFilterFragmentShader(), 3, BLEND_ALPHA);
2469
+ this.createFilterPipelineWithLayout("gradient_bevel_filter", ShaderSource.getGradientBevelFilterFragmentShader(), 3, BLEND_ALPHA);
2470
+ }
2471
+ createComplexBlendPipelines() {
2472
+ const bindGroupLayout = this.device.createBindGroupLayout({
2473
+ "entries": [
2474
+ {
2475
+ "binding": 0,
2476
+ "visibility": GPUShaderStage.FRAGMENT,
2477
+ "buffer": { "type": "uniform" }
2478
+ },
2479
+ {
2480
+ "binding": 1,
2481
+ "visibility": GPUShaderStage.FRAGMENT,
2482
+ "sampler": {}
2483
+ },
2484
+ {
2485
+ "binding": 2,
2486
+ "visibility": GPUShaderStage.FRAGMENT,
2487
+ "texture": {}
2488
+ },
2489
+ {
2490
+ "binding": 3,
2491
+ "visibility": GPUShaderStage.FRAGMENT,
2492
+ "texture": {}
2493
+ }
2494
+ ]
2495
+ });
2496
+ this.bindGroupLayouts.set("complex_blend", bindGroupLayout);
2497
+ const pipelineLayout = this.device.createPipelineLayout({
2498
+ "bindGroupLayouts": [bindGroupLayout]
2499
+ });
2500
+ const vertexShaderModule = this.getOrCreateShaderModule("complexBlendVertex", ShaderSource.getComplexBlendVertexShader());
2501
+ const fragmentShaderModule = this.getOrCreateShaderModule("unifiedComplexBlendFragment", ShaderSource.getUnifiedComplexBlendFragmentShader());
2502
+ const pipeline = this.device.createRenderPipeline({
2503
+ "layout": pipelineLayout,
2504
+ "vertex": {
2505
+ "module": vertexShaderModule,
2506
+ "entryPoint": "main",
2507
+ "buffers": []
2508
+ },
2509
+ "fragment": {
2510
+ "module": fragmentShaderModule,
2511
+ "entryPoint": "main",
2512
+ "targets": [{
2513
+ "format": "rgba8unorm",
2514
+ "blend": {
2515
+ "color": {
2516
+ "srcFactor": "one",
2517
+ "dstFactor": "zero",
2518
+ "operation": "add"
2519
+ },
2520
+ "alpha": {
2521
+ "srcFactor": "one",
2522
+ "dstFactor": "zero",
2523
+ "operation": "add"
2524
+ }
2525
+ }
2526
+ }]
2527
+ },
2528
+ "primitive": {
2529
+ "topology": "triangle-list",
2530
+ "cullMode": "none"
2531
+ }
2532
+ });
2533
+ this.pipelines.set("complex_blend", pipeline);
2534
+ this.createComplexBlendCopyPipeline();
2535
+ this.createComplexBlendOutputPipeline();
2536
+ }
2537
+ createComplexBlendCopyPipeline() {
2538
+ const BLEND_REPLACE = {
2539
+ "color": { "srcFactor": "one", "dstFactor": "zero", "operation": "add" },
2540
+ "alpha": { "srcFactor": "one", "dstFactor": "zero", "operation": "add" }
2541
+ };
2542
+ const copyLayout = this.bindGroupLayouts.get("texture_copy");
2543
+ if (copyLayout) {
2544
+ const copyPipelineLayout = this.device.createPipelineLayout({ "bindGroupLayouts": [copyLayout] });
2545
+ const copyVS = this.getOrCreateShaderModule("complexBlendCopyVertex", ShaderSource.getComplexBlendCopyVertexShader());
2546
+ const copyFS = this.getOrCreateShaderModule("textureCopyFragment", ShaderSource.getTextureCopyFragmentShader());
2547
+ this.pipelines.set("complex_blend_copy", this.createFullscreenQuadPipeline(copyPipelineLayout, copyVS, copyFS, "rgba8unorm", BLEND_REPLACE));
2548
+ }
2549
+ const scaleLayout = this.bindGroupLayouts.get("texture_scale");
2550
+ if (scaleLayout) {
2551
+ const scalePipelineLayout = this.device.createPipelineLayout({ "bindGroupLayouts": [scaleLayout] });
2552
+ const scaleVS = this.getOrCreateShaderModule("complexBlendScaleVertex", ShaderSource.getComplexBlendScaleVertexShader());
2553
+ const scaleFS = this.getOrCreateShaderModule("positionedTextureFragment", ShaderSource.getPositionedTextureFragmentShader());
2554
+ this.pipelines.set("complex_blend_scale", this.createFullscreenQuadPipeline(scalePipelineLayout, scaleVS, scaleFS, "rgba8unorm", BLEND_REPLACE));
2555
+ }
2556
+ }
2557
+ createComplexBlendOutputPipeline() {
2558
+ const bindGroupLayout = this.bindGroupLayouts.get("positioned_texture");
2559
+ if (!bindGroupLayout) {
2560
+ return;
2561
+ }
2562
+ const pipelineLayout = this.device.createPipelineLayout({ "bindGroupLayouts": [bindGroupLayout] });
2563
+ const fragmentShaderModule = this.getOrCreateShaderModule("positionedTextureFragment", ShaderSource.getPositionedTextureFragmentShader());
2564
+ const blend = {
2565
+ "color": { "srcFactor": "one", "dstFactor": "one-minus-src-alpha", "operation": "add" },
2566
+ "alpha": { "srcFactor": "one", "dstFactor": "one-minus-src-alpha", "operation": "add" }
2567
+ };
2568
+ const blendOutputVS = this.getOrCreateShaderModule("complexBlendOutputVertex", ShaderSource.getComplexBlendOutputVertexShader());
2569
+ this.pipelines.set("complex_blend_output", this.createFullscreenQuadPipeline(pipelineLayout, blendOutputVS, fragmentShaderModule, this.format, blend));
2570
+ if (this.sampleCount > 1) {
2571
+ this.pipelines.set("complex_blend_output_msaa", this.createFullscreenQuadPipeline(pipelineLayout, blendOutputVS, fragmentShaderModule, this.format, blend, this.sampleCount));
2572
+ }
2573
+ const filterBlendOutputVS = this.getOrCreateShaderModule("filterComplexBlendOutputVertex", ShaderSource.getFilterComplexBlendOutputVertexShader());
2574
+ this.pipelines.set("filter_complex_blend_output", this.createFullscreenQuadPipeline(pipelineLayout, filterBlendOutputVS, fragmentShaderModule, this.format, blend));
2575
+ if (this.sampleCount > 1) {
2576
+ this.pipelines.set("filter_complex_blend_output_msaa", this.createFullscreenQuadPipeline(pipelineLayout, filterBlendOutputVS, fragmentShaderModule, this.format, blend, this.sampleCount));
2577
+ }
2578
+ }
2579
+ createFilterPipelineWithLayout(name, fragmentShaderCode, textureCount, blend) {
2580
+ let bindGroupLayout = this.filterBindGroupLayouts.get(textureCount);
2581
+ if (!bindGroupLayout) {
2582
+ const entries = [
2583
+ { "binding": 0, "visibility": GPUShaderStage.FRAGMENT, "buffer": { "type": "uniform" } },
2584
+ { "binding": 1, "visibility": GPUShaderStage.FRAGMENT, "sampler": {} }
2585
+ ];
2586
+ for (let i = 0; i < textureCount; i++) {
2587
+ entries.push({ "binding": 2 + i, "visibility": GPUShaderStage.FRAGMENT, "texture": {} });
2588
+ }
2589
+ bindGroupLayout = this.device.createBindGroupLayout({ "entries": entries });
2590
+ this.filterBindGroupLayouts.set(textureCount, bindGroupLayout);
2591
+ }
2592
+ this.bindGroupLayouts.set(name, bindGroupLayout);
2593
+ const pipelineLayout = this.device.createPipelineLayout({ "bindGroupLayouts": [bindGroupLayout] });
2594
+ const vertexShaderModule = this.getOrCreateShaderModule("blurFilterVertex", ShaderSource.getBlurFilterVertexShader());
2595
+ const fragmentShaderModule = this.getOrCreateShaderModule(`filter_${name}`, fragmentShaderCode);
2596
+ this.pipelines.set(name, this.createFullscreenQuadPipeline(pipelineLayout, vertexShaderModule, fragmentShaderModule, "rgba8unorm", blend));
2597
+ }
2598
+ createFullscreenQuadPipeline(pipelineLayout, vertexModule, fragmentModule, format, blend, multisampleCount, depthStencil) {
2599
+ const descriptor = {
2600
+ "layout": pipelineLayout,
2601
+ "vertex": {
2602
+ "module": vertexModule,
2603
+ "entryPoint": "main",
2604
+ "buffers": []
2605
+ },
2606
+ "fragment": {
2607
+ "module": fragmentModule,
2608
+ "entryPoint": "main",
2609
+ "targets": [{ "format": format, "blend": blend }]
2610
+ },
2611
+ "primitive": {
2612
+ "topology": "triangle-list",
2613
+ "cullMode": "none"
2614
+ }
2615
+ };
2616
+ if (multisampleCount && multisampleCount > 1) {
2617
+ descriptor.multisample = { "count": multisampleCount };
2618
+ }
2619
+ if (depthStencil) {
2620
+ descriptor.depthStencil = depthStencil;
2621
+ }
2622
+ return this.device.createRenderPipeline(descriptor);
2623
+ }
2624
+ getPipeline(name) {
2625
+ let pipeline = this.pipelines.get(name);
2626
+ if (!pipeline) {
2627
+ this.ensureLazyGroup(name);
2628
+ pipeline = this.pipelines.get(name);
2629
+ }
2630
+ return pipeline;
2631
+ }
2632
+ /**
2633
+ * @description フィルターパイプラインのoverride定数バリアントを取得
2634
+ * GPU warp divergenceを排除するコンパイル時分岐特殊化
2635
+ */
2636
+ getFilterPipeline(baseName, constants) {
2637
+ // キャッシュキーを生成
2638
+ const keys = Object.keys(constants).sort();
2639
+ const suffix = keys.map((k) => `${k}${constants[k]}`).join("_");
2640
+ const cacheKey = `${baseName}_${suffix}`;
2641
+ let pipeline = this.pipelines.get(cacheKey);
2642
+ if (pipeline) {
2643
+ return pipeline;
2644
+ }
2645
+ // ベースグループのロードを確保
2646
+ this.ensureLazyGroup(baseName);
2647
+ const fragmentModule = this.shaderModuleCache.get(`filter_${baseName}`);
2648
+ const vertexModule = this.shaderModuleCache.get("blurFilterVertex");
2649
+ const bindGroupLayout = this.bindGroupLayouts.get(baseName);
2650
+ if (!fragmentModule || !vertexModule || !bindGroupLayout) {
2651
+ return this.pipelines.get(baseName);
2652
+ }
2653
+ const pipelineLayout = this.device.createPipelineLayout({
2654
+ "bindGroupLayouts": [bindGroupLayout]
2655
+ });
2656
+ pipeline = this.device.createRenderPipeline({
2657
+ "layout": pipelineLayout,
2658
+ "vertex": {
2659
+ "module": vertexModule,
2660
+ "entryPoint": "main",
2661
+ "buffers": []
2662
+ },
2663
+ "fragment": {
2664
+ "module": fragmentModule,
2665
+ "entryPoint": "main",
2666
+ "targets": [{
2667
+ "format": "rgba8unorm",
2668
+ "blend": {
2669
+ "color": { "srcFactor": "one", "dstFactor": "one-minus-src-alpha", "operation": "add" },
2670
+ "alpha": { "srcFactor": "one", "dstFactor": "one-minus-src-alpha", "operation": "add" }
2671
+ }
2672
+ }],
2673
+ "constants": constants
2674
+ },
2675
+ "primitive": {
2676
+ "topology": "triangle-list",
2677
+ "cullMode": "none"
2678
+ }
2679
+ });
2680
+ this.pipelines.set(cacheKey, pipeline);
2681
+ return pipeline;
2682
+ }
2683
+ /**
2684
+ * @description グラデーションタイプとスプレッドモードに応じた特殊化パイプラインを取得
2685
+ * override定数でGPU warp divergenceを排除
2686
+ */
2687
+ getGradientPipeline(baseName, gradientType, spreadMode) {
2688
+ const key = `${baseName}_t${gradientType}s${spreadMode}`;
2689
+ let pipeline = this.pipelines.get(key);
2690
+ if (pipeline) {
2691
+ return pipeline;
2692
+ }
2693
+ if (!this.gradientPipelineLayout) {
2694
+ return this.getPipeline(baseName);
2695
+ }
2696
+ // ベースパイプラインと同じ構成でoverride定数を変えて作成
2697
+ pipeline = this.createGradientVariant(baseName, gradientType, spreadMode);
2698
+ if (pipeline) {
2699
+ this.pipelines.set(key, pipeline);
2700
+ return pipeline;
2701
+ }
2702
+ // フォールバック: デフォルト定数のベースパイプラインを使用
2703
+ return this.getPipeline(baseName);
2704
+ }
2705
+ createGradientVariant(baseName, gradientType, spreadMode) {
2706
+ if (!this.gradientPipelineLayout) {
2707
+ return undefined;
2708
+ }
2709
+ const constants = {
2710
+ "GRADIENT_TYPE": gradientType,
2711
+ "SPREAD_MODE": spreadMode
2712
+ };
2713
+ const vertexBufferLayout = VERTEX_BUFFER_LAYOUT_4F;
2714
+ const blendState = BLEND_PREMULTIPLIED_ALPHA;
2715
+ // ベース名からパイプライン構成を決定
2716
+ const isStencilFragment = baseName.includes("stencil_atlas") || baseName === "gradient_fill_stencil_main";
2717
+ const fragModule = isStencilFragment ? this.gradientStencilFragmentShaderModule : this.gradientFragmentShaderModule;
2718
+ const isBGRA = baseName.includes("bgra") || baseName === "gradient_fill_stencil_main";
2719
+ const format = isBGRA ? this.format : "rgba8unorm";
2720
+ const needsYFlip = baseName.includes("bgra") || baseName === "gradient_fill_stencil_main";
2721
+ const vertexConstants = {};
2722
+ if (needsYFlip) {
2723
+ vertexConstants.yFlipSign = -1.0;
2724
+ }
2725
+ let depthStencil;
2726
+ let sampleCount = this.sampleCount;
2727
+ if (baseName.includes("stroke")) {
2728
+ depthStencil = {
2729
+ "format": "stencil8",
2730
+ "stencilFront": { "compare": "always", "failOp": "keep", "depthFailOp": "keep", "passOp": "keep" },
2731
+ "stencilBack": { "compare": "always", "failOp": "keep", "depthFailOp": "keep", "passOp": "keep" },
2732
+ "stencilReadMask": 0x00,
2733
+ "stencilWriteMask": 0x00
2734
+ };
2735
+ }
2736
+ else if (baseName === "gradient_fill_stencil" || baseName === "gradient_fill_stencil_atlas") {
2737
+ depthStencil = {
2738
+ "format": "stencil8",
2739
+ "stencilFront": { "compare": "not-equal", "failOp": "keep", "depthFailOp": "zero", "passOp": "zero" },
2740
+ "stencilBack": { "compare": "not-equal", "failOp": "keep", "depthFailOp": "zero", "passOp": "zero" },
2741
+ "stencilReadMask": 0xFF,
2742
+ "stencilWriteMask": 0xFF
2743
+ };
2744
+ }
2745
+ else if (baseName === "gradient_fill_stencil_main") {
2746
+ depthStencil = {
2747
+ "format": "stencil8",
2748
+ "stencilFront": { "compare": "not-equal", "failOp": "keep", "depthFailOp": "zero", "passOp": "zero" },
2749
+ "stencilBack": { "compare": "not-equal", "failOp": "keep", "depthFailOp": "zero", "passOp": "zero" },
2750
+ "stencilReadMask": 0xFF,
2751
+ "stencilWriteMask": 0xFF
2752
+ };
2753
+ sampleCount = 1;
2754
+ }
2755
+ else if (baseName === "gradient_fill_bgra_stencil") {
2756
+ depthStencil = {
2757
+ "format": "stencil8",
2758
+ "stencilFront": { "compare": "equal", "failOp": "keep", "depthFailOp": "keep", "passOp": "keep" },
2759
+ "stencilBack": { "compare": "equal", "failOp": "keep", "depthFailOp": "keep", "passOp": "keep" },
2760
+ "stencilReadMask": 0xFF,
2761
+ "stencilWriteMask": 0x00
2762
+ };
2763
+ }
2764
+ else if (baseName === "gradient_fill_bgra_no_msaa") {
2765
+ sampleCount = 1;
2766
+ }
2767
+ const descriptor = {
2768
+ "layout": this.gradientPipelineLayout,
2769
+ "vertex": {
2770
+ "module": this.gradientVertexShaderModule,
2771
+ "entryPoint": "main",
2772
+ "buffers": [vertexBufferLayout],
2773
+ "constants": Object.keys(vertexConstants).length > 0 ? vertexConstants : undefined
2774
+ },
2775
+ "fragment": {
2776
+ "module": fragModule,
2777
+ "entryPoint": "main",
2778
+ "targets": [{ "format": format, "blend": blendState }],
2779
+ "constants": constants
2780
+ },
2781
+ "primitive": { "topology": "triangle-list", "cullMode": "none" },
2782
+ "multisample": { "count": sampleCount }
2783
+ };
2784
+ if (depthStencil) {
2785
+ descriptor.depthStencil = depthStencil;
2786
+ }
2787
+ return this.device.createRenderPipeline(descriptor);
2788
+ }
2789
+ getBindGroupLayout(name) {
2790
+ let layout = this.bindGroupLayouts.get(name);
2791
+ if (!layout) {
2792
+ this.ensureLazyGroup(name);
2793
+ layout = this.bindGroupLayouts.get(name);
2794
+ }
2795
+ return layout;
2796
+ }
2797
+ createNodeClearPipeline() {
2798
+ const vertexBufferLayout = {
2799
+ "arrayStride": 2 * 4,
2800
+ "attributes": [
2801
+ {
2802
+ "shaderLocation": 0,
2803
+ "offset": 0,
2804
+ "format": "float32x2"
2805
+ }
2806
+ ]
2807
+ };
2808
+ const nodeClearPipeline = this.device.createRenderPipeline({
2809
+ "layout": "auto",
2810
+ "vertex": {
2811
+ "module": this.getOrCreateShaderModule("nodeClearVertex", ShaderSource.getNodeClearVertexShader()),
2812
+ "entryPoint": "main",
2813
+ "buffers": [vertexBufferLayout]
2814
+ },
2815
+ "fragment": {
2816
+ "module": this.getOrCreateShaderModule("nodeClearFragment", ShaderSource.getNodeClearFragmentShader()),
2817
+ "entryPoint": "main",
2818
+ "targets": [{
2819
+ "format": "rgba8unorm",
2820
+ "blend": {
2821
+ "color": {
2822
+ "srcFactor": "one",
2823
+ "dstFactor": "zero",
2824
+ "operation": "add"
2825
+ },
2826
+ "alpha": {
2827
+ "srcFactor": "one",
2828
+ "dstFactor": "zero",
2829
+ "operation": "add"
2830
+ }
2831
+ },
2832
+ "writeMask": GPUColorWrite.ALL
2833
+ }]
2834
+ },
2835
+ "primitive": {
2836
+ "topology": "triangle-list",
2837
+ "cullMode": "none"
2838
+ },
2839
+ "depthStencil": {
2840
+ "format": "stencil8",
2841
+ "stencilFront": {
2842
+ "compare": "always",
2843
+ "failOp": "zero",
2844
+ "depthFailOp": "zero",
2845
+ "passOp": "zero"
2846
+ },
2847
+ "stencilBack": {
2848
+ "compare": "always",
2849
+ "failOp": "zero",
2850
+ "depthFailOp": "zero",
2851
+ "passOp": "zero"
2852
+ },
2853
+ "stencilReadMask": 0xFF,
2854
+ "stencilWriteMask": 0xFF
2855
+ },
2856
+ "multisample": {
2857
+ "count": this.sampleCount
2858
+ }
2859
+ });
2860
+ this.pipelines.set("node_clear_atlas", nodeClearPipeline);
2861
+ }
2862
+ dispose() {
2863
+ this.pipelines.clear();
2864
+ this.bindGroupLayouts.clear();
2865
+ this.shaderModuleCache.clear();
2866
+ this.filterBindGroupLayouts.clear();
2867
+ }
2868
+ }