EGL Context Creation with tx1

Hello, I’m trying to create an egl context with a jetson tx1 devkit running L4T 24.2.1

This is a distilled example of the failure (it’s in a file called simpletest.c):

#include <X11/Xatom.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GL/gl.h>
#include <GL/glx.h>
#include <GL/glext.h>
#include <stdio.h>

int main(int argc, char *argv[]) {    

    EGLDisplay display;
    EGLSurface surface;
    Display *x11 = XOpenDisplay(NULL);
    Window root = DefaultRootWindow(x11);
    Window window;
    XSetWindowAttributes swa = {};
    EGLConfig egl_config;
    EGLContext context;
    
    display = eglGetDisplay(x11);
    
    window  =  XCreateWindow (   // create a window with the provided parameters
        x11, root,
        0, 0, 640, 480,   0,
        CopyFromParent, InputOutput,
        CopyFromParent, CWEventMask,
        &swa );
    
    eglInitialize(display, NULL, NULL);
    if (EGL_FALSE == eglBindAPI(EGL_OPENGL_API)) {
        fprintf(stderr, "Failed to bind OpenGL\n");
        return -1;
    }

    {    
        static EGLint attribute_list[] = {
            EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 
            EGL_SURFACE_TYPE, 0,
            EGL_NONE
        };
        EGLint num_config;
        EGLConfig egl_config_array[128];

        egl_config = 0;
        
        eglChooseConfig(display, attribute_list, egl_config_array, 128, &num_config);

        for (int i = 0; i < num_config; i++) {
            EGLint attrib = 0;
            
            // Color bits.
            eglGetConfigAttrib(display, egl_config_array[i], EGL_BUFFER_SIZE, &attrib);
            if (attrib != 32)
                continue;
            
            // Depth bits.
            eglGetConfigAttrib(display, egl_config_array[i], EGL_DEPTH_SIZE, &attrib);
            if (attrib != 24)
                continue;
            
            // Samples.
            eglGetConfigAttrib(display, egl_config_array[i], EGL_SAMPLES, &attrib);
            if (attrib != 0)
                continue;

            eglGetConfigAttrib(display, egl_config_array[i], EGL_SURFACE_TYPE, &attrib);
            
            if ((attrib & ((x11)?EGL_WINDOW_BIT:EGL_PBUFFER_BIT)) != 0) {
                egl_config = egl_config_array[i];
                printf("CHOSE %d!\n", i);
                break;
            }
        }

        if (egl_config == 0) {
            fprintf(stderr, "Failed to choose an EGL config (from %d)\n", num_config);
            return -1;
        }
        printf("chose config %p from %d\n", egl_config, num_config);
    }
    {
        static const EGLint contextAttribs[] = {
            EGL_CONTEXT_CLIENT_VERSION, 3,
            EGL_NONE
        };
        context = 0;
        context = eglCreateContext(display, egl_config, EGL_NO_CONTEXT, contextAttribs);
    }

    if (context == EGL_NO_CONTEXT) {
        fprintf(stderr, "Could not create EGL context\n");
        return -1;
    }

surface = eglCreateWindowSurface(display, egl_config, window, NULL);
    
    if (surface == EGL_NO_SURFACE) {
        fprintf(stderr, "EGL ERROR 0x%x\n", eglGetError());
    }
    
    /* connect the context to the surface */
    if (EGL_FALSE == eglMakeCurrent(display, surface, surface, context)) {
            
        fprintf(stderr, "Failed to select the egl context\n");
        return -1;
    }

    printf("CURRENT_CONTEXT: %p\n", eglGetCurrentContext());

    {
        GLint maj=0, min=0;
        glGetIntegerv(GL_MAJOR_VERSION, &maj);
        glGetIntegerv(GL_MINOR_VERSION, &min);
        printf("\tOPENGL %d.%d INFO:\n", maj, min);
    }

    printf("\tVENDOR: %s\n", glGetString(GL_VENDOR));
    printf("\tRENDERER: %s\n", glGetString(GL_RENDERER));
    printf("\tVERSION: %s\n", glGetString(GL_VERSION));
    printf("\tGLSL VERSION: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
    printf("\tEGL VENDOR: %s\n", eglQueryString(display, EGL_VENDOR));
    printf("\tEGL VERSION: %s\n", eglQueryString(display, EGL_VERSION));
    printf("\tEGL CLIENT APIS: %s\n", eglQueryString(display, EGL_CLIENT_APIS));
    printf("\tEGL EXTENSIONS: %s\n", eglQueryString(display, EGL_EXTENSIONS));

    if (EGL_FALSE == eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) {
            
        fprintf(stderr, "Failed to release the egl context\n");
        return -1;
    }

    eglDestroyContext(display, context);
    eglDestroySurface(display, surface);
    eglTerminate(display);
    
    return 0;
    
}

I’m building it with this makefile:

CFLAGS=--std=gnu11 -ggdb -Wall

simpletest: simpletest.o Makefile
	cc -o $@ $< -lGLU -lGL -lEGL -lX11 -lXext

simpletest.o:Makefile

clean: .PHONY
	rm -f simpletest simpletest.o

.PHONY:

After calling eglMakeCurrent, i expect to see the opengl version, vender, etc fields to be populated. THis is a simple example of the many things that aren’t working on my tx1.

The code that this example is distilled from is a much larger rendering engine that works on my laptop and on my tx2 (this is a back port, to support a leopard camera driver)

Can anyone help me debug this issue? thank you.

Please try if this attribute list can work

EGLint attribute_list[] = {
          EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
          EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
          EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER,
          EGL_RED_SIZE, 8,
          EGL_GREEN_SIZE, 8,
          EGL_BLUE_SIZE, 8,
          EGL_ALPHA_SIZE, 8,
          EGL_NONE
      };

Could you also share your error message?

Found out that the problem was actually in my makefile. I needed to link libGLESv2 in order for it to work.

IN the failure case, the output looks like this

CHOSE 34!
chose config 0xcaf32c from 58
CURRENT_CONTEXT: 0x46c281
	OPENGL 0.0 INFO:
	VENDOR: (null)
	RENDERER: (null)
	VERSION: (null)
	GLSL VERSION: (null)
	EGL VENDOR: NVIDIA
	EGL VERSION: 1.4
	EGL CLIENT APIS: OpenGL_ES OpenGL
	EGL EXTENSIONS: EGL_EXT_buffer_age EGL_EXT_create_context_robustness EGL_EXT_output_base EGL_EXT_stream_acquire_mode 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_partial_update EGL_KHR_swap_buffers_with_damage EGL_KHR_gl_renderbuffer_image EGL_KHR_gl_texture_2D_image EGL_KHR_gl_texture_cubemap_image EGL_KHR_image EGL_KHR_image_base EGL_KHR_image_pixmap EGL_KHR_reusable_sync EGL_KHR_stream EGL_KHR_stream_consumer_gltexture EGL_KHR_stream_cross_process_fd EGL_KHR_stream_fifo EGL_KHR_stream_producer_eglsurface EGL_KHR_surfaceless_context EGL_NV_cuda_event EGL_NV_post_sub_buffer EGL_NV_stream_metadata EGL_NV_stream_remote EGL_NV_stream_reset EGL_NV_stream_socket EGL_NV_stream_socket_unix EGL_NV_stream_sync EGL_NV_stream_fifo_next EGL_NV_stream_consumer_gltexture_yuv EGL_NV_sync EGL_NV_system_time EGL_NV_output_drm_atomic EGL_WL_bind_wayland_display

when it works, the output looks like this

CHOSE 34!
chose config 0xcaf32c from 58
CURRENT_CONTEXT: 0x42a5a1
	OPENGL 3.2 INFO:
	VENDOR: NVIDIA Corporation
	RENDERER: NVIDIA Tegra X1 (nvgpu)/integrated
	VERSION: OpenGL ES 3.2 NVIDIA 24.2.1
	GLSL VERSION: OpenGL ES GLSL ES 3.20
	EGL VENDOR: NVIDIA
	EGL VERSION: 1.4
	EGL CLIENT APIS: OpenGL_ES OpenGL
	EGL EXTENSIONS: EGL_EXT_buffer_age EGL_EXT_create_context_robustness EGL_EXT_output_base EGL_EXT_stream_acquire_mode 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_partial_update EGL_KHR_swap_buffers_with_damage EGL_KHR_gl_renderbuffer_image EGL_KHR_gl_texture_2D_image EGL_KHR_gl_texture_cubemap_image EGL_KHR_image EGL_KHR_image_base EGL_KHR_image_pixmap EGL_KHR_reusable_sync EGL_KHR_stream EGL_KHR_stream_consumer_gltexture EGL_KHR_stream_cross_process_fd EGL_KHR_stream_fifo EGL_KHR_stream_producer_eglsurface EGL_KHR_surfaceless_context EGL_NV_cuda_event EGL_NV_post_sub_buffer EGL_NV_stream_metadata EGL_NV_stream_remote EGL_NV_stream_reset EGL_NV_stream_socket EGL_NV_stream_socket_unix EGL_NV_stream_sync EGL_NV_stream_fifo_next EGL_NV_stream_consumer_gltexture_yuv EGL_NV_sync EGL_NV_system_time EGL_NV_output_drm_atomic EGL_WL_bind_wayland_display

Do i need to link GLESv2 instead of GL, or in addition to it?

Please only use GLESv2. You can refer to our Makefile of mmapi sample.