Skip to content
This repository has been archived by the owner on Dec 2, 2019. It is now read-only.

[request] Add Raspberry Pi accelerated Open GL output (8$) #748

Closed
DeXP opened this issue Sep 27, 2018 · 17 comments
Closed

[request] Add Raspberry Pi accelerated Open GL output (8$) #748

DeXP opened this issue Sep 27, 2018 · 17 comments

Comments

@DeXP
Copy link
Contributor

DeXP commented Sep 27, 2018

sdl_opengles2 already supports Open GL ES 2 and Web GL. It can be compiled on Raspberry Pi (Raspbian Linux), but gives black square only. Please fix it to have an ability to have accelerated Open GL ES output on Raspberry Pi.

8$ bounty

@DeXP DeXP changed the title [request] Add Raspberry Pi accelerated Open GL output [request] Add Raspberry Pi accelerated Open GL output (8$) Sep 27, 2018
@alvaropg
Copy link

I have not experimented problems with OpenGL ES 2 in a Raspberry Pi 3. Just make sure that you compile against the Broadcom libraries in /opt (if you are using Raspbian). You can use pkg-config to ensure:

$ PKG_CONFIG_PATH=/opt/vc/lib/pkgconfig/ pkg-config --cflags bcm_host brcmglesv2

I hope it helps!

@DeXP
Copy link
Contributor Author

DeXP commented Sep 27, 2018

@alvaropg It've compiled SDL2 OpenGL ES 2 with the following command line:

$ cc main.c -std=c99 -pedantic -O2 -o bin/demo `PKG_CONFIG_PATH=/opt/vc/lib/pkgconfig/ pkg-config --cflags --libs bcm_host brcmglesv2` -lSDL2 -lm

