rust-windowing / glutin

A low-level library for OpenGL context creation
Apache License 2.0
1.98k stars 475 forks source link

[Windows] Unable to create non-SRGB framebuffer #1175

Closed LukasKalbertodt closed 2 years ago

LukasKalbertodt commented 5 years ago

Hello there!

I have found a few other issues related to sRGB, but they simply do not help me and I am still incredibly confused. My problem is that ContextBuilder::with_srgb does not seem to have any effect. Check out this minimal example (using glium):

```rust #[macro_use] extern crate glium; fn main() { #[allow(unused_imports)] use glium::{glutin, Surface}; let events_loop = glutin::EventsLoop::new(); let wb = glutin::WindowBuilder::new(); let cb = glutin::ContextBuilder::new().with_srgb(false); // MARK A ------- let display = glium::Display::new(wb, cb, &events_loop).unwrap(); #[derive(Copy, Clone)] struct Vertex { position: [f32; 2], } implement_vertex!(Vertex, position); let shape = vec![ Vertex { position: [-1.0, -1.0] }, Vertex { position: [-1.0, 1.0] }, Vertex { position: [ 1.0, -1.0] }, Vertex { position: [ 1.0, 1.0] }, ]; let vertex_buffer = glium::VertexBuffer::new(&display, &shape).unwrap(); let indices = glium::index::NoIndices(glium::index::PrimitiveType::TriangleStrip); let vertex_shader_src = r#" #version 140 in vec2 position; void main() { gl_Position = vec4(position, 0.0, 1.0); } "#; let fragment_shader_src = r#" #version 140 out vec4 color; void main() { color = vec4(vec3(0.5), 1.0); } "#; let program = glium::Program::new( &display, glium::program::ProgramCreationInput::SourceCode { vertex_shader: vertex_shader_src, tessellation_control_shader: None, tessellation_evaluation_shader: None, geometry_shader: None, fragment_shader: fragment_shader_src, transform_feedback_varyings: None, outputs_srgb: false, // MARK B ---------------------------------- uses_point_size: false, } ).unwrap(); loop { let mut target = display.draw(); target.draw(&vertex_buffer, &indices, &program, &uniform!{}, &Default::default()).unwrap(); target.finish().unwrap(); } } ```

There are two places of interest which I will explain later.

My test setup is the following: I run this program and take a screenshot and then inspect what color value the pixels have. For the four possible configurations, I get the following values:

.with_srgb(false) .with_srgb(true)
outputs_srgb: false #bbbbbb #bbbbbb
outputs_srgb: true #808080 #808080

So as far as I understand: there is the GL_FRAMEBUFFER_SRGB flag. If that flag is false, OpenGL does not perform any conversion from fragment shader to frame buffer. If it is enabled, however, OpenGL assumes that the shader output is linear RGB and will thus -- if the frame buffer has an sRGB format -- convert the shader output to sRGB. In glium, GL_FRAMEBUFFER_SRGB is controlled by the outputs_srgb parameter of the program. If the latter is false, GL_FRAMEBUFFER_SRGB is set to true and the other way around.

Additionally, I would expect glutin to create a framebuffer with the format specified by .with_srgb(_). As such, I have the following expectations:

This issue is about the first situation. As far as I can tell, this is just wrong.

