obsproject / obs-studio

OBS Studio - Free and open source software for live streaming and screen recording
https://obsproject.com
GNU General Public License v2.0
59.61k stars 7.9k forks source link

regression: xcomposite on EGL broken on nvidia drivers 390 and 450 #6722

Closed theofficialgman closed 2 years ago

theofficialgman commented 2 years ago

Operating System Info

Ubuntu 18.04

Other OS

No response

OBS Studio Version

Git

OBS Studio Version (Other)

49c20c6cc1e14f142660553b04d969edaf989212

OBS Studio Log URL

https://obsproject.com/logs/9AVtHontM-jHqDU1

OBS Studio Crash Log URL

No response

Expected Behavior

xcomposite still works after the mandatory switch to EGL from here: https://github.com/obsproject/obs-studio/pull/6475

Current Behavior

window capture with xcomposite does NOT work (no image). the available windows are correctly listed in the list, but none of them work. fullscreen capture does work.

pinging @GeorgesStavracas

Steps to Reproduce

  1. compile and install obs from git (at the time 49c20c6cc1e14f142660553b04d969edaf989212 )
  2. launch and try to capture with xcomposite
  3. see it does not function

Anything else we should know?

my hardware/driver DOES have support for GL_OES_EGL_image http://opengl.gpuinfo.org/displayreport.php?id=7655 http://opengl.gpuinfo.org/displayreport.php?id=7656 (See below for EGL extensions). OBS incorrectly states that my hardware does NOT support GL_OES_EGL_IMAGE

note: both window capture (xcomposite) and screen capture worked with GLX (like on this commit or earlier: f8d415afbee4873a3eb15c7e77833fbee6c87871 )

GeorgesStavracas commented 2 years ago

GL_OES_EGL_image is required for bridging EGL images and big GL textures. It is quite unfortunate that the NVIDIA driver doesn't support it, but I honestly don't see why it doesn't implement that. I don't think there's much that OBS Studio can do on its own if the driver doesn't implement that extension.

theofficialgman commented 2 years ago

actually my hardware DOES support it. I was mistaken with the tools I was using to query only the GLX accessible extensions. your query must be returning incomplete information https://github.com/obsproject/obs-studio/blob/49c20c6cc1e14f142660553b04d969edaf989212/libobs-opengl/gl-egl-common.c#L73

es2_info
EGL_VERSION: 1.5
EGL_VENDOR: NVIDIA
EGL_EXTENSIONS:
    EGL_EXT_buffer_age, EGL_EXT_client_sync, 
    EGL_EXT_create_context_robustness, EGL_EXT_image_dma_buf_import, 
    EGL_EXT_image_dma_buf_import_modifiers, EGL_EXT_output_base, 
    EGL_EXT_stream_acquire_mode, EGL_EXT_sync_reuse, EGL_IMG_context_priority, 
    EGL_KHR_config_attribs, EGL_KHR_create_context_no_error, 
    EGL_KHR_context_flush_control, EGL_KHR_create_context, 
    EGL_KHR_display_reference, EGL_KHR_fence_sync, 
    EGL_KHR_get_all_proc_addresses, EGL_KHR_partial_update, 
    EGL_KHR_swap_buffers_with_damage, EGL_KHR_no_config_context, 
    EGL_KHR_gl_colorspace, EGL_KHR_gl_renderbuffer_image, 
    EGL_KHR_gl_texture_2D_image, EGL_KHR_gl_texture_3D_image, 
    EGL_KHR_gl_texture_cubemap_image, EGL_KHR_image, EGL_KHR_image_base, 
    EGL_KHR_image_pixmap, EGL_KHR_reusable_sync, EGL_KHR_stream, 
    EGL_KHR_stream_attrib, EGL_KHR_stream_consumer_gltexture, 
    EGL_KHR_stream_cross_process_fd, EGL_KHR_stream_fifo, 
    EGL_KHR_stream_producer_eglsurface, EGL_KHR_surfaceless_context, 
    EGL_KHR_wait_sync, EGL_NV_cuda_event, EGL_NV_nvrm_fence_sync, 
    EGL_NV_post_sub_buffer, EGL_NV_stream_cross_display, 
    EGL_NV_stream_cross_object, EGL_NV_stream_cross_process, 
    EGL_NV_stream_flush, EGL_NV_stream_metadata, EGL_NV_stream_remote, 
    EGL_NV_stream_reset, EGL_NV_stream_socket, EGL_NV_stream_socket_unix, 
    EGL_NV_stream_sync, EGL_NV_stream_fifo_next, 
    EGL_NV_stream_consumer_gltexture_yuv, EGL_NV_stream_attrib, 
    EGL_NV_system_time, EGL_NV_output_drm_flip_event, 
    EGL_WL_bind_wayland_display, EGL_WL_wayland_eglstream
EGL_CLIENT_APIS: OpenGL_ES OpenGL
GL_VERSION: OpenGL ES 3.2 NVIDIA 32.3.1
GL_RENDERER: NVIDIA Tegra X1 (nvgpu)/integrated
GL_EXTENSIONS:
    GL_EXT_base_instance, GL_EXT_blend_func_extended, GL_EXT_blend_minmax, 
    GL_EXT_buffer_storage, GL_EXT_clear_texture, GL_EXT_clip_control, 
    GL_EXT_clip_cull_distance, GL_EXT_color_buffer_float, 
    GL_EXT_color_buffer_half_float, GL_EXT_conservative_depth, 
    GL_EXT_copy_image, GL_EXT_debug_label, GL_EXT_discard_framebuffer, 
    GL_EXT_disjoint_timer_query, GL_EXT_draw_buffers_indexed, 
    GL_EXT_draw_elements_base_vertex, GL_EXT_EGL_image_array, 
    GL_EXT_EGL_image_storage, GL_EXT_EGL_image_external_wrap_modes, 
    GL_EXT_float_blend, GL_EXT_frag_depth, GL_EXT_geometry_point_size, 
    GL_EXT_geometry_shader, GL_EXT_gpu_shader5, GL_EXT_map_buffer_range, 
    GL_EXT_multi_draw_indirect, GL_EXT_multisample_compatibility, 
    GL_EXT_multisampled_render_to_texture, 
    GL_EXT_multisampled_render_to_texture2, GL_EXT_occlusion_query_boolean, 
    GL_EXT_polygon_offset_clamp, GL_EXT_post_depth_coverage, 
    GL_EXT_primitive_bounding_box, GL_EXT_raster_multisample, 
    GL_EXT_render_snorm, GL_EXT_robustness, GL_EXT_separate_shader_objects, 
    GL_EXT_shader_group_vote, GL_EXT_shader_implicit_conversions, 
    GL_EXT_shader_integer_mix, GL_EXT_shader_io_blocks, 
    GL_EXT_shader_non_constant_global_initializers, GL_EXT_shader_texture_lod, 
    GL_EXT_shadow_samplers, GL_EXT_sparse_texture, GL_EXT_sparse_texture2, 
    GL_EXT_sRGB, GL_EXT_sRGB_write_control, GL_EXT_tessellation_point_size, 
    GL_EXT_tessellation_shader, GL_EXT_texture_border_clamp, 
    GL_EXT_texture_buffer, GL_EXT_texture_compression_bptc, 
    GL_EXT_texture_compression_dxt1, GL_EXT_texture_compression_rgtc, 
    GL_EXT_texture_compression_s3tc, GL_EXT_texture_cube_map_array, 
    GL_EXT_texture_filter_anisotropic, GL_EXT_texture_filter_minmax, 
    GL_EXT_texture_format_BGRA8888, GL_EXT_texture_mirror_clamp_to_edge, 
    GL_EXT_texture_norm16, GL_EXT_texture_rg, GL_EXT_texture_sRGB_R8, 
    GL_EXT_texture_sRGB_decode, GL_EXT_texture_storage, GL_EXT_texture_view, 
    GL_EXT_draw_transform_feedback, GL_EXT_unpack_subimage, 
    GL_EXT_window_rectangles, GL_KHR_context_flush_control, GL_KHR_debug, 
    GL_EXT_memory_object, GL_EXT_memory_object_fd, 
    GL_KHR_parallel_shader_compile, GL_KHR_no_error, 
    GL_KHR_robust_buffer_access_behavior, GL_KHR_robustness, GL_EXT_semaphore, 
    GL_EXT_semaphore_fd, GL_KHR_texture_compression_astc_ldr, 
    GL_KHR_texture_compression_astc_sliced_3d, GL_NV_bgr, 
    GL_NV_bindless_texture, GL_NV_blend_equation_advanced, 
    GL_NV_blend_equation_advanced_coherent, GL_NV_blend_minmax_factor, 
    GL_NV_conditional_render, GL_NV_conservative_raster, GL_NV_copy_buffer, 
    GL_NV_copy_image, GL_NV_draw_buffers, GL_NV_draw_instanced, 
    GL_NV_draw_texture, GL_NV_draw_vulkan_image, 
    GL_NV_EGL_stream_consumer_external, GL_NV_explicit_attrib_location, 
    GL_NV_fbo_color_attachments, GL_NV_fill_rectangle, 
    GL_NV_fragment_coverage_to_color, GL_NV_fragment_shader_interlock, 
    GL_NV_framebuffer_blit, GL_NV_framebuffer_mixed_samples, 
    GL_NV_framebuffer_multisample, GL_NV_generate_mipmap_sRGB, 
    GL_NV_geometry_shader_passthrough, GL_NV_instanced_arrays, 
    GL_NV_internalformat_sample_query, GL_NV_gpu_shader5, GL_NV_image_formats, 
    GL_NV_occlusion_query_samples, GL_NV_non_square_matrices, 
    GL_NV_pack_subimage, GL_NV_packed_float, GL_NV_packed_float_linear, 
    GL_NV_path_rendering, GL_NV_path_rendering_shared_edge, 
    GL_NV_pixel_buffer_object, GL_NV_polygon_mode, GL_NV_read_buffer, 
    GL_NV_read_depth, GL_NV_read_depth_stencil, GL_NV_read_stencil, 
    GL_NV_sample_locations, GL_NV_sample_mask_override_coverage, 
    GL_NV_shader_atomic_fp16_vector, GL_NV_shader_noperspective_interpolation, 
    GL_NV_shadow_samplers_array, GL_NV_shadow_samplers_cube, 
    GL_NV_sRGB_formats, GL_NV_texture_array, GL_NV_texture_barrier, 
    GL_NV_texture_border_clamp, GL_NV_texture_compression_latc, 
    GL_NV_texture_compression_s3tc, GL_NV_texture_compression_s3tc_update, 
    GL_NV_timer_query, GL_NV_viewport_array, GL_NV_viewport_array2, 
    GL_NV_viewport_swizzle, GL_KHR_blend_equation_advanced, 
    GL_KHR_blend_equation_advanced_coherent, 
    GL_OES_compressed_ETC1_RGB8_texture, 
    GL_EXT_compressed_ETC1_RGB8_sub_texture, GL_OES_depth24, GL_OES_depth32, 
    GL_OES_depth_texture, GL_OES_depth_texture_cube_map, GL_OES_copy_image, 
    GL_OES_draw_buffers_indexed, GL_OES_draw_elements_base_vertex, 
    GL_OES_texture_border_clamp, GL_OES_tessellation_point_size, 
    GL_OES_tessellation_shader, GL_OES_texture_buffer, 
    GL_OES_geometry_point_size, GL_OES_geometry_shader, GL_OES_gpu_shader5, 
    GL_OES_shader_io_blocks, GL_OES_texture_view, 
    GL_OES_primitive_bounding_box, GL_OES_EGL_image, 
    GL_OES_EGL_image_external, GL_OES_EGL_image_external_essl3, 
    GL_OES_EGL_sync, GL_OES_element_index_uint, GL_OES_fbo_render_mipmap, 
    GL_OES_get_program_binary, GL_OES_mapbuffer, GL_OES_packed_depth_stencil, 
    GL_OES_rgb8_rgba8, GL_OES_sample_shading, GL_OES_sample_variables, 
    GL_OES_shader_image_atomic, GL_OES_shader_multisample_interpolation, 
    GL_OES_standard_derivatives, GL_OES_surfaceless_context, 
    GL_OES_texture_cube_map_array, GL_OES_texture_npot, GL_OES_texture_float, 
    GL_OES_texture_float_linear, GL_OES_texture_half_float, 
    GL_OES_texture_half_float_linear, GL_OES_texture_stencil8, 
    GL_OES_texture_storage_multisample_2d_array, GL_OES_vertex_array_object, 
    GL_OES_vertex_half_float, GL_OES_viewport_array, GL_OVR_multiview, 
    GL_OVR_multiview2, GL_OVR_multiview_multisampled_render_to_texture, 
    GL_ANDROID_extension_pack_es31a