ldd demo:

	linux-vdso.so.1 (0x7ee4f000)
	/usr/lib/arm-linux-gnueabihf/libarmmem.so (0x76faa000)
	libbrcmGLESv2.so => /opt/vc/lib/libbrcmGLESv2.so (0x76f6f000)
	libbcm_host.so => /opt/vc/lib/libbcm_host.so (0x76f48000)
	libvcos.so => /opt/vc/lib/libvcos.so (0x76f2e000)
	libvchiq_arm.so => /opt/vc/lib/libvchiq_arm.so (0x76f18000)
	libSDL2-2.0.so.0 => /usr/lib/arm-linux-gnueabihf/libSDL2-2.0.so.0 (0x76e0d000)
	libm.so.6 => /lib/arm-linux-gnueabihf/libm.so.6 (0x76d8e000)
	libpthread.so.0 => /lib/arm-linux-gnueabihf/libpthread.so.0 (0x76d65000)
	libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0x76c26000)
	libbrcmEGL.so => /opt/vc/lib/libbrcmEGL.so (0x76bed000)
	libdl.so.2 => /lib/arm-linux-gnueabihf/libdl.so.2 (0x76bda000)
	librt.so.1 => /lib/arm-linux-gnueabihf/librt.so.1 (0x76bc3000)
	libasound.so.2 => /usr/lib/arm-linux-gnueabihf/libasound.so.2 (0x76ad6000)
	libpulse-simple.so.0 => /usr/lib/arm-linux-gnueabihf/libpulse-simple.so.0 (0x76ac2000)
	libpulse.so.0 => /usr/lib/arm-linux-gnueabihf/libpulse.so.0 (0x76a6b000)
	libsndio.so.6.1 => /usr/lib/arm-linux-gnueabihf/libsndio.so.6.1 (0x76a4c000)
	libX11.so.6 => /usr/lib/arm-linux-gnueabihf/libX11.so.6 (0x76929000)
	libXext.so.6 => /usr/lib/arm-linux-gnueabihf/libXext.so.6 (0x7690a000)
	libXcursor.so.1 => /usr/lib/arm-linux-gnueabihf/libXcursor.so.1 (0x768f1000)
	libXinerama.so.1 => /usr/lib/arm-linux-gnueabihf/libXinerama.so.1 (0x768de000)
	libXi.so.6 => /usr/lib/arm-linux-gnueabihf/libXi.so.6 (0x768c0000)
	libXrandr.so.2 => /usr/lib/arm-linux-gnueabihf/libXrandr.so.2 (0x768a7000)
	libXss.so.1 => /usr/lib/arm-linux-gnueabihf/libXss.so.1 (0x7689d000)
	libXxf86vm.so.1 => /usr/lib/arm-linux-gnueabihf/libXxf86vm.so.1 (0x76888000)
	libwayland-egl.so.1 => /usr/lib/arm-linux-gnueabihf/libwayland-egl.so.1 (0x76876000)
	libwayland-client.so.0 => /usr/lib/arm-linux-gnueabihf/libwayland-client.so.0 (0x7685c000)
	libwayland-cursor.so.0 => /usr/lib/arm-linux-gnueabihf/libwayland-cursor.so.0 (0x76845000)
	libxkbcommon.so.0 => /usr/lib/arm-linux-gnueabihf/libxkbcommon.so.0 (0x767fc000)
	/lib/ld-linux-armhf.so.3 (0x76fc0000)
	libpulsecommon-10.0.so => /usr/lib/arm-linux-gnueabihf/pulseaudio/libpulsecommon-10.0.so (0x7677b000)
	libcap.so.2 => /lib/arm-linux-gnueabihf/libcap.so.2 (0x76766000)
	libdbus-1.so.3 => /lib/arm-linux-gnueabihf/libdbus-1.so.3 (0x76713000)
	libbsd.so.0 => /lib/arm-linux-gnueabihf/libbsd.so.0 (0x766ea000)
	libxcb.so.1 => /usr/lib/arm-linux-gnueabihf/libxcb.so.1 (0x766bb000)
	libXrender.so.1 => /usr/lib/arm-linux-gnueabihf/libXrender.so.1 (0x766a2000)
	libXfixes.so.3 => /usr/lib/arm-linux-gnueabihf/libXfixes.so.3 (0x7668d000)
	libffi.so.6 => /usr/lib/arm-linux-gnueabihf/libffi.so.6 (0x76675000)
	libX11-xcb.so.1 => /usr/lib/arm-linux-gnueabihf/libX11-xcb.so.1 (0x76663000)
	libICE.so.6 => /usr/lib/arm-linux-gnueabihf/libICE.so.6 (0x7663d000)
	libSM.so.6 => /usr/lib/arm-linux-gnueabihf/libSM.so.6 (0x76626000)
	libXtst.so.6 => /usr/lib/arm-linux-gnueabihf/libXtst.so.6 (0x76611000)
	libsystemd.so.0 => /lib/arm-linux-gnueabihf/libsystemd.so.0 (0x76597000)
	libwrap.so.0 => /lib/arm-linux-gnueabihf/libwrap.so.0 (0x7657f000)
	libsndfile.so.1 => /usr/lib/arm-linux-gnueabihf/libsndfile.so.1 (0x76504000)
	libasyncns.so.0 => /usr/lib/arm-linux-gnueabihf/libasyncns.so.0 (0x764ef000)
	libXau.so.6 => /usr/lib/arm-linux-gnueabihf/libXau.so.6 (0x764e4000)
	libXdmcp.so.6 => /usr/lib/arm-linux-gnueabihf/libXdmcp.so.6 (0x764cf000)
	libgcc_s.so.1 => /lib/arm-linux-gnueabihf/libgcc_s.so.1 (0x764a2000)
	libuuid.so.1 => /lib/arm-linux-gnueabihf/libuuid.so.1 (0x7648e000)
	libselinux.so.1 => /lib/arm-linux-gnueabihf/libselinux.so.1 (0x7645b000)
	liblzma.so.5 => /lib/arm-linux-gnueabihf/liblzma.so.5 (0x7642a000)
	liblz4.so.1 => /usr/lib/arm-linux-gnueabihf/liblz4.so.1 (0x76409000)
	libgcrypt.so.20 => /lib/arm-linux-gnueabihf/libgcrypt.so.20 (0x76338000)
	libnsl.so.1 => /lib/arm-linux-gnueabihf/libnsl.so.1 (0x76314000)
	libFLAC.so.8 => /usr/lib/arm-linux-gnueabihf/libFLAC.so.8 (0x762b5000)
	libogg.so.0 => /usr/lib/arm-linux-gnueabihf/libogg.so.0 (0x762a7000)
	libvorbis.so.0 => /usr/lib/arm-linux-gnueabihf/libvorbis.so.0 (0x76270000)
	libvorbisenc.so.2 => /usr/lib/arm-linux-gnueabihf/libvorbisenc.so.2 (0x761de000)
	libresolv.so.2 => /lib/arm-linux-gnueabihf/libresolv.so.2 (0x761b9000)
	libpcre.so.3 => /lib/arm-linux-gnueabihf/libpcre.so.3 (0x76140000)
	libgpg-error.so.0 => /lib/arm-linux-gnueabihf/libgpg-error.so.0 (0x76120000)

And running the app:

