Raspberry Pi® 3B+ Graphics Mode

You need the following Simdify® modules to complete all exercises involving the Raspberry Pi® 3B+: Simdify® Free Edition, Simdify® Export Module

This exercise does not apply to Raspberry Pi 4 devices.

Broadly speaking, OpenGL® is separated into three components: the OpenGL® graphics system itself, the OpenGL® shading language you can use to write shaders, and optional extensions that implement extended functionality.

Component Description
OpenGL® ImplementationThis is the core graphics subsystem. This has a version number such as 2.1 or 4.0.
GLSLThis is the language you use to write shaders. This has a version number such as 100, 140, 300, or 450.
ExtensionsAdditional packages that extend the capabilities or the core graphics subsytem. These have names such as GL_ARB_compute_shader.

According to the way OpenGL® works, if a manufacturer says their device/driver supports a particular version of OpenGL® and GLSL, then certain features must work in order for the manufacturer to be able to say that their implementation is compliant. Reality is a little different, and this means that when we work with OpenGL®, it's our job to figure out the features and capabilities of the target hardware in order to write shaders that execute the desired workload.

Let's review all the versions of OpenGL® and GLSL that have ever been made. We'll deal with extensions later, when we start to explore the exact features and capabilities of a specific device and driver.
OpenGL® Version GLSL Version Issue Date Available Extensions
2.0100May 2009Depends on device and driver.
2.0110April 2004Depends on device and driver.
2.1120September 2006Depends on device and driver.
3.0130November 2009Depends on device and driver.
3.1140November 2009Depends on device and driver.
3.2150December 2009Depends on device and driver.
3.0300January 2016Depends on device and driver.
3.1310January 2016Depends on device and driver.
3.2320January 2019Depends on device and driver.
3.3330March 2010Depends on device and driver.
4.0400July 2010Depends on device and driver.
4.1410July 2010Depends on device and driver.
4.2420December 2011Depends on device and driver.
4.3430February 2013Depends on device and driver.
4.4440June 2014Depends on device and driver.
4.5450May 2017Depends on device and driver.
4.6460June 2018Depends on device and driver.

Configure Raspberry Pi® Graphics Mode

The OpenGL® graphics options on the Raspberry Pi® 3B Plus are complicated. First, let's review the most important setting: the graphics driver mode. This defines the features and capabilities of the OpenGL implementation used by your Raspberry Pi® 3B Plus device. The options you choose for the graphics driver mode control whether the shader is hardware accelerated or emulated, and what GLSL features you can use.

It's true that emulated graphics aren't as fast as hardware accelerated graphics, but the Raspberry Pi® 3B Plus emulated graphics mode will allow you to access a lot more features than the hardware accelerated modes. So if you don't have a Raspberry Pi® 4, you can still experiment with some advanced OpenGL® features (and the performance is pretty good).

  1. Open a terminal on your Raspberry Pi® 3B Plus.

    You can connect with RealVNC®, Microsoft® PowerShell, or something else if you prefer.

    This is a picture of the Raspberry Pi terminal.
  2. Type the following command and hit ENTER when you are finished.

    Copy Text To Clipboard

    sudo nano /boot/config.txt

    The nano text editing interface appears:

    This is a picture of the nano text editing interface.

    We don't want to make any changes to this file!

  3. Scroll down to the bottom and find the section named [Pi3] or [Pi4]:

    Your options might look like this. If you see #dtoverlay=vc4-fkms-v3d and #dtoverlay=vc4-kms-v3d are commented out, this means your device is currently using the G1 Legacy mode. Write this down. Note that we've highlighted the options in purple below so you can see them clearly.

    This configuration means your device is currently using G1 Legacy graphics mode.

    This is a picture of the nano text editing interface.

    This configuration means your device is currently using G2 GL (Fake KMS) graphics mode.

    This is a picture of the nano text editing interface.

    This configuration means your device is currently using G2 GL (Full KMS) graphics mode.

    This is a picture of the nano text editing interface.

    Write down the current configuration. It's one of the following: G1 Legacy, G2 GL (Fake KMS), or G2 GL (Full KMS).

    You can skip the instructions in the next section if your device is already set to use the G2 GL (Full KMS) mode. However, even if you skip the instructions, you should read the content.

  4. Hit CTRL + X to exit the nano text editor.

