Skip to content

Commit ffb52a6

Browse files
committed
docs: add note on pixijs rendering failure
1 parent ab82224 commit ffb52a6

File tree

3 files changed

+110
-21
lines changed

3 files changed

+110
-21
lines changed

.obsidian/workspace.json

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,21 @@
44
"type": "split",
55
"children": [
66
{
7-
"id": "016e2593f42f7857",
7+
"id": "bfe4873542277a4b",
88
"type": "tabs",
99
"children": [
1010
{
11-
"id": "5f72ed50e9188153",
11+
"id": "8dd041c7ad6f1612",
1212
"type": "leaf",
1313
"state": {
1414
"type": "markdown",
1515
"state": {
16-
"file": "content/🧠 Knowledge/🧑🏼‍💻 Programming/Javascript & Typescript/Libraries/Pixijs/WebGPU compatibility issues.md",
16+
"file": "content/🧠 Knowledge/🧑🏼‍💻 Programming/Javascript & Typescript/Libraries/PixiJS/PixiJS rendering failure.md",
1717
"mode": "source",
1818
"source": false
1919
},
2020
"icon": "lucide-file",
21-
"title": "WebGPU compatibility issues"
21+
"title": "PixiJS rendering failure"
2222
}
2323
}
2424
]
@@ -142,13 +142,13 @@
142142
"state": {
143143
"type": "outline",
144144
"state": {
145-
"file": "content/🧠 Knowledge/🧑🏼‍💻 Programming/Javascript & Typescript/Libraries/Pixijs/WebGPU compatibility issues.md",
145+
"file": "content/🧠 Knowledge/🧑🏼‍💻 Programming/Javascript & Typescript/Libraries/PixiJS/PixiJS rendering failure.md",
146146
"followCursor": false,
147147
"showSearch": false,
148148
"searchQuery": ""
149149
},
150150
"icon": "lucide-list",
151-
"title": "Outline of WebGPU compatibility issues"
151+
"title": "Outline of PixiJS rendering failure"
152152
}
153153
}
154154
],
@@ -167,11 +167,22 @@
167167
"command-palette:Open command palette": false
168168
}
169169
},
170-
"active": "5f72ed50e9188153",
170+
"active": "8dd041c7ad6f1612",
171171
"lastOpenFiles": [
172172
"content/🧠 Knowledge/🧑🏼‍💻 Programming/Java/Frameworks/Java Springboot/Java Springboot Project Layout.md",
173-
"content/🧠 Knowledge/🧑🏼‍💻 Programming/Javascript & Typescript/Libraries/Pixijs/WebGPU compatibility issues.md",
174-
"content/🧠 Knowledge/🧑🏼‍💻 Programming/Javascript & Typescript/Libraries/Pixijs",
173+
"content/🧠 Knowledge/🧑🏼‍💻 Programming/Javascript & Typescript/Libraries/PixiJS/PixiJS rendering failure.md",
174+
"content/_images/Pasted image 20250429220222.png",
175+
"content/🧠 Knowledge/📜 Software Licensing/Copyleft Licenses/GPL-2.0.md",
176+
"content/_images/Knowledge/Programming/Javascript & Typescript/Libraries/PixiJS/html5-webgl-2d-renderer-sample-3.gif",
177+
"content/_images/Knowledge/Programming/Javascript & Typescript/Libraries/PixiJS",
178+
"content/_images/Knowledge/Programming/Javascript & Typescript/Libraries/Pixijs",
179+
"content/_images/Knowledge/Programming/Javascript & Typescript/Libraries",
180+
"content/_images/Knowledge/Programming/Javascript & Typescript",
181+
"content/_images/Knowledge/Programming",
182+
"content/_images/Knowledge/Programming/Javascript & Typescript/Libraries/PixiJS/pixijs-playground.gif",
183+
"content/_images/Knowledge/html5-webgl-2d-renderer-sample-3.gif",
184+
"content/_images/Knowledge/html5-webgl-2d-renderer-sample-3-ezgif.com-crop.gif",
185+
"content/🧠 Knowledge/🧑🏼‍💻 Programming/Javascript & Typescript/Libraries/PixiJS",
175186
"content/🧠 Knowledge/🧑🏼‍💻 Programming/C++/Compilation Process.md",
176187
"content/🧠 Knowledge/🧑🏼‍💻 Programming/Javascript & Typescript/Libraries",
177188
"content/🧠 Knowledge/🧑🏼‍💻 Programming/Javascript & Typescript",
@@ -197,24 +208,12 @@
197208
"content/🧠 Knowledge/🖥️ Systems Programming/Language Processors/Pieces of the puzzle/Pre-processors.md",
198209
"content/🧠 Knowledge/🖥️ Systems Programming/Language Processors/Pieces of the puzzle/Linkers.md",
199210
"content/🧠 Knowledge/🖥️ Systems Programming/Language Processors/Pieces of the puzzle/JIT Compilers.md",
200-
"content/🧠 Knowledge/🖥️ Systems Programming/Language Processors/Pieces of the puzzle/Interpreters.md",
201-
"content/🧠 Knowledge/🖥️ Systems Programming/Language Processors/Pieces of the puzzle/Compilers.md",
202211
"customisations/quartz/build.ts",
203212
"content/_images/Knowledge/Tools & Platforms/Operating System/Ubuntu/Display/cursor-size.png",
204213
"content/_images/Knowledge/Tools & Platforms/Operating System/Ubuntu/Display/dock-icon-scale.png",
205214
"content/_images/Knowledge/Tools & Platforms/Operating System/Ubuntu/Display/gnome-tweaks-font-size.png",
206215
"content/_images/Knowledge/Tools & Platforms/Operating System/Ubuntu/Display/gnome-tweaks-font-size.png",
207-
"content/_images/Knowledge/Tools & Platforms/Operating System/Ubuntu/Display",
208216
"content/_images/Knowledge/Tools & Platforms/Operating System/Ubuntu/Display/display-settings.png",
209-
"content/🧠 Knowledge/🛠️ Tools & Platforms/Operating Systems/Linux/Ubuntu/Display",
210-
"content/_images/Knowledge/Tools & Platforms/IDEs/JetBrains/opengl-glitchy-ui.png",
211-
"content/_images/Knowledge/Tools & Platforms/IDEs/JetBrains/Pasted image 20250419215032.png",
212-
"content/_images/Knowledge/Tools & Platforms/IDEs/JetBrains",
213-
"content/_images/Knowledge/Tools & Platforms/IDEs",
214-
"content/🧠 Knowledge/🛠️ Tools & Platforms/IDEs/JetBrains",
215-
"content copy/pactl-list-sink-active-port.png",
216-
"content copy/alsamixer-select-sound-card.png",
217-
"content copy/alsamixer-sliders.png",
218217
"Untitled.canvas"
219218
]
220219
}
2.88 MB
Loading
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
---
2+
title: PixiJS rendering failure
3+
tags:
4+
- pixijs
5+
- webgl
6+
- webgpu
7+
- typescript
8+
url: pixijs-rendering-failure
9+
---
10+
## Summary
11+
The [PixiJS v8 release](https://github.com/pixijs/pixijs/releases/tag/v8.0.0) introduced WebGPU support to leverage modern GPU capabilities when rendering rather than just WebGL. Unfortunately, this has come with a rendering issue where certain devices seemingly fail to render anything when WebGPU is used.
12+
13+
>This is still a bug as of [v8.9.2](https://github.com/pixijs/pixijs/releases/tag/v8.9.2), with issue [#11389](https://github.com/pixijs/pixijs/issues/11389 ) raised detailing the cause and potential fix. This note summarises the cause as well as a workaround for versions with the issue.
14+
15+
For example, the example PixiJS script at https://pixijs.com/8.x/playground outputs the following:
16+
17+
![[pixijs-playground.gif|350]]
18+
19+
This works on all devices since it defaults to using WebGL. However, if we were to modify the call to `app.init` to prefer WebGPU like so:
20+
```ts
21+
await app.init({ background: '#1099bb', resizeTo: window, preference: "webgpu" });
22+
```
23+
the script would only render on *some* devices. A known example of this are Google Pixel 9 phones.
24+
## Root cause
25+
The cause of this actually boils down to how PixiJS batches display objects for rendering. To optimise performance, PixiJS groups compatible display objects, such as sprites sharing similar textures and shaders, into batches. These batches are then rendered in a single GPU draw call, significantly reducing overhead.
26+
27+
A critical constraint in the batching process is the maximum number of textures that can used in a single draw call. Versions of PixiJS with the rendering issue falsely assume that the WebGPU limit for maximum textures is the same as the WebGL limit on a given device.
28+
29+
Unfortunately, there are some WebGPU supported devices where the WebGL limit is greater than the WebGPU limit. This causes rendering to fail and the console logs to show something similar to the following:
30+
31+
```log
32+
The number of sampled textures (32) in the Fragment stage exceeds the maximum per-stage limit (16).
33+
- While validating binding counts
34+
- While validating [BindGroupLayoutDescriptor]
35+
- While calling [Device].CreateBindGroupLayout([BindGroupLayoutDescriptor]).
36+
37+
Invalid BindGroupLayout (unlabeled)] is invalid.
38+
- While calling [Device].CreatePipelineLayout([PipelineLayoutDescriptor]).
39+
40+
[Invalid PipelineLayout (unlabeled)] is invalid.
41+
- While calling [Device].CreateRenderPipeline([RenderPipelineDescriptor ""PIXI Pipeline""]).
42+
43+
[Invalid BindGroupLayout (unlabeled)] is invalid.
44+
- While validating [BindGroupDescriptor] against [Invalid BindGroupLayout (unlabeled)]
45+
- While calling [Device].CreateBindGroup([BindGroupDescriptor]).
46+
47+
WebGPU: too many warnings, no more warnings will be reported to the console for this GPUDevice.
48+
```
49+
50+
In the above example, WebGL's limit (`gl.MAX_TEXTURE_IMAGE_UNITS`) is 32 whereas WebGPU's limit (`device.limits.maxSampledTexturesPerShaderStage`) is 16. Specifically, the code in [getTextureBatchBindGroup.ts](https://github.com/pixijs/pixijs/blob/v8.9.2/src/rendering/batcher/gpu/getTextureBatchBindGroup.ts#L31):
51+
52+
```ts
53+
if (!maxTextures)maxTextures = getMaxTexturesPerBatch();
54+
```
55+
and in [Batcher.ts](https://github.com/pixijs/pixijs/blob/v8.9.2/src/rendering/batcher/shared/Batcher.ts#L358):
56+
```ts
57+
Batcher.defaultOptions.maxTextures = Batcher.defaultOptions.maxTextures ?? getMaxTexturesPerBatch();
58+
```
59+
Both call [getMaxTexturesPerBatch()](https://github.com/pixijs/pixijs/blob/v8.9.2/src/rendering/batcher/gl/utils/maxRecommendedTextures.ts#L13) which relies on `gl.MAX_TEXTURE_IMAGE_UNITS`
60+
## Workaround
61+
Until PixiJS provides a fix for this, the best thing to do is check for mismatched limits and fallback to WebGL if there is a discrepancy. This can be done like so:
62+
63+
```ts
64+
async function determineGraphicsAPI(): Promise<"webgpu" | "webgl"> {
65+
const adapter = await navigator.gpu?.requestAdapter().catch(() => null);
66+
const device = adapter && (await adapter.requestDevice().catch(() => null));
67+
if (!device) {
68+
return "webgl";
69+
}
70+
71+
const canvas = document.createElement("canvas");
72+
const gl =
73+
(canvas.getContext("webgl2") as WebGL2RenderingContext | null) ??
74+
(canvas.getContext("webgl") as WebGLRenderingContext | null);
75+
76+
// we have to return webgl so pixijs automatically falls back to canvas
77+
if (!gl) {
78+
return "webgl";
79+
}
80+
81+
const webglMaxTextures = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS);
82+
const webgpuMaxTextures = device.limits.maxSampledTexturesPerShaderStage;
83+
84+
return webglMaxTextures === webgpuMaxTextures ? "webgpu" : "webgl";
85+
}
86+
87+
const pixiPreference = await determineGraphicsAPI();
88+
const app = new Application();
89+
await app.init({ background: '#1099bb', resizeTo: window, preference: pixiPreference });
90+
```

0 commit comments

Comments
 (0)