Open tycho opened 2 years ago
Please note my EGL knowledge is very limited, but I still wanted to respond before looking further into the details.
Also I had to restore the --mx-global feature, I'm not sure why that's gone in the glad2 branch right now?)
This came up before releasing version 2.0 that the feature may actually be not useful. If you want to have multiple contexts, why not also get rid of the global state and handle it properly through the context struct? There were also 1-2 things not sound in the implementation and overall it adds a lot of problems to the code generation. That's why I disabled it for 2.0 and to reconsider if a usecase comes up. I am curious about your opinion on mx-global and why you need it.
Regardless of the quality of my changes (man, that templating stuff is a headache),
It unfortunately is.
https://github.com/tycho/glad/commit/ba3c786f5f32ce562a327c5b14894955577e8f17 Implement plain C API function declarations as MSVC IntelliSense hints, because the global context macro definitions don't give any source-level hints for arguments. This change allows Visual Studio to do this:
I don't understand why an IDE/LSP can't resolve 1 layer of #define
's...
I'd like to share these changes with you in case you can get them into better shape!
Thanks! This was always on the TODO, but I never personally needed it and I havent heard from anyone (until now) that this is actually something they would use.
That is, if EGL_NO_DISPLAY is provided, only discover client extensions, and if a real EGLDisplay handle is provided, do one pass to discover client extensions via EGL_NO_DISPLAY and then do a second pass to discover display extensions with the provided EGLDisplay, and store both of them within the same GladEGLContext structure.
This would be the way to go if all extension with EGL_NO_DISPLAY are also available with a EGLDisplay. Why does discovering extensions with a valid EGLDisplay not include all extensions you would also get with EGL_NO_DISPLAY?
This beahviour would also be similar to Vulkan. Vulkan loads device pointers with the device, instance pointers with the instance and passes null when necessary.
Anyway, the multi-context support for EGL can be used in practice something like this:
GladEGLContext s_contextEGL[2]; [...] gladSetEGLContext(&s_contextEGL[0]); gladLoadEGL(EGL_NO_DISPLAY, (GLADloadfunc)SDL_EGL_GetProcAddress); gladSetEGLContext(&s_contextEGL[1]); gladLoadEGL(eglDisplay, (GLADloadfunc)SDL_EGL_GetProcAddress);
Why do you need different contexts for EGL_NO_DISPLAY
and eglDisplay
? This comes back to the previous point, why is a context with a display potentially less powerful than one without?
I don't understand why an IDE/LSP can't resolve 1 layer of
#define
's...
Yes, it's really dumb.
This came up before releasing version 2.0 that the feature may actually be not useful. If you want to have multiple contexts, why not also get rid of the global state and handle it properly through the context struct? There were also 1-2 things not sound in the implementation and overall it adds a lot of problems to the code generation. That's why I disabled it for 2.0 and to reconsider if a usecase comes up. I am curious about your opinion on mx-global and why you need it.
I technically don't actually want multiple contexts, at least in the GL case.
I just want two things:
Glad{api}Context
structure, instead of tons of individual globals since it aids in debugging especiallyGladGLContext
pointer to call GL functionsI prefer to have the multi-context support just for the GladGLContext
structure type definition. It's trivial to reset it after unload (via memset
), which has aided in debugging when my program didn't do something I expected. I found it's easier to debug a null pointer dereference than a dereference of pointers into an unloaded library's former address space (right now glad doesn't zero those out on unload, it just unloads the library).
But I do want the global multi-context support as well. With non-global multi-context, I have none of the API wrapper macros, which sucks for usability, and there's no way I'm going to go through my code just to replace glBindTexture
-> someGlobal->BindTexture
or whatever.
This would be the way to go if all extension with EGL_NO_DISPLAY are also available with a EGLDisplay. Why does discovering extensions with a valid EGLDisplay not include all extensions you would also get with EGL_NO_DISPLAY?
Why do you need different contexts for
EGL_NO_DISPLAY
andeglDisplay
? This comes back to the previous point, why is a context with a display potentially less powerful than one without?
I think I explained it poorly...
If you do eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS)
you will get client extensions, and if you do eglQueryString(realEglDisplay, EGL_EXTENSIONS)
you get display extensions -- but there is no overlap between the two.
For example, here's what ANGLE gives for client extensions on Windows:
EGL_ANGLE_device_creation
EGL_ANGLE_device_creation_d3d11
EGL_ANGLE_experimental_present_path
EGL_ANGLE_feature_control
EGL_ANGLE_platform_angle
EGL_ANGLE_platform_angle_d3d
EGL_ANGLE_platform_angle_d3d11on12
EGL_ANGLE_platform_angle_device_id
EGL_ANGLE_platform_angle_opengl
EGL_ANGLE_platform_angle_vulkan
EGL_EXT_client_extensions
EGL_EXT_device_query
EGL_EXT_platform_base
EGL_EXT_platform_device
EGL_KHR_client_get_all_proc_addresses
EGL_KHR_debug
And here's the display extensions list when using the ANGLE Vulkan backend:
EGL_ANDROID_blob_cache
EGL_ANDROID_recordable
EGL_ANGLE_create_context_backwards_compatible
EGL_ANGLE_create_context_client_arrays
EGL_ANGLE_create_context_extensions_enabled
EGL_ANGLE_create_context_webgl_compatibility
EGL_ANGLE_create_surface_swap_interval
EGL_ANGLE_display_semaphore_share_group
EGL_ANGLE_display_texture_share_group
EGL_ANGLE_program_cache_control
EGL_ANGLE_robust_resource_initialization
EGL_ANGLE_surface_orientation
EGL_ANGLE_vulkan_image
EGL_CHROMIUM_create_context_bind_generates_resource
EGL_EXT_buffer_age
EGL_EXT_create_context_robustness
EGL_EXT_gl_colorspace_scrgb_linear
EGL_EXT_image_gl_colorspace
EGL_EXT_pixel_format_float
EGL_IMG_context_priority
EGL_KHR_create_context
EGL_KHR_create_context_no_error
EGL_KHR_fence_sync
EGL_KHR_get_all_proc_addresses
EGL_KHR_gl_colorspace
EGL_KHR_gl_renderbuffer_image
EGL_KHR_gl_texture_2D_image
EGL_KHR_gl_texture_cubemap_image
EGL_KHR_image
EGL_KHR_image_base
EGL_KHR_no_config_context
EGL_KHR_partial_update
EGL_KHR_reusable_sync
EGL_KHR_surfaceless_context
EGL_KHR_swap_buffers_with_damage
EGL_KHR_wait_sync
So in order to represent all client and display extensions within a single GladEGLContext
, you would need to query once with eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS)
and again with eglQueryString(realEglDisplay, EGL_EXTENSIONS)
, concatenate the two strings, and use that as the full extension list for the rest of the detection process.
I did a test with this idea here https://github.com/tycho/glad/commit/fc5c72433af83d9b9498327bd22d3e11ea3226c4 and it seems to work, creating an amalgamated client + display extension context.
EDIT: Cleaning up some poor wording and adding some newer findings.
I missed a bunch when I was doing the EGL multi-context stuff, this is a much better change, though probably still not complete: https://github.com/tycho/glad/commit/d6d562c7376a1da01f505bbdb87b99b1cadd0b51
tycho@ba3c786 Implement plain C API function declarations as MSVC IntelliSense hints, because the global context macro definitions don't give any source-level hints for arguments.
Thank you!
It seems like the EGL loader could really benefit from multi-context support. With EGL 1.5, or with EGL_EXT_client_extensions, different extensions are made available without and with an
EGLDisplay
, i.e. client vs display extensions respectively. I found that in my code I was forced to re-load the context any time I needed to switch back and forth between the two, which is a bit cumbersome.I've been maintaining my own fork of glad2 to better handle this. My changes are almost certainly not ready to merge as-is, because I only really use glad2 with these arguments:
So there's a high chance that my changes break other argument combinations, or tests, in some way. (Also I had to restore the
--mx-global
feature, I'm not sure why that's gone in the glad2 branch right now?)Regardless of the quality of my changes (man, that templating stuff is a headache), I'd like to share these changes with you in case you can get them into better shape!
https://github.com/tycho/glad/commit/f0a1597f5125b6b7e0805ce1108b3ac146f5133e Allow loading with
EGL_NO_DISPLAY
(to get client extensions), and do not implicitly get the currentEGLDisplay
whenEGL_NO_DISPLAY
is passed https://github.com/tycho/glad/commit/10c9b1d52376a7056a81595da165ef35e242cc4a EGL multi-context supportAnd this change is less relevant to this specific problem, but maybe worth review anyway:
https://github.com/tycho/glad/commit/ba3c786f5f32ce562a327c5b14894955577e8f17 Implement plain C API function declarations as MSVC IntelliSense hints, because the global context macro definitions don't give any source-level hints for arguments. This change allows Visual Studio to do this:
Anyway, the multi-context support for EGL can be used in practice something like this:
So the context at index 0 includes the supported client extensions, while index 1 contains the supported display extensions.
As I'm writing this, I had an afterthought that maybe an alternative to doing this (and possibly a more usable one) would be to make the EGL loader discover the client and display extensions at the same time. That is, if
EGL_NO_DISPLAY
is provided, only discover client extensions, and if a realEGLDisplay
handle is provided, do one pass to discover client extensions viaEGL_NO_DISPLAY
and then do a second pass to discover display extensions with the providedEGLDisplay
, and store both of them within the sameGladEGLContext
structure.