theofficialgman commented 2 years ago

you may want to correct your code to query EGL using the api that es2_info uses to obtain the supported EGL extensions https://www.khronos.org/registry/EGL/sdk/docs/man/html/eglQueryString.xhtml https://github.com/JoakimSoderberg/mesademos/blob/6eef979a5488dab01088412f88374b2ea9d615cd/src/egl/opengles1/es1_info.c#L87 there could be other ways, but that is the one I found immediately

GeorgesStavracas commented 2 years ago

Can you try this diff and see if it works?

diff --git a/libobs-opengl/gl-egl-common.c b/libobs-opengl/gl-egl-common.c
index bda4a6883..4537371cf 100644
--- a/libobs-opengl/gl-egl-common.c
+++ b/libobs-opengl/gl-egl-common.c
@@ -63,14 +63,40 @@ static bool find_gl_extension(const char *extension)
        return false;
 }

-static bool init_egl_image_target_texture_2d_ext(void)
+
+static bool find_egl_extension(EGLDisplay egl_display, const char *extension)
+{
+       char *egl_extensions;
+       char *to_be_freed;
+       char *ext;
+       bool found;
+
+       found = false;
+       egl_extensions = bstrdup(eglQueryString(egl_display, EGL_EXTENSIONS));
+       to_be_freed = egl_extensions;
+
+       while ((ext = strsep(&egl_extensions, " "))) {
+               blog(LOG_INFO, "EGL extension token: %s", ext);
+               if (extension && strcmp(ext, extension) == 0) {
+                       found = true;
+                       break;
+               }
+       }
+
+       bfree(to_be_freed);
+
+       return found;
+}
+
+static bool init_egl_image_target_texture_2d_ext(EGLDisplay egl_display)
 {
        static bool initialized = false;

        if (!initialized) {
                initialized = true;

-               if (!find_gl_extension("GL_OES_EGL_image")) {
+               if (!find_gl_extension("GL_OES_EGL_image") &&
+                   !find_egl_extension(egl_display, "GL_OES_EGL_image")) {
                        blog(LOG_ERROR, "No GL_OES_EGL_image");
                        return false;
                }
@@ -212,7 +238,7 @@ gl_egl_create_dmabuf_image(EGLDisplay egl_display, unsigned int width,
        struct gs_texture *texture = NULL;
        EGLImage egl_image;

-       if (!init_egl_image_target_texture_2d_ext())
+       if (!init_egl_image_target_texture_2d_ext(egl_display))
                return NULL;

        egl_image = create_dmabuf_egl_image(egl_display, width, height,
@@ -239,7 +265,7 @@ gl_egl_create_texture_from_pixmap(EGLDisplay egl_display, uint32_t width,
                                  enum gs_color_format color_format,
                                  EGLint target, EGLClientBuffer pixmap)
 {
-       if (!init_egl_image_target_texture_2d_ext())
+       if (!init_egl_image_target_texture_2d_ext(egl_display))
                return NULL;

        const EGLAttrib pixmap_attrs[] = {

Please send the output

kkartaltepe commented 2 years ago

Based on the implementation of eglinfo and the values it outputs, it seems likely to me that nvidia reports fewer extensions via GL_NUM_EXTENSIONS than it actually reports via GL_EXTENSIONS on your hardware. If can can hack on eglinfo please add some output for the value of glGetIntegerv(GL_NUM_EXTENSIONS, &n);

kkartaltepe commented 2 years ago

It appears that it may be due to glGetString(GL_EXTENSIONS) being a GLES extension, so nvidia only reports OES extensions when it is called. We do the current checks for opengl using glGetStringi(GL_EXTENSIONS, i) which is defined for both GLES and GL.

actually my hardware DOES support it.

If you hardware does not report it supported for OpenGL contexts via the OpenGL queries then it may not work. Please patch out this check and confirm if these calls actually work or not. If they do work then we can consider patches to support it.

--- edit For reference these extensions are reported as supported by OpenGL contexts on nvidia's desktop class drivers. So it may not be a mistake that they are not reported as supported in OpenGL contexts on your hardware.

theofficialgman commented 2 years ago

@GeorgesStavracas the patch doesn't seem to apply to master. can you make sure you generated it off of the master branch and upload it as a .txt

It appears that it may be due to glGetString(GL_EXTENSIONS) being a GLES extension, so nvidia only reports OES extensions when it is called. We do the current checks for opengl using glGetStringi(GL_EXTENSIONS, i) which is defined for both GLES and GL.

it actually is more specifically an EGL opengl extension. not a GLX extension which is what find_gl_extension reports (find_gl_extension is the same output as glxinfo).

If you hardware does not report it supported for OpenGL contexts via the OpenGL queries then it may not work. Please patch out this check and confirm if these calls actually work or not. If they do work then we can consider patches to support it.

removing the check DOES work, I have functional xcomposite. (just commenting out the below lines) https://github.com/obsproject/obs-studio/blob/49c20c6cc1e14f142660553b04d969edaf989212/libobs-opengl/gl-egl-common.c#L73-L76

theofficialgman commented 2 years ago

@GeorgesStavracas I went ahead and just manually edited in the patch https://obsproject.com/logs/JUHby51OdUGLDSdc doesn't work

theofficialgman commented 2 years ago

@GeorgesStavracas the problem with your patch is you are querying the EGL_EXTENSIONS from EGL this is a GL_EXTENSIONS from EGL. I pointed you to the wrong spot before https://github.com/JoakimSoderberg/mesademos/blob/6eef979a5488dab01088412f88374b2ea9d615cd/src/egl/opengles1/es1_info.c#L98

kkartaltepe commented 2 years ago

it actually is more specifically an EGL opengl extension. not a GLX extension which is what find_gl_extension reports (find_gl_extension is the same output as glxinfo).

GLX extensions would unsurprisingly begin with GLX (Consider GLX_EXT_texture_from_pixmap). GL_OES_EGL_image is a GLES extension (GL_OES) to support EGL_image's. As mentioned our query is the only correct on per the GL spec, but your driver does not report this extension for GL contexts. The alternate query is only valid for GLES contexts.

Since you said it works then this is a bug in the nvidia driver for your platform (and we have seen it is fixed on their desktop platform). Consider updating your system to see if that resolves the issue ubuntu 18.04 wont be supported in our next release with EGL anyway.

theofficialgman commented 2 years ago

Since you said it works then this is a bug in the nvidia driver for your platform (and we have seen it is fixed on their desktop platform). Consider updating your system to see if that resolves the issue ubuntu 18.04 wont be supported in our next release with EGL anyway.

the drivers all operate the same on this platform. if you look at conformance numbers on http://opengl.gpuinfo.org/listreports.php?extension=GL_OES_EGL_image&option=not you will see that this is very common and I don't think its a bug. there are many other drivers (nvidia, amd, intel) and multiple platforms (windows, linux) and all do not report GL_OES_EGL_image via the method you are using

kkartaltepe commented 2 years ago

if you look at conformance numbers on http://opengl.gpuinfo.org/listreports.php?extension=GL_OES_EGL_image&option=not you will see that this is very common and I don't think its a bug.

Conformance tests can run on EGL or GLX, of course no one will implement the EGL_image extension on GLX and the platform layer is not reported in these tests that I can see. Similarly no one is going to implement the GLX_EXT_texture_from_pixmap extension replacement on windows/mac.

Again I have a desktop nvidia device and it works exactly as I have described. So this is either a bug or an intentional omission by nvidia for your device. Consider raising a bug with them or updating your system to see if that helps.

theofficialgman commented 2 years ago

this is an embedded system. there are not updates. this again is not a bug.

OBS is querying GLX opengl extensions, not EGL opengl extensions.

OBS outputs a list of 368 extensions on my system. these are GLX opengl extensions

es_info ouputs a list of 192 extensions. these are EGL opengl extensions.

the extensions are entirely different. OBS is querying the wrong ones. take a closer look at https://gitlab.freedesktop.org/mesa/demos/-/blob/main/src/egl/opengles1/es1_info.c

I'll give you a hint (because I know the bug in OBS), you haven't created a EGL context in OBS before getting GL_EXTENSIONS

I won't give you my proof of concept code inside OBS since it is a mess, but let me just say it does now report the correct extensions and number inside of OBS:

info: GL_EXTENSIONS:

    GL_EXT_base_instance, GL_EXT_blend_func_extended, GL_EXT_blend_minmax, 
    GL_EXT_buffer_storage, GL_EXT_clear_texture, GL_EXT_clip_control, 
    GL_EXT_clip_cull_distance, GL_EXT_color_buffer_float, 
    GL_EXT_color_buffer_half_float, GL_EXT_conservative_depth, 
    GL_EXT_copy_image, GL_EXT_debug_label, GL_EXT_discard_framebuffer, 
    GL_EXT_disjoint_timer_query, GL_EXT_draw_buffers_indexed, 
    GL_EXT_draw_elements_base_vertex, GL_EXT_EGL_image_array, 
    GL_EXT_EGL_image_storage, GL_EXT_EGL_image_external_wrap_modes, 
    GL_EXT_float_blend, GL_EXT_frag_depth, GL_EXT_geometry_point_size, 
    GL_EXT_geometry_shader, GL_EXT_gpu_shader5, GL_EXT_map_buffer_range, 
    GL_EXT_multi_draw_indirect, GL_EXT_multisample_compatibility, 
    GL_EXT_multisampled_render_to_texture, 
    GL_EXT_multisampled_render_to_texture2, GL_EXT_occlusion_query_boolean, 
    GL_EXT_polygon_offset_clamp, GL_EXT_post_depth_coverage, 
    GL_EXT_primitive_bounding_box, GL_EXT_raster_multisample, 
    GL_EXT_render_snorm, GL_EXT_robustness, GL_EXT_separate_shader_objects, 
    GL_EXT_shader_group_vote, GL_EXT_shader_implicit_conversions, 
    GL_EXT_shader_integer_mix, GL_EXT_shader_io_blocks, 
    GL_EXT_shader_non_constant_global_initializers, GL_EXT_shader_texture_lod, 
    GL_EXT_shadow_samplers, GL_EXT_sparse_texture, GL_EXT_sparse_texture2, 
    GL_EXT_sRGB, GL_EXT_sRGB_write_control, GL_EXT_tessellation_point_size, 
    GL_EXT_tessellation_shader, GL_EXT_texture_border_clamp, 
    GL_EXT_texture_buffer, GL_EXT_texture_compression_bptc, 
    GL_EXT_texture_compression_dxt1, GL_EXT_texture_compression_rgtc, 
    GL_EXT_texture_compression_s3tc, GL_EXT_texture_cube_map_array, 
    GL_EXT_texture_filter_anisotropic, GL_EXT_texture_filter_minmax, 
    GL_EXT_texture_format_BGRA8888, GL_EXT_texture_mirror_clamp_to_edge, 
    GL_EXT_texture_norm16, GL_EXT_texture_rg, GL_EXT_texture_sRGB_R8, 
    GL_EXT_texture_sRGB_decode, GL_EXT_texture_storage, GL_EXT_texture_view, 
    GL_EXT_draw_transform_feedback, GL_EXT_unpack_subimage, 
    GL_EXT_window_rectangles, GL_KHR_context_flush_control, GL_KHR_debug, 
    GL_EXT_memory_object, GL_EXT_memory_object_fd, 
    GL_KHR_parallel_shader_compile, GL_KHR_no_error, 
    GL_KHR_robust_buffer_access_behavior, GL_KHR_robustness, GL_EXT_semaphore, 
    GL_EXT_semaphore_fd, GL_KHR_texture_compression_astc_ldr, 
    GL_KHR_texture_compression_astc_sliced_3d, GL_NV_bgr, 
    GL_NV_bindless_texture, GL_NV_blend_equation_advanced, 
    GL_NV_blend_equation_advanced_coherent, GL_NV_blend_minmax_factor, 
    GL_NV_conditional_render, GL_NV_conservative_raster, GL_NV_copy_buffer, 
    GL_NV_copy_image, GL_NV_draw_buffers, GL_NV_draw_instanced, 
    GL_NV_draw_texture, GL_NV_draw_vulkan_image, 
    GL_NV_EGL_stream_consumer_external, GL_NV_explicit_attrib_location, 
    GL_NV_fbo_color_attachments, GL_NV_fill_rectangle, 
    GL_NV_fragment_coverage_to_color, GL_NV_fragment_shader_interlock, 
    GL_NV_framebuffer_blit, GL_NV_framebuffer_mixed_samples, 
    GL_NV_framebuffer_multisample, GL_NV_generate_mipmap_sRGB, 
    GL_NV_geometry_shader_passthrough, GL_NV_instanced_arrays, 
    GL_NV_internalformat_sample_query, GL_NV_gpu_shader5, GL_NV_image_formats, 
    GL_NV_occlusion_query_samples, GL_NV_non_square_matrices, 
    GL_NV_pack_subimage, GL_NV_packed_float, GL_NV_packed_float_linear, 
    GL_NV_path_rendering, GL_NV_path_rendering_shared_edge, 
    GL_NV_pixel_buffer_object, GL_NV_polygon_mode, GL_NV_read_buffer, 
    GL_NV_read_depth, GL_NV_read_depth_stencil, GL_NV_read_stencil, 
    GL_NV_sample_locations, GL_NV_sample_mask_override_coverage, 
    GL_NV_shader_atomic_fp16_vector, GL_NV_shader_noperspective_interpolation, 
    GL_NV_shadow_samplers_array, GL_NV_shadow_samplers_cube, 
    GL_NV_sRGB_formats, GL_NV_texture_array, GL_NV_texture_barrier, 
    GL_NV_texture_border_clamp, GL_NV_texture_compression_latc, 
    GL_NV_texture_compression_s3tc, GL_NV_texture_compression_s3tc_update, 
    GL_NV_timer_query, GL_NV_viewport_array, GL_NV_viewport_array2, 
    GL_NV_viewport_swizzle, GL_KHR_blend_equation_advanced, 
    GL_KHR_blend_equation_advanced_coherent, 
    GL_OES_compressed_ETC1_RGB8_texture, 
    GL_EXT_compressed_ETC1_RGB8_sub_texture, GL_OES_depth24, GL_OES_depth32, 
    GL_OES_depth_texture, GL_OES_depth_texture_cube_map, GL_OES_copy_image, 
    GL_OES_draw_buffers_indexed, GL_OES_draw_elements_base_vertex, 
    GL_OES_texture_border_clamp, GL_OES_tessellation_point_size, 
    GL_OES_tessellation_shader, GL_OES_texture_buffer, 
    GL_OES_geometry_point_size, GL_OES_geometry_shader, GL_OES_gpu_shader5, 
    GL_OES_shader_io_blocks, GL_OES_texture_view, 
    GL_OES_primitive_bounding_box, GL_OES_EGL_image, 
    GL_OES_EGL_image_external, GL_OES_EGL_image_external_essl3, 
    GL_OES_EGL_sync, GL_OES_element_index_uint, GL_OES_fbo_render_mipmap, 
    GL_OES_get_program_binary, GL_OES_mapbuffer, GL_OES_packed_depth_stencil, 
    GL_OES_rgb8_rgba8, GL_OES_sample_shading, GL_OES_sample_variables, 
    GL_OES_shader_image_atomic, GL_OES_shader_multisample_interpolation, 
    GL_OES_standard_derivatives, GL_OES_surfaceless_context, 
    GL_OES_texture_cube_map_array, GL_OES_texture_npot, GL_OES_texture_float, 
    GL_OES_texture_float_linear, GL_OES_texture_half_float, 
    GL_OES_texture_half_float_linear, GL_OES_texture_stencil8, 
    GL_OES_texture_storage_multisample_2d_array, GL_OES_vertex_array_object, 
    GL_OES_vertex_half_float, GL_OES_viewport_array, GL_OVR_multiview, 
    GL_OVR_multiview2, GL_OVR_multiview_multisampled_render_to_texture, 
    GL_ANDROID_extension_pack_es31a
info: Number of GL Extensions: 192
kkartaltepe commented 2 years ago

es_info ouputs a list of 192 extensions. these are EGL opengl extensions.

As the name implies and as explained earlier, this is querying OpenGL ES extensions. OBS does not support OpenGL ES. So this list of extensions is not accurate for the rendering context that OBS uses.

this again is not a bug.

Please provide replies from Nvidia engineers supporting this. Considering nvidia drivers do work exactly as I described and as the specification declares it should on every device it ships except the one you are using I find this hard to believe without some supporting evidence.

I'll give you a hint (because I know the bug in OBS), you haven't created a EGL context in OBS before getting GL_EXTENSIONS.

Patches welcome, but as explained earlier the specification clearly states that GL_EXTENSIONS is not supported on OpenGL and that this is an OpenGL ES only query. Querying this would not only violate the spec but introduce exactly the OpenGL ES/OpenGL mixup we want to avoid.

this is an embedded system. there are not updates.

You cannot expect us to work around errata for unsupported devices for all time. There must be some point at which we stop carrying around hacks for broken platforms. Considering we will stop supporting the Ubuntu version that your out of support device uses it seems like a good time for us to not support it as well.

theofficialgman commented 2 years ago

Considering nvidia drivers do work exactly as I described and as the specification declares it should on every device it ships except the one you are using I find this hard to believe without some supporting evidence.

thats where you would be wrong. please look at the website I linked AGAIN: http://opengl.gpuinfo.org/listextensions.php and tell me how 45% coverage == every single device Screenshot_20220712_232153

Screenshot_20220712_232217

Screenshot_20220712_232228

as you can see there are MANY drivers which do NOT show 'GL_OES_EGL_image` due to obtaining this info from GLX instead of EGL (this is just page one, feel free to search yourself)

kkartaltepe commented 2 years ago

Im sorry this is such a subtle specification issue but definitely the best way for you right now is to carry a patch for your environment that disables this check (just delete the line we talked about) since you wont be able to use the next release of OBS packaged by us anyway this shouldnt affect you much.But for correctness in OBS should probably leave this check in to avoid crashes or incorrect results on other users machines.

If more users find this affects them and drivers supported by the manufacturer or community we can consider relaxing the checks further.

theofficialgman commented 2 years ago

like I said. it is not allowed to call glGetString() before binding a context. this is what OBS is doing, calling glGetString before binding a context (or calling it from the wrong context, IE: not an EGL window)

from the GL spec:

Issuing GL commands when the program is not connected to a context results in undefined behavior

some driver manufactuers must have implemented a workaround for bad programmers not binding the context and make glGetString report all values regardless of context.

kkartaltepe commented 2 years ago

like I said. it is not allowed to call glGetString() before binding a context. this is what OBS is doing, calling glGetString before binding a context (or calling it from the wrong context, IE: not an EGL window)

This is not the case on my machine. Can you provide more context on your testing? On my system this query is initiated once OBS has finished initializing the graphics context, bound OpenGL as the API, and is attempting to capture the X11 window within a graphics context. This code should only ever be reachable after obs has locked the graphics context in order to make graphics calls.

--- edit For example the stacktrace where you see init_egl_image_target_texture_2d_ext being called from outside of a graphics context would be great.

theofficialgman commented 2 years ago

it is being called from an EGL opengl window which has initialized. GL_OES_EGL_image is not part of the OpenGL spec, it is an OpenGLES extension. Checking for it on OpenGL IS AGAINST SPEC. SOME drivers have gone against that and implemented hacks to add it in, like the mesa drivers (where it has been added and removed multiple times over its history):

   /*  FIXME: Mesa expects GL_OES_EGL_image to be available in OpenGL contexts. */
   { "GL_OES_EGL_image",                           o(OES_EGL_image),                           GL | ES1 | ES2, 2006 },
mesa/extensions: restrict GL_OES_EGL_image to GLES

Driver vendors do this as well. The extension specification
lists GLES 1.1 or 2.0 as requirements.

you are going to find that this is going to be a major issue for linux uses on the release of OBS 28 as some drivers will have done the CORRECT thing and not included OES_EGL_IMAGE in OpenGL context, and others will have implemented the hack and included OES_EGL_IMAGE in OpenGL context.

kkartaltepe commented 2 years ago

Im glad that we can agree OBS is querying the correct extensions for its rendering context and platform. As I said earlier usage of this extension is a tricky specification issue. Like you say the GL_OES_EGL_image extension is written against GLES, and OBS does not have a GLES renderer. However there are no OpenGL specifications for texturing from a EGLImage so vendors and mesa have so far just implemented this extension in OpenGL and exposed it appropriately as an OpenGL extension.

As you mention mesa has tried removing this before but https://gitlab.freedesktop.org/mesa/mesa/-/commit/b5df52b1128049bf688cace6e581a16d5f1ad5bb since X11 depends on this extension existing in OpenGL for hardware accel it's existence and support on platforms by all vendors is fairly robust in drivers created after that time. And its correctness is fairly trustworthy as well since it powers X11.

you are going to find that this is going to be a major issue for linux uses on the release of OBS 28 as some drivers will have done the CORRECT thing and not included OES_EGL_IMAGE in OpenGL context, and others will have implemented the hack and included OES_EGL_IMAGE in OpenGL context.

Its definitely possible more drivers will behave like yours, we depend on reports like yours to find the kinds of systems where it will cause an issue.

PatTheMav commented 2 years ago

@kkartaltepe Would you deem this an issue that requires fixing or is this an unfortunate situation where we don't support this configuration moving forward?

kkartaltepe commented 2 years ago

I think we are still waiting to see if this affects any real modern drivers, if it doesnt affect any modern drivers then we can close this.

ehdocumentdesign commented 2 years ago

I've encountered this also. I have an older computer, but it's running Linux Mint 21 with no problems elsewhere. The NVIDIA driver is version 390.154-0ubuntu0.22.04.1

No problems with Window Capture (Xcomposite) until I installed OBS version 28. Now I get the previously mentioned error

error: No GL_OES_EGL_image

Pipewire could be an alternative to Xcomposite but it looks like Mint hasn't adopted wayland yet? Building from source with -DENABLE_PIPEWIRE didn't give me the possibility as an input source.

From the comments above, it seems my best option is to try building version 27 from the source code.

I saw the warnings about plugins and Qt6, but no warning suggested this type of hardware issue.

kkartaltepe commented 2 years ago

Please provide some system information like gpu model so we have a better idea of what we are working with. Also please attempt the change noted in https://github.com/obsproject/obs-studio/issues/6722#issuecomment-1182645480 if you are comfortable compiling code and let us know if it works on your system.

ehdocumentdesign commented 2 years ago

Thanks for the quick reply. I attempted the change you noted and compiled the code. However, the change did not enable Xcomposite to capture any of the window content.

I'm using an older computer, so I know these issues might arise.

Graphics card: NVIDIA Corporation GK107M [GeForce GT 640M Mac Edition] Hardware driver: is nvidia-driver-390, version 390.154-0ubuntu0.22.04.1

Switching to the open source driver "xserver-xorg-video-nouveau" (version 1:1.0.17-2build1) and running OBS did bring back the Xcomposite capture functionality, but naturally puts a greater burden on the CPU.

kkartaltepe commented 2 years ago

Your system appears supported by the nvidia 470 driver, have you tried updating it?

--- edit Sorry similar cards are supported in the 470 series, but it seems your card stopped being documented by nvidia later in the 4xx series.

kkartaltepe commented 2 years ago

Thanks for testing the workaround and confirming it doesnt work on desktop releases of the 390 drivers despite working on their tegra drivers.

ehdocumentdesign commented 2 years ago

Yes, the NVIDIA product names are a bit confusing.

It looks like the "GeForce GT 640" and the "GeForce GT 640M LE" cards are supported by the 470 driver, but not the "GeForce GT 640M".

Glad I could help even if it didn't work for me. I'll check the forums for the version 27 build instructions. I was able to build, but I might be missing a dependency or two.

kkartaltepe commented 2 years ago

Also since the workaround does not work you should just stay on the older version, instead of building yourself, until you decide to upgrade your system. You can find all ppa releases at https://launchpad.net/~obsproject/+archive/ubuntu/obs-studio/+packages?field.name_filter=&field.status_filter=&field.series_filter=jammy and manually install the deb that way.

ehdocumentdesign commented 2 years ago

Thanks for the link, I was having trouble finding older PPA versions.

Let me restore a backup of my system from before I added all the version 28 build dependencies. I'll reply again later.

ehdocumentdesign commented 2 years ago

Followup-- Yes, the .deb package for version 27.2.4 is running, and Window Capture (Xcomposite) works as expected.

Worth noting, .deb package wanted to replace several codec libraries. For example, it seems Linux Mint 21 ships with its own libavcodec-extra58 instead of the standard libavcodec58. I was able to install the libraries OBS requested with no trouble, and (so far) my other multimedia apps work with them as well.

theofficialgman commented 2 years ago

It looks like the "GeForce GT 640" and the "GeForce GT 640M LE" cards are supported by the 470 driver, but not the "GeForce GT 640M".

While these cards share similar names, they are not similar. the GT 640 is a Fermi based card (GF116-150-A1), the GT 640M LE is luck of the draw with two variants one Kepler and one Fermi (GF108 GK107), and finally (your card) is Kepler based (GK107).

You are lucky as this card CAN get a more modern driver based on the 400 series (since it is a Kepler based card which is newer architecture than fermi).

the driver you can uses is the 430.40 series, there is no ppa for this so you will need to manually install from nvidia's website https://www.nvidia.com/Download/driverResults.aspx/149138/en-us/ Note that later releaeses of the 430.XX series driver removed support for this card, 430.40 is the latest. There is also no guarantee that this older driver (released in 2019) has a kernel module that will build on your newer kernel.

The tegra driver which I had tested that worked with the check removed is based on the 400 series drivers

kkartaltepe commented 2 years ago

It looks like we've got some good feedback so far. Desktop machines that are on the 390 LTS branch wont work even if the check for the extension is removed. Desktop machines somewhere after that might work when ignoring the check, but the next nvidia+debian supported LTS 470 (and all later releases) works as expected.

The list of devices supported on 470 is available at https://download.nvidia.com/XFree86/Linux-x86_64/470.129.06/README/supportedchips.html

--- edit Also see this nice list of support timelines for the nvidia driver series, the 390 series is end of life at the end of this year. https://endoflife.date/nvidia