Set The Graphics Mode

  1. Type the following command and hit ENTER when you are finished.

    Copy Text To Clipboard

    sudo raspi-config

    The Raspberry Pi® Software Configuration Tool interface appears:

    This is a picture of the Raspberry Pi Software Configuration Tool interface.
  2. Select Advanced Options from the menu.

    This displays the advanced configuration options menu.

    This is a picture of the Raspberry Pi Software Configuration Tool 'Advanced Options' dialog.
  3. Select GL Driver from the menu.

    This displays the GL driver mode options menu.

    This is a picture of the Raspberry Pi Software Configuration Tool 'Advanced Options' dialog.
    Item Description
    G1 LegacyThis is the original, non-GL desktop driver. While it's not hardware accelerated, it can still run quite a lot of shader programs, including shaders that use advanced features such as image load/store operations. For Raspberry Pi® 3B+ devices, this is the only mode with enough OpenGL® feature support to write shaders that process video.
    G2 GL (Fake KMS)This mode uses hardware acceleration, but it supports a more limited set of OpenGL features than the G1 Legacy mode setting. This uses "fake" KMS, which means that access to the hardware framebuffer is provided through a software layer.
    G2 GL (Full KMS)This mode uses hardware acceleration, but it supports a more limited set of OpenGL features than the G1 Legacy mode setting. This uses "full" KMS, which provides native access to hardware framebuffers.

    When you're writing shaders for your Raspberry Pi® 3B Plus device, you'll need to know which graphics mode is active on your device. Shaders that work fine in one mode may not work at all in a different mode. Make note of your original default graphics mode in case you want to return to it when you are done working with shaders.

  4. Select G2 GL (Full KMS) and hit ENTER.

    The system notifies you that the driver has changed.

    This is a picture of the Raspberry Pi Software Configuration Tool 'Full KMS Driver Enabled' screen.
  5. Hit ENTER to return to the Raspberry Pi® Software Configuration Tool main screen. This is a picture of the Raspberry Pi Software Configuration Tool 'Main Configuration Options' screen.
  6. Select Finish and hit ENTER to exit the Raspberry Pi® Software Configuration Tool.

    If you return to the command line immediately after selecting Finish, it means your device graphics mode was already set to G2 GL (Full KMS). Otherwise, you will be prompted to restart your device. In this case, wait until you are back at the terminal before proceeding.

Querying Hardware Capabilities

By itself, the graphics mode doesn't exactly tell us what OpenGL® features we can use. To know this, we need to query the hardware by running a command that will enumerate the precise features and capabilities available to us in a particular graphics mode.

