mosra / magnum

Lightweight and modular C++11 graphics middleware for games and data visualization
https://magnum.graphics/
Other
4.74k stars 439 forks source link

Segmentation fault with nullptr instruction in AbstractShaderProgram at Cross-Compile #635

Open Desperado17 opened 5 months ago

Desperado17 commented 5 months ago

With magnum and corrade 2020.06

Greetings,

when cross-compiling magnum/corrade for GLES and Aarch64, the program suddenly runs into a nullptr instruction:

0 0x0000000000000000 in ?? ()

1 0x0000007ff7c04efc in Magnum::GL::AbstractShaderProgram::setUniform (this=this@entry=0x7fffff87d8, location=2, values=...) at ext-corrade-dev/1/workspace/usr/include/Corrade/Containers/Pointer.h:217

2 0x0000007ff7ae9630 in Magnum::GL::AbstractShaderProgram::setUniform (value=, location=, this=0x7fffff87d8)

at ext-corrade-dev/1/workspace/usr/include/Corrade/Containers/ArrayView.h:195

3 Magnum::Shaders::Flat<2u>::Flat (this=0x7fffff87d8, flags=...) at ext-magnum/1/workspace/ext.magnum/src/Magnum/Shaders/Flat.cpp:140

Flat.cpp 136:

ifndef MAGNUM_TARGET_GLES

if(!GL::Context::current().isExtensionSupported<GL::Extensions::ARB::shading_language_420pack>(version))
#endif
{
    if(flags & Flag::Textured) setUniform(uniformLocation("textureData"), TextureUnit);   <---
}

AbstractShaderProgram.cpp:640: void AbstractShaderProgram::setUniform(const Int location, const Containers::ArrayView values) { (this->*Context::current().state().shaderProgram->uniform1ivImplementation)(location, values.size(), values); }

The error is 100% reproducible. Is it possible that uniform1ivImplementation is corrupted at some point?

Regards

mosra commented 5 months ago

Hello,

the backtrace is a bit confusing, it shows setUniform() being located in Pointer.h, but I assume that's due to some optimizations / inlining happening (-fno-omit-stack-pointer helps with that I think).

In general, such nasty null pointer access happens only when attempting to access GL functionality that isn't actually present in the driver. In this case it might be that GL_EXT_separate_shader_objects is advertised by the driver but the actual functionality is not, so eglGetProcAddress("glProgramUniform1ivEXT") returns nullptr, which is then crashed on here.

Can you post the engine startup log it prints to the console? It should show the GL version and driver it detected, and a list of opt-in extensions it found and uses. Based on that I should be better able to figure out what's going on and how to prevent this from happening.

Another possibility when this could happen would be with some multithreading going on and a GL context attempted to be used on a thread it wasn't created on, or with some particularly interesting shared + static library setup, but I don't think either of that is the case here.

Thank you!

(By the way, the 2020.06 tag is rather old -- unfortunately I didn't have the capacity to bring the roadmap to a releaseable state since then so there's no newer tagged version, but the master branch is kept always stable and can be relied on. So, feel free to update. I don't think that alone would fix the problem you're facing -- I don't remember encountering any library bug related to this problem -- but the library evolved and improved quite a bit since.)

Desperado17 commented 5 months ago

Ok, some more info:

It's a nullptr access to an uninitialized function pointer to an OpenGL function who as I can tell should be initialized here:

https://github.com/mosra/magnum/blob/6394c85c06a5eb67713763c7e471e0fef3160c41/src/MagnumExternal/OpenGL/GLES3/flextGLPlatform.cpp

The nullptr are for all the core functions. For example

flextGL.ProgramUniform1ui = reinterpret_cast<void(APIENTRY*)(GLuint, GLint, GLuint)>(loader.load("glProgramUniform1ui"));

yields a nullptr on my platform. As far as I can tell OpenGLFunctionLoader uses eglGetProcAddress

https://github.com/mosra/magnum/blob/6394c85c06a5eb67713763c7e471e0fef3160c41/src/Magnum/Platform/Implementation/OpenGLFunctionLoader.cpp#L67

This function returns nullptr for core functions on my platform.

mosra commented 5 months ago

Just to clarify -- the function will return nullptr for functions from extensions that are not supported by the driver. So if you have for example just a barebones ES 3.0 driver, almost all of these will be null. That's fine. The set of functions that should be available in GLES3 always is linked statically, and the engine "just" needs to ensure the null ones are not used by anything afterwards, which it usually does.

What I'm trying to get at is what's actually advertised as supported by the driver, which is shown in the startup log right after you run the application and before it crashes. Can you get me that? It'd be something like this and the list of extensions and workarounds is what I need:

Renderer: NVIDIA GeForce RTX 3050 Laptop GPU/PCIe/SSE2 by NVIDIA Corporation
OpenGL version: OpenGL ES 3.2 NVIDIA 535.113.01
Using optional features:
    GL_EXT_texture_filter_anisotropic
    GL_EXT_robustness
    ...

Thank you!

Desperado17 commented 5 months ago

I have to come back for the log tomorrow when I'm back at work. But some more info:

flextGL.ProgramUniform1ui = reinterpret_cast<void(APIENTRY*)(GLuint, GLint, GLuint)>(loader.load("glProgramUniform1ui"));

yields nullptr but

flextGL.ProgramUniform1uiEXT = reinterpret_cast<void(APIENTRY*)(GLuint, GLint, GLuint)>(loader.load("glProgramUniform1uiEXT"));

returns a fully working pointer that, according to gdb, points to the very available glProgramUniform1ui .

The system with this driver supports at least GLES 3.1, I know that from other applications.

As far as I know in EGL 1.4 eglGetProcAddress does not guarantee pointers for core functions. https://registry.khronos.org/EGL/extensions/KHR/EGL_KHR_get_all_proc_addresses.txt "eglGetProcAddress is currently defined to not support the querying of non-extension EGL or client API functions."

mosra commented 5 months ago

Awesome, that's good to know, so there's at least some possible path forward.

As far as I know in EGL 1.4 eglGetProcAddress does not guarantee pointers for core functions.

Oh, that's not great. I hope I won't need to add a workaround with dlsym() or something :/ So far the eglGetProcAddress() approach worked for all drivers I had the chance to test in the past decade+. Though I have to admit it wasn't many of the interesting ones.

Looking forward to the log.

Desperado17 commented 5 months ago

Do I need to set special environment variables for the log or so?

My short-term solution is to try load the ext version of a function if the core version is not returned. Don't know if this can still yield nullptr access for some stuff, I'm not seeing check in the accessing functions.

Edit: In EGL 1.5 pointers for core should be guaranteed.

mosra commented 5 months ago

Do I need to set special environment variables for the log or so?

It's printed by default unless suppressed by some log redirection, so assuming a Linux box, it should be there always. On Android it's thrown into logcat, on Windows you'd have to build a console app to have the standard output visible.

My short-term solution is to try load the ext version of a function if the core version is not returned.

A quick patch to achieve what you need would be this:

diff --git a/src/Magnum/GL/Implementation/ShaderProgramState.cpp b/src/Magnum/GL/Implementation/ShaderProgramState.cpp
index 8a87a8b59..d49b45e95 100644
--- a/src/Magnum/GL/Implementation/ShaderProgramState.cpp
+++ b/src/Magnum/GL/Implementation/ShaderProgramState.cpp
@@ -93,7 +93,7 @@ ShaderProgramState::ShaderProgramState(Context& context, Containers::StaticArray
     #ifndef MAGNUM_TARGET_GLES
     if(context.isExtensionSupported<Extensions::ARB::separate_shader_objects>())
     #else
-    if(context.isVersionSupported(Version::GLES310))
+    if(false && context.isVersionSupported(Version::GLES310))
     #endif
     {
         #ifndef MAGNUM_TARGET_GLES

If we don't find any better solution, then I turn this into a driver-specific workaround that gets enabled automatically. But I hope we find something better :)

I'm not seeing check in the accessing functions.

There's none for perf reasons. For core functionality (like shaders, buffers, textures) it internally picks a variant that should be there, and for APIs that aren't guaranteed to be present (say, compute shaders), it's up to the application to do an extension / version check upfront.

Desperado17 commented 5 months ago

Hmm I cannot find your logging. Can you tell me which function call in magnum supposedly triggers it? I copied the weston output if that helps:

23:00:00.478 [Warn] [user] weston@tty1: [23:00:00.474] EGL version: 1.4 23:00:00.478 [Warn] [user] weston@tty1: [23:00:00.474] EGL vendor: Imagination Technologies 23:00:00.478 [Warn] [user] weston@tty1: [23:00:00.474] EGL client APIs: OpenGL_ES 23:00:00.478 [Warn] [user] weston@tty1: [23:00:00.474] EGL extensions: EGL_KHR_image EGL_KHR_image_base 23:00:00.478 [Warn] [user] weston@tty1: EGL_KHR_gl_texture_2D_image EGL_KHR_gl_texture_cubemap_image 23:00:00.478 [Warn] [user] weston@tty1: EGL_KHR_gl_texture_3D_image EGL_KHR_gl_renderbuffer_image 23:00:00.478 [Warn] [user] weston@tty1: EGL_IMG_cl_image EGL_KHR_fence_sync EGL_KHR_wait_sync 23:00:00.478 [Warn] [user] weston@tty1: EGL_EXT_create_context_robustness EGL_IMG_image_plane_attribs 23:00:00.478 [Warn] [user] weston@tty1: EGL_EXT_swap_buffers_with_damage 23:00:00.478 [Warn] [user] weston@tty1: EGL_KHR_swap_buffers_with_damage EGL_KHR_partial_update 23:00:00.478 [Warn] [user] weston@tty1: EGL_EXT_buffer_age EGL_EXT_image_dma_buf_import 23:00:00.478 [Warn] [user] weston@tty1: EGL_EXT_image_dma_buf_import_modifiers EGL_EXT_yuv_surface 23:00:00.478 [Warn] [user] weston@tty1: EGL_IMG_context_priority EGL_KHR_create_context 23:00:00.478 [Warn] [user] weston@tty1: EGL_KHR_surfaceless_context EGL_KHR_no_config_context 23:00:00.478 [Warn] [user] weston@tty1: EGL_WL_bind_wayland_display 23:00:00.479 [Warn] [user] weston@tty1: [23:00:00.474] warning: Disabling render GPU timeline and explicit synchronization due to missing EGL_ANDROID_native_fence_sync extension 23:00:00.479 [Warn] [user] weston@tty1: [23:00:00.474] Retrieving EGL client extension string failed. 23:00:00.479 [Warn] [user] weston@tty1: [23:00:00.475] EGL_KHR_surfaceless_context available 23:00:00.508 [Warn] [user] weston@tty1: [23:00:00.503] GL version: OpenGL ES 3.2 23:00:00.508 [Warn] [user] weston@tty1: [23:00:00.504] GLSL version: OpenGL ES GLSL ES 3.20 23:00:00.508 [Warn] [user] weston@tty1: [23:00:00.504] GL vendor: Imagination Technologies 23:00:00.508 [Warn] [user] weston@tty1: [23:00:00.504] GL renderer: PowerVR Rogue GX6650 23:00:00.508 [Warn] [user] weston@tty1: [23:00:00.504] GL extensions: GL_ANDROID_extension_pack_es31a 23:00:00.508 [Warn] [user] weston@tty1: GL_APPLE_texture_format_BGRA8888 GL_EXT_blend_minmax 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_buffer_storage GL_EXT_clear_texture GL_EXT_clip_control 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_color_buffer_float GL_EXT_color_buffer_half_float 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_compressed_ETC1_RGB8_sub_texture 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_conservative_depth GL_EXT_copy_image 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_discard_framebuffer GL_EXT_draw_buffers 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_draw_buffers_indexed GL_EXT_draw_elements_base_vertex 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_EGL_image_array GL_EXT_float_blend 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_geometry_point_size GL_EXT_geometry_shader 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_gpu_shader5 GL_EXT_memory_object GL_EXT_memory_object_fd 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_multi_draw_arrays GL_EXT_multisampled_render_to_texture 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_multisampled_render_to_texture2 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_occlusion_query_boolean GL_EXT_polygon_offset_clamp 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_primitive_bounding_box GL_EXT_pvrtc_sRGB 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_read_format_bgra GL_EXT_robustness 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_separate_shader_objects GL_EXT_shader_framebuffer_fetch 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_shader_group_vote GL_EXT_shader_implicit_conversions 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_shader_io_blocks 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_shader_non_constant_global_initializers 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_shader_pixel_local_storage 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_shader_pixel_local_storage2 GL_EXT_shader_texture_lod 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_shadow_samplers GL_EXT_sparse_texture 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_sRGB_write_control GL_EXT_tessellation_point_size 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_tessellation_shader GL_EXT_texture_border_clamp 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_texture_buffer GL_EXT_texture_cube_map_array 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_texture_filter_anisotropic 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_texture_format_BGRA8888 23:00:00.508 [Warn] [user] weston@tty1: GL_EXT_texture_format_sRGB_override GL_EXT_texture_rg 23:00:00.509 [Warn] [user] weston@tty1: GL_EXT_texture_shadow_lod GL_EXT_texture_sRGB_decode 23:00:00.509 [Warn] [user] weston@tty1: GL_EXT_texture_sRGB_R8 GL_EXT_texture_sRGB_RG8 23:00:00.509 [Warn] [user] weston@tty1: GL_EXT_YUV_target GL_IMG_framebuffer_downsample 23:00:00.509 [Warn] [user] weston@tty1: GL_IMG_multisampled_render_to_texture GL_IMG_program_binary 23:00:00.509 [Warn] [user] weston@tty1: GL_IMG_read_format GL_IMG_shader_binary 23:00:00.509 [Warn] [user] weston@tty1: GL_IMG_texture_compression_pvrtc 23:00:00.509 [Warn] [user] weston@tty1: GL_IMG_texture_compression_pvrtc2 GL_IMG_texture_filter_cubic 23:00:00.509 [Warn] [user] weston@tty1: GL_IMG_texture_format_BGRA8888 GL_IMG_texture_npot 23:00:00.509 [Warn] [user] weston@tty1: GL_KHR_blend_equation_advanced 23:00:00.509 [Warn] [user] weston@tty1: GL_KHR_blend_equation_advanced_coherent GL_KHR_debug 23:00:00.509 [Warn] [user] weston@tty1: GL_KHR_robustness GL_KHR_texture_compression_astc_ldr 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_compressed_ETC1_RGB8_texture GL_OES_depth24 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_depth_texture GL_OES_draw_buffers_indexed 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_draw_elements_base_vertex GL_OES_EGL_image 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_EGL_image_external GL_OES_EGL_image_external_essl3 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_EGL_sync GL_OES_element_index_uint 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_fragment_precision_high GL_OES_geometry_point_size 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_geometry_shader GL_OES_get_program_binary 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_gpu_shader5 GL_OES_mapbuffer GL_OES_packed_depth_stencil 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_required_internalformat GL_OES_rgb8_rgba8 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_sample_shading GL_OES_sample_variables 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_shader_image_atomic GL_OES_shader_io_blocks 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_shader_multisample_interpolation 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_standard_derivatives GL_OES_surfaceless_context 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_tessellation_point_size GL_OES_tessellation_shader 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_texture_border_clamp GL_OES_texture_buffer 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_texture_cube_map_array GL_OES_texture_float 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_texture_half_float GL_OES_texture_npot 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_texture_stencil8 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_texture_storage_multisample_2d_array 23:00:00.509 [Warn] [user] weston@tty1: GL_OES_vertex_array_object GL_OES_vertex_half_float 23:00:00.509 [Warn] [user] weston@tty1: GL_OVR_multiview GL_OVR_multiview2 23:00:00.509 [Warn] [user] weston@tty1: GL_OVR_multiview_multisampled_render_to_texture

mosra commented 5 months ago

It's printed by GL::Context::tryCreate(), which is usually done during Platform::Application construction, or alternatively if you use a custom windowing toolkit, then it's during Platform::GLContext construction.

Or just show me how you initialize the application, I'll point you to where it should get printed. Alternatively you could build the magnum-gl-info utility (MAGNUM_WITH_GL_INFO in CMake) and post what it prints. But if everything is set up as expected, you should get the startup log in your application as well.

Desperado17 commented 5 months ago

Platform::GLContext ctx{argc, argv};

Should this be enough to trigger the code?

mosra commented 5 months ago

Yes.

Do you get anything printed if you #include <Corrade/Utility/Debug.h> and do Debug{} << "hello?";? If you do, then you should get the output from the above as well. There's also an env var, MAGNUM_LOG=quiet, that would suppress the output, but I don't suppose you have it set by accident.

Desperado17 commented 5 months ago

Ok, so I added the Platform::GLContext ctx{argc, argv}; directly after the eglMakeCurrent of the OpenGL context I create myself. No output.

The I added the header and Debug{} << "hello?"; no output

Do I need to set up something else? Is it generally possible to combine Magnum with an existing EGContext?

Only magnum-gl-info worked:

  +---------------------------------------------------------+
  |   Information about Magnum engine OpenGL capabilities   |
  +---------------------------------------------------------+

Used application: Platform::WindowlessEglApplication
Compilation flags:
    CORRADE_BUILD_DEPRECATED
    CORRADE_BUILD_MULTITHREADED
    CORRADE_TARGET_UNIX
    CORRADE_TARGET_ARM
    CORRADE_TARGET_GCC
    CORRADE_TARGET_LIBSTDCXX
    MAGNUM_BUILD_DEPRECATED
    MAGNUM_TARGET_GLES

Renderer: PowerVR Rogue GX6650 by Imagination Technologies
OpenGL version: OpenGL ES 3.2 build 1.15@6052913
Using optional features:
    GL_EXT_multi_draw_arrays
    GL_EXT_robustness
    GL_EXT_texture_filter_anisotropic

Context flags: GL::Context::Flags{}
Detected driver: GL::Context::DetectedDrivers{}
Supported GLSL versions:
    OpenGL ES GLSL ES 3.20 build 1.15@6052913

Vendor extension support:
    GL_ANDROID_extension_pack_es31a                               SUPPORTED
    GL_ANGLE_texture_compression_dxt1                                 -
    GL_ANGLE_texture_compression_dxt3                                 -
    GL_ANGLE_texture_compression_dxt5                                 -
    GL_APPLE_clip_distance                                            -
    GL_APPLE_texture_format_BGRA8888                              SUPPORTED
    GL_ARM_shader_framebuffer_fetch                                   -
    GL_ARM_shader_framebuffer_fetch_depth_stencil                     -
    GL_EXT_clip_cull_distance                                         -
    GL_EXT_debug_label                                                -
    GL_EXT_debug_marker                                               -
    GL_EXT_disjoint_timer_query                                       -
    GL_EXT_multi_draw_arrays                                      SUPPORTED
    GL_EXT_multisampled_render_to_texture                         SUPPORTED
    GL_EXT_polygon_offset_clamp                                   SUPPORTED
    GL_EXT_pvrtc_sRGB                                             SUPPORTED
    GL_EXT_read_format_bgra                                       SUPPORTED
    GL_EXT_robustness                                             SUPPORTED
    GL_EXT_sRGB_write_control                                     SUPPORTED
    GL_EXT_separate_shader_objects                                SUPPORTED
    GL_EXT_shader_framebuffer_fetch                               SUPPORTED
    GL_EXT_shader_integer_mix                                         -
    GL_EXT_texture_compression_bptc                                   -
    GL_EXT_texture_compression_dxt1                                   -
    GL_EXT_texture_compression_rgtc                                   -
    GL_EXT_texture_compression_s3tc                                   -
    GL_EXT_texture_compression_s3tc_srgb                              -
    GL_EXT_texture_filter_anisotropic                             SUPPORTED
    GL_EXT_texture_format_BGRA8888                                SUPPORTED
    GL_EXT_texture_sRGB_R8                                        SUPPORTED
    GL_EXT_texture_sRGB_RG8                                       SUPPORTED
    GL_EXT_texture_sRGB_decode                                    SUPPORTED
    GL_IMG_texture_compression_pvrtc                              SUPPORTED
    GL_KHR_blend_equation_advanced_coherent                       SUPPORTED
    GL_KHR_context_flush_control                                      -
    GL_KHR_no_error                                                   -
    GL_KHR_texture_compression_astc_hdr                               -
    GL_KHR_texture_compression_astc_sliced_3d                         -
    GL_NV_fragment_shader_barycentric                                 -
    GL_NV_polygon_mode                                                -
    GL_NV_read_buffer_front                                           -
    GL_NV_read_depth                                                  -
    GL_NV_read_depth_stencil                                          -
    GL_NV_read_stencil                                                -
    GL_NV_sample_locations                                            -
    GL_NV_shader_noperspective_interpolation                          -
    GL_NV_texture_border_clamp                                        -
    GL_OES_depth32                                                    -
    GL_OES_mapbuffer                                              SUPPORTED
    GL_OES_stencil1                                                   -
    GL_OES_stencil4                                                   -
    GL_OES_texture_compression_astc                                   -
    GL_OES_texture_float_linear                                       -
    GL_OVR_multiview                                              SUPPORTED
    GL_OVR_multiview2                                             SUPPORTED
mosra commented 5 months ago

Thank you. The magnum-gl-info output alone will be enough for me to make a driver-specific workaround, but I'd like to have the problem with no output solved as well :)

I have no idea what's going on. This is a Linux system, not Android or something specific, right? Can you try to reduce your application to a small self-contained repro case that compiles & runs (and crashes) on your end, and prints no output? I suspect there's something else going on that flew under the radar for me so far, and I can't really help if I can't see any code.

Desperado17 commented 5 months ago

Does this print to stdout or stderr?

mosra commented 5 months ago

Standard output, std::cout basically. Error{} << "foo"; will print to standard error / std::cerr.

Desperado17 commented 5 months ago

Just for check:

Do you see a problem with any of these cmake configure parameters?

-DWITH_GL=1 -DTARGET_GLES=ON -DTARGET_GLES2=OFF -DTARGET_GLES3=ON -DWITH_GLXCONTEXT=OFF -DWITH_EGLCONTEXT=ON -DMAGNUM_WITH_GLM=ON -DWITH_WINDOWLESSGLXAPPLICATION=OFF -DWITH_WINDOWLESSEGLXAPPLICATION=OFF -DWITH_ANYIMAGEIMPORTER=ON -DWITH_GL_INFO=ON

mosra commented 5 months ago

Everything looks fine. Can you show me some minimal code that reproduces the problem? I still know only very little about the setup you have.

Desperado17 commented 5 months ago

Working on it. Meanwhile, another problem has arised:

It seems that some of the GL related flags like WITH_GL, TARGET_GLES, TARGET_GLES3 or WITH_EGLCONTEXT cause header conflicts with Qt6:

/usr/include/x86_64-linux-gnu/qt6/QtGui/qopenglext.h:12411:61: error: ‘GLdouble’ does not name a type; did you mean ‘double’?
12411 | typedef void (APIENTRYP PFNGLREFERENCEPLANESGIXPROC) (const GLdouble *equation);
      |                                                             ^~~~~~~~
      |                                                             double
/usr/include/x86_64-linux-gnu/qt6/QtGui/qopenglext.h:12612:25: error: typedef ‘PFNGLGLOBALALPHAFACTORBSUNPROC’ is initialized (use ‘decltype’ instead)
12612 | typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor);
      |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/x86_64-linux-gnu/qt6/QtGui/qopenglext.h:12612:58: error: ‘GLbyte’ was not declared in this scope; did you mean ‘GLubyte’?
12612 | typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor);
      |                                                          ^~~~~~
      |                                                          GLubyte
/usr/include/x86_64-linux-gnu/qt6/QtGui/qopenglext.h:12613:25: error: typedef ‘PFNGLGLOBALALPHAFACTORSSUNPROC’ is initialized (use ‘decltype’ instead)
12613 | typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor);
      |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/x86_64-linux-gnu/qt6/QtGui/qopenglext.h:12613:58: error: ‘GLshort’ was not declared in this scope; did you mean ‘ushort’?
