gl4es and SFML Segmentation fault
I'm trying to get SFML working through gl4es on the Raspberry PI, but I'm getting al ot of errors like this below:
LIBGL: Stacktrace: 2
/usr/local/lib/libGL.so.1(+0x10cea0)[0x76ec7ea0]
/lib/arm-linux-gnueabihf/libc.so.6(__default_sa_restorer+0x0)[0x769aa6b0]
Segmentation fault
Would you please guide mi in the right direction as this error is not descriptive enough to even try to investigate.
I've narrowed it down to the GL_MODELVIEW, weird... Here is the console output from the glCheck function and the error
- glDisable(GL_CULL_FACE)
- glDisable(GL_DEPTH_TEST)
- glEnable(GL_BLEND)
- glMatrixMode(GL_MODELVIEW)
- glLoadIdentity()
- glEnableClientState(GL_VERTEX_ARRAY)
- glEnableClientState(GL_COLOR_ARRAY)
- glEnableClientState(GL_TEXTURE_COORD_ARRAY)
- glBlendFunc( factorToGlConstant(mode.colorSrcFactor), factorToGlConstant(mode.colorDstFactor))
- glBindTexture(GL_TEXTURE_2D, 0)
- glMatrixMode(GL_TEXTURE)
- glLoadIdentity()
- glMatrixMode(GL_MODELVIEW)
LIBGL: Stacktrace: 2
/usr/local/lib/libGL.so.1(+0x10cea0)[0x76e4fea0]
/lib/arm-linux-gnueabihf/libc.so.6(__default_sa_restorer+0x0)[0x769326b0]
Segmentation fault
Can you try to run through GDB and have a backtrace of the crash?
I assume you are using GLES2 backend?
- glLoadIdentity()
- glMatrixMode(GL_MODELVIEW)
Thread 1 "sfmlgl" received signal SIGSEGV, Segmentation fault.
0x00000000 in ?? ()
(gdb) kill
Yes, My app is properly reporting context version as:
Version : OpenGL ES 2.0
Vendor : Broadcom
Renderer : VideoCore IV HW
Shader : OpenGL ES GLSL ES 1.00
I'm sorry, here is the backtrace:
#0 0x00000000 in ?? ()
#1 0x76d9b194 in sf::Shader::bind (shader=0x0) at /home/pi/dev/sfml-pi/src/SFML/Graphics/Shader.cpp:768
#2 0x76d978a8 in sf::RenderTarget::applyShader (this=0x7efff1c0, shader=0x0)
at /home/pi/dev/sfml-pi/src/SFML/Graphics/RenderTarget.cpp:660
#3 0x76d97048 in sf::RenderTarget::resetGLStates (this=0x7efff1c0)
at /home/pi/dev/sfml-pi/src/SFML/Graphics/RenderTarget.cpp:536
#4 0x76d978f0 in sf::RenderTarget::setupDraw (this=0x7efff1c0, useVertexCache=false, states=...)
at /home/pi/dev/sfml-pi/src/SFML/Graphics/RenderTarget.cpp:670
#5 0x76d95f5c in sf::RenderTarget::draw (this=0x7efff1c0, vertices=0x480e8, vertexCount=6, type=sf::TriangleFan,
states=...) at /home/pi/dev/sfml-pi/src/SFML/Graphics/RenderTarget.cpp:285
#6 0x76db1738 in sf::VertexArray::draw (this=0x7efff148, target=..., states=...)
at /home/pi/dev/sfml-pi/src/SFML/Graphics/VertexArray.cpp:147
#7 0x76d95d78 in sf::RenderTarget::draw (this=0x7efff1c0, drawable=..., states=...)
at /home/pi/dev/sfml-pi/src/SFML/Graphics/RenderTarget.cpp:247
#8 0x76dabad0 in sf::Shape::draw (this=0x7efff07c, target=..., states=...)
at /home/pi/dev/sfml-pi/src/SFML/Graphics/Shape.cpp:220
#9 0x76d95d78 in sf::RenderTarget::draw (this=0x7efff1c0, drawable=..., states=...)
at /home/pi/dev/sfml-pi/src/SFML/Graphics/RenderTarget.cpp:247
#10 0x00011d20 in main () at test/sfmlgl.cpp:113
I think there is an issue with the GL context creation. In line 36 of src/glx/glx.c can you rmove the commant, so there wil be trace of the GLX initialization.
I create my own context as I mentioned before. I run SFML in Xless environment so I use Dispmanx and Egl and just create a dummy RenderWindow Class so I can draw on my window. I've skipped all context and window related functions in SFML.
Shall I expect something in the console after uncommenting the debug? I do not see anything extra. Maybe because I do not call any context related Opengl functions after creating the context with the egl? What I get is a window, I can clear the screen using SFML window.clear(), but as soon as I try to draw something with window.draw(shape) I get this error.
Ah yes, sorry, now I remember.
Did you create an GLES2 context (and not an GLES1.1)?
Also, how do you do the swap of Context, using glXSwapBuffer or your own?
Can you copy/paste the GL4ES Initialization printf that you should have when launching the SFML app.
Yes, the context is GLES 2.0 and to swap I call
eglFlushBRCM();
eglSwapBuffers(display, surface);
Ok.
I guess you will miss some "Flush" in GL4ES Side too. Look in src/gl/gl.c, in the end of the file, the #ifdef AMIGAOS4 part. You will need something similar.
But that probably wont fix the issue you have for now. Can you copy/paste the printf of gl4es initialize (all the "LIBGL:..." lines)
LIBGL: Initialising gl4es
LIBGL: v1.1.1 built on Jan 24 2019 18:50:44
LIBGL: Using GLES 2.0 backend
LIBGL: loaded: libbcm_host.so
LIBGL: loaded: libvcos.so
LIBGL: loaded: libbrcmGLESv2.so
[New Thread 0x7646a440 (LWP 969)]
[New Thread 0x75aff440 (LWP 970)]
[New Thread 0x752ff440 (LWP 971)]
[New Thread 0x74aff440 (LWP 972)]
LIBGL: Hardware test disabled, nothing activated...
LIBGL: Targeting OpenGL 2.0
LIBGL: Forcing NPOT support by disabling MIPMAP support for NPOT textures
LIBGL: Current folder is:/home/pi/dev/sfml
Ah yes, not much here.
I have just pushed a commit to export 3 new functions. You will need to declare them yourself as
extern void GetHardwareExtensions(int notest);
extern void gl4es_pre_swap()
extern void gl4es_post_swap()
Now, after you have created your GLES2 context, call GetHardwareExtensions(0); and call the gl4es_pres_swap() and gl4es_post_swap() before and after doing the Swap.
Not sure it will fix the crash, but that should help.
Thanks, I'll try.
Nothing's changed unfortunately. It's still crashing on setting GL_MODELVIEW matrix
I think it's trying to do GLES1.1 stuff. Not sure why because LIBGL: shows it's using GLES2. But there is probably some varaible not correctly initialized somewhere.
If you look at gl4es_glMatrixMode(...) line 93 of src/gl/matrix.c you'll see it doesn't do much, but call in the gles_glMatrixMode(...) line 109. This is in fact a function pointer that is setup'd by the line before LOAD_GLES_FPE(...) that is a macro that either load the GLES function in case of GLES1.1 or the "FPE" version (i.e.: Fixed Pipeline Emulator) that is defined in src/gl/fpe.c and that is empty (because there is no Matrix mode in GLES2).
The macro is defined line 88 of src/gl/loader.h and use the fpe version if hardext.esversion!=1. All seems correct. I need to think a bit more...
Mmmm
That hardext.esversion is initialized with globals4es.es that in turn take the DEFAULT_ES unless if forced on command line (with "LIBGL_ES=2").
That DEFAULT_ES macro is supposed to be set in the CMakeList, but maybe this is not working and the default of "1" is forced with the line 33 of src/gl/init.c...
I'll change the default to 2 for a start.
I'm pasting the init log after adding that extern call to GetHardwareExtensions() Just in case
LIBGL: Initialising gl4es
LIBGL: v1.1.1 built on Jan 24 2019 23:08:30
LIBGL: Using GLES 2.0 backend
LIBGL: loaded: libbcm_host.so
LIBGL: loaded: libvcos.so
LIBGL: loaded: libbrcmGLESv2.so
LIBGL: Hardware test disabled, nothing activated...
LIBGL: Targeting OpenGL 2.0
LIBGL: Forcing NPOT support by disabling MIPMAP support for NPOT textures
LIBGL: Current folder is:/home/pi/dev/dg
LIBGL: Hardware test on current Context...
LIBGL: Hardware Full NPOT detected and used
LIBGL: FBO are in core, and so used
LIBGL: PointSprite are in core, and so used
LIBGL: CubeMap are in core, and so used
LIBGL: BlendColor is in core, and so used
LIBGL: Blend Substract is in core, and so used
LIBGL: Blend Function and Equation Separation is in core, and so used
LIBGL: Texture Mirrored Repeat is in core, and so used
LIBGL: Extension GL_OES_mapbuffer detected
LIBGL: Extension GL_OES_depth24 detected and used
LIBGL: Extension GL_OES_rgb8_rgba8 detected and used
LIBGL: Extension GL_EXT_texture_format_BGRA8888 detected and used
LIBGL: high precision float in fragment shader available and used
LIBGL: Max vertex attrib: 8
LIBGL: Max texture size: 2048
LIBGL: Max Varying Vector: 8
LIBGL: Texture Units: 4(8), Max lights: 8, Max planes: 6
LIBGL: Hardware vendor is Broadcom
Ok, I found a mistake, SFML's glCheck function was first executing the gl function and was not throwing it to the console if it failed. so I mistakenly thought it was glMatrixMode() crashing, but it actually was GLEXT_glUseProgramObject(0)
Here is the proper log of gl functions (there are also some other errors, but not causing the crash)
LIBGL: Initialising gl4es
LIBGL: v1.1.1 built on Jan 24 2019 23:08:30
LIBGL: Using GLES 2.0 backend
LIBGL: loaded: libbcm_host.so
LIBGL: loaded: libvcos.so
LIBGL: loaded: libbrcmGLESv2.so
LIBGL: Hardware test disabled, nothing activated...
LIBGL: Targeting OpenGL 2.0
LIBGL: Forcing NPOT support by disabling MIPMAP support for NPOT textures
LIBGL: Current folder is:/home/pi/dev/dg
EglContext::createContext - SKIP
Failed to get vendor ID of joystick /dev/input/js0
Failed to get product ID of joystick /dev/input/js0
EglContext::createContext - SKIP
EglContext::createSurface - SKIP
- glGetIntegerv(GLEXT_GL_FRAMEBUFFER_BINDING, reinterpret_cast<GLint*>(&m_defaultFrameBuffer))
LIBGL: Hardware test on current Context...
LIBGL: Hardware Full NPOT detected and used
LIBGL: FBO are in core, and so used
LIBGL: PointSprite are in core, and so used
LIBGL: CubeMap are in core, and so used
LIBGL: BlendColor is in core, and so used
LIBGL: Blend Substract is in core, and so used
LIBGL: Blend Function and Equation Separation is in core, and so used
LIBGL: Texture Mirrored Repeat is in core, and so used
LIBGL: Extension GL_OES_mapbuffer detected
LIBGL: Extension GL_OES_depth24 detected and used
LIBGL: Extension GL_OES_rgb8_rgba8 detected and used
LIBGL: Extension GL_EXT_texture_format_BGRA8888 detected and used
LIBGL: high precision float in fragment shader available and used
LIBGL: Max vertex attrib: 8
LIBGL: Max texture size: 2048
LIBGL: Max Varying Vector: 8
LIBGL: Texture Units: 4(8), Max lights: 8, Max planes: 6
LIBGL: Hardware vendor is Broadcom
- glBindTexture(GL_TEXTURE_2D, 0)
- glMatrixMode(GL_TEXTURE)
- glLoadIdentity()
- glMatrixMode(GL_MODELVIEW)
- glClearColor(color.r / 255.f, color.g / 255.f, color.b / 255.f, color.a / 255.f)
- glClear(GL_COLOR_BUFFER_BIT)
- glDisable(GL_CULL_FACE)
- glDisable(GL_LIGHTING)
- glDisable(GL_DEPTH_TEST)
glGetError 0x500
An internal OpenGL call failed in RenderTarget.cpp(521).
Expression:
glDisable(GL_DEPTH_TEST)
Error description:
GL_INVALID_ENUM
An unacceptable value has been specified for an enumerated argument.
- glDisable(GL_ALPHA_TEST)
- glEnable(GL_TEXTURE_2D)
glGetError 0x500
An internal OpenGL call failed in RenderTarget.cpp(523).
Expression:
glEnable(GL_TEXTURE_2D)
Error description:
GL_INVALID_ENUM
An unacceptable value has been specified for an enumerated argument.
- glEnable(GL_BLEND)
glGetError 0x500
An internal OpenGL call failed in RenderTarget.cpp(524).
Expression:
glEnable(GL_BLEND)
Error description:
GL_INVALID_ENUM
An unacceptable value has been specified for an enumerated argument.
- glMatrixMode(GL_MODELVIEW)
- glLoadIdentity()
- glEnableClientState(GL_VERTEX_ARRAY)
- glEnableClientState(GL_COLOR_ARRAY)
- glEnableClientState(GL_TEXTURE_COORD_ARRAY)
- glBlendFunc( factorToGlConstant(mode.colorSrcFactor), factorToGlConstant(mode.colorDstFactor))
- glBindTexture(GL_TEXTURE_2D, 0)
- glMatrixMode(GL_TEXTURE)
- glLoadIdentity()
- glMatrixMode(GL_MODELVIEW)
- GLEXT_glUseProgramObject(0)
Segmentation fault
I've somehow managed to make it not to crash, please don't ask why :)
https://pastebin.com/i6dd9C2u
I just clear the screen in red, draw a pink rectangle, then clear the screen in gray and draw the same rectangle in a loop every 1s. I do not see the rectangle unfortunately, only the background colour is changing.
I'm also not entirely sure where this glBindTexture is coming from, as I'm just drawing a rectangle.
Oh yeah I remember now why. I skipped shader binding because it was crashing on GLEXT_glUseProgramObject(0)
Oh, but glUseProgramObject(...) is part of "GL_ARB_shader_object" extension. It should be supported, but maybe the way it grab extensions make it fail? Run it with "LIBGL_SILENTSTUB=0" env. var. to see all the glXGetProcAddress that fail.
Also, I see on the log that glEnable(GL_TEXTURE_2D); provoke an error 0x500. That clearly means that gl4es is running in "GLES1.1" mode and not GLES2 as it should.
Did you use the latest sources, with the modified DEFAULT_ES in src/glx/hardext.c ?
Also, are you building with cmake or some custom Makefile?
I've added a printf just after the DEFAULT_ES definition as a sanity check and it's printing 2.
I call cmake . -DBCMHOST=1 -DNOEGL=1 -DNOX11=1 and then make
Then I build my project with the following bash script:
#!/bin/sh
export SFML_DEBUG=1
cd ..
cd _build/sfml-pi
cmake ../../sfml-pi -DSFML_RPI=1 -DCMAKE_BUILD_TYPE=debug -DEGL_INCLUDE_DIR=/opt/vc/include -DEGL_LIBRARY=/opt/vc/lib/libbrcmEGL.so -DGLES_INCLUDE_DIR=/opt/vc/include -DGLES_LIBRARY=/opt/vc/lib/libbrcmGLESv2.so -DDG_INCLUDE_DIR=extlibs/headers/dg -DDG_LIBRARY=/usr/local/lib/libdg.so
sudo make -j4 install
sudo ldconfig
cd ../..
export LIBGL_SILENTSTUB=0
export LD_LIBRARY_PATH=/home/pi/dev/gl4es/lib
cd dg
rm -r -f sfmlgl
g++ test/sfmlgl.cpp -g -DSFML_DEBUG=1 -Iinclude/ -I/opt/vc/include/ -L/opt/vc/lib/ -L/usr/local/lib -lbrcmEGL -lbrcmGLESv2 -ldgp -l:libGL.so.1 -lsfml-graphics-d -lsfml-window-d -lsfml-system-d -o sfmlgl
#gdb -ex run ./sfmlgl
./sfmlgl
Mmm, are you sure SFML is calling gl4es and not libbcrmGLESv2.so ?
Now when you said it, I do not. I need it for my window/context creation. How can I check it?
you were right :) now the version is showing finally your wrapper
Version : 2.0 gl4es wrapper 1.1.1
Vendor : ptitSeb
Renderer : GL4ES wrapper
Shader : 1.10 via gl4es
Unfortunately still no shapes are being drawn, I'll try to "unskip" one by one those problematic parts of sfml and I'll see how it goes. At least I'm getting somewhere, thanks for the lead.
Ok, that's some progress :)
Unskip the code yes, it should works now.
It was a matter of priorities of loading libraries
-l:libGL.so.1 -lbrcmEGL -lbrcmGLESv2 solved the errors. I'll give you a report soon how it goes.
I've managed to succesfully uncomment most of the functions except resetGLstates()which crashes on calling glCheck(GLEXT_glClientActiveTexture(GLEXT_GL_TEXTURE0)); which translates to glClientActiveTextureARB(GL_TEXTURE0_ARB))
if (GLEXT_multitexture)
{
glCheck(GLEXT_glClientActiveTexture(GLEXT_GL_TEXTURE0));
glCheck(GLEXT_glActiveTexture(GLEXT_GL_TEXTURE0));
}
It actually crashes on both calls. When commented the next break point is on constructing blend separates glBlendFuncSeparateEXT
and the usual glUseProgramObjectARB(0)
glClientActiveTexture is defined in line 2407 of src/gl/texture.c. My guess is that it load the copy from GLES2 for some reason.
I suggest you try to adapt your code for creating the EGL context and swp the buffer directly in gl4es, and stop linking with EGL and GLESv2 (and use the LOAD_EGL) stuff provided by gl4es.
I can probably help and put thoses functions in the rpi specific file in src/glx folder, with some Interface API to be decided.