When you run this command, the system prints a lot more information about the OpenGL capabilities in the terminal. Specifically, it prints a list of OpenGL® versions, GLSL versions, and available extensions. The OpenGL® and the GLSL version give us some idea about what basic capabilities should be available according to the OpenGL® specification, but the list of extensions tells us what features we can actually use when we write shaders.

  1. In the terminal, type the following command and hit ENTER when you are finished.

    Copy Text To Clipboard

    glxinfo -display :0

    The system displays a complete list of capabilities.

    The first section displays low-level OpenGL® capabilities that are used by the application itself to create an OpenGL® device context, move memory around, and so on. These don't really matter for the purposes of writing shaders.

    pi@raspberrypi:~ $ glxinfo -display :0
    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_no_error,
        GLX_ARB_create_context_profile, 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_no_config_context,
        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_no_error, 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_no_error,
        GLX_ARB_create_context_profile, 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
    

    The second part describes capabilities that are of interest. Here we can see that OpenGL® 2.1 is available with GLSL version 120. You can also see that there are quite a few extensions available.

    Extended renderer info (GLX_MESA_query_renderer):
        Vendor: Broadcom (0x14e4)
        Device: VC4 V3D 2.1 (0xffffffff)
        Version: 19.3.2
        Accelerated: yes
        Video memory: 874MB
        Unified memory: yes
        Preferred profile: compat (0x2)
        Max core profile version: 0.0
        Max compat profile version: 2.1
        Max GLES1 profile version: 1.1
        Max GLES[23] profile version: 2.0
    OpenGL vendor string: Broadcom
    OpenGL renderer string: VC4 V3D 2.1
    OpenGL version string: 2.1 Mesa 19.3.2
    OpenGL shading language version string: 1.20
    OpenGL extensions:
        GL_AMD_performance_monitor, GL_AMD_shader_trinary_minmax,
        GL_APPLE_packed_pixels, GL_ARB_ES2_compatibility, GL_ARB_buffer_storage,
        GL_ARB_clear_buffer_object, GL_ARB_color_buffer_float,
        GL_ARB_compressed_texture_pixel_storage, GL_ARB_copy_buffer,
        GL_ARB_debug_output, GL_ARB_depth_texture, GL_ARB_draw_buffers,
        GL_ARB_draw_elements_base_vertex, GL_ARB_explicit_attrib_location,
        GL_ARB_explicit_uniform_location, GL_ARB_fragment_coord_conventions,
        GL_ARB_fragment_program, GL_ARB_fragment_program_shadow,
        GL_ARB_fragment_shader, 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_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_multisample, GL_ARB_multitexture, GL_ARB_occlusion_query,
        GL_ARB_occlusion_query2, GL_ARB_parallel_shader_compile,
        GL_ARB_pixel_buffer_object, GL_ARB_point_parameters, GL_ARB_point_sprite,
        GL_ARB_program_interface_query, GL_ARB_provoking_vertex,
        GL_ARB_robustness, GL_ARB_sampler_objects, GL_ARB_separate_shader_objects,
        GL_ARB_shader_objects, GL_ARB_shading_language_100, GL_ARB_shadow,
        GL_ARB_sync, GL_ARB_texture_barrier, GL_ARB_texture_border_clamp,
        GL_ARB_texture_compression, GL_ARB_texture_cube_map,
        GL_ARB_texture_env_add, GL_ARB_texture_env_combine,
        GL_ARB_texture_env_crossbar, GL_ARB_texture_env_dot3,
        GL_ARB_texture_mirrored_repeat, GL_ARB_texture_multisample,
        GL_ARB_texture_non_power_of_two, GL_ARB_texture_rectangle,
        GL_ARB_texture_storage, GL_ARB_texture_storage_multisample,
        GL_ARB_texture_swizzle, GL_ARB_transpose_matrix,
        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_window_pos, GL_ATI_blend_equation_separate, GL_ATI_draw_buffers,
        GL_ATI_fragment_shader, GL_ATI_separate_stencil,
        GL_ATI_texture_env_combine3, GL_EXT_EGL_sync, 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_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_pixels,
        GL_EXT_pixel_buffer_object, GL_EXT_point_parameters,
        GL_EXT_provoking_vertex, GL_EXT_rescale_normal, GL_EXT_secondary_color,
        GL_EXT_separate_specular_color, GL_EXT_shader_integer_mix,
        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_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_lod_bias, GL_EXT_texture_object,
        GL_EXT_texture_rectangle, GL_EXT_texture_sRGB, GL_EXT_texture_sRGB_decode,
        GL_EXT_texture_swizzle, GL_EXT_vertex_array, GL_IBM_multimode_draw_arrays,
        GL_IBM_rasterpos_clip, GL_IBM_texture_mirrored_repeat,
        GL_INGR_blend_func_separate, GL_KHR_context_flush_control, GL_KHR_debug,
        GL_KHR_no_error, GL_KHR_parallel_shader_compile,
        GL_KHR_texture_compression_astc_ldr,
        GL_KHR_texture_compression_astc_sliced_3d, GL_MESA_pack_invert,
        GL_MESA_tile_raster_order, GL_MESA_window_pos, GL_NV_blend_square,
        GL_NV_fog_distance, GL_NV_light_max_exponent, GL_NV_packed_depth_stencil,
        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_SGIS_generate_mipmap, GL_SGIS_texture_border_clamp,
        GL_SGIS_texture_edge_clamp, GL_SGIS_texture_lod, GL_SUN_multi_draw_arrays
    

    The third part also describes capabilities that are of interest. Here we can see that OpenGL® 2.0 is available with GLSL version 100. Not nearly as many extensions are available for writing shaders.

    OpenGL ES profile version string: OpenGL ES 2.0 Mesa 19.3.2
    OpenGL ES profile shading language version string: OpenGL ES GLSL ES 1.0.16
    OpenGL ES profile extensions:
        GL_AMD_performance_monitor, GL_APPLE_texture_max_level,
        GL_EXT_blend_minmax, GL_EXT_compressed_ETC1_RGB8_sub_texture,
        GL_EXT_discard_framebuffer, GL_EXT_draw_buffers,
        GL_EXT_draw_elements_base_vertex, GL_EXT_frag_depth,
        GL_EXT_map_buffer_range, GL_EXT_multi_draw_arrays,
        GL_EXT_occlusion_query_boolean, GL_EXT_read_format_bgra,
        GL_EXT_separate_shader_objects, GL_EXT_texture_border_clamp,
        GL_EXT_texture_format_BGRA8888, GL_EXT_unpack_subimage,
        GL_KHR_context_flush_control, GL_KHR_debug, GL_KHR_no_error,
        GL_KHR_parallel_shader_compile, GL_KHR_texture_compression_astc_ldr,
        GL_KHR_texture_compression_astc_sliced_3d, GL_MESA_tile_raster_order,
        GL_NV_draw_buffers, GL_NV_fbo_color_attachments, 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_sync,
        GL_OES_compressed_ETC1_RGB8_texture, GL_OES_depth24, GL_OES_depth_texture,
        GL_OES_draw_elements_base_vertex, 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_required_internalformat,
        GL_OES_rgb8_rgba8, GL_OES_stencil8, GL_OES_surfaceless_context,
        GL_OES_texture_3D, GL_OES_texture_border_clamp, GL_OES_texture_npot,
        GL_OES_vertex_array_object, GL_OES_vertex_half_float
    

    Finally, we get a long list of framebuffer configurations. These also aren't of interest to us right now.

    234 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
    ----------------------------------------------------------------------------
    0x021 24 tc  0  32  0 r  y .   8  8  8  8 .  .  0 24  8  0  0  0  0  0 0 None
    ...
    

    The G2 GL (Full KMS) driver provides us with the ability to compile and run the following versions of GLSL.

    OpenGL® Version GLSL Version Extensions
    OpenGL 2.0100 (es)Some extensions are available.
    OpenGL 2.1120Many extensions are available.

    Now we know what features and capabilities are available to us when the G2 GL (Full KMS) driver is active. It looks like OpenGL® 2.1 with GLSL 120 has the most features available. Let's start there.