12613 | typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor);
      |                                                          ^~~~~~~

Is there something special one has to do to either Magnum or Qt so the two work together?

mosra commented 5 months ago

Not sure about Qt 6 yet, but a setup that worked for Qt 5 is here -- one has to ensure a certain order of includes, and convince Qt to use external GL definitions: https://github.com/mosra/magnum-bootstrap/blob/ea8e1b0b449c3e67dee337e46d71c1735a4b7f56/src/MyApplication.cpp#L1-L23

Desperado17 commented 5 months ago

This is the current setup. Still fails with undefined symbol in the include hierarchy of

include <QtGui/qopenglfunctions.h>

#include <Corrade/PluginManager/Manager.h>

#include <Magnum/GL/Framebuffer.h>
#include <Magnum/GL/Mesh.h>
#include <Magnum/GL/Renderer.h>
#include <Magnum/Magnum.h>
#include <Magnum/Math/Color.h>
#include <Magnum/Math/Matrix4.h>
#include <Magnum/Math/Quaternion.h>
#include <Magnum/MeshTools/Compile.h>
#include <Magnum/Platform/GLContext.h>
#include <Magnum/Primitives/Cube.h>
#include <Magnum/Shaders/Flat.h>
#include <Magnum/Shaders/Phong.h>
#include <Magnum/Trade/AbstractImporter.h>
#include <Magnum/Trade/MeshData.h>

typedef GLfloat GLclampf;
#undef __glew_h__
#undef __GLEW_H__
#include <QtGui/qopenglfunctions.h>
#define QOPENGLEXTRAFUNCTIONS_H
#include <QtGui/qopenglextrafunctions.h>
mosra commented 5 months ago

Alright, I think I know what's going on -- Qt's GL headers are the big, desktop version, while Magnum built for GLES uses the ES headers. Not really sure if anything about this can be done on Qt's side (if it can be persuaded to expose the GLES API set instead) but I managed to fix the build by adding

#define __glext_h_
typedef double GLdouble;

at the top. The #define __glext_h_ is present in GL headers of the desktop build of Magnum, but on ES the extension header uses #define __gl2ext_h_ / #define __gl2ext_h_ because that's what <GLES3/gl3ext.h> etc uses.

(The bootstrap project is updated with this info as of https://github.com/mosra/magnum-bootstrap/commit/195e71324bb70c521f61b5a0891647e00bf7dc56.)