demo: nuklear_sdl_gles2.h:116: nk_sdl_device_create: Assertion `status == GL_TRUE' failed.

The lines 115-116 are:

    glGetShaderiv(dev->vert_shdr, GL_COMPILE_STATUS, &status);
    assert(status == GL_TRUE);

So, the application is not able to compile the shaders. Do you have the same issue? Or demo just works for you?

# uname -a
Linux raspberrypi 4.14.70-v7+ #1144 SMP Tue Sep 18 17:34:46 BST 2018 armv7l GNU/Linux

@ghost
Copy link

ghost commented Oct 5, 2018

@DeXP That is very strange. I did not have the same issue, and I was able to get the demo to work on my Raspberry Pi Zero. But I also noticed that the GLES2 demo does not have full error reporting. I added error reporting in a branch so please try that and see if it mentions what problems it was having with the shader compilation.

@DeXP
Copy link
Contributor Author

DeXP commented Oct 6, 2018

@cyclopsian, I have Raspberry Pi 3, most updated raspbian:

$ ./bin/demo
[GL]: failed to compile vertex shader: 
demo: nuklear_sdl_gles2.h:125: nk_sdl_device_create: Assertion `status == GL_TRUE' failed.
Aborted

@ghost
Copy link

ghost commented Oct 7, 2018

@DeXP That is strange, the error message is coming up blank. You may want to try and see if you can run some other OpenGL programs such as the hello_triangle one in the demo directory (see instructions here). If those work then it's possible the issue is with your version of SDL.

@DeXP
Copy link
Contributor Author

DeXP commented Oct 9, 2018

@cyclopsian Yep, hello_triangle just works: shows spinnig textured cube, no additional info in the console. I've installed SD2 development package form apt, official repos (just typed something like aptitude install libsdl2-dev in the console). Could it be wrong somehow?

@ghost
Copy link

ghost commented Oct 13, 2018

@DeXP Upon inspection it looks like the version of SDL2 in the raspbian repo is not properly compiled with Raspberry Pi Support. I was able to get it to work, but I compiled my own SDL2. If you do that it should automatically build the RPI video driver.

@DeXP
Copy link
Contributor Author

DeXP commented Oct 28, 2018

@cyclopsian I did it, mostly according to https://choccyhobnob.com/raspberry-pi/sdl2-2-0-8-on-raspberry-pi/ :
$ ./configure --disable-pulseaudio --disable-esd --disable-video-mir --disable-video-wayland --host=arm-raspberry-linux-gnueabihf

SDL2 Configure Summary:
Building Shared Libraries
Building Static Libraries
Enabled modules : atomic audio video render events joystick haptic sensor power filesystem threads timers file loadso cpuinfo assembly
Assembly Math   :
Audio drivers   : disk dummy oss alsa(dynamic) nas(dynamic)
Video drivers   : dummy rpi x11(dynamic) opengl opengl_es1 opengl_es2 vulkan
X11 libraries   : xcursor xdbe xinerama xinput2 xinput2_multitouch xrandr xscrnsaver xshape xvidmode
Input drivers   : linuxev linuxkd
Using libsamplerate : NO
Using libudev       : YES
Using dbus          : NO
Using ime           : YES
Using ibus          : NO
Using fcitx         : NO

Then compiled demo with usage of SDL2 from /usr/local/lib:

$ cc main.c -std=c99 -pedantic -O2 -o bin/demo `PKG_CONFIG_PATH=/opt/vc/lib/pkgconfig/ pkg-config --cflags --libs bcm_host brcmglesv2` -L/usr/local/lib -lSDL2 -lm -Wl,-rpath=/usr/local/lib
$ ldd bin/demo
	linux-vdso.so.1 (0x7ed41000)
	/usr/lib/arm-linux-gnueabihf/libarmmem.so (0x76ed9000)
	libbrcmGLESv2.so => /opt/vc/lib/libbrcmGLESv2.so (0x76e9c000)
	libbcm_host.so => /opt/vc/lib/libbcm_host.so (0x76e75000)
	libvcos.so => /opt/vc/lib/libvcos.so (0x76e5b000)
	libvchiq_arm.so => /opt/vc/lib/libvchiq_arm.so (0x76e45000)
	libSDL2-2.0.so.0 => /usr/local/lib/libSDL2-2.0.so.0 (0x76d2d000)
	libm.so.6 => /lib/arm-linux-gnueabihf/libm.so.6 (0x76cae000)
	libpthread.so.0 => /lib/arm-linux-gnueabihf/libpthread.so.0 (0x76c85000)
	libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0x76b46000)
	libbrcmEGL.so => /opt/vc/lib/libbrcmEGL.so (0x76b0d000)
	libdl.so.2 => /lib/arm-linux-gnueabihf/libdl.so.2 (0x76afa000)
	librt.so.1 => /lib/arm-linux-gnueabihf/librt.so.1 (0x76ae3000)
	/lib/ld-linux-armhf.so.3 (0x76eef000)

The result is the same:

$ ./demo
[GL]: failed to compile vertex shader: 
demo: nuklear_sdl_gles2.h:125: nk_sdl_device_create: Assertion `status == GL_TRUE' failed.
Aborted

@DeXP
Copy link
Contributor Author

DeXP commented Oct 28, 2018

I get it working, finally! Yep, the problem was in a SDL's videodriver. And yes, default version in a Raspbian's repo do not supports rpi driver. So SDL have to be compiled.

However, default x11 driver is not working for accelerated Open GL ES2 too. There are two ways to solve this:

  1. Compile SDL without X11 support: --disable-video-x11 configure option.

  2. Set SDL_VIDEODRIVER environment variable before each run to rpi: export SDL_VIDEODRIVER=rpi

@cyclopsian you gived me the key to solve the issue. Can you claim fixed the issue on BountySource? Otherwise I will move the funds to Mac Request.

@ghost
Copy link

ghost commented Oct 28, 2018

@DeXP Thanks so much, glad to hear it worked! I started a solution on BountySource, I believe that means you can close the issue now and I will be assigned the bounty.

@DeXP
Copy link
Contributor Author

DeXP commented Oct 28, 2018

Yep, solved

@DeXP DeXP closed this as completed Oct 28, 2018
@ktb92677
Copy link

ktb92677 commented Aug 1, 2019

Hey guys, sorry to revive a dead topic like this but does anyone here know why my instance is fairly laggy? I am measuring it takes around 36ms per render cycle to show on the screen. This is worse than 30fps. Any help would be greatly appreciated!

@ktb92677
Copy link

ktb92677 commented Aug 1, 2019

FYI I have narrowed down the problematic lines. They are as follows:

glBufferData(GL_ARRAY_BUFFER, max_vertex_buffer, NULL, GL_STREAM_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, max_element_buffer, NULL, GL_STREAM_DRAW);

Those two lines take 10ms and 24ms respectively. If anyone who knows a lot of Opengles2 it would be great if you could chime in as I really want to bring the FPS closer to 60 if possible.

@ghost
Copy link

ghost commented Aug 2, 2019

@ktb92677 If you want to know more about the topic, emscripten has some docs on optimizing GLES (WebGL is an implementation of the GLES API). Particularly this section which is relevant: https://emscripten.org/docs/optimizing/Optimizing-WebGL.html#gpu-driver-friendly-memory-access-behavior

  • Prefer calling glBufferSubData() and glTexSubImage2D/3D() when updating buffer texture data, even when the whole contents of the texture or the buffer changes. If the size of a buffer would shrink, do not eagerly re-create the storage, but simply ignore the excess size.
  • For dynamic vertex buffer data, consider double- or even triple-buffering VBOs each frame, to avoid uploading a VBO that is still in use. Prefer using GL_DYNAMIC vertex buffers over GL_STREAM.

This may or may not help depending on the device & driver you're using.

@ktb92677
Copy link

For anyone else stumbling across this sometime in the future here was the solution:

Adjusting these lines:

#define MAX_VERTEX_MEMORY 512 * 1024
#define MAX_ELEMENT_MEMORY 128 * 1024

To this:

#define MAX_VERTEX_MEMORY 128 * 1024
#define MAX_ELEMENT_MEMORY 32 * 1024

Solved the performance issues and now the FPS is sitting comfortably at 60FPS.

@ktb92677
Copy link

@cyclopsian any chance you can help me with this issue:

What I would like to do is within the same instance of the program fully initialize and delete an SDL+GLES instance twice within the run time of the same program. I have adapted the code base posted above to simply call the contents of main() twice with a slight pause in between. However on the second run the following assert fails:

glShaderSource(dev->vert_shdr, 1, &vertex_shader, 0);
    glShaderSource(dev->frag_shdr, 1, &fragment_shader, 0);
    glCompileShader(dev->vert_shdr);
    glCompileShader(dev->frag_shdr);
    glGetShaderiv(dev->vert_shdr, GL_COMPILE_STATUS, &status);
    assert(status == GL_TRUE);

I used the following code to print the error:

if (status != GL_TRUE) {
                GLint maxLength;
        glGetShaderiv(dev->vert_shdr, GL_INFO_LOG_LENGTH, &maxLength);

                GLchar infoLog[maxLength];

                memset(&infoLog, 0, maxLength);

                glGetShaderInfoLog(dev->vert_shdr, maxLength, &maxLength, infoLog);

                printf("error: %s\n", infoLog);
        }

maxLength is zero after glGetShaderiv returns. Also if I manually set maxLength to a larger number glGetShaderInfoLog doesn't even touch infoLog. It leaves it completely empty. Any help would be greatly appreciated

@dumblob
Copy link
Contributor

dumblob commented Aug 14, 2019

#define MAX_VERTEX_MEMORY 128 * 1024
#define MAX_ELEMENT_MEMORY 32 * 1024

I think this deserves PR - will you make one?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants