Hi,
I'm trying to use iced on my Raspberry 4. So far I managed to make it compile. It even runs and the window is shown, but no frame is rendered. Eventually it exits with the following error:
thread 'main' panicked at 'Next frame: TimeOut', /home/pi/work/iced/wgpu/src/window/compositor.rs:110:21
Before I patched the iced dependencies it failed to compile:
error[E0308]: mismatched types
--> /home/pi/.cargo/registry/src/github.com-1ecc6299db9ec823/font-kit-0.6.0/src/loaders/freetype.rs:804:20
|
804 | x: vector.x() as i64,
| ^^^^^^^^^^^^^^^^^ expected `i32`, found `i64`
error[E0308]: mismatched types
--> /home/pi/.cargo/registry/src/github.com-1ecc6299db9ec823/font-kit-0.6.0/src/loaders/freetype.rs:805:20
|
805 | y: -vector.y() as i64,
| ^^^^^^^^^^^^^^^^^^ expected `i32`, found `i64`
error[E0308]: mismatched types
--> /home/pi/.cargo/registry/src/github.com-1ecc6299db9ec823/font-kit-0.6.0/src/loaders/freetype.rs:808:21
|
808 | xx: matrix.x() as i64,
| ^^^^^^^^^^^^^^^^^ expected `i32`, found `i64`
error[E0308]: mismatched types
--> /home/pi/.cargo/registry/src/github.com-1ecc6299db9ec823/font-kit-0.6.0/src/loaders/freetype.rs:809:21
|
809 | xy: matrix.y() as i64,
| ^^^^^^^^^^^^^^^^^ expected `i32`, found `i64`
error[E0308]: mismatched types
--> /home/pi/.cargo/registry/src/github.com-1ecc6299db9ec823/font-kit-0.6.0/src/loaders/freetype.rs:810:21
|
810 | yx: matrix.z() as i64,
| ^^^^^^^^^^^^^^^^^ expected `i32`, found `i64`
error[E0308]: mismatched types
--> /home/pi/.cargo/registry/src/github.com-1ecc6299db9ec823/font-kit-0.6.0/src/loaders/freetype.rs:811:21
|
811 | yy: matrix.w() as i64,
| ^^^^^^^^^^^^^^^^^ expected `i32`, found `i64`
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0308`.
error: could not compile `font-kit`.
I updated iced_graphics' font-kit dependency to 0.9 and the error disappeared. I was able to build and execute examples, but rendering fails for some reason. Here's the typical output: https://gist.github.com/0x7CFE/3f29f6d7fccd67bd8804ad47c97daaa5 Also, please notice a ton of font errors.
Currently Raspberry Pi 4 has only experimental but working Vulkan support. Yet I thought that for 2D stuff it should probably be enough.
I will be happy to hear any suggestions.
P.S.: Since iced is render agnostc, is it possible to build it on top of OpenGL? Maybe that would be easier than trying to debug alpha version of the Vulkan driver.
Interesting!
I updated iced_graphics' font-kit dependency to 0.9
We should definitely update this dependency in iced_graphics. I will take a look.
Since iced is render agnostc, is it possible to build it on top of OpenGL? Maybe that would be easier than trying to debug alpha version of the Vulkan driver.
I recently implemented an OpenGL renderer in #354. You can enable it using the glow and glow_canvas features. However, keep in mind the Image and Svg widgets are not supported by this backend yet.
I recently implemented an OpenGL renderer in #354. You can enable it using the glow and glow_canvas features.
Awesome! I will have a look.
However, keep in mind the Image and Svg widgets are not supported by this backend yet.
Oh, that's unfortunate. Being able to render images is key to my application. Could you please give me a hint on how hard or time consuming it is to implement image support for this backend?
Just in case, I've tried to build stopwatch example with glow feature enabled and got this:
Finished dev [unoptimized + debuginfo] target(s) in 0.52s
Running `target/debug/stopwatch`
thread 'main' panicked at '0:1(10): error: GLSL 3.30 is not supported. Supported versions are: 1.10, 1.20, 1.00 ES, and 3.00 ES
', /home/pi/.cargo/registry/src/github.com-1ecc6299db9ec823/glow_glyph-0.2.0/src/pipeline.rs:287:13
Is it possible to lower required GL version? It's kinda strange to think that 2D rendering stuff requires the latest GL version.
A temporary workaround for GLSL ES issue would be to replace the #version 330 line with
#version 300 es
precision mediump float;
In both shaders like this:
diff --git a/src/shader/fragment.frag b/src/shader/fragment.frag
index 5464b3f..60fb836 100644
--- a/src/shader/fragment.frag
+++ b/src/shader/fragment.frag
@@ -1,7 +1,9 @@
-#version 330
+#version 300 es
+precision mediump float;
uniform sampler2D font_sampler;
in vec2 f_tex_pos;
in vec4 f_color;
diff --git a/src/shader/vertex.vert b/src/shader/vertex.vert
index 023ce31..968f197 100644
--- a/src/shader/vertex.vert
+++ b/src/shader/vertex.vert
@@ -1,4 +1,5 @@
-#version 330
+#version 300 es
+precision mediump float;
uniform mat4 transform;
I've only tested this on https://github.com/hecrj/glow_glyph repo on Raspberry Pi 4 device, haven't really tested further with iced.
A proper fix would be to dynamically detect what version and flavour of OpenGL context glow_glyph has got, and dynamically decide which shader version it should use, either by choosing from different files, or by patching up version-header. Unfortunately #version directive has to be the first non-commented line of a shader, so no preprocessor tricks like #ifdef GL_ES are valid.
Also precision mediump float is too broad. It may be worth optimizing this on per-variable basis for lower-end devices. Lots of text will lead to a non-trivial amount of computation, given that IIUTC each glyph will be rendered using a separate quad (which I would recommend against, but this is a separate huge topic :D).
Got bezier_tool to work on RPi4 with these changes:
diff --git a/Cargo.toml b/Cargo.toml
index 9ab57bc..f61890f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -90,3 +90,6 @@ iced_web = { version = "0.2", path = "web" }
[package.metadata.docs.rs]
rustdoc-args = ["--cfg", "docsrs"]
features = ["image", "svg", "canvas"]
+
+# glow_glyph with patched shaders
+[patch.crates-io]
+glow_glyph = { path = "../glow_glyph" }
diff --git a/examples/bezier_tool/Cargo.toml b/examples/bezier_tool/Cargo.toml
index a88975a..e1c32f4 100644
--- a/examples/bezier_tool/Cargo.toml
+++ b/examples/bezier_tool/Cargo.toml
@@ -6,4 +6,4 @@ edition = "2018"
publish = false
[dependencies]
-iced = { path = "../..", features = ["canvas"] }
+iced = { path = "../..", features = ["canvas", "glow", "glow_canvas"] }
diff --git a/glow/src/shader/quad.frag b/glow/src/shader/quad.frag
index cea36bd..aa6045d 100644
--- a/glow/src/shader/quad.frag
+++ b/glow/src/shader/quad.frag
@@ -1,4 +1,5 @@
-#version 330
+#version 300 es
+precision mediump float;
uniform float u_ScreenHeight;
@@ -11,7 +12,7 @@ in float v_BorderWidth;
out vec4 o_Color;
-float distance(in vec2 frag_coord, in vec2 position, in vec2 size, float radius)
+// Apparently this conflicts with existing GLSL distance(T a, T b) function
+float distance1(in vec2 frag_coord, in vec2 position, in vec2 size, float radius)
{
// TODO: Try SDF approach: https://www.shadertoy.com/view/wd3XRN
vec2 inner_size = size - vec2(radius, radius) * 2.0;
@@ -35,10 +36,10 @@ void main() {
vec2 fragCoord = vec2(gl_FragCoord.x, u_ScreenHeight - gl_FragCoord.y);
// TODO: Remove branching (?)
- if(v_BorderWidth > 0) {
+ if(v_BorderWidth > 0.) { // 0 is int, 0. is float
float internal_border = max(v_BorderRadius - v_BorderWidth, 0.0);
- float internal_distance = distance(
+ float internal_distance = distance1(
fragCoord,
v_Pos + vec2(v_BorderWidth),
v_Scale - vec2(v_BorderWidth * 2.0),
@@ -56,7 +57,7 @@ void main() {
mixed_color = v_Color;
}
- float d = distance(
+ float d = distance1(
fragCoord,
v_Pos,
v_Scale,
diff --git a/glow/src/shader/quad.vert b/glow/src/shader/quad.vert
index d37b5c8..08a4d7c 100644
--- a/glow/src/shader/quad.vert
+++ b/glow/src/shader/quad.vert
@@ -1,4 +1,5 @@
-#version 330
+#version 300 es
+precision mediump float;
uniform mat4 u_Transform;
uniform float u_Scale;
diff --git a/glow/src/shader/triangle.frag b/glow/src/shader/triangle.frag
index d186784..e71c07c 100644
--- a/glow/src/shader/triangle.frag
+++ b/glow/src/shader/triangle.frag
@@ -1,4 +1,5 @@
-#version 330
+#version 300 es
+precision mediump float;
in vec4 v_Color;
diff --git a/glow/src/shader/triangle.vert b/glow/src/shader/triangle.vert
index 5723436..e1efa59 100644
--- a/glow/src/shader/triangle.vert
+++ b/glow/src/shader/triangle.vert
@@ -1,4 +1,5 @@
-#version 330
+#version 300 es
+precision mediump float;
uniform mat4 u_Transform;
diff --git a/graphics/Cargo.toml b/graphics/Cargo.toml
index 8e078d7..9a1e912 100644
--- a/graphics/Cargo.toml
+++ b/graphics/Cargo.toml
@@ -29,7 +29,7 @@ version = "0.15"
optional = true
[dependencies.font-kit]
-version = "0.6"
+version = "0.9"
optional = true
[package.metadata.docs.rs]
Correction: it really should be precision highp float; for compatibility.
A temporary workaround for GLSL ES issue
@w23, awesome, thank you very much for looking into this!
@hecrj, any ideas on why Vulkan version does not work?
The UI window is shown, but not a single frame is rendered. Eventually the app crashes with the message:
thread 'main' panicked at 'Next frame: TimeOut', /home/pi/work/iced/wgpu/src/window/compositor.rs:110:21
I've updated vulkan drivers and standard demos like gears are working perfectly. Even complicated scenes like this are reportedly working. So I doubt that the issue is with the drivers themselves. How can I help to debug the issue?
@0x7CFE It'd help if you could try the wgpu examples.
@0x7CFE It'd help if you could try the
wgpuexamples.
In the meantime I contacted wgpu developers on their Matrix channel and we discussed the situation. Wgpu examples all fail in one way or another. They also suggested me to try out the ash library. After some hacks and tweaks I was able to make triangle and texture examples work there. But something more complex still doesn't work. After examining the example output, wgpu developers said that the driver looks half finished and all issues are probably because of that. Indeed, the driver is very much work in progress, but the pace makes me optimistic.
Still, I think that implementing image and svg support for glow backend is probably the fastest way to make iced work on Raspberry Pi 4.
Here's the issue related to a swap chain timeout error that's triggered by the Vulkan backend: https://gitlab.freedesktop.org/apinheiro/mesa/-/issues/8
Looks like the v3dv authors do not quite understand why that happens. Unfortunately, that probably means that they would not investigate more before sorting out other issues and making the driver conformant. So far, nothing had changed regarding the issue :(
Good news everyone! I was finally able to run some iced examples on Raspberry Pi 4 using Igalia v3dv driver and it worked! :tada:
Igalia v3dv driver is now approaching its 1.0 and authors are working on Vulkan conformance tests, so core functionality is already there. Hopefully we would have real Vulkan support soon on RPi4.
Still, current performance is quite low and there are a lot of rendering artifacts.
Most helpful comment
Good news everyone! I was finally able to run some
icedexamples on Raspberry Pi 4 using Igalia v3dv driver and it worked! :tada:Igalia v3dv driver is now approaching its 1.0 and authors are working on Vulkan conformance tests, so core functionality is already there. Hopefully we would have real Vulkan support soon on RPi4.