mripard / sunxi-mali

GNU General Public License v2.0
100 stars 54 forks source link

/dev/dri/card0 not created #45

Closed Draghtnod closed 6 years ago

Draghtnod commented 6 years ago

Greetings!

$ dmesg | tail
[   17.665857] IPv6: ADDRCONF(NETDEV_UP): wlan0: link is not ready
[   59.953662] mali: loading out-of-tree module taints kernel.
[   59.965564] platform mali-utgard: assigned reserved memory node linux,cma
[   59.967252] Allwinner sunXi mali glue initialized
[   59.969557] Mali:
[   59.969571] Found Mali GPU Mali-400 MP r1p1
[   59.972005] Mali:
[   59.972012] 2+0 PP cores initialized
[   59.972794] Mali:
[   59.972800] Mali device driver loaded

$ cat /var/log/Xorg.0.log
[ 13130.386]
X.Org X Server 1.19.2
Release Date: 2017-03-02
[ 13130.386] X Protocol Version 11, Revision 0
[ 13130.386] Build Operating System: Linux 4.9.0-4-armmp-lpae armv7l Debian
[ 13130.386] Current Operating System: Linux orangepizero 4.14.18-sunxi #24 SMP Fri Feb 9 16:24:32 CET 2018 armv7l
[ 13130.387] Kernel command line: root=UUID=a2c25aee-d15d-4aa7-8f41-ab6bb511776f rootwait rootfstype=ext4 console=tty1 console=ttyS0,115200 hdmi.audio=EDID:0 disp.screen0_output_mode=1920x1080p60 panic=10 consoleblank=0 loglevel=1 ubootpart=378fc799-01 ubootsource=mmc usb-storage.quirks=0x2537:0x1066:u,0x2537:0x1068:u spidev.bufsiz=16384  sunxi_ve_mem_reserve=0 sunxi_g2d_mem_reserve=0 sunxi_fb_mem_reserve=16 cgroup_enable=memory swapaccount=1
[ 13130.387] Build Date: 16 October 2017  09:48:39AM
[ 13130.387] xorg-server 2:1.19.2-1+deb9u2 (https://www.debian.org/support)
[ 13130.387] Current version of pixman: 0.34.0
[ 13130.387]    Before reporting problems, check http://wiki.x.org
        to make sure that you have the latest version.
[ 13130.387] Markers: (--) probed, (**) from config file, (==) default setting,
        (++) from command line, (!!) notice, (II) informational,
        (WW) warning, (EE) error, (NI) not implemented, (??) unknown.
[ 13130.388] (==) Log file: "/var/log/Xorg.0.log", Time: Sun Jul 22 16:56:40 2018
[ 13130.389] (==) Using config directory: "/etc/X11/xorg.conf.d"
[ 13130.390] (==) Using system config directory "/usr/share/X11/xorg.conf.d"
[ 13130.391] (==) No Layout section.  Using the first Screen section.
[ 13130.391] (**) |-->Screen "Headless Screen" (0)
[ 13130.391] (**) |   |-->Monitor "Monitor0"
[ 13130.393] (**) |   |-->Device "Allwinner sun4i DRM driver"
[ 13130.393] (**) Option "BlankTime" "0"
[ 13130.393] (**) Option "StandbyTime" "0"
[ 13130.393] (**) Option "SuspendTime" "0"
[ 13130.393] (**) Option "OffTime" "0"
[ 13130.394] (==) Automatically adding devices
[ 13130.394] (==) Automatically enabling devices
[ 13130.394] (==) Automatically adding GPU devices
[ 13130.394] (==) Max clients allowed: 256, resource mask: 0x1fffff
[ 13130.394] (WW) The directory "/usr/share/fonts/X11/misc" does not exist.
[ 13130.394]    Entry deleted from font path.
[ 13130.394] (WW) The directory "/usr/share/fonts/X11/cyrillic" does not exist.
[ 13130.394]    Entry deleted from font path.
[ 13130.394] (WW) The directory "/usr/share/fonts/X11/100dpi/" does not exist.
[ 13130.394]    Entry deleted from font path.
[ 13130.394] (WW) The directory "/usr/share/fonts/X11/75dpi/" does not exist.
[ 13130.394]    Entry deleted from font path.
[ 13130.394] (WW) The directory "/usr/share/fonts/X11/Type1" does not exist.
[ 13130.394]    Entry deleted from font path.
[ 13130.394] (WW) The directory "/usr/share/fonts/X11/100dpi" does not exist.
[ 13130.394]    Entry deleted from font path.
[ 13130.394] (WW) The directory "/usr/share/fonts/X11/75dpi" does not exist.
[ 13130.394]    Entry deleted from font path.
[ 13130.395] (==) FontPath set to:
        built-ins
[ 13130.395] (==) ModulePath set to "/usr/lib/xorg/modules"
[ 13130.396] (II) The server relies on udev to provide the list of input devices.
        If no devices become available, reconfigure udev or disable AutoAddDevices.
[ 13130.397] (II) Loader magic: 0x633f60
[ 13130.398] (II) Module ABI versions:
[ 13130.398]    X.Org ANSI C Emulation: 0.4
[ 13130.399]    X.Org Video Driver: 23.0
[ 13130.399]    X.Org XInput driver : 24.1
[ 13130.399]    X.Org Server Extension : 10.0
[ 13130.402] (--) using VT number 2

[ 13130.402] (II) systemd-logind: logind integration requires -keeptty and -keeptty was not provided, disabling logind integration
[ 13130.403] (II) no primary bus or device found
[ 13130.403] (II) LoadModule: "glx"
[ 13130.404] (II) Loading /usr/lib/xorg/modules/extensions/libglx.so
[ 13130.410] (II) Module glx: vendor="X.Org Foundation"
[ 13130.410]    compiled for 1.19.2, module version = 1.0.0
[ 13130.410]    ABI class: X.Org Server Extension, version 10.0
[ 13130.410] (II) LoadModule: "armsoc"
[ 13130.411] (II) Loading /usr/lib/xorg/modules/drivers/armsoc_drv.so
[ 13130.411] (II) Module armsoc: vendor="X.Org Foundation"
[ 13130.411]    compiled for 1.19.2, module version = 1.4.1
[ 13130.411]    Module class: X.Org Video Driver
[ 13130.411]    ABI class: X.Org Video Driver, version 23.0
[ 13130.411] (II) ARMSOC: Driver for ARM Mali compatible chipsets
[ 13130.412] (WW) Falling back to old probe method for armsoc
[ 13130.412] (II) No BusID or DriverName specified - opening /dev/dri/card0
[ 13130.412] (EE) ERROR: Cannot open a connection with the DRM - No such file or directory
[ 13130.412] (EE) No devices detected.
[ 13130.412] (EE)
Fatal server error:
[ 13130.412] (EE) no screens found(EE)
[ 13130.412] (EE)
Please consult the The X.Org Foundation support
         at http://wiki.x.org
 for help.
[ 13130.412] (EE) Please also check the log file at "/var/log/Xorg.0.log" for additional information.
[ 13130.412] (EE)
[ 13130.413] (EE) Server terminated with error (1). Closing log file.

Am i missing something?

giuliobenetti commented 6 years ago

Hi, can you pastebin your entire dmesg? There you should see that no panel or bridge or output in general can get registered. IMHO This should be why it can't find dri/card0.

Draghtnod commented 6 years ago

Complete dmesg: https://pastebin.com/raw/9QRC7JTG I don't see anything unusual. It's an OrangePI Zero running current Armbian Stretch. Applying this dts https://pastebin.com/raw/yTEkUpjX had no effect. :disappointed:

giuliobenetti commented 6 years ago

It seems drm is not compiled in kernel. So try to enable it and recompile(drm-sun4i). For dts, you could use latest kernel >= 4.17, where Mali node is already present for H3.

Draghtnod commented 6 years ago

Ok, i removed the dts overlay, upgraded to 4.17 and recompiled the driver. Still no /dev/dri/*. Modprobing sun4i-drm works silently.

CONFIG_DRM_SUN4I=y
CONFIG_DRM_SUN4I_HDMI=y
CONFIG_DRM_SUN4I_HDMI_CEC=y
CONFIG_DRM_SUN4I_BACKEND=y
CONFIG_DRM_SUN8I_DW_HDMI=y
CONFIG_DRM_SUN8I_MIXER=y

$ sudo modprobe sun4i-drm
$ sudo modprobe sun4i-frontend
$ sudo modprobe sun4i-backend
$ sudo insmod mali.ko
$ ls /dev/dri
ls: cannot access '/dev/dri': No such file or directory

I tried Mali driver version r6p2 and r8p1, no difference. Dmesg: https://pastebin.com/raw/M1HjzjQP

giuliobenetti commented 6 years ago

Modprobing should leave a trace in dmesg. Did you get dmesg before or after modprobe? If before, please pastebin dmesg after modprobe. Thanks

Draghtnod commented 6 years ago

The dmesg was after the modprobe. No trace, except for the mali driver.

giuliobenetti commented 6 years ago

Ah, try changing loglevel=7 instead of loglevel=1 in your bootargs, this will make kernel more verbose. Then repastebin dmesg. Thanks

Draghtnod commented 6 years ago

I am the one that has to thank you Mr. Benetti! Without you i woulnd't have a clue where to search.

Ok, loglevel=10, same procedure. Doesn't seem to produce more log entries. Still nothing from sun4i-drm and friends. https://pastebin.com/raw/2Ygh0JmD

sergey-suloev commented 6 years ago

@Draghtnod That all is really strange. You can try to compile SUN4I DRM as a module just to make sure it is loaded.By the way, "modprobe sun4i-drm" IMHO makes no sense as soon as you compile DRM into the kernel. You can setup your config as below:

CONFIG_DRM_SUN4I=m CONFIG_DRM_SUN4I_HDMI=m CONFIG_DRM_SUN4I_HDMI_CEC=y CONFIG_DRM_SUN4I_BACKEND=m CONFIG_DRM_SUN8I_DW_HDMI=m CONFIG_DRM_SUN8I_MIXER=m

After you recompile your image you can issue "lsmod" to see what is really loaded. And please pastebin your kernel config and device tree files too.

mripard commented 6 years ago

This isn't a Mali driver issue.

Draghtnod commented 6 years ago

I finally had time to contunue pursuing this endeavour and tried to compile the Kernel with the DRM_SUN4I as Modules. Switching any of these CONFIG_DRM_SUN4I=m CONFIG_DRM_SUN4I_BACKEND=m CONFIG_DRM_SUN8I_MIXER=m to m will break the compilation process. Sometimes with error, sometimes without. Turning them to y or n will compile just fine.

While searching i noticed, that insmod mali.ko will create /dev/mali, but not /dev/dri/card0. And there is a separate mali_drm module here, which won't compile because drm_sman.h is missing in mainline kernel. Maybe mali_drm will create the /dev/dri/card0 device? I couldn't find any documentation on this. :/

giuliobenetti commented 6 years ago

You should ask on linux-sunxi irc. You can't find /dev/dri/card0 because of wrong drm setup in your kernel. Mali should be OK at that point. On irc they can help you for drm to work. And mali_drm as I know won't show up /dev/dri/card0.

Draghtnod commented 6 years ago

Ok thank you. Ill try to find help in IRC. Meanwhile i tried to patch mali_drm to compile with mainline. But phew.. Its not only the drm_sman, i glued that. There are lots of things restructured and renamed. That code seems to be very old.

sergey-suloev commented 6 years ago

@Draghtnod "to m will break the compilation process"

I don't believe you :-)) .. because this is just impossible. DRM can be compiled as modules, it has been proved by many people with different kernel versions. If this happens can you pastebin the compilation error ? You can also analyze my config which is 100% working. https://pastebin.com/72LttH3E

And you don't need mali_drm.

Draghtnod commented 6 years ago

I am using the docker support of armbian build.

git checkout https://github.com/armbian/build.git
cd build
docker build -t armbian-kenel .
docker run -it armbian-kenel

I tried it about 20 times. No luck with m.

Nevertheless, I found the problem with some help of the linux-sunxi team. The problem was the missing de (display-engine) node in the device tree. Adding this will cause the sun4i-drm to start up at boot and throw an error, becuase the system is headless. Patching the kernel with this new patch from Paul today, the /dev/dri/card0 finally shows up.

Using the mali driver + sun4i-drm + wayland version of mali-blob + GBM, i should finally be able to render stuff headless. Maybe tomorrow i'll know. :)

sergey-suloev commented 6 years ago

@Draghtnod Nice to hear that you have some progress. Now I understand that you're trying to render without HDMI display connected. I have never run this scenario.

Draghtnod commented 6 years ago

Alright i found a little time again to further pursue this adventure.

/dev/mali is present /dev/dri/card0 is present Mali Blobs user space driver, wayland version (for GBM support) r6p2 is installed A little Rust program to utilize GBM for a virtual display and EGL is written.

These lines

    let apis = egl::query_string( egl::EGL_NO_DISPLAY, egl::EGL_EXTENSIONS );
    if apis.is_some() {
        println!( "Display Extensions: {}", apis.unwrap().to_str().unwrap_or( "unwrap error" ) );
    }
    let dri = OpenOptions::new().read( true ).write( true ).open( "/dev/dri/card0" ).unwrap();
    let gbm = unsafe { gbm_sys::gbm_create_device( dri.as_raw_fd() ) };

output this:

Display Extensions: EGL_EXT_client_extensions EGL_EXT_platform_base EGL_KHR_platform_gbm EGL_KHR_platform_wayland 
MESA-LOADER: failed to retrieve device information
gbm: failed to open any driver (search paths /usr/lib/arm-linux-gnueabihf/dri:${ORIGIN}/dri:/usr/lib/dri)
gbm: Last dlopen error: /usr/lib/dri/sun4i-drm_dri.so: cannot open shared object file: No such file or directory
failed to load driver: sun4i-drm
No Display: 0x3000
Process exited with code 0.

dmesg:

[  119.472305] mali: loading out-of-tree module taints kernel.
[  119.480885] Allwinner sunXi mali glue initialized
[  119.483224] Mali:
[  119.483234] Found Mali GPU Mali-400 MP r1p1
[  119.483679] Mali:
[  119.483685] 2+0 PP cores initialized
[  119.484711] Mali:
[  119.484719] Mali device driver loaded
[  193.857641] [drm:drm_stub_open]
[  193.857702] [drm:drm_open] pid = 1201, minor = 0
[  193.857901] [drm:drm_open]
[  194.940518] [drm:drm_ioctl] pid=1201, dev=0xe200, auth=1, DRM_IOCTL_VERSION
[  194.940541] [drm:drm_ioctl] pid=1201, dev=0xe200, auth=1, DRM_IOCTL_VERSION
[  197.611710] [drm:drm_ioctl] pid=1201, dev=0xe200, auth=1, DRM_IOCTL_GET_CAP
[  197.772350] [drm:drm_release] open_count = 1
[  197.772366] [drm:drm_release] pid = 1204, device = 0xe200, open_count = 1
[  197.772389] [drm:drm_lastclose]
[  197.772395] [drm:drm_lastclose] driver lastclose completed

Appearantly there is a sun4i-drm_dri.so missing. I found some more error messages around the web with that problem as well, but no info on how to find or compile this file or where it comes from. The name suggests it belongs to the sunxi DRM drivers, but i didn't find anything there. Maybe someone of you has seen this before?

If i linkt the missing /usr/lib/dri/sun4i-drm_dri.so to the mali blobs libMali.so, it complains about missing functions:

Display Extensions: EGL_EXT_client_extensions EGL_EXT_platform_base EGL_KHR_platform_gbm EGL_KHR_platform_wayland 
MESA-LOADER: failed to retrieve device information
gbm: driver exports no extensions (/usr/lib/libEGL.so.1: undefined symbol: __driDriverExtensions)failed to load driver: sun4i-drm
No Display: 0x3000
Process exited with code 0.
Draghtnod commented 6 years ago

This issue came up here as well. No solution tho.. It seems to be the DRM interface of the device driver. So sunxi-mali should be the right spot. Correct?

timdorohin commented 5 years ago

MESA-LOADER

lol u did mesa again mesa libs must not be included in library path. Also make link "libwayland-egl.so.1" > "libwayland-egl.so" where your mali libs located

Draghtnod commented 5 years ago

Duh.. Thank you.. I totally forgot to copy the mali-blobs to the compiling system.

gbm_create_device() works now, egl_get_display() too! New Error now at egl_initialize (yay!):

Display Extensions: EGL_EXT_client_extensions EGL_EXT_platform_base EGL_KHR_platform_gbm EGL_KHR_platform_wayland 
Initialize failed: 0x3003
Process exited with code 0.

0x3003 is EGL_BAD_ALLOC. Looks like the driver is not happy with the drm memory allocations. :/ This thing really doesn't like to render stuff.

sergey-suloev commented 5 years ago

@Draghtnod It seems to me that we already had this problem before. Try searching in closed issues , there should be a big discussion about it.

timdorohin commented 5 years ago

@Draghtnod this can be:

Draghtnod commented 5 years ago

Holy Moly it WORKS!!

Display Extensions: EGL_EXT_client_extensions EGL_EXT_platform_base EGL_KHR_platform_gbm EGL_KHR_platform_wayland 
GBM: 0xb6821030
Display: 0x1
EGL initialized with v1.4
apis: OpenGL_ES
vendor: ARM
version: 1.4 Linux-r6p2-01rel0
extensions: EGL_KHR_image EGL_KHR_image_base EGL_KHR_image_pixmap EGL_EXT_image_dma_buf_import EGL_KHR_gl_texture_2D_image EGL_KHR_gl_texture_cubemap_image EGL_KHR_gl_renderbuffer_image EGL_KHR_reusable_sync EGL_KHR_fence_sync EGL_KHR_swap_buffers_with_damage EGL_EXT_swap_buffers_with_damage EGL_KHR_lock_surface EGL_KHR_lock_surface2 EGL_EXT_create_context_robustness EGL_ANDROID_blob_cache EGL_KHR_create_context EGL_WL_bind_wayland_display EGL_KHR_partial_update EGL_KHR_create_context_no_error 
EGL_RENDERABLE_TYPE: 5

That was NOT obvious at all. This driver and the mali blobs feel like a big horrible hack. Here is how it works:

Basically every function you call and resource you use is contained within the sunxi-mali and mali-blobs ecosystem. No external library or resource is touched at all, even if all the functions, libraries are called this way and all the docs you find tell a different story. Not intuitive at all.

Thank you again everyone for all the help! I'll write a little HOTWO in the armbian forums. Maybe someone with a H2+/H3 is crazy enough to try to do the same.

HeatfanJohn commented 5 years ago

@Draghtnod Can you post your complete rust test program and requirements to build it? I'm trying to get the Mali driver and r6p2 wayland blobs working on an A64 and your rust program can help me see if I have it working.

HeatfanJohn commented 5 years ago

@Draghtnod Here's what I have to try to run your sample rust code:

src/main.rs:

extern crate egl;
extern crate gbm_sys;

use std::fs::OpenOptions;
use std::os::unix::io::AsRawFd;

// This is the main function
fn main() {
    // Print text to the console
    println!("GBM Test");
    let apis = egl::query_string( egl::EGL_NO_DISPLAY, egl::EGL_EXTENSIONS );
    if apis.is_some() {
        println!( "Display Extensions: {}", apis.unwrap().to_str().unwrap_or( "unwrap error" ) );
    }
    let dri = OpenOptions::new().read( true ).write( true ).open( "/dev/mali" ).unwrap();
    let gbm = unsafe { gbm_sys::gbm_create_device( dri.as_raw_fd() ) };
}

Cargo.toml:

[package]
name = "gbm-test"
version = "0.1.0"
authors = ["John P. Masseria <jpmasseria@gmail.com>"]

[dependencies]
egl = "0.2.7"
gbm-sys = "0.1.0"

But cargo build yields error[E0425]: cannot find functiongbm_create_devicein modulegbm_sys`

error[E0425]: cannot find function `gbm_create_device` in module `gbm_sys`
  --> src/main.rs:20:33
   |
20 |     let gbm = unsafe { gbm_sys::gbm_create_device( dri.as_raw_fd() ) };
   |                                 ^^^^^^^^^^^^^^^^^ not found in `gbm_sys`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0425`.
error: Could not compile `gbm-test`.
Draghtnod commented 5 years ago

@HeatfanJohn Sorry I'm a bit late. You have to use the "gen" feature of gbm_sys, so the gmb_create_device function gets wired to the mali blobs, to which libgbm should symlink to. Make sure you have uninstalled the genuine libgbm. I had problems with gbm_sys and the gen feature, so i forked it and made some bugfixes. Works fine for me now. :) Good Luck!

extern crate log;
extern crate gbm;
extern crate egl;

use std::fs::{ OpenOptions, File };
use self::gbm::AsRaw;

/// A virtual EGL Display based on a GBM buffer.
#[allow(dead_code)]
pub struct GBMEGLDisplay {
    gbm_device: gbm::Device< File >,
    egl_display: egl::EGLDisplay,
}

impl GBMEGLDisplay {

    /// Creates a virtual EGL Display based on a GBM buffer and makes it current.
    /// # Arguments
    /// `size` - Width and height of the display buffer in pixels.
    pub fn create( size : ( u32, u32 ) ) -> Result< GBMEGLDisplay, () > {
        // Print available EGL Display Extensions
        debug!( "EGL Display Extensions: {}", egl::query_string( egl::EGL_NO_DISPLAY, egl::EGL_EXTENSIONS ).unwrap_or_default().to_str().unwrap_or( "unwrap error" ) );

        // Open the mali device
        let mali_device = try!( OpenOptions::new().read( true ).write( true ).open( "/dev/mali" ).or_else( |error| {
            error!( "Could not access /dev/mali device: {:?}", error );
            Err(())
        } ) );

        // Create a GBM device from the mali device
        let gbm_device = try!( gbm::Device::new( mali_device ).or_else( |error| {
            error!( "Could not create GBM device: {:?}", error );
            Err(())
        } ) );

        // Get an EGL Display from the GBM device    
        let egl_display = try!( egl::get_display( gbm_device.as_raw_mut() as egl::EGLDisplay ).ok_or_else( || {
            error!( "Could not aquire an EGL display: Error {:#X?}", egl::get_error() );
            ()
        } ) );

        // Initialize EGL
        let mut maj = 0;
        let mut min = 0;
        if !egl::initialize( egl_display, &mut maj, &mut min ) {
            error!( "Initialize failed: Error {:#X?}", egl::get_error() );
            return Err(());
        }
        info!( "EGL initialized with v{}.{}", maj, min );

        // Print Various infos
        debug!( "EGL Version: {}", egl::query_string( egl_display, egl::EGL_VERSION ).unwrap_or_default().to_str().unwrap_or( "unwrap error" ) );
        debug!( "EGL Vendor: {}", egl::query_string( egl_display, egl::EGL_VENDOR ).unwrap_or_default().to_str().unwrap_or( "unwrap error" ) );
        debug!( "EGL Apis: {}", egl::query_string( egl_display, egl::EGL_CLIENT_APIS ).unwrap_or_default().to_str().unwrap_or( "unwrap error" ) );
        debug!( "EGL Extensions: {}", egl::query_string( egl_display, egl::EGL_EXTENSIONS ).unwrap_or_default().to_str().unwrap_or( "unwrap error" ) );

        // Choose a suitable config
        let attrib_list = [
            egl::EGL_RENDERABLE_TYPE, egl::EGL_OPENGL_ES2_BIT,
            egl::EGL_CONFORMANT, egl::EGL_OPENGL_ES2_BIT,
            egl::EGL_SURFACE_TYPE, egl::EGL_PBUFFER_BIT,
            egl::EGL_BIND_TO_TEXTURE_RGB, egl::EGL_TRUE as egl::EGLint,
            egl::EGL_BIND_TO_TEXTURE_RGBA, egl::EGL_TRUE as egl::EGLint,
            egl::EGL_RED_SIZE, 8,
            egl::EGL_GREEN_SIZE, 8,
            egl::EGL_BLUE_SIZE, 8,
            egl::EGL_ALPHA_SIZE, 0,
            egl::EGL_DEPTH_SIZE, 0,
            egl::EGL_STENCIL_SIZE, 0,
            egl::EGL_NONE
        ];
        let config = try!( egl::choose_config( egl_display, &attrib_list, 1 ).ok_or_else( || {
            error!( "Config not available: {:#X?}", egl::get_error() );
            egl::terminate( egl_display );
            ()
        } ) );

        // Print some debug info
        let mut value = 0;
        if egl::get_config_attrib( egl_display, config, egl::EGL_RED_SIZE,              &mut value ) { debug!( "EGL_RED_SIZE: {}", value ); }
        if egl::get_config_attrib( egl_display, config, egl::EGL_GREEN_SIZE,            &mut value ) { debug!( "EGL_GREEN_SIZE: {}", value ); }
        if egl::get_config_attrib( egl_display, config, egl::EGL_BLUE_SIZE,             &mut value ) { debug!( "EGL_BLUE_SIZE: {}", value ); }
        if egl::get_config_attrib( egl_display, config, egl::EGL_ALPHA_SIZE,            &mut value ) { debug!( "EGL_ALPHA_SIZE: {}", value ); }
        if egl::get_config_attrib( egl_display, config, egl::EGL_BUFFER_SIZE,           &mut value ) { debug!( "EGL_BUFFER_SIZE: {}", value ); }
        if egl::get_config_attrib( egl_display, config, egl::EGL_DEPTH_SIZE,            &mut value ) { debug!( "EGL_DEPTH_SIZE: {}", value ); }
        if egl::get_config_attrib( egl_display, config, egl::EGL_STENCIL_SIZE,          &mut value ) { debug!( "EGL_STENCIL_SIZE: {}", value ); }
        if egl::get_config_attrib( egl_display, config, egl::EGL_LUMINANCE_SIZE,        &mut value ) { debug!( "EGL_LUMINANCE_SIZE: {}", value ); }
        if egl::get_config_attrib( egl_display, config, egl::EGL_COLOR_BUFFER_TYPE,     &mut value ) { debug!( "EGL_COLOR_BUFFER_TYPE: {}", value ); }
        if egl::get_config_attrib( egl_display, config, egl::EGL_MAX_PBUFFER_WIDTH,     &mut value ) { debug!( "EGL_MAX_PBUFFER_WIDTH: {}", value ); }
        if egl::get_config_attrib( egl_display, config, egl::EGL_MAX_PBUFFER_HEIGHT,    &mut value ) { debug!( "EGL_MAX_PBUFFER_HEIGHT: {}", value ); }
        if egl::get_config_attrib( egl_display, config, egl::EGL_MAX_PBUFFER_PIXELS,    &mut value ) { debug!( "EGL_MAX_PBUFFER_PIXELS: {}", value ); }
        if egl::get_config_attrib( egl_display, config, egl::EGL_NATIVE_RENDERABLE,     &mut value ) { debug!( "EGL_NATIVE_RENDERABLE: {}", value ); }
        if egl::get_config_attrib( egl_display, config, egl::EGL_RENDERABLE_TYPE,       &mut value ) { debug!( "EGL_RENDERABLE_TYPE: {}", value ); }
        if egl::get_config_attrib( egl_display, config, egl::EGL_CONFORMANT,            &mut value ) { debug!( "EGL_CONFORMANT: {}", value ); }
        if egl::get_config_attrib( egl_display, config, egl::EGL_BIND_TO_TEXTURE_RGB,   &mut value ) { debug!( "EGL_BIND_TO_TEXTURE_RGB: {}", value ); }
        if egl::get_config_attrib( egl_display, config, egl::EGL_BIND_TO_TEXTURE_RGBA,  &mut value ) { debug!( "EGL_BIND_TO_TEXTURE_RGBA: {}", value ); }
        if egl::get_config_attrib( egl_display, config, egl::EGL_MATCH_NATIVE_PIXMAP,   &mut value ) { debug!( "EGL_MATCH_NATIVE_PIXMAP: {}", value ); }

        // Create a context
        let attrib_list = [
            egl::EGL_CONTEXT_CLIENT_VERSION, 2,
            egl::EGL_NONE
        ];   
        let context = try!( egl::create_context( egl_display, config, egl::EGL_NO_CONTEXT, &attrib_list ).ok_or_else( || {
            error!( "Could not create context: {:#X?}", egl::get_error() );
            egl::terminate( egl_display );
            ()
        } ) );

        // Create a render buffer
        let attrib_list = [
            egl::EGL_WIDTH, size.0 as egl::EGLint,
            egl::EGL_HEIGHT, size.1 as egl::EGLint,
            egl::EGL_NONE
        ];    
        let pbuffer = try!( egl::create_pbuffer_surface( egl_display, config, &attrib_list ).ok_or_else( || {
            error!( "Could not create pbuffer surface: {:#X?}", egl::get_error() );
            egl::terminate( egl_display );
            ()
        } ) );

        // Select the render buffer
        if !egl::make_current( egl_display, pbuffer, pbuffer, context ) {
            error!( "Make current failed: {:#X?}", egl::get_error() );
            egl::terminate( egl_display );
            return Err(());
        }

        Ok( GBMEGLDisplay {
            gbm_device,
            egl_display,
        } )
    }
}

impl Drop for GBMEGLDisplay {

    /// Releases internal resources.
    fn drop( &mut self ) {
        if !egl::terminate( self.egl_display ) {
            error!( "Could not terminate EGL display: {:#X?}", egl::get_error() );
        } else {
            debug!( "EGL display terminated.")
        }
    }

}

Cargo.toml

[dependencies.gbm]
git = "https://github.com/Draghtnod/gbm.rs.git"
default-features = false 
features = [ "gen" ]

[dependencies.opengles]
git = "https://github.com/Draghtnod/rust-opengles.git"

[dependencies]
log = "*"
egl = "*"
...