I tested the above on several platforms: Ubuntu 18.04, MacOS and Windows. I always got the same results (well, on MacOS and Windows the #bbbbbb was slightly off, but still way more than #808080).

(I also did a test with GLFW in case that's interesting. I used the simple example and changed line 63 to " gl_FragColor = vec4(vec3(0.5), 1.0);\n". Running that, I get a #808080 triangle.)

Am I doing something wrong? Am I completely misunderstanding color spaces? Is this a bug in glutin/glium/...? Would be super great if someone could help me!

goddessfreya commented 5 years ago

Can you call this function and see if you actually got an sRGB context on linux? https://docs.rs/glutin/0.22.0-alpha1/glutin/struct.ContextWrapper.html#method.get_pixel_format

Can you call this function to check if you got an EGL context on linux? https://docs.rs/glutin/0.22.0-alpha1/glutin/struct.Context.html#method.get_egl_display

Currently sRGB support should work with GLX, but not EGL. No clue about WGL. on MacOS I have a burning suspicion it is broken (https://github.com/rust-windowing/glutin/issues/1160).

LukasKalbertodt commented 5 years ago

Executing the following immediately after creating the display:

use crate::glium::glutin::os::ContextTraitExt;
println!("{:#?}", display.gl_window().get_pixel_format());
println!("{:?}", unsafe { display.gl_window().get_egl_display() });

... with with_srgb(false) results in:

PixelFormat {
    hardware_accelerated: true,
    color_bits: 24,
    alpha_bits: 8,
    depth_bits: 24,
    stencil_bits: 8,
    stereoscopy: false,
    double_buffer: true,
    multisampling: None,
    srgb: false,
}
None

With with_srgb(true) the field srgb is true. So judging from this, it seems to work! However, that still doesn't explain why I get the wrong color (in other words: why the color conversion is performed).

EDIT: I guess it would be useful to see the output of glGetFramebufferAttachmentParameter(GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING)). I will try to get that information later!

goddessfreya commented 5 years ago

Right, hmmm. On linux, can you check if it thinks it's srgb? https://community.khronos.org/t/check-color-encoding-in-the-default-framebuffer-draw-buffer-for-srgb/72854

Also, can you provide some hardware info: Linux: Just run glxinfo && glinfo && lspci

LukasKalbertodt commented 5 years ago

Thanks for answering so fast! :)

Right, hmmm. On linux, can you check if it thinks it's srgb? https://community.khronos.org/t/check-color-encoding-in-the-default-framebuffer-draw-buffer-for-srgb/72854

I never executed raw OpenGL calls when using glium. Could you give me a quick pointer how I would do that? I can also figure it out myself tomorrow, that would not be a problem, but maybe you can speed this up by giving me some pointers ^_^

Also, can you provide some hardware info: Linux: Just run glxinfo && glinfo && lspci

Did you mean eglinfo?

``` $ lspci 00:00.0 Host bridge: Intel Corporation Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor Host Bridge/DRAM Registers (rev 07) 00:01.0 PCI bridge: Intel Corporation Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor PCIe Controller (x16) (rev 07) 00:01.2 PCI bridge: Intel Corporation Xeon E3-1200 v5/E3-1500 v5/6th Gen Core Processor PCIe Controller (x4) (rev 07) 00:02.0 VGA compatible controller: Intel Corporation HD Graphics 530 (rev 06) 00:14.0 USB controller: Intel Corporation 100 Series/C230 Series Chipset Family USB 3.0 xHCI Controller (rev 31) 00:14.2 Signal processing controller: Intel Corporation 100 Series/C230 Series Chipset Family Thermal Subsystem (rev 31) 00:16.0 Communication controller: Intel Corporation 100 Series/C230 Series Chipset Family MEI Controller #1 (rev 31) 00:17.0 SATA controller: Intel Corporation HM170/QM170 Chipset SATA Controller [AHCI Mode] (rev 31) 00:1c.0 PCI bridge: Intel Corporation 100 Series/C230 Series Chipset Family PCI Express Root Port #1 (rev f1) 00:1c.4 PCI bridge: Intel Corporation 100 Series/C230 Series Chipset Family PCI Express Root Port #5 (rev f1) 00:1f.0 ISA bridge: Intel Corporation QM170 Chipset LPC/eSPI Controller (rev 31) 00:1f.2 Memory controller: Intel Corporation 100 Series/C230 Series Chipset Family Power Management Controller (rev 31) 00:1f.3 Audio device: Intel Corporation 100 Series/C230 Series Chipset Family HD Audio Controller (rev 31) 00:1f.4 SMBus: Intel Corporation 100 Series/C230 Series Chipset Family SMBus (rev 31) 00:1f.6 Ethernet controller: Intel Corporation Ethernet Connection (2) I219-LM (rev 31) 02:00.0 3D controller: NVIDIA Corporation GM108M [GeForce 940MX] (rev a2) 03:00.0 Network controller: Intel Corporation Wireless 8260 (rev 3a) 04:00.0 Unassigned class [ff00]: Realtek Semiconductor Co., Ltd. RTS522A PCI Express Card Reader (rev 01) $ glxinfo name of display: :0 display: :0 screen: 0 direct rendering: Yes server glx vendor string: SGI server glx version string: 1.4 server glx extensions: GLX_ARB_create_context, GLX_ARB_create_context_profile, GLX_ARB_create_context_robustness, GLX_ARB_fbconfig_float, GLX_ARB_framebuffer_sRGB, GLX_ARB_multisample, GLX_EXT_create_context_es2_profile, GLX_EXT_create_context_es_profile, GLX_EXT_fbconfig_packed_float, GLX_EXT_framebuffer_sRGB, GLX_EXT_import_context, GLX_EXT_libglvnd, GLX_EXT_texture_from_pixmap, GLX_EXT_visual_info, GLX_EXT_visual_rating, GLX_INTEL_swap_event, GLX_MESA_copy_sub_buffer, GLX_OML_swap_method, GLX_SGIS_multisample, GLX_SGIX_fbconfig, GLX_SGIX_pbuffer, GLX_SGIX_visual_select_group, GLX_SGI_make_current_read, GLX_SGI_swap_control client glx vendor string: Mesa Project and SGI client glx version string: 1.4 client glx extensions: GLX_ARB_context_flush_control, GLX_ARB_create_context, GLX_ARB_create_context_profile, GLX_ARB_create_context_robustness, GLX_ARB_fbconfig_float, GLX_ARB_framebuffer_sRGB, GLX_ARB_get_proc_address, GLX_ARB_multisample, GLX_EXT_buffer_age, GLX_EXT_create_context_es2_profile, GLX_EXT_create_context_es_profile, GLX_EXT_fbconfig_packed_float, GLX_EXT_framebuffer_sRGB, GLX_EXT_import_context, GLX_EXT_texture_from_pixmap, GLX_EXT_visual_info, GLX_EXT_visual_rating, GLX_INTEL_swap_event, GLX_MESA_copy_sub_buffer, GLX_MESA_multithread_makecurrent, GLX_MESA_query_renderer, GLX_MESA_swap_control, GLX_OML_swap_method, GLX_OML_sync_control, GLX_SGIS_multisample, GLX_SGIX_fbconfig, GLX_SGIX_pbuffer, GLX_SGIX_visual_select_group, GLX_SGI_make_current_read, GLX_SGI_swap_control, GLX_SGI_video_sync GLX version: 1.4 GLX extensions: GLX_ARB_create_context, GLX_ARB_create_context_profile, GLX_ARB_create_context_robustness, GLX_ARB_fbconfig_float, GLX_ARB_framebuffer_sRGB, GLX_ARB_get_proc_address, GLX_ARB_multisample, GLX_EXT_buffer_age, GLX_EXT_create_context_es2_profile, GLX_EXT_create_context_es_profile, GLX_EXT_fbconfig_packed_float, GLX_EXT_framebuffer_sRGB, GLX_EXT_import_context, GLX_EXT_texture_from_pixmap, GLX_EXT_visual_info, GLX_EXT_visual_rating, GLX_INTEL_swap_event, GLX_MESA_copy_sub_buffer, GLX_MESA_query_renderer, GLX_MESA_swap_control, GLX_OML_swap_method, GLX_OML_sync_control, GLX_SGIS_multisample, GLX_SGIX_fbconfig, GLX_SGIX_pbuffer, GLX_SGIX_visual_select_group, GLX_SGI_make_current_read, GLX_SGI_swap_control, GLX_SGI_video_sync Extended renderer info (GLX_MESA_query_renderer): Vendor: Intel Open Source Technology Center (0x8086) Device: Mesa DRI Intel(R) HD Graphics 530 (Skylake GT2) (0x191b) Version: 18.2.8 Accelerated: yes Video memory: 3072MB Unified memory: yes Preferred profile: core (0x1) Max core profile version: 4.5 Max compat profile version: 3.0 Max GLES1 profile version: 1.1 Max GLES[23] profile version: 3.2 OpenGL vendor string: Intel Open Source Technology Center OpenGL renderer string: Mesa DRI Intel(R) HD Graphics 530 (Skylake GT2) OpenGL core profile version string: 4.5 (Core Profile) Mesa 18.2.8 OpenGL core profile shading language version string: 4.50 OpenGL core profile context flags: (none) OpenGL core profile profile mask: core profile OpenGL core profile extensions: GL_3DFX_texture_compression_FXT1, GL_AMD_conservative_depth, GL_AMD_draw_buffers_blend, GL_AMD_seamless_cubemap_per_texture, GL_AMD_shader_stencil_export, GL_AMD_shader_trinary_minmax, GL_AMD_vertex_shader_layer, GL_AMD_vertex_shader_viewport_index, GL_ANGLE_texture_compression_dxt3, GL_ANGLE_texture_compression_dxt5, GL_APPLE_object_purgeable, GL_ARB_ES2_compatibility, GL_ARB_ES3_1_compatibility, GL_ARB_ES3_2_compatibility, GL_ARB_ES3_compatibility, GL_ARB_arrays_of_arrays, GL_ARB_base_instance, GL_ARB_blend_func_extended, GL_ARB_buffer_storage, GL_ARB_clear_buffer_object, GL_ARB_clear_texture, GL_ARB_clip_control, GL_ARB_compressed_texture_pixel_storage, GL_ARB_compute_shader, GL_ARB_conditional_render_inverted, GL_ARB_conservative_depth, GL_ARB_copy_buffer, GL_ARB_copy_image, GL_ARB_cull_distance, GL_ARB_debug_output, GL_ARB_depth_buffer_float, GL_ARB_depth_clamp, GL_ARB_derivative_control, GL_ARB_direct_state_access, GL_ARB_draw_buffers, GL_ARB_draw_buffers_blend, GL_ARB_draw_elements_base_vertex, GL_ARB_draw_indirect, GL_ARB_draw_instanced, GL_ARB_enhanced_layouts, GL_ARB_explicit_attrib_location, GL_ARB_explicit_uniform_location, GL_ARB_fragment_coord_conventions, GL_ARB_fragment_layer_viewport, GL_ARB_fragment_shader, GL_ARB_fragment_shader_interlock, GL_ARB_framebuffer_no_attachments, GL_ARB_framebuffer_object, GL_ARB_framebuffer_sRGB, GL_ARB_get_program_binary, GL_ARB_get_texture_sub_image, GL_ARB_gpu_shader5, GL_ARB_gpu_shader_fp64, GL_ARB_gpu_shader_int64, GL_ARB_half_float_pixel, GL_ARB_half_float_vertex, GL_ARB_indirect_parameters, GL_ARB_instanced_arrays, GL_ARB_internalformat_query, GL_ARB_internalformat_query2, GL_ARB_invalidate_subdata, GL_ARB_map_buffer_alignment, GL_ARB_map_buffer_range, GL_ARB_multi_bind, GL_ARB_multi_draw_indirect, GL_ARB_occlusion_query2, GL_ARB_pipeline_statistics_query, GL_ARB_pixel_buffer_object, GL_ARB_point_sprite, GL_ARB_polygon_offset_clamp, GL_ARB_post_depth_coverage, GL_ARB_program_interface_query, GL_ARB_provoking_vertex, GL_ARB_query_buffer_object, GL_ARB_robust_buffer_access_behavior, GL_ARB_robustness, GL_ARB_sample_shading, GL_ARB_sampler_objects, GL_ARB_seamless_cube_map, GL_ARB_seamless_cubemap_per_texture, GL_ARB_separate_shader_objects, GL_ARB_shader_atomic_counter_ops, GL_ARB_shader_atomic_counters, GL_ARB_shader_ballot, GL_ARB_shader_bit_encoding, GL_ARB_shader_clock, GL_ARB_shader_draw_parameters, GL_ARB_shader_group_vote, GL_ARB_shader_image_load_store, GL_ARB_shader_image_size, GL_ARB_shader_objects, GL_ARB_shader_precision, GL_ARB_shader_stencil_export, GL_ARB_shader_storage_buffer_object, GL_ARB_shader_subroutine, GL_ARB_shader_texture_image_samples, GL_ARB_shader_texture_lod, GL_ARB_shader_viewport_layer_array, GL_ARB_shading_language_420pack, GL_ARB_shading_language_packing, GL_ARB_stencil_texturing, GL_ARB_sync, GL_ARB_tessellation_shader, GL_ARB_texture_barrier, GL_ARB_texture_buffer_object, GL_ARB_texture_buffer_object_rgb32, GL_ARB_texture_buffer_range, GL_ARB_texture_compression_bptc, GL_ARB_texture_compression_rgtc, GL_ARB_texture_cube_map_array, GL_ARB_texture_filter_anisotropic, GL_ARB_texture_float, GL_ARB_texture_gather, GL_ARB_texture_mirror_clamp_to_edge, GL_ARB_texture_multisample, GL_ARB_texture_non_power_of_two, GL_ARB_texture_query_levels, GL_ARB_texture_query_lod, GL_ARB_texture_rectangle, GL_ARB_texture_rg, GL_ARB_texture_rgb10_a2ui, GL_ARB_texture_stencil8, GL_ARB_texture_storage, GL_ARB_texture_storage_multisample, GL_ARB_texture_swizzle, GL_ARB_texture_view, GL_ARB_timer_query, GL_ARB_transform_feedback2, GL_ARB_transform_feedback3, GL_ARB_transform_feedback_instanced, GL_ARB_transform_feedback_overflow_query, GL_ARB_uniform_buffer_object, GL_ARB_vertex_array_bgra, GL_ARB_vertex_array_object, GL_ARB_vertex_attrib_64bit, GL_ARB_vertex_attrib_binding, GL_ARB_vertex_shader, GL_ARB_vertex_type_10f_11f_11f_rev, GL_ARB_vertex_type_2_10_10_10_rev, GL_ARB_viewport_array, GL_ATI_blend_equation_separate, GL_ATI_texture_float, GL_EXT_abgr, GL_EXT_blend_equation_separate, GL_EXT_draw_buffers2, GL_EXT_draw_instanced, GL_EXT_framebuffer_blit, GL_EXT_framebuffer_multisample, GL_EXT_framebuffer_multisample_blit_scaled, GL_EXT_framebuffer_sRGB, GL_EXT_packed_depth_stencil, GL_EXT_packed_float, GL_EXT_pixel_buffer_object, GL_EXT_polygon_offset_clamp, GL_EXT_provoking_vertex, GL_EXT_shader_framebuffer_fetch, GL_EXT_shader_framebuffer_fetch_non_coherent, GL_EXT_shader_integer_mix, GL_EXT_shader_samples_identical, GL_EXT_texture_array, GL_EXT_texture_compression_dxt1, GL_EXT_texture_compression_rgtc, GL_EXT_texture_compression_s3tc, GL_EXT_texture_filter_anisotropic, GL_EXT_texture_integer, GL_EXT_texture_sRGB, GL_EXT_texture_sRGB_decode, GL_EXT_texture_shared_exponent, GL_EXT_texture_snorm, GL_EXT_texture_swizzle, GL_EXT_timer_query, GL_EXT_transform_feedback, GL_EXT_vertex_array_bgra, GL_IBM_multimode_draw_arrays, GL_INTEL_conservative_rasterization, GL_INTEL_performance_query, GL_KHR_blend_equation_advanced, GL_KHR_blend_equation_advanced_coherent, GL_KHR_context_flush_control, GL_KHR_debug, GL_KHR_no_error, GL_KHR_robust_buffer_access_behavior, GL_KHR_robustness, GL_KHR_texture_compression_astc_ldr, GL_KHR_texture_compression_astc_sliced_3d, GL_MESA_pack_invert, GL_MESA_shader_integer_functions, GL_MESA_texture_signed_rgba, GL_NV_conditional_render, GL_NV_depth_clamp, GL_NV_packed_depth_stencil, GL_NV_texture_barrier, GL_OES_EGL_image, GL_S3_s3tc OpenGL version string: 3.0 Mesa 18.2.8 OpenGL shading language version string: 1.30 OpenGL context flags: (none) OpenGL extensions: GL_3DFX_texture_compression_FXT1, GL_AMD_conservative_depth, GL_AMD_draw_buffers_blend, GL_AMD_seamless_cubemap_per_texture, GL_AMD_shader_stencil_export, GL_AMD_shader_trinary_minmax, GL_ANGLE_texture_compression_dxt3, GL_ANGLE_texture_compression_dxt5, GL_APPLE_object_purgeable, GL_APPLE_packed_pixels, GL_ARB_ES2_compatibility, GL_ARB_ES3_1_compatibility, GL_ARB_ES3_compatibility, GL_ARB_arrays_of_arrays, GL_ARB_blend_func_extended, GL_ARB_buffer_storage, GL_ARB_clear_buffer_object, GL_ARB_clear_texture, GL_ARB_clip_control, GL_ARB_color_buffer_float, GL_ARB_compressed_texture_pixel_storage, GL_ARB_compute_shader, GL_ARB_conditional_render_inverted, GL_ARB_conservative_depth, GL_ARB_copy_buffer, GL_ARB_copy_image, GL_ARB_cull_distance, GL_ARB_debug_output, GL_ARB_depth_buffer_float, GL_ARB_depth_clamp, GL_ARB_depth_texture, GL_ARB_derivative_control, GL_ARB_draw_buffers, GL_ARB_draw_buffers_blend, GL_ARB_draw_elements_base_vertex, GL_ARB_draw_indirect, GL_ARB_draw_instanced, GL_ARB_explicit_attrib_location, GL_ARB_explicit_uniform_location, GL_ARB_fragment_coord_conventions, GL_ARB_fragment_layer_viewport, GL_ARB_fragment_program, GL_ARB_fragment_program_shadow, GL_ARB_fragment_shader, GL_ARB_fragment_shader_interlock, GL_ARB_framebuffer_no_attachments, GL_ARB_framebuffer_object, GL_ARB_framebuffer_sRGB, GL_ARB_get_program_binary, GL_ARB_get_texture_sub_image, GL_ARB_half_float_pixel, GL_ARB_half_float_vertex, GL_ARB_indirect_parameters, GL_ARB_instanced_arrays, GL_ARB_internalformat_query, GL_ARB_internalformat_query2, GL_ARB_invalidate_subdata, GL_ARB_map_buffer_alignment, GL_ARB_map_buffer_range, GL_ARB_multi_bind, GL_ARB_multi_draw_indirect, GL_ARB_multisample, GL_ARB_multitexture, GL_ARB_occlusion_query, GL_ARB_occlusion_query2, GL_ARB_pipeline_statistics_query, GL_ARB_pixel_buffer_object, GL_ARB_point_parameters, GL_ARB_point_sprite, GL_ARB_polygon_offset_clamp, GL_ARB_program_interface_query, GL_ARB_provoking_vertex, GL_ARB_query_buffer_object, GL_ARB_robust_buffer_access_behavior, GL_ARB_robustness, GL_ARB_sample_shading, GL_ARB_sampler_objects, GL_ARB_seamless_cube_map, GL_ARB_seamless_cubemap_per_texture, GL_ARB_separate_shader_objects, GL_ARB_shader_atomic_counter_ops, GL_ARB_shader_atomic_counters, GL_ARB_shader_ballot, GL_ARB_shader_bit_encoding, GL_ARB_shader_clock, GL_ARB_shader_draw_parameters, GL_ARB_shader_group_vote, GL_ARB_shader_image_load_store, GL_ARB_shader_image_size, GL_ARB_shader_objects, GL_ARB_shader_precision, GL_ARB_shader_stencil_export, GL_ARB_shader_storage_buffer_object, GL_ARB_shader_texture_image_samples, GL_ARB_shader_texture_lod, GL_ARB_shading_language_100, GL_ARB_shading_language_420pack, GL_ARB_shading_language_packing, GL_ARB_shadow, GL_ARB_stencil_texturing, GL_ARB_sync, GL_ARB_texture_barrier, GL_ARB_texture_border_clamp, GL_ARB_texture_compression, GL_ARB_texture_compression_bptc, GL_ARB_texture_compression_rgtc, GL_ARB_texture_cube_map, GL_ARB_texture_cube_map_array, GL_ARB_texture_env_add, GL_ARB_texture_env_combine, GL_ARB_texture_env_crossbar, GL_ARB_texture_env_dot3, GL_ARB_texture_filter_anisotropic, GL_ARB_texture_float, GL_ARB_texture_gather, GL_ARB_texture_mirror_clamp_to_edge, GL_ARB_texture_mirrored_repeat, GL_ARB_texture_multisample, GL_ARB_texture_non_power_of_two, GL_ARB_texture_query_levels, GL_ARB_texture_query_lod, GL_ARB_texture_rectangle, GL_ARB_texture_rg, GL_ARB_texture_rgb10_a2ui, GL_ARB_texture_stencil8, GL_ARB_texture_storage, GL_ARB_texture_storage_multisample, GL_ARB_texture_swizzle, GL_ARB_texture_view, GL_ARB_timer_query, GL_ARB_transform_feedback2, GL_ARB_transform_feedback3, GL_ARB_transform_feedback_instanced, GL_ARB_transform_feedback_overflow_query, GL_ARB_transpose_matrix, GL_ARB_uniform_buffer_object, GL_ARB_vertex_array_bgra, GL_ARB_vertex_array_object, GL_ARB_vertex_attrib_binding, GL_ARB_vertex_buffer_object, GL_ARB_vertex_program, GL_ARB_vertex_shader, GL_ARB_vertex_type_10f_11f_11f_rev, GL_ARB_vertex_type_2_10_10_10_rev, GL_ARB_window_pos, GL_ATI_blend_equation_separate, GL_ATI_draw_buffers, GL_ATI_separate_stencil, GL_ATI_texture_env_combine3, GL_ATI_texture_float, GL_EXT_abgr, GL_EXT_bgra, GL_EXT_blend_color, GL_EXT_blend_equation_separate, GL_EXT_blend_func_separate, GL_EXT_blend_minmax, GL_EXT_blend_subtract, GL_EXT_compiled_vertex_array, GL_EXT_copy_texture, GL_EXT_draw_buffers2, GL_EXT_draw_instanced, GL_EXT_draw_range_elements, GL_EXT_fog_coord, GL_EXT_framebuffer_blit, GL_EXT_framebuffer_multisample, GL_EXT_framebuffer_multisample_blit_scaled, GL_EXT_framebuffer_object, GL_EXT_framebuffer_sRGB, GL_EXT_gpu_program_parameters, GL_EXT_multi_draw_arrays, GL_EXT_packed_depth_stencil, GL_EXT_packed_float, GL_EXT_packed_pixels, GL_EXT_pixel_buffer_object, GL_EXT_point_parameters, GL_EXT_polygon_offset_clamp, GL_EXT_provoking_vertex, GL_EXT_rescale_normal, GL_EXT_secondary_color, GL_EXT_separate_specular_color, GL_EXT_shader_framebuffer_fetch, GL_EXT_shader_framebuffer_fetch_non_coherent, GL_EXT_shader_integer_mix, GL_EXT_shader_samples_identical, GL_EXT_shadow_funcs, GL_EXT_stencil_two_side, GL_EXT_stencil_wrap, GL_EXT_subtexture, GL_EXT_texture, GL_EXT_texture3D, GL_EXT_texture_array, GL_EXT_texture_compression_dxt1, GL_EXT_texture_compression_rgtc, GL_EXT_texture_compression_s3tc, GL_EXT_texture_cube_map, GL_EXT_texture_edge_clamp, GL_EXT_texture_env_add, GL_EXT_texture_env_combine, GL_EXT_texture_env_dot3, GL_EXT_texture_filter_anisotropic, GL_EXT_texture_integer, GL_EXT_texture_lod_bias, GL_EXT_texture_object, GL_EXT_texture_rectangle, GL_EXT_texture_sRGB, GL_EXT_texture_sRGB_decode, GL_EXT_texture_shared_exponent, GL_EXT_texture_snorm, GL_EXT_texture_swizzle, GL_EXT_timer_query, GL_EXT_transform_feedback, GL_EXT_vertex_array, GL_EXT_vertex_array_bgra, GL_IBM_multimode_draw_arrays, GL_IBM_rasterpos_clip, GL_IBM_texture_mirrored_repeat, GL_INGR_blend_func_separate, GL_INTEL_performance_query, GL_KHR_blend_equation_advanced, GL_KHR_blend_equation_advanced_coherent, GL_KHR_context_flush_control, GL_KHR_debug, GL_KHR_no_error, GL_KHR_robust_buffer_access_behavior, GL_KHR_robustness, GL_KHR_texture_compression_astc_ldr, GL_KHR_texture_compression_astc_sliced_3d, GL_MESA_pack_invert, GL_MESA_shader_integer_functions, GL_MESA_texture_signed_rgba, GL_MESA_window_pos, GL_NV_blend_square, GL_NV_conditional_render, GL_NV_depth_clamp, GL_NV_fog_distance, GL_NV_light_max_exponent, GL_NV_packed_depth_stencil, GL_NV_primitive_restart, GL_NV_texgen_reflection, GL_NV_texture_barrier, GL_NV_texture_env_combine4, GL_NV_texture_rectangle, GL_OES_EGL_image, GL_OES_read_format, GL_S3_s3tc, GL_SGIS_generate_mipmap, GL_SGIS_texture_border_clamp, GL_SGIS_texture_edge_clamp, GL_SGIS_texture_lod, GL_SUN_multi_draw_arrays OpenGL ES profile version string: OpenGL ES 3.2 Mesa 18.2.8 OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.20 OpenGL ES profile extensions: GL_ANDROID_extension_pack_es31a, GL_ANGLE_texture_compression_dxt3, GL_ANGLE_texture_compression_dxt5, GL_APPLE_texture_max_level, GL_EXT_base_instance, GL_EXT_blend_func_extended, GL_EXT_blend_minmax, GL_EXT_buffer_storage, GL_EXT_clip_cull_distance, GL_EXT_color_buffer_float, GL_EXT_compressed_ETC1_RGB8_sub_texture, GL_EXT_copy_image, GL_EXT_discard_framebuffer, GL_EXT_disjoint_timer_query, GL_EXT_draw_buffers, GL_EXT_draw_buffers_indexed, GL_EXT_draw_elements_base_vertex, 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_arrays, GL_EXT_occlusion_query_boolean, GL_EXT_polygon_offset_clamp, GL_EXT_primitive_bounding_box, GL_EXT_read_format_bgra, GL_EXT_robustness, GL_EXT_separate_shader_objects, GL_EXT_shader_framebuffer_fetch, GL_EXT_shader_framebuffer_fetch_non_coherent, GL_EXT_shader_integer_mix, GL_EXT_shader_io_blocks, GL_EXT_shader_samples_identical, GL_EXT_tessellation_point_size, GL_EXT_tessellation_shader, GL_EXT_texture_border_clamp, GL_EXT_texture_buffer, GL_EXT_texture_compression_dxt1, GL_EXT_texture_cube_map_array, GL_EXT_texture_filter_anisotropic, GL_EXT_texture_format_BGRA8888, GL_EXT_texture_norm16, GL_EXT_texture_rg, GL_EXT_texture_sRGB_decode, GL_EXT_texture_type_2_10_10_10_REV, GL_EXT_unpack_subimage, GL_INTEL_conservative_rasterization, GL_INTEL_performance_query, GL_KHR_blend_equation_advanced, GL_KHR_blend_equation_advanced_coherent, GL_KHR_context_flush_control, GL_KHR_debug, GL_KHR_no_error, GL_KHR_robust_buffer_access_behavior, GL_KHR_robustness, GL_KHR_texture_compression_astc_ldr, GL_KHR_texture_compression_astc_sliced_3d, GL_MESA_framebuffer_flip_y, GL_MESA_shader_integer_functions, GL_NV_draw_buffers, GL_NV_fbo_color_attachments, GL_NV_image_formats, GL_NV_read_buffer, GL_NV_read_depth, GL_NV_read_depth_stencil, GL_NV_read_stencil, GL_OES_EGL_image, GL_OES_EGL_image_external, GL_OES_EGL_image_external_essl3, GL_OES_EGL_sync, GL_OES_compressed_ETC1_RGB8_texture, GL_OES_copy_image, GL_OES_depth24, GL_OES_depth_texture, GL_OES_depth_texture_cube_map, GL_OES_draw_buffers_indexed, GL_OES_draw_elements_base_vertex, GL_OES_element_index_uint, GL_OES_fbo_render_mipmap, GL_OES_geometry_point_size, GL_OES_geometry_shader, GL_OES_get_program_binary, GL_OES_gpu_shader5, GL_OES_mapbuffer, GL_OES_packed_depth_stencil, GL_OES_primitive_bounding_box, GL_OES_required_internalformat, GL_OES_rgb8_rgba8, GL_OES_sample_shading, GL_OES_sample_variables, GL_OES_shader_image_atomic, GL_OES_shader_io_blocks, GL_OES_shader_multisample_interpolation, GL_OES_standard_derivatives, GL_OES_stencil8, GL_OES_surfaceless_context, GL_OES_tessellation_point_size, GL_OES_tessellation_shader, GL_OES_texture_3D, GL_OES_texture_border_clamp, GL_OES_texture_buffer, GL_OES_texture_cube_map_array, GL_OES_texture_float, GL_OES_texture_float_linear, GL_OES_texture_half_float, GL_OES_texture_half_float_linear, GL_OES_texture_npot, GL_OES_texture_stencil8, GL_OES_texture_storage_multisample_2d_array, GL_OES_texture_view, GL_OES_vertex_array_object, GL_OES_vertex_half_float, GL_OES_viewport_array 94 GLX Visuals visual x bf lv rg d st colorbuffer sr ax dp st accumbuffer ms cav id dep cl sp sz l ci b ro r g b a F gb bf th cl r g b a ns b eat ---------------------------------------------------------------------------- 0x041 24 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None 0x042 24 dc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None 0x161 24 tc 0 32 0 r y . 8 8 8 8 . . 0 0 0 0 0 0 0 0 0 None 0x162 24 tc 0 32 0 r . . 8 8 8 8 . . 0 0 0 0 0 0 0 0 0 None 0x163 24 tc 0 32 0 r . . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None 0x164 24 tc 0 24 0 r y . 8 8 8 0 . . 0 0 0 0 0 0 0 0 0 None 0x165 24 tc 0 24 0 r . . 8 8 8 0 . . 0 0 0 0 0 0 0 0 0 None 0x166 24 tc 0 24 0 r y . 8 8 8 0 . . 0 24 8 0 0 0 0 0 0 None 0x167 24 tc 0 24 0 r . . 8 8 8 0 . . 0 24 8 0 0 0 0 0 0 None 0x168 24 tc 0 32 0 r y . 8 8 8 8 . s 0 0 0 0 0 0 0 0 0 None 0x169 24 tc 0 32 0 r . . 8 8 8 8 . s 0 0 0 0 0 0 0 0 0 None 0x16a 24 tc 0 32 0 r y . 8 8 8 8 . s 0 24 8 0 0 0 0 0 0 None 0x16b 24 tc 0 32 0 r . . 8 8 8 8 . s 0 24 8 0 0 0 0 0 0 None 0x16c 24 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None 0x16d 24 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 16 16 16 16 0 0 Slow 0x16e 24 tc 0 24 0 r y . 8 8 8 0 . . 0 24 8 0 0 0 0 0 0 None 0x16f 24 tc 0 24 0 r y . 8 8 8 0 . . 0 24 8 16 16 16 0 0 0 Slow 0x170 24 tc 0 32 0 r y . 8 8 8 8 . s 0 24 8 0 0 0 0 0 0 None 0x171 24 tc 0 32 0 r y . 8 8 8 8 . s 0 24 8 16 16 16 16 0 0 Slow 0x172 24 tc 0 32 0 r y . 8 8 8 8 . . 0 0 0 0 0 0 0 2 1 None 0x173 24 tc 0 32 0 r y . 8 8 8 8 . . 0 0 0 0 0 0 0 4 1 None 0x174 24 tc 0 32 0 r y . 8 8 8 8 . . 0 0 0 0 0 0 0 8 1 None 0x175 24 tc 0 32 0 r y . 8 8 8 8 . . 0 0 0 0 0 0 0 16 1 None 0x176 24 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 2 1 None 0x177 24 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 4 1 None 0x178 24 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 8 1 None 0x179 24 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 16 1 None 0x17a 24 tc 0 24 0 r y . 8 8 8 0 . . 0 0 0 0 0 0 0 2 1 None 0x17b 24 tc 0 24 0 r y . 8 8 8 0 . . 0 0 0 0 0 0 0 4 1 None 0x17c 24 tc 0 24 0 r y . 8 8 8 0 . . 0 0 0 0 0 0 0 8 1 None 0x17d 24 tc 0 24 0 r y . 8 8 8 0 . . 0 0 0 0 0 0 0 16 1 None 0x17e 24 tc 0 24 0 r y . 8 8 8 0 . . 0 24 8 0 0 0 0 2 1 None 0x17f 24 tc 0 24 0 r y . 8 8 8 0 . . 0 24 8 0 0 0 0 4 1 None 0x180 24 tc 0 24 0 r y . 8 8 8 0 . . 0 24 8 0 0 0 0 8 1 None 0x181 24 tc 0 24 0 r y . 8 8 8 0 . . 0 24 8 0 0 0 0 16 1 None 0x182 24 tc 0 32 0 r y . 8 8 8 8 . s 0 0 0 0 0 0 0 2 1 None 0x183 24 tc 0 32 0 r y . 8 8 8 8 . s 0 0 0 0 0 0 0 4 1 None 0x184 24 tc 0 32 0 r y . 8 8 8 8 . s 0 0 0 0 0 0 0 8 1 None 0x185 24 tc 0 32 0 r y . 8 8 8 8 . s 0 0 0 0 0 0 0 16 1 None 0x186 24 tc 0 32 0 r y . 8 8 8 8 . s 0 24 8 0 0 0 0 2 1 None 0x187 24 tc 0 32 0 r y . 8 8 8 8 . s 0 24 8 0 0 0 0 4 1 None 0x188 24 tc 0 32 0 r y . 8 8 8 8 . s 0 24 8 0 0 0 0 8 1 None 0x189 24 tc 0 32 0 r y . 8 8 8 8 . s 0 24 8 0 0 0 0 16 1 None 0x18a 24 dc 0 32 0 r y . 8 8 8 8 . . 0 0 0 0 0 0 0 0 0 None 0x18b 24 dc 0 32 0 r . . 8 8 8 8 . . 0 0 0 0 0 0 0 0 0 None 0x18c 24 dc 0 32 0 r . . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None 0x18d 24 dc 0 24 0 r y . 8 8 8 0 . . 0 0 0 0 0 0 0 0 0 None 0x18e 24 dc 0 24 0 r . . 8 8 8 0 . . 0 0 0 0 0 0 0 0 0 None 0x18f 24 dc 0 24 0 r y . 8 8 8 0 . . 0 24 8 0 0 0 0 0 0 None 0x190 24 dc 0 24 0 r . . 8 8 8 0 . . 0 24 8 0 0 0 0 0 0 None 0x191 24 dc 0 32 0 r y . 8 8 8 8 . s 0 0 0 0 0 0 0 0 0 None 0x192 24 dc 0 32 0 r . . 8 8 8 8 . s 0 0 0 0 0 0 0 0 0 None 0x193 24 dc 0 32 0 r y . 8 8 8 8 . s 0 24 8 0 0 0 0 0 0 None 0x194 24 dc 0 32 0 r . . 8 8 8 8 . s 0 24 8 0 0 0 0 0 0 None 0x195 24 dc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None 0x196 24 dc 0 32 0 r y . 8 8 8 8 . . 0 24 8 16 16 16 16 0 0 Slow 0x197 24 dc 0 24 0 r y . 8 8 8 0 . . 0 24 8 0 0 0 0 0 0 None 0x198 24 dc 0 24 0 r y . 8 8 8 0 . . 0 24 8 16 16 16 0 0 0 Slow 0x199 24 dc 0 32 0 r y . 8 8 8 8 . s 0 24 8 0 0 0 0 0 0 None 0x19a 24 dc 0 32 0 r y . 8 8 8 8 . s 0 24 8 16 16 16 16 0 0 Slow 0x19b 24 dc 0 32 0 r y . 8 8 8 8 . . 0 0 0 0 0 0 0 2 1 None 0x19c 24 dc 0 32 0 r y . 8 8 8 8 . . 0 0 0 0 0 0 0 4 1 None 0x19d 24 dc 0 32 0 r y . 8 8 8 8 . . 0 0 0 0 0 0 0 8 1 None 0x19e 24 dc 0 32 0 r y . 8 8 8 8 . . 0 0 0 0 0 0 0 16 1 None 0x19f 24 dc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 2 1 None 0x1a0 24 dc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 4 1 None 0x1a1 24 dc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 8 1 None 0x1a2 24 dc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 16 1 None 0x1a3 24 dc 0 24 0 r y . 8 8 8 0 . . 0 0 0 0 0 0 0 2 1 None 0x1a4 24 dc 0 24 0 r y . 8 8 8 0 . . 0 0 0 0 0 0 0 4 1 None 0x1a5 24 dc 0 24 0 r y . 8 8 8 0 . . 0 0 0 0 0 0 0 8 1 None 0x1a6 24 dc 0 24 0 r y . 8 8 8 0 . . 0 0 0 0 0 0 0 16 1 None 0x1a7 24 dc 0 24 0 r y . 8 8 8 0 . . 0 24 8 0 0 0 0 2 1 None 0x1a8 24 dc 0 24 0 r y . 8 8 8 0 . . 0 24 8 0 0 0 0 4 1 None 0x1a9 24 dc 0 24 0 r y . 8 8 8 0 . . 0 24 8 0 0 0 0 8 1 None 0x1aa 24 dc 0 24 0 r y . 8 8 8 0 . . 0 24 8 0 0 0 0 16 1 None 0x1ab 24 dc 0 32 0 r y . 8 8 8 8 . s 0 0 0 0 0 0 0 2 1 None 0x1ac 24 dc 0 32 0 r y . 8 8 8 8 . s 0 0 0 0 0 0 0 4 1 None 0x1ad 24 dc 0 32 0 r y . 8 8 8 8 . s 0 0 0 0 0 0 0 8 1 None 0x1ae 24 dc 0 32 0 r y . 8 8 8 8 . s 0 0 0 0 0 0 0 16 1 None 0x1af 24 dc 0 32 0 r y . 8 8 8 8 . s 0 24 8 0 0 0 0 2 1 None 0x1b0 24 dc 0 32 0 r y . 8 8 8 8 . s 0 24 8 0 0 0 0 4 1 None 0x1b1 24 dc 0 32 0 r y . 8 8 8 8 . s 0 24 8 0 0 0 0 8 1 None 0x1b2 24 dc 0 32 0 r y . 8 8 8 8 . s 0 24 8 0 0 0 0 16 1 None 0x0e2 32 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None 0x1b3 32 tc 0 32 0 r y . 8 8 8 8 . . 0 0 0 0 0 0 0 0 0 None 0x1b4 32 tc 0 32 0 r . . 8 8 8 8 . . 0 0 0 0 0 0 0 0 0 None 0x1b5 32 tc 0 32 0 r . . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None 0x1b6 32 tc 0 32 0 r y . 8 8 8 8 . s 0 0 0 0 0 0 0 0 0 None 0x1b7 32 tc 0 32 0 r . . 8 8 8 8 . s 0 0 0 0 0 0 0 0 0 None 0x1b8 32 tc 0 32 0 r y . 8 8 8 8 . s 0 24 8 0 0 0 0 0 0 None 0x1b9 32 tc 0 32 0 r . . 8 8 8 8 . s 0 24 8 0 0 0 0 0 0 None 0x1ba 32 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None 0x1bb 32 tc 0 32 0 r y . 8 8 8 8 . s 0 24 8 0 0 0 0 0 0 None 126 GLXFBConfigs: visual x bf lv rg d st colorbuffer sr ax dp st accumbuffer ms cav id dep cl sp sz l ci b ro r g b a F gb bf th cl r g b a ns b eat ---------------------------------------------------------------------------- 0x0e3 0 tc 0 16 0 r y . 5 6 5 0 . . 0 0 0 0 0 0 0 0 0 None 0x0e4 0 tc 0 16 0 r . . 5 6 5 0 . . 0 0 0 0 0 0 0 0 0 None 0x0e5 0 tc 0 16 0 r y . 5 6 5 0 . . 0 16 0 0 0 0 0 0 0 None 0x0e6 0 tc 0 16 0 r . . 5 6 5 0 . . 0 16 0 0 0 0 0 0 0 None 0x0e7 0 tc 0 16 0 r y . 5 6 5 0 . . 0 24 8 0 0 0 0 0 0 None 0x0e8 0 tc 0 16 0 r . . 5 6 5 0 . . 0 24 8 0 0 0 0 0 0 None 0x0e9 24 tc 0 32 0 r y . 8 8 8 8 . . 0 0 0 0 0 0 0 0 0 None 0x0ea 24 tc 0 32 0 r . . 8 8 8 8 . . 0 0 0 0 0 0 0 0 0 None 0x0eb 24 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None 0x0ec 24 tc 0 32 0 r . . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None 0x0ed 24 tc 0 24 0 r y . 8 8 8 0 . . 0 0 0 0 0 0 0 0 0 None 0x0ee 24 tc 0 24 0 r . . 8 8 8 0 . . 0 0 0 0 0 0 0 0 0 None 0x0ef 24 tc 0 24 0 r y . 8 8 8 0 . . 0 24 8 0 0 0 0 0 0 None 0x0f0 24 tc 0 24 0 r . . 8 8 8 0 . . 0 24 8 0 0 0 0 0 0 None 0x0f1 24 tc 0 32 0 r y . 8 8 8 8 . s 0 0 0 0 0 0 0 0 0 None 0x0f2 24 tc 0 32 0 r . . 8 8 8 8 . s 0 0 0 0 0 0 0 0 0 None 0x0f3 24 tc 0 32 0 r y . 8 8 8 8 . s 0 24 8 0 0 0 0 0 0 None 0x0f4 24 tc 0 32 0 r . . 8 8 8 8 . s 0 24 8 0 0 0 0 0 0 None 0x0f5 0 tc 0 16 0 r y . 5 6 5 0 . . 0 16 0 0 0 0 0 0 0 None 0x0f6 0 tc 0 16 0 r y . 5 6 5 0 . . 0 16 0 16 16 16 0 0 0 Slow 0x0f7 24 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None 0x0f8 24 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 16 16 16 16 0 0 Slow 0x0f9 24 tc 0 24 0 r y . 8 8 8 0 . . 0 24 8 0 0 0 0 0 0 None 0x0fa 24 tc 0 24 0 r y . 8 8 8 0 . . 0 24 8 16 16 16 0 0 0 Slow 0x0fb 24 tc 0 32 0 r y . 8 8 8 8 . s 0 24 8 0 0 0 0 0 0 None 0x0fc 24 tc 0 32 0 r y . 8 8 8 8 . s 0 24 8 16 16 16 16 0 0 Slow 0x0fd 0 tc 0 16 0 r y . 5 6 5 0 . . 0 0 0 0 0 0 0 2 1 None 0x0fe 0 tc 0 16 0 r y . 5 6 5 0 . . 0 0 0 0 0 0 0 4 1 None 0x0ff 0 tc 0 16 0 r y . 5 6 5 0 . . 0 0 0 0 0 0 0 8 1 None 0x100 0 tc 0 16 0 r y . 5 6 5 0 . . 0 0 0 0 0 0 0 16 1 None 0x101 0 tc 0 16 0 r y . 5 6 5 0 . . 0 16 0 0 0 0 0 2 1 None 0x102 0 tc 0 16 0 r y . 5 6 5 0 . . 0 16 0 0 0 0 0 4 1 None 0x103 0 tc 0 16 0 r y . 5 6 5 0 . . 0 16 0 0 0 0 0 8 1 None 0x104 0 tc 0 16 0 r y . 5 6 5 0 . . 0 16 0 0 0 0 0 16 1 None 0x105 24 tc 0 32 0 r y . 8 8 8 8 . . 0 0 0 0 0 0 0 2 1 None 0x106 24 tc 0 32 0 r y . 8 8 8 8 . . 0 0 0 0 0 0 0 4 1 None 0x107 24 tc 0 32 0 r y . 8 8 8 8 . . 0 0 0 0 0 0 0 8 1 None 0x108 24 tc 0 32 0 r y . 8 8 8 8 . . 0 0 0 0 0 0 0 16 1 None 0x109 24 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 2 1 None 0x10a 24 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 4 1 None 0x10b 24 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 8 1 None 0x10c 24 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 16 1 None 0x10d 24 tc 0 24 0 r y . 8 8 8 0 . . 0 0 0 0 0 0 0 2 1 None 0x10e 24 tc 0 24 0 r y . 8 8 8 0 . . 0 0 0 0 0 0 0 4 1 None 0x10f 24 tc 0 24 0 r y . 8 8 8 0 . . 0 0 0 0 0 0 0 8 1 None 0x110 24 tc 0 24 0 r y . 8 8 8 0 . . 0 0 0 0 0 0 0 16 1 None 0x111 24 tc 0 24 0 r y . 8 8 8 0 . . 0 24 8 0 0 0 0 2 1 None 0x112 24 tc 0 24 0 r y . 8 8 8 0 . . 0 24 8 0 0 0 0 4 1 None 0x113 24 tc 0 24 0 r y . 8 8 8 0 . . 0 24 8 0 0 0 0 8 1 None 0x114 24 tc 0 24 0 r y . 8 8 8 0 . . 0 24 8 0 0 0 0 16 1 None 0x115 24 tc 0 32 0 r y . 8 8 8 8 . s 0 0 0 0 0 0 0 2 1 None 0x116 24 tc 0 32 0 r y . 8 8 8 8 . s 0 0 0 0 0 0 0 4 1 None 0x117 24 tc 0 32 0 r y . 8 8 8 8 . s 0 0 0 0 0 0 0 8 1 None 0x118 24 tc 0 32 0 r y . 8 8 8 8 . s 0 0 0 0 0 0 0 16 1 None 0x119 24 tc 0 32 0 r y . 8 8 8 8 . s 0 24 8 0 0 0 0 2 1 None 0x11a 24 tc 0 32 0 r y . 8 8 8 8 . s 0 24 8 0 0 0 0 4 1 None 0x11b 24 tc 0 32 0 r y . 8 8 8 8 . s 0 24 8 0 0 0 0 8 1 None 0x11c 24 tc 0 32 0 r y . 8 8 8 8 . s 0 24 8 0 0 0 0 16 1 None 0x11d 0 dc 0 16 0 r y . 5 6 5 0 . . 0 0 0 0 0 0 0 0 0 None 0x11e 0 dc 0 16 0 r . . 5 6 5 0 . . 0 0 0 0 0 0 0 0 0 None 0x11f 0 dc 0 16 0 r y . 5 6 5 0 . . 0 16 0 0 0 0 0 0 0 None 0x120 0 dc 0 16 0 r . . 5 6 5 0 . . 0 16 0 0 0 0 0 0 0 None 0x121 0 dc 0 16 0 r y . 5 6 5 0 . . 0 24 8 0 0 0 0 0 0 None 0x122 0 dc 0 16 0 r . . 5 6 5 0 . . 0 24 8 0 0 0 0 0 0 None 0x123 24 dc 0 32 0 r y . 8 8 8 8 . . 0 0 0 0 0 0 0 0 0 None 0x124 24 dc 0 32 0 r . . 8 8 8 8 . . 0 0 0 0 0 0 0 0 0 None 0x125 24 dc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None 0x126 24 dc 0 32 0 r . . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None 0x127 24 dc 0 24 0 r y . 8 8 8 0 . . 0 0 0 0 0 0 0 0 0 None 0x128 24 dc 0 24 0 r . . 8 8 8 0 . . 0 0 0 0 0 0 0 0 0 None 0x129 24 dc 0 24 0 r y . 8 8 8 0 . . 0 24 8 0 0 0 0 0 0 None 0x12a 24 dc 0 24 0 r . . 8 8 8 0 . . 0 24 8 0 0 0 0 0 0 None 0x12b 24 dc 0 32 0 r y . 8 8 8 8 . s 0 0 0 0 0 0 0 0 0 None 0x12c 24 dc 0 32 0 r . . 8 8 8 8 . s 0 0 0 0 0 0 0 0 0 None 0x12d 24 dc 0 32 0 r y . 8 8 8 8 . s 0 24 8 0 0 0 0 0 0 None 0x12e 24 dc 0 32 0 r . . 8 8 8 8 . s 0 24 8 0 0 0 0 0 0 None 0x12f 0 dc 0 16 0 r y . 5 6 5 0 . . 0 16 0 0 0 0 0 0 0 None 0x130 0 dc 0 16 0 r y . 5 6 5 0 . . 0 16 0 16 16 16 0 0 0 Slow 0x131 24 dc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None 0x132 24 dc 0 32 0 r y . 8 8 8 8 . . 0 24 8 16 16 16 16 0 0 Slow 0x133 24 dc 0 24 0 r y . 8 8 8 0 . . 0 24 8 0 0 0 0 0 0 None 0x134 24 dc 0 24 0 r y . 8 8 8 0 . . 0 24 8 16 16 16 0 0 0 Slow 0x135 24 dc 0 32 0 r y . 8 8 8 8 . s 0 24 8 0 0 0 0 0 0 None 0x136 24 dc 0 32 0 r y . 8 8 8 8 . s 0 24 8 16 16 16 16 0 0 Slow 0x137 0 dc 0 16 0 r y . 5 6 5 0 . . 0 0 0 0 0 0 0 2 1 None 0x138 0 dc 0 16 0 r y . 5 6 5 0 . . 0 0 0 0 0 0 0 4 1 None 0x139 0 dc 0 16 0 r y . 5 6 5 0 . . 0 0 0 0 0 0 0 8 1 None 0x13a 0 dc 0 16 0 r y . 5 6 5 0 . . 0 0 0 0 0 0 0 16 1 None 0x13b 0 dc 0 16 0 r y . 5 6 5 0 . . 0 16 0 0 0 0 0 2 1 None 0x13c 0 dc 0 16 0 r y . 5 6 5 0 . . 0 16 0 0 0 0 0 4 1 None 0x13d 0 dc 0 16 0 r y . 5 6 5 0 . . 0 16 0 0 0 0 0 8 1 None 0x13e 0 dc 0 16 0 r y . 5 6 5 0 . . 0 16 0 0 0 0 0 16 1 None 0x13f 24 dc 0 32 0 r y . 8 8 8 8 . . 0 0 0 0 0 0 0 2 1 None 0x140 24 dc 0 32 0 r y . 8 8 8 8 . . 0 0 0 0 0 0 0 4 1 None 0x141 24 dc 0 32 0 r y . 8 8 8 8 . . 0 0 0 0 0 0 0 8 1 None 0x142 24 dc 0 32 0 r y . 8 8 8 8 . . 0 0 0 0 0 0 0 16 1 None 0x143 24 dc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 2 1 None 0x144 24 dc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 4 1 None 0x145 24 dc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 8 1 None 0x146 24 dc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 16 1 None 0x147 24 dc 0 24 0 r y . 8 8 8 0 . . 0 0 0 0 0 0 0 2 1 None 0x148 24 dc 0 24 0 r y . 8 8 8 0 . . 0 0 0 0 0 0 0 4 1 None 0x149 24 dc 0 24 0 r y . 8 8 8 0 . . 0 0 0 0 0 0 0 8 1 None 0x14a 24 dc 0 24 0 r y . 8 8 8 0 . . 0 0 0 0 0 0 0 16 1 None 0x14b 24 dc 0 24 0 r y . 8 8 8 0 . . 0 24 8 0 0 0 0 2 1 None 0x14c 24 dc 0 24 0 r y . 8 8 8 0 . . 0 24 8 0 0 0 0 4 1 None 0x14d 24 dc 0 24 0 r y . 8 8 8 0 . . 0 24 8 0 0 0 0 8 1 None 0x14e 24 dc 0 24 0 r y . 8 8 8 0 . . 0 24 8 0 0 0 0 16 1 None 0x14f 24 dc 0 32 0 r y . 8 8 8 8 . s 0 0 0 0 0 0 0 2 1 None 0x150 24 dc 0 32 0 r y . 8 8 8 8 . s 0 0 0 0 0 0 0 4 1 None 0x151 24 dc 0 32 0 r y . 8 8 8 8 . s 0 0 0 0 0 0 0 8 1 None 0x152 24 dc 0 32 0 r y . 8 8 8 8 . s 0 0 0 0 0 0 0 16 1 None 0x153 24 dc 0 32 0 r y . 8 8 8 8 . s 0 24 8 0 0 0 0 2 1 None 0x154 24 dc 0 32 0 r y . 8 8 8 8 . s 0 24 8 0 0 0 0 4 1 None 0x155 24 dc 0 32 0 r y . 8 8 8 8 . s 0 24 8 0 0 0 0 8 1 None 0x156 24 dc 0 32 0 r y . 8 8 8 8 . s 0 24 8 0 0 0 0 16 1 None 0x157 32 tc 0 32 0 r y . 8 8 8 8 . . 0 0 0 0 0 0 0 0 0 None 0x158 32 tc 0 32 0 r . . 8 8 8 8 . . 0 0 0 0 0 0 0 0 0 None 0x159 32 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None 0x15a 32 tc 0 32 0 r . . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None 0x15b 32 tc 0 32 0 r y . 8 8 8 8 . s 0 0 0 0 0 0 0 0 0 None 0x15c 32 tc 0 32 0 r . . 8 8 8 8 . s 0 0 0 0 0 0 0 0 0 None 0x15d 32 tc 0 32 0 r y . 8 8 8 8 . s 0 24 8 0 0 0 0 0 0 None 0x15e 32 tc 0 32 0 r . . 8 8 8 8 . s 0 24 8 0 0 0 0 0 0 None 0x15f 32 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None 0x160 32 tc 0 32 0 r y . 8 8 8 8 . s 0 24 8 0 0 0 0 0 0 None $ eglinfo EGL client extensions string: EGL_EXT_platform_base EGL_KHR_client_get_all_proc_addresses EGL_EXT_client_extensions EGL_KHR_debug EGL_EXT_platform_wayland EGL_EXT_platform_x11 EGL_MESA_platform_gbm EGL_MESA_platform_surfaceless GBM platform: i965_dri.so does not support the 0xffffffff PCI ID. EGL API version: 1.4 EGL vendor string: Mesa Project EGL version string: 1.4 (DRI2) EGL client APIs: OpenGL OpenGL_ES EGL extensions string: EGL_EXT_buffer_age EGL_EXT_image_dma_buf_import EGL_KHR_cl_event2 EGL_KHR_config_attribs 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_3D_image EGL_KHR_gl_texture_cubemap_image EGL_KHR_image EGL_KHR_image_base EGL_KHR_image_pixmap EGL_KHR_no_config_context EGL_KHR_reusable_sync EGL_KHR_surfaceless_context EGL_EXT_pixel_format_float EGL_KHR_wait_sync EGL_MESA_configless_context EGL_MESA_image_dma_buf_export Configurations: bf lv colorbuffer dp st ms vis cav bi renderable supported id sz l r g b a th cl ns b id eat nd gl es es2 vg surfaces --------------------------------------------------------------------- 0x01 32 0 8 8 8 8 0 0 0 0 0x34325241-- y y y win 0x02 32 0 8 8 8 8 16 0 0 0 0x34325241-- y y y win 0x03 32 0 8 8 8 8 24 0 0 0 0x34325241-- y y y win 0x04 32 0 8 8 8 8 24 8 0 0 0x34325241-- y y y win 0x05 32 0 8 8 8 8 32 0 0 0 0x34325241-- y y y win 0x06 24 0 8 8 8 0 0 0 0 0 0x34325258-- y y y win 0x07 24 0 8 8 8 0 16 0 0 0 0x34325258-- y y y win 0x08 24 0 8 8 8 0 24 0 0 0 0x34325258-- y y y win 0x09 24 0 8 8 8 0 24 8 0 0 0x34325258-- y y y win 0x0a 24 0 8 8 8 0 32 0 0 0 0x34325258-- y y y win 0x0b 16 0 5 6 5 0 0 0 0 0 0x36314752-- y y y win 0x0c 16 0 5 6 5 0 16 0 0 0 0x36314752-- y y y win 0x0d 16 0 5 6 5 0 24 0 0 0 0x36314752-- y y y win 0x0e 16 0 5 6 5 0 24 8 0 0 0x36314752-- y y y win 0x0f 16 0 5 6 5 0 32 0 0 0 0x36314752-- y y y win Wayland platform: eglinfo: eglInitialize failed X11 platform: EGL API version: 1.4 EGL vendor string: Mesa Project EGL version string: 1.4 (DRI2) EGL client APIs: OpenGL OpenGL_ES EGL extensions string: EGL_ANDROID_blob_cache EGL_ANDROID_native_fence_sync EGL_CHROMIUM_sync_control EGL_EXT_buffer_age EGL_EXT_create_context_robustness EGL_EXT_image_dma_buf_import EGL_EXT_image_dma_buf_import_modifiers EGL_IMG_context_priority EGL_KHR_config_attribs 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_3D_image EGL_KHR_gl_texture_cubemap_image EGL_KHR_image EGL_KHR_image_base EGL_KHR_image_pixmap EGL_KHR_no_config_context EGL_KHR_reusable_sync EGL_KHR_surfaceless_context EGL_EXT_pixel_format_float EGL_KHR_wait_sync EGL_MESA_configless_context EGL_MESA_drm_image EGL_MESA_image_dma_buf_export EGL_NOK_texture_from_pixmap EGL_WL_bind_wayland_display Configurations: bf lv colorbuffer dp st ms vis cav bi renderable supported id sz l r g b a th cl ns b id eat nd gl es es2 vg surfaces --------------------------------------------------------------------- 0x01 32 0 8 8 8 8 0 0 0 0 0x41TC a y y y win,pb,pix 0x02 32 0 8 8 8 8 24 8 0 0 0x41TC a y y y win,pb,pix 0x03 24 0 8 8 8 0 0 0 0 0 0x41TC y y y y win,pb,pix 0x04 24 0 8 8 8 0 24 8 0 0 0x41TC y y y y win,pb,pix 0x05 32 0 8 8 8 8 0 0 2 1 0x41TC a y y y win 0x06 32 0 8 8 8 8 0 0 4 1 0x41TC a y y y win 0x07 32 0 8 8 8 8 0 0 8 1 0x41TC a y y y win 0x08 32 0 8 8 8 8 0 0 16 1 0x41TC a y y y win 0x09 32 0 8 8 8 8 24 8 2 1 0x41TC a y y y win 0x0a 32 0 8 8 8 8 24 8 4 1 0x41TC a y y y win 0x0b 32 0 8 8 8 8 24 8 8 1 0x41TC a y y y win 0x0c 32 0 8 8 8 8 24 8 16 1 0x41TC a y y y win 0x0d 24 0 8 8 8 0 0 0 2 1 0x41TC y y y y win 0x0e 24 0 8 8 8 0 0 0 4 1 0x41TC y y y y win 0x0f 24 0 8 8 8 0 0 0 8 1 0x41TC y y y y win 0x10 24 0 8 8 8 0 0 0 16 1 0x41TC y y y y win 0x11 24 0 8 8 8 0 24 8 2 1 0x41TC y y y y win 0x12 24 0 8 8 8 0 24 8 4 1 0x41TC y y y y win 0x13 24 0 8 8 8 0 24 8 8 1 0x41TC y y y y win 0x14 24 0 8 8 8 0 24 8 16 1 0x41TC y y y y win 0x15 32 0 8 8 8 8 0 0 0 0 0x42DC a y y y win,pb,pix 0x16 32 0 8 8 8 8 24 8 0 0 0x42DC a y y y win,pb,pix 0x17 24 0 8 8 8 0 0 0 0 0 0x42DC y y y y win,pb,pix 0x18 24 0 8 8 8 0 24 8 0 0 0x42DC y y y y win,pb,pix 0x19 32 0 8 8 8 8 0 0 2 1 0x42DC a y y y win 0x1a 32 0 8 8 8 8 0 0 4 1 0x42DC a y y y win 0x1b 32 0 8 8 8 8 0 0 8 1 0x42DC a y y y win 0x1c 32 0 8 8 8 8 0 0 16 1 0x42DC a y y y win 0x1d 32 0 8 8 8 8 24 8 2 1 0x42DC a y y y win 0x1e 32 0 8 8 8 8 24 8 4 1 0x42DC a y y y win 0x1f 32 0 8 8 8 8 24 8 8 1 0x42DC a y y y win 0x20 32 0 8 8 8 8 24 8 16 1 0x42DC a y y y win 0x21 24 0 8 8 8 0 0 0 2 1 0x42DC y y y y win 0x22 24 0 8 8 8 0 0 0 4 1 0x42DC y y y y win 0x23 24 0 8 8 8 0 0 0 8 1 0x42DC y y y y win 0x24 24 0 8 8 8 0 0 0 16 1 0x42DC y y y y win 0x25 24 0 8 8 8 0 24 8 2 1 0x42DC y y y y win 0x26 24 0 8 8 8 0 24 8 4 1 0x42DC y y y y win 0x27 24 0 8 8 8 0 24 8 8 1 0x42DC y y y y win 0x28 24 0 8 8 8 0 24 8 16 1 0x42DC y y y y win ```
goddessfreya commented 5 years ago

I've never used glium, sorry.

LukasKalbertodt commented 5 years ago

So ok, I ran this code using glutin and the gl crate.

let events_loop = glutin::EventsLoop::new();
let wb = glutin::WindowBuilder::new();
let gl_window = glutin::ContextBuilder::new()
    .with_srgb(false)  // <------------------------------------------
    .build_windowed(wb, &events_loop)
    .unwrap();

let gl_window = unsafe { gl_window.make_current().unwrap() };
gl::load_with(|symbol| gl_window.get_proc_address(symbol) as *const _);

let mut out: gl::types::GLint = 0;
unsafe {
    gl::GetFramebufferAttachmentParameteriv(
        gl::DRAW_FRAMEBUFFER,
        gl::BACK,
        gl::FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING,
        &mut out as *mut _,
    );
}
println!("out: {}", out);
if out == gl::LINEAR as i32 {
    println!("    linear");
} else if out == gl::SRGB as i32 {
    println!("    srgb");
}

It always prints, regardless of the value in with_srgb(_):

out: 35904
    srgb

I only checked this on Ubuntu now, but I might check it on windows later. In any case, this seems like a bug somewhere, right? The framebuffer is sRGB but it shouldn't. glutin incorrectly thinks the pixel format is not sRGB.

Any idea what could be wrong here?

EDIT: I tested it on Windows and it get's stranger. Regardless of the with_srgb parameter, I get the following output:

out: 9729
    linear
PixelFormat {
    hardware_accelerated: true,
    color_bits: 24,
    alpha_bits: 8,
    depth_bits: 24,
    stencil_bits: 8,
    stereoscopy: false,
    double_buffer: true,
    multisampling: None,
    srgb: true,
}

The shown color is #bdbdbd.

I uploaded my test program now: https://github.com/LukasKalbertodt/srgb-test

sumit0190 commented 5 years ago

So on Windows (with WGL) what might be happening is that the function choose_arb_pixel_format returns true for sRGB (since WGL_EXT_framebuffer_sRGB is available on my machine; maybe it's the same on your machine, or maybe you have WGL_ARB_framebuffer_sRGB), and then returns that value in the PixelFormat struct. Finally, this struct is stored in the pixel_format field of the Context struct.

From there, any call to get_pixel_format() simply clones this field and returns it, and that's how you end up seeing weird behavior where OpenGL claims to be seeing linear but glutin thinks sRGB is being used.

@ZeGentzy Should choose_arb_pixel_format take into consideration the pixel format that the user has specified?

goddessfreya commented 5 years ago

@sumit0190 choose_arb_pixel_format will only say that it is sRGB if the call to GetPixelFormatAttribivARB says it is. At this point, the format has already been chosen earlier and we are just returning it's properties.

If the claim is that the format is not actually sRGB but GetPixelFormatAttribivARB is saying it is, then this is a winapi bug, and should be filed with Microsoft (good luck on that), although I highly doubt this is the case.

On windows, the format is decided by calling GetPixelFormat to get the format of the window.

If a format is found after calling that function, we use that format, as we cannot change it, see the remarks for SetPixelFormat:

[...] Setting the pixel format of a window more than once can lead to significant complications for the Window Manager and for multithread applications, so it is not allowed. An application can only set the pixel format of a window one time. Once a window's pixel format is set, it cannot be changed.

-- https://docs.microsoft.com/en-us/windows/desktop/api/wingdi/nf-wingdi-setpixelformat

If not found (as in previously unset), we either call choose_arb_pixel_format_id or choose_native_pixel_format_id (depending on the presence of WGL_ARB_pixel_format) and set the format of the window to that.

choose_native_pixel_format_id simply errors implying this is not the function in use by your computer: https://github.com/rust-windowing/glutin/blob/master/glutin/src/api/wgl/mod.rs#L495

choose_arb_pixel_format_id only requests an sRGB context if the user requested it: https://github.com/rust-windowing/glutin/blob/master/glutin/src/api/wgl/mod.rs#L704

Looking over the code I see one potential issues which should be investigated by someone in procession of a windows computer: It might be possible that the lack of a FRAMEBUFFER_SRGB_CAPABLE_{EXT,ARB} here is treated as a don't care. This is unlikely, as that would break all existing opengl programs. A simple test would be to add FRAMEBUFFER_SRGB_CAPABLE_{EXT,ARB} followed by 0 if sRGB is not requested.

goddessfreya commented 5 years ago

So ok, I ran this code using glutin and the gl crate.

let events_loop = glutin::EventsLoop::new();
let wb = glutin::WindowBuilder::new();
let gl_window = glutin::ContextBuilder::new()
    .with_srgb(false)  // <------------------------------------------
    .build_windowed(wb, &events_loop)
    .unwrap();

let gl_window = unsafe { gl_window.make_current().unwrap() };
gl::load_with(|symbol| gl_window.get_proc_address(symbol) as *const _);

let mut out: gl::types::GLint = 0;
unsafe {
    gl::GetFramebufferAttachmentParameteriv(
        gl::DRAW_FRAMEBUFFER,
        gl::BACK,
        gl::FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING,
        &mut out as *mut _,
    );
}
println!("out: {}", out);
if out == gl::LINEAR as i32 {
    println!("    linear");
} else if out == gl::SRGB as i32 {
    println!("    srgb");
}

Numerous things: 1- Afaik, GL_BACK is not a valid attachment. If you check for an error after that call, I suspect you'll be receiving GL_INVALID_ENUM. Then again, since stereoscopy is not in use, maybe it is treating it as an alias for GL_BACK_LEFT. 2- You are not enabling GL_FRAMEBUFFER_SRGB when intending to use sRGB. From the ARB_framebuffer_sRGB extension:

18) Why is the sRGB framebuffer GL_FRAMEBUFFER_SRGB enable disabled by default?

   RESOLVED:  This extension could have a boolean
   sRGB-versus-non-sRGB pixel format configuration mode that
   determined whether or not sRGB framebuffer update and blending
   occurs.  The problem with this approach is 1) it creates may more
   pixel formation configurations because sRGB and non-sRGB versions
   of lots of existing configurations must be advertised, and 2)
   applicaitons unaware of sRGB might unknowingly select an sRGB
   configuration and then generate over-bright rendering.

   It seems more appropriate to have a capability for sRGB
   framebuffer update and blending that is disabled by default.
   This allows existing RGB8 and RGBA8 framebuffer configurations
   to be marked as sRGB capable (so no additional configurations
   need be enumerated).  Applications that desire sRGB rendering
   should identify an sRGB-capable framebuffer configuration and
   __then enable sRGB rendering.__
LukasKalbertodt commented 5 years ago

1- Afaik, GL_BACK is not a valid attachment. If you check for an error after that call, I suspect you'll be receiving GL_INVALID_ENUM. Then again, since stereoscopy is not in use, maybe it is treating it as an alias for GL_BACK_LEFT.

Good point. I changed it but it didn't change anything on Ubuntu or Windows. I pushed the change to the repo I linked above. I also checked glGetError with just GL_BACK and it returned 0 so apparently it was fine.

2- You are not enabling GL_FRAMEBUFFER_SRGB when intending to use sRGB. From the ARB_framebuffer_sRGB extension:

I'm not quite sure what you want to say by that, sorry! This tiny program I posted is just to test what various sources report about the framebuffer.


And could someone clarify in what state this issue is? Like:

  1. Do you agree that what I'm reporting is a bug (somewhere)? As in: the example programs I'm posting with with_srgb(false) and a standard shader that returns 0.5 should result in an image that is #808080 and not #bbbbbb? This behavior is unintended, right? It's not my fault, right?
  2. Does this happen on your machines, too? Or is that just something that happens to me?
  3. What are the next steps? I have no clue about the glutin codebase, but can help somehow?
sumit0190 commented 5 years ago

There's definitely something funky going on here, although my cursory knowledge of OpenGL/glutin may not be enough to figure it out and @ZeGentzy might have to help me out in the end.

Interestingly, at least on my machine, changing with_srgb to true doesn't change the pixel_format_id at all; plus, GetFramebufferAttachmentParameteriv still returns linear (I made sure to enable GL_FRAMEBUFFER_SRGB before trying this out).

goddessfreya commented 5 years ago

@sumit0190 Can you check that 1 is being pushed by one of these: https://github.com/rust-windowing/glutin/blob/master/glutin/src/api/wgl/mod.rs#L704 ?

sumit0190 commented 5 years ago

@ZeGentzy So here's some more interesting stuff.

with_srgb set to false returns this descriptor: [8193, 1, 8208, 1, 8211, 8235, 8195, 8231, 8212, 24, 8219, 8, 8226, 24, 8227, 8, 8209, 1, 8210, 0, 0]

with_srgb set to true returns this descriptor: [8193, 1, 8208, 1, 8211, 8235, 8195, 8231, 8212, 24, 8219, 8, 8226, 24, 8227, 8, 8209, 1, 8210, 0, 8361, 1, 0]

So the with_srgb parameter is doing it's job and adding the right attribute (8361). But the pixel_format_id returned in both cases is 10, which is weird, right?

Then I decide to use my own dummy descriptor, with some random values for all attributes. This is what that looks like:

    let descriptor = 
    [
    gl::wgl_extra::DRAW_TO_WINDOW_ARB as i32, 1 as i32,
    gl::wgl_extra::SUPPORT_OPENGL_ARB as i32, 1 as i32,
    gl::wgl_extra::DOUBLE_BUFFER_ARB as i32, 1 as i32,
    gl::wgl_extra::PIXEL_TYPE_ARB as i32, gl::wgl_extra::TYPE_RGBA_ARB as i32,
    gl::wgl_extra::COLOR_BITS_ARB as i32, 32 as i32,
    gl::wgl_extra::DEPTH_BITS_ARB as i32, 24 as i32,
    gl::wgl_extra::STENCIL_BITS_ARB as i32, 8 as i32,
    // gl::wgl_extra::FRAMEBUFFER_SRGB_CAPABLE_EXT as i32, pf_reqs.srgb as i32,
    0 as i32, // End
    ];

Still the same result though; a format of 9 is returned, and glutin still thinks srgb is set.

But if I uncomment the commented line, suddenly things change: now, a format of 9 is returned when with_srgb is set to true, but when set to false, a format of 105 is returned, and glutin behaves correctly.

Now that makes me think: it looks like FRAMEBUFFER_SRGB_CAPABLE_EXT should be always defined, and just as you recommended, it should be set to 0 or 1 depending on whether sRGB is requested.

So I make these modifications:

        // Find out if sRGB is needed and explicitly set its value to 0 or 1.
        if extensions
            .split(' ')
            .find(|&i| i == "WGL_ARB_framebuffer_sRGB")
            .is_some()
        {
            out.push(
                gl::wgl_extra::FRAMEBUFFER_SRGB_CAPABLE_ARB as raw::c_int,
            );
        } else if extensions
            .split(' ')
            .find(|&i| i == "WGL_EXT_framebuffer_sRGB")
            .is_some()
        {
            out.push(
                gl::wgl_extra::FRAMEBUFFER_SRGB_CAPABLE_EXT as raw::c_int,
            );
        } else {
            return Err(());
        }
        out.push(pf_reqs.srgb as raw::c_int);

And this should do the same thing as my dummy descriptor. But even though I can see the attribute (8361) added with a 0 or 1 depending on my with_srgb, it gives me the same pixel_format_id regardless (10). Needs some more investigation, I guess.

goddessfreya commented 5 years ago

Please submit a PR with this code instead:

        // Find out if an sRGB extension is present then explicitly set its value to 0 or 1.
        if extensions
            .split(' ')
            .find(|&i| i == "WGL_ARB_framebuffer_sRGB")
            .is_some()
        {
            out.push(
                gl::wgl_extra::FRAMEBUFFER_SRGB_CAPABLE_ARB as raw::c_int,
            );
            out.push(pf_reqs.srgb as raw::c_int);
        } else if extensions
            .split(' ')
            .find(|&i| i == "WGL_EXT_framebuffer_sRGB")
            .is_some()
        {
            out.push(
                gl::wgl_extra::FRAMEBUFFER_SRGB_CAPABLE_EXT as raw::c_int,
            );
            out.push(pf_reqs.srgb as raw::c_int);
        } else {
            if pf_reqs.srgb {
                return Err(());
            }
        }

as we should only error if srgb was requested and there was no srgb extension.

Nvm, didn't read hard enough, you said it still doesn't work in the end... hmmmm.

goddessfreya commented 5 years ago

Can you comment out the code specifying things like alpha, stencil bits, ect, ect, then add them back one by one. The goal is to discover if one of the other options is conflicting/overriding our what we set FRAMEBUFFER_SRGB_CAPABLE_* to.

sumit0190 commented 5 years ago

Nvm, didn't read hard enough, you said it still doesn't work in the end... hmmmm.

We'd still need to modify it anyway, since if it's left unspecified it's somehow assumed to be true (this is contrary to the documented behavior; I should try this on Linux sometime).

Anyway, I was doing exactly what you suggested and narrowed down the culprit to ALPHA_BITS_ARB.

So just to be clear: if ALPHA_BITS_ARB is specified in the descriptor, then FRAMEBUFFER_SRGB_CAPABLE_* is somehow not taken into consideration by ChoosePixelFormat (i.e., a pixel format that has SRGB enabled is returned). This is why my dummy descriptor works (if I always specify FRAMEBUFFER_SRGB_CAPABLE_*), but the same logic doesn't work in the existing method since it also needs to specify ALPHA_BITS_ARB.

goddessfreya commented 5 years ago

Can you run this program and check the available pixel formats: http://realtech-vr.com/admin/glview

This just strikes me as shitty intel drivers.

sumit0190 commented 5 years ago

Available pixel formats seem right to me. And I did my investigation on an Nvidia Quadro with recent-ish drivers (although theirs have been known to be shitty as well, so you never know).

Also, I just verified that setting ALPHA_BITS_ARB to 0 (instead of the default 8) seems to also give the right results (i.e., sRGB is false).

sumit0190 commented 5 years ago

@ZeGentzy Here's an interesting link that chronicles similar oddities: https://devtalk.nvidia.com/default/topic/776591/opengl/gl_framebuffer_srgb-functions-incorrectly/

Note that while the thread itself is from 2014, the last post (by which time the issue hadn't been resolved yet) is from a year ago.

Interestingly, on my Linux VM, get_pixel_format returns the right value that corresponds to with_srgb, but OpenGL always returns sRGB. It might be worth a try to try all these experiments (especially the one on Windows) using FBOs.

goddessfreya commented 5 years ago

@sumit0190 Is there a format with non-zero alpha bits which is also not-srgb?

sumit0190 commented 5 years ago

@ZeGentzy Not that I can find. glview doesn't list out alpha-bits, and visualinfo (from glew) doesn't list out SRGB_EXT. I was able to combine information from the two for my experiments though.

Anyway, from what I can observe, this behavior is visible outside of glutin too - a simple C++ program using wgl that uses wglChoosePixelFormat also displays the same behavior.

I created this table to better document this weird behavior. Note that while this experiment was done with the C++ version, glutin also agrees with it. In my test program, I try to render a window with glClearColor(0.5f, 0.5f, 0.5f, 1.0f). Sometimes, the result would be with #808080, which is expected, but often it would show up with #bbbbbb. I have also included certain properties of my pixel formats for easier reference.

Without further ado:

Default attributes:

WGL_DRAW_TO_WINDOW_ARB,     TRUE,
WGL_ACCELERATION_ARB,       WGL_FULL_ACCELERATION_ARB,
WGL_SUPPORT_OPENGL_ARB,     TRUE,
WGL_DOUBLE_BUFFER_ARB,      TRUE,
WGL_PIXEL_TYPE_ARB,         WGL_TYPE_RGBA_ARB,
WGL_COLOR_BITS_ARB,         24,
WGL_DEPTH_BITS_ARB,         24,
WGL_STENCIL_BITS_ARB,       0,

Pixel formats:

Pixel Format Alpha Bits WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT
7 - 1
8 8 1
103 - 0

Observations:

WGL_ALPHA_BITS_ARB listed? WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT listed? glEnable(GL_FRAMEBUFFER_SRGB)? Pixel format selected Output color
No No No 7 #808080
No No Yes 7 #bbbbbb
No Yes (1) No 7 #808080
No Yes (0) No 103 #808080
No Yes (1) Yes 7 #bbbbbb
No Yes (0) Yes 103 #808080
Yes (8) No No 8 #808080
Yes (8) No Yes 8 #bbbbbb
Yes (8) Yes (1) No 8 #808080
Yes (8) Yes (0) No 8 #808080
Yes (8) Yes (1) Yes 8 #bbbbbb
Yes (8) Yes (0) Yes 8 #bbbbbb

Summary: So this pretty much confirms what we see with glutin. Granted, all of this maybe because my PC has some stupid driver issue, but it's still odd. 1) If WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT is not listed, then it's assumed to be true. This is why if you then use glEnable(GL_FRAMEBUFFER_SRGB), you will see sRGB output (which is only possible if WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT is true and glEnable is used). 2) If WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT is listed, then the behavior is the same as what you'd expect - the glEnable call will then combine with the value of WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT to determine if sRGB needs to be shown. 3) If WGL_ALPHA_BITS_ARB is listed, then WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT is assumed to be true, regardless of what the listed value says (we already know it's true if not listed). Again, this is why the sRGB output is solely controlled by the glEnable call.

@ZeGentzy Thoughts?

goddessfreya commented 5 years ago

Silly driver issues are silly. Not much we can do. Please file this as a PR: https://github.com/rust-windowing/glutin/issues/1175#issuecomment-506984460

I'm opening separate issues for X11 and macOS, so that this issue doesn't get too cluttered.

Edit: anyways, I'll close this issue as wontfix (as there is nothing we can do) once you got that PR filed. Thanks for your time :)

goddessfreya commented 5 years ago

Appoligies, @LukasKalbertodt, you sorta got drowned out.

2- You are not enabling GL_FRAMEBUFFER_SRGB when intending to use sRGB. From the ARB_framebuffer_sRGB extension:

I'm not quite sure what you want to say by that, sorry! This tiny program I posted is just to test what various sources report about the framebuffer.

What I'm saying is, while that code is satisfactory for testing if the FBO is linear/srgb, actually drawing to it would cause silly stuff. I just wanted to point that out, altho it wasn't not actually relevant to what it was demonstrating.

1. Do you agree that what I'm reporting is a bug (somewhere)? As in: the example programs I'm posting with `with_srgb(false)` and a standard shader that returns `0.5` should result in an image that is `#808080` and _not_ `#bbbbbb`? This behavior is unintended, right? It's not my fault, right?

Yeah something looks wrong, altho I'm not all too familiar with how sRGB works. Yeah, it's not your fault.

2. Does this happen on your machines, too? Or is that just something that happens to me?

Yeah, I've experienced sRGB issues. I usually fiddle with the supplied colors until I get my expected color.

3. What are the next steps? I have no clue about the `glutin` codebase, but can help somehow?

Most likely there is little we can do. If the drivers are broken, the drivers are broken. Feel free to scheme up workarounds like that in https://github.com/rust-windowing/glutin/issues/1175#issuecomment-506984460. If they aren't too intrusive, I'm fine with including them.

sumit0190 commented 5 years ago

@ZeGentzy I'll have that PR ready by tomorrow. It was fun investigating this; I hope to be able to contribute more to the project!

@LukasKalbertodt With my PR, sRGB rendering will be controlled by a glEnable(GL_FRAMEBUFFER_SRGB) call and NOT by the with_srgb parameter. This is because with the current default alpha value, with_srgb will always be assumed to be true.

goddessfreya commented 5 years ago

@LukasKalbertodt With my PR, sRGB rendering will be controlled by a glEnable(GL_FRAMEBUFFER_SRGB) call and NOT by the with_srgb parameter. This is because with the current default alpha value, with_srgb will always be assumed to be true.

Well, with your specific drivers, yes. Other drivers might behave differently, so users should still set with_srgb appropriately.

sumit0190 commented 5 years ago

@ZeGentzy Well that's the thing: I tested this with Nvidia, Intel and AMD and got the same results on all three when testing with Windows 10 (with the latest drivers). OP's Intel behaves the same way.

All this makes me think that it's at least partially due to WGL, but I could be wrong. So yeah, I don't think this has anything to do with the driver version.

goddessfreya commented 5 years ago

@sumit0190 Older/newer implementations might behave differently, idk. Maybe I'm reading the extension wrong. Maybe none of the drivers bothered caring. Nevertheless, users should set with_srgb correctly.

LukasKalbertodt commented 5 years ago

Sorry for the super late reply!

Appoligies, @LukasKalbertodt, you sorta got drowned out.

No problem! Thank you two for investigating this so quickly!

I unfortunately do not understand everything you wrote as I have no idea about the windowing site of OpenGL. As I understand all comments: "drivers are bad & strange, set with_srgb() correctly but assume it won't be used on some machines". I will continue to tell glium that my shader outputs sRGB (which is technically a lie) such that GL_FRAMEBUFFER_SRGB is not enabled by glium to avoid color conversion.

So I think this all is pretty unfortunate because AIFACT most glium programs on most machines are just "wrong" then. Meaning: colors are incorrectly converted. I mean from the artistic point of view it doesn't matter because you just tweak your colors until you like it. But returning 0.5 from the pixel shader and not getting #808080 is really not great IMO. However, this is not meant as a critique, just as a statement of how unfortunate this is! Thanks again for helping out!

Boscop commented 4 years ago

@LukasKalbertodt Is this still an issue? I noticed that when I render a shader from shadertoy using glium, it looks brighter. Is that because of this sRGB issue? What's the recommended fix?

On Shadertoy: image

Using glium: image

LukasKalbertodt commented 4 years ago

I just tested this again with more or less the code from my first comment:

(glium 0.27.0) ```rust #[macro_use] extern crate glium; use glium::Surface; fn main() { let events_loop = glium::glutin::event_loop::EventLoop::new(); let wb = glium::glutin::window::WindowBuilder::new() .with_inner_size(glium::glutin::dpi::LogicalSize::new(1024.0, 768.0)) .with_title("Hello world"); let cb = glium::glutin::ContextBuilder::new().with_srgb(true); let display = glium::Display::new(wb, cb, &events_loop).unwrap(); #[derive(Copy, Clone)] struct Vertex { position: [f32; 2], } implement_vertex!(Vertex, position); let shape = vec![ Vertex { position: [-1.0, -1.0] }, Vertex { position: [-1.0, 1.0] }, Vertex { position: [ 1.0, -1.0] }, Vertex { position: [ 1.0, 1.0] }, ]; let vertex_buffer = glium::VertexBuffer::new(&display, &shape).unwrap(); let indices = glium::index::NoIndices(glium::index::PrimitiveType::TriangleStrip); let vertex_shader_src = r#" #version 140 in vec2 position; void main() { gl_Position = vec4(position, 0.0, 1.0); } "#; let fragment_shader_src = r#" #version 140 out vec4 color; void main() { color = vec4(vec3(0.5), 1.0); } "#; let program = glium::Program::new( &display, glium::program::ProgramCreationInput::SourceCode { vertex_shader: vertex_shader_src, tessellation_control_shader: None, tessellation_evaluation_shader: None, geometry_shader: None, fragment_shader: fragment_shader_src, transform_feedback_varyings: None, outputs_srgb: false, // MARK B ---------------------------------- uses_point_size: false, } ).unwrap(); loop { let mut target = display.draw(); target.draw(&vertex_buffer, &indices, &program, &uniform!{}, &Default::default()).unwrap(); target.finish().unwrap(); } } ```

And I indeed still get exactly the same colors for the four scenarios I described. So yes, this issue still exists as far as I can tell. I just tested on Ubuntu 20.04 now, though.

Boscop commented 4 years ago

@LukasKalbertodt In my situation, it worked as expected to add outputs_srgb: true for all shaders, but is there a solution that doesn't require this?

Btw, why does no conversion from sRGB to RGB happen in the case of "with_srgb(false) and outputs_srgb: true"?

LukasKalbertodt commented 4 years ago

@Boscop Yes adding outputs_srgb: true to all shaders works. And after dealing with all this color space issue for some time, I believe this is even the "correct" solution in many situations (just as an FYI, for anyone stumbling upon this issue).

Regarding your question, see my first comment, in particular:

as above, the framebuffer should be linear RGB, meaning that no conversion should happen, regardless of GL_FRAMEBUFFER_SRGB.

Boscop commented 4 years ago

@LukasKalbertodt Thanks, I read that, but why does that mean that no conversion happens (if the framebuffer is RGB but the shader outputs sRGB)?

LukasKalbertodt commented 4 years ago

To be honest, I already forgot most of the details. I can't tell you why this is, but that's apparently how OpenGL works. For example. also see this StackOverflow answer.

Any writes to images that are not in the sRGB format should not be affected.

kchibisov commented 2 years ago

Fixed in #1435, I guess.