This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[FAQ] TDA4VM: Sample Wayland application of OpenGL to run on TI board

Part Number: TDA4VM

Hi Team,

I'm new to TI, I am currently working on running a sample application of OpenGL on TI TDA4VM board.

I have copied the code pasted below from a github repository which uses wayland for displaying a triangle in Linux environment.

/*
* A simple Wayland EGL program to show a triangle
*
* cc -o triangle_simple triangle_simple.c -lwayland-client -lwayland-egl -lEGL -lGLESv2
*/

#include <EGL/egl.h>
#include <GLES2/gl2.h>
#include <assert.h>
#include <string.h>
#include <wayland-client.h>
#include <wayland-egl.h>

struct WaylandGlobals {
struct wl_compositor* compositor;
struct wl_shell* shell;
};

/*
* Registry callbacks
*/
static void registry_global(void* data, struct wl_registry* registry, uint32_t id, const char* interface, uint32_t version)
{
struct WaylandGlobals* globals = (struct WaylandGlobals *)data;
if (strcmp(interface, "wl_compositor") == 0) {
globals->compositor = wl_registry_bind(registry, id, &wl_compositor_interface, 1);
} else if (strcmp(interface, "wl_shell") == 0) {
globals->shell = wl_registry_bind(registry, id, &wl_shell_interface, 1);
}
}

static const struct wl_registry_listener registry_listener = { registry_global, NULL };

/*
* Connect to the Wayland display and return the display and the surface
* output wlDisplay
* output wlSurface
*/
static void initWaylandDisplay(struct wl_display** wlDisplay, struct wl_surface** wlSurface)
{
struct WaylandGlobals globals = {0};

*wlDisplay = wl_display_connect(NULL);
assert(*wlDisplay != NULL);

struct wl_registry* registry = wl_display_get_registry(*wlDisplay);
wl_registry_add_listener(registry, &registry_listener, (void *) &globals);

wl_display_dispatch(*wlDisplay);
wl_display_roundtrip(*wlDisplay);
assert(globals.compositor);
assert(globals.shell);

*wlSurface = wl_compositor_create_surface(globals.compositor);
assert(*wlSurface != NULL);

struct wl_shell_surface* shellSurface = wl_shell_get_shell_surface(globals.shell, *wlSurface);
wl_shell_surface_set_toplevel(shellSurface);
}

/*
* Configure EGL and return necessary resources
* input nativeDisplay
* input nativeWindow
* output eglDisplay
* output eglSurface
*/
static void initEGLDisplay(EGLNativeDisplayType nativeDisplay, EGLNativeWindowType nativeWindow, EGLDisplay* eglDisplay, EGLSurface* eglSurface)
{
EGLint number_of_config;
EGLint config_attribs[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_NONE
};

static const EGLint context_attribs[] = {
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};

*eglDisplay = eglGetDisplay(nativeDisplay);
assert(*eglDisplay != EGL_NO_DISPLAY);

EGLBoolean initialized = eglInitialize(*eglDisplay, NULL, NULL);
assert(initialized == EGL_TRUE);

EGLConfig configs[1];

eglChooseConfig(*eglDisplay, config_attribs, configs, 1, &number_of_config);
assert(number_of_config);

EGLContext eglContext = eglCreateContext(*eglDisplay, configs[0], EGL_NO_CONTEXT, context_attribs);

*eglSurface = eglCreateWindowSurface(*eglDisplay, configs[0], nativeWindow, NULL);
assert(*eglSurface != EGL_NO_SURFACE);

EGLBoolean makeCurrent = eglMakeCurrent(*eglDisplay, *eglSurface, *eglSurface, eglContext);
assert(makeCurrent == EGL_TRUE);
}

/*
* Connect Wayland and make EGL
* input width
* input height
* output wlDisplay
* output eglDisplay
* output eglSurface
*/
static void initWindow(GLint width, GLint height, struct wl_display** wlDisplay, EGLDisplay* eglDisplay, EGLSurface* eglSurface)
{
struct wl_surface* wlSurface;
initWaylandDisplay(wlDisplay, &wlSurface);

struct wl_egl_window* wlEglWindow = wl_egl_window_create(wlSurface, width, height);
assert(wlEglWindow != NULL);

initEGLDisplay((EGLNativeDisplayType) *wlDisplay, (EGLNativeWindowType) wlEglWindow, eglDisplay, eglSurface);
}

/*
* Return the loaded and compiled shader
*/
GLuint LoadShader(GLenum type, const char* shaderSrc)
{
GLuint shader = glCreateShader(type);
assert(shader);

glShaderSource(shader, 1, &shaderSrc, NULL);
glCompileShader(shader);

GLint compiled;
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
assert(compiled);

return shader;
}

/*
* Initialize the shaders and return the program object
*/
GLuint initProgramObject()
{
char vShaderStr[] = "#version 300 es \n"
"layout(location = 0) in vec4 vPosition; \n"
"void main() \n"
"{ \n"
" gl_Position = vPosition; \n"
"} \n";

char fShaderStr[] = "#version 300 es \n"
"precision mediump float; \n"
"out vec4 fragColor; \n"
"void main() \n"
"{ \n"
" fragColor = vec4 ( 1.0, 0.0, 0.0, 1.0 ); \n"
"} \n";

GLuint vertexShader = LoadShader(GL_VERTEX_SHADER, vShaderStr);
GLuint fragmentShader = LoadShader(GL_FRAGMENT_SHADER, fShaderStr);

GLuint programObject = glCreateProgram();
assert(programObject);

glAttachShader(programObject, vertexShader);
glAttachShader(programObject, fragmentShader);

glLinkProgram(programObject);

GLint linked;
glGetProgramiv(programObject, GL_LINK_STATUS, &linked);
assert(linked);

return programObject;
}

/*
* Draw a triangle
*/
void draw(GLuint programObject, GLint width, GLint height)
{
GLfloat vVertices[] = { -0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f };

glViewport(0, 0, width, height);
glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(programObject);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vVertices);
glEnableVertexAttribArray(0);
glDrawArrays(GL_TRIANGLES, 0, 3);
}

int main(int argc, char** argv)
{
int width = 750;
int height = 500;

struct wl_display* wlDisplay;
EGLDisplay eglDisplay;
EGLSurface eglSurface;

initWindow(width, height, &wlDisplay, &eglDisplay, &eglSurface);

GLuint programObject = initProgramObject();
assert(programObject);

draw(programObject, width, height);
eglSwapBuffers(eglDisplay, eglSurface);

while (wl_display_dispatch(wlDisplay) != -1) {
}

glDeleteProgram(programObject);

wl_display_disconnect(wlDisplay);

return 0;
}





The triangle is displaying successfully.
My main query is
1)how to run this code on TI TDA4 board and get the output...What is the procedure I need to follow?
2)Where can I find the demos related to OpenGL in TI SDK which gives me a reference?
3)As per my research, I came to know that wayland is not supported on TI board, So what changes I need to make and what is the way of displaying triangle using OpenGL on TI board?
Thanks and Regards
Chaitanya Prakash Uppala
  • Hello,

    1)how to run this code on TI TDA4 board and get the output...What is the procedure I need to follow?

    You can run the same compilation, but use a cross compiler for ARM64, and also point to your filesystem for the sysroot, as follows:

    aarch64-none-linux-gnu-gcc --sysroot=<path-to-your-TDA4VM-filesystem> -o triangle_simple triangle_simple.c -lwayland-client -lwayland-egl -lEGL -lGLESv2

    2)Where can I find the demos related to OpenGL in TI SDK which gives me a reference?

    We do ship some OpenGL examples in the SDK, however, they are not simple examples that display on the screen directly. In our VisionApps project, you will find a few OpenGL examples that are in a OpenVX graph. Please take a look at these: https://software-dl.ti.com/jacinto7/esd/processor-sdk-rtos-jacinto7/08_04_00_06/exports/docs/vision_apps/docs/user_guide/index.html

    Most OpenGLES examples from online will work on our device, you can use them as a reference as you did with the simple triangle example.

    3)As per my research, I came to know that wayland is not supported on TI board, So what changes I need to make and what is the way of displaying triangle using OpenGL on TI board?

    Wayland is supported, in fact it is the default windowing system that comes up when you boot up the SDK Linux image. You will see weston come up and you can run some of our example applications in our SDK such as wgles1test1 or the binaries in the /usr/bin/SGX/demos/Wayland/.

    Thank you,

    Erick

  • Hi Mr.Erick

    Thanks for your valuable reply.

    I have followed the process you have mentioned in the reply for my 1st question. I am able to compile successfully and able to get a executable after compilation. But when I'm trying to run that executable on TI TDA4 board I'm getting the following log.

    root@j7-evm:/opt/vision_apps# ./sample_triangle
    sample_triangle: sample_triangle.c:45: initWaylandDisplay: Assertion `*wlDisplay != NULL' failed.
    Aborted (core dumped)
    root@j7-evm:/opt/vision_apps#

    Could you please help me out in resolving that error.

    Thank you,

    Chaitanya Prakash Uppala

  • Hello,

    Are you able to see the weston background before you run the application? It will run as long as a wayland compositor (weston) is running correctly. It is a "Grey" background. Perhaps send a screenshot of your display, it should not be "blank" as if it's turned off, it should be showing the weston running like below:

    Regards,

    Erick

  • Hi Mr.Erick,

    I'm able to get the output as shown in the attached image file when running on PC(In Linux environment).

    PC_output

    I'm not using weston, I'm using wayland display part in the code I have written(The code is attached in my 1st query).

    Thanks,

    Chaitanya Prakash Uppala

  • Hello,

    Weston is the implementation of the wayland compositor. I am assuming you are running Linux with Wayland on your PC (like Ubuntu 22.04). This implements the wayland protocol. In a similar way, the GPU driver on the EVM will not just run a wayland application on its own, it will need a wayland compositor (we support weston) running in the background. When you boot the board, weston should come up automatically. Then you will be able to run the application. To test that weston is running , you can run the following application in your command line: `wgles2test1`

    Regards,

    Erick

  • Hello Mr.Erick,

    I have tried in testing whether weston is running or not by the process you have mentioned above reply and got the log as shown below

    root@j7-evm:/usr/bin# ./wgles2test1
    Failed to connect to Wayland display
    root@j7-evm:/usr/bin#

    Could you please let me know what steps I need to follow next?

    Thanks,

    Chaitanya Prakash Uppala

  • This is quite strange, if weston is running and you can see it on the display, I don't see this error. Have you made any modifications to the default SDK SD card image?

    Regards,

    Erick

  • No, I'm not bale to see the grey background while running. I'm getting blank screen.

  • Ok, something is not right in the display setup. Can you let me know which display you are using? In the default SDK, the best way would be to use DISPLAY0 connector on the EVM, which is displayport, and connect to a displayport monitor, with no adapters in between.

    What is your current monitor setup?

    Regards,

    Erick

  • I'm using a DELL monitor for display, and the connections are in the same way you mentioned above, that is no adapter used in between displayport and monitor. Images attached here for reference.

    .

  • This setup looks good. Perhaps there is an issue with the display. We can test the display, could you please provide the logs of running the following:

    modetest -D tidss

  • The logs for running the command were mentioned below 


    root@j7-evm:/opt/vision_apps# modetest -D tidss
    trying to open device 'i915'...failed
    trying to open device 'amdgpu'...failed
    trying to open device 'radeon'...failed
    trying to open device 'nouveau'...failed
    trying to open device 'vmwgfx'...failed
    trying to open device 'omapdrm'...failed
    trying to open device 'exynos'...failed
    trying to open device 'tilcdc'...failed
    trying to open device 'msm'...failed
    trying to open device 'sti'...failed
    trying to open device 'tegra'...failed
    trying to open device 'imx-drm'...failed
    trying to open device 'rockchip'...failed
    trying to open device 'atmel-hlcdc'...failed
    trying to open device 'fsl-dcu-drm'...failed
    trying to open device 'vc4'...failed
    trying to open device 'virtio_gpu'...failed
    trying to open device 'mediatek'...failed
    trying to open device 'meson'...failed
    trying to open device 'pl111'...failed
    trying to open device 'stm'...failed
    trying to open device 'sun4i-drm'...failed
    trying to open device 'armada-drm'...failed
    no device found
    root@j7-evm:/opt/vision_apps#

  • Hello,

    Apologies, I gave you the wrong instruction. The flag should be -M, not -D.

    Can you please try this and send back the results?

    In order to keep moving forward, once you have those logs, you can use the following command to check if the display is recognized:

    Encoders:                                                                                                
    id      crtc    type    possible crtcs  possible clones                                                                                                                                                            
    38      37      none    0x00000001      0x00000001                                                                                                                                                                 
    47      0       none    0x00000002      0x00000002                                                       
                                                                                                             
    Connectors:                                                                                              
    id      encoder status          name            size (mm)       modes   encoders                         
    39      38      connected       DP-1            640x400         31      38                               
      modes:                                                                                                 
            index name refresh (Hz) hdisp hss hse htot vdisp vss vse vtot)                                   
      #0 1920x1080 60.00 1920 2008 2052 2200 1080 1084 1089 1125 148500 flags: phsync, pvsync; type: driver                                                                                                            
      #1 1920x1080 60.00 1920 2008 2052 2200 1080 1084 1089 1125 148500 flags: phsync, pvsync; type: driver  
      #2 1920x1080 59.94 1920 2008 2052 2200 1080 1084 1089 1125 148352 flags: phsync, pvsync; type: driver  
      #3 1920x1080 50.00 1920 2448 2492 2640 1080 1084 1089 1125 148500 flags: phsync, pvsync; type: driver  
      #4 1920x1080 24.00 1920 2558 2602 2750 1080 1084 1089 1125 74250 flags: phsync, pvsync; type: driver   
      #5 1920x1080 23.98 1920 2558 2602 2750 1080 1084 1089 1125 74176 flags: phsync, pvsync; type: driver   
      #6 1600x1200 60.00 1600 1664 1856 2160 1200 1201 1204 1250 162000 flags: phsync, pvsync; type: driver  
      #7 1280x1024 75.02 1280 1296 1440 1688 1024 1025 1028 1066 135000 flags: phsync, pvsync; type: driver  
      #8 1280x1024 60.02 1280 1328 1440 1688 1024 1025 1028 1066 108000 flags: phsync, pvsync; type: driver                                                                                                            
      #9 1280x800 59.81 1280 1352 1480 1680 800 803 809 831 83500 flags: nhsync, pvsync; type: driver                                                                                                                  
      #10 1152x864 75.00 1152 1216 1344 1600 864 865 868 900 108000 flags: phsync, pvsync; type: driver                                                                                                                
      #11 1280x720 60.00 1280 1390 1430 1650 720 725 730 750 74250 flags: phsync, pvsync; type: driver       
      #12 1280x720 60.00 1280 1390 1430 1650 720 725 730 750 74250 flags: phsync, pvsync; type: driver       
      #13 1280x720 59.94 1280 1390 1430 1650 720 725 730 750 74176 flags: phsync, pvsync; type: driver
      #14 1280x720 50.00 1280 1720 1760 1980 720 725 730 750 74250 flags: phsync, pvsync; type: driver       
      #15 1024x768 75.03 1024 1040 1136 1312 768 769 772 800 78750 flags: phsync, pvsync; type: driver       
      #16 1024x768 60.00 1024 1048 1184 1344 768 771 777 806 65000 flags: nhsync, nvsync; type: driver       
      #17 800x600 75.00 800 816 896 1056 600 601 604 625 49500 flags: phsync, pvsync; type: driver           
      #18 800x600 60.32 800 840 968 1056 600 601 605 628 40000 flags: phsync, pvsync; type: driver           
      #19 720x576 50.00 720 732 796 864 576 581 586 625 27000 flags: nhsync, nvsync; type: driver            
      #20 720x576 50.00 720 732 796 864 576 581 586 625 27000 flags: nhsync, nvsync; type: driver            
      #21 720x480 60.00 720 736 798 858 480 489 495 525 27027 flags: nhsync, nvsync; type: driver            
      #22 720x480 60.00 720 736 798 858 480 489 495 525 27027 flags: nhsync, nvsync; type: driver            
      #23 720x480 59.94 720 736 798 858 480 489 495 525 27000 flags: nhsync, nvsync; type: driver            
      #24 720x480 59.94 720 736 798 858 480 489 495 525 27000 flags: nhsync, nvsync; type: driver            
      #25 720x480 59.94 720 736 798 858 480 489 495 525 27000 flags: nhsync, nvsync; type: driver            
      #26 640x480 75.00 640 656 720 840 480 481 484 500 31500 flags: nhsync, nvsync; type: driver            
      #27 640x480 60.00 640 656 752 800 480 490 492 525 25200 flags: nhsync, nvsync; type: driver            
      #28 640x480 59.94 640 656 752 800 480 490 492 525 25175 flags: nhsync, nvsync; type: driver            
      #29 640x480 59.94 640 656 752 800 480 490 492 525 25175 flags: nhsync, nvsync; type: driver            
      #30 720x400 70.08 720 738 846 900 400 412 414 449 28320 flags: nhsync, pvsync; type: driver
      ...
      CRTCs:
    id      fb      pos     size
    37      0       (0,0)   (1920x1080)
      #0 1920x1080 60.00 1920 2008 2052 2200 1080 1084 1089 1125 148500 flags: phsync, pvsync; type: driver
      props:
            22 ACTIVE:
                    flags: range
                    values: 0 1
                    value: 1
    ...

    You will notice that the Connector ID is 39 for the DP-1. And the CRTC id is 37. And from the supported resolutions, I just picked the top one (1920x1080-60).

    Then the command to run this test is the following:

    modetest -M tidss -s 39@37:1920x1080-60 -d

    modetest -M tidss -s <connector ID>@<CRTC ID>:<Resolution>-<FPS> -d

    If you send your logs, I will also be able to tell you what to fill in.

    Also, question for you. You seem to have Fuision board connected. Have you changed anything about the way you formatted your SD card from the default? The reason I ask is that the vision_apps demos will remove the display from control by the A72, hence, you won't be able to use the display from Linux natively. So if you have made any changes to the default filesystem or boot partition from the Linux SDK default, please let me know.

    Thanks,

    Erick

  • Hello,

    When trying to run the command "modetest -M tidss" got the following log.

    root@j7-evm:/opt/vision_apps# modetest -M tidss
    failed to open device 'tidss': No such file or directory
    root@j7-evm:/opt/vision_apps#

    I have checked in TI forum for relevant log to solve but couldn't find.

    Can u tell what to do next?

    And the answer to the question you asked me is "No, I haven't changed anything in the way of formatting the SD card. I have followed the way described in TI site.

    Thanks,

    Chaitanya Prakash Uppala

  • Hello,

    From your logs, I see that you are running the vision_apps demo. Unfortunately, this disables the Display! It uses an R5 based display using the OpenVX framework. You would need to use the default filesystem provided in the linux SDK. I usually use the following script to setup the SD card:

    cd ti-processor-sdk-linux-j7-evm-08_06_00_11/bin/
    
    sudo ./mksdboot.sh --device /dev/sda --sdk ../

    Then you can boot the board, and should see the display working. Can you please try this and let me know?

    Thanks,

    Erick

  • Hello,

    After running the command you have shared and booting the board, the monitor display is as shown in below image.

    Kindly let me know what to be done in next.

    Thanks,

    Chaitanya Prakash Uppala

  • Great! You should be able to run your example now, this background is running on weston, the wayland example implementation. Once the board is in this state, could you run the following:

    wgles2test1

    This will start a wayland example of spinning triangles. Then, if that works, you can run your example that you have ported.

    Please let me know the log when you try to run this.

    Thanks,

    Erick

  • Hello,

    When I ran "wgles2test1" after booting the board, the following logs are observed in terminal and a spinning triangle is observed on monitor.

    j7-evm login: root
    root@j7-evm:~# cd /usr/bin/
    root@j7-evm:/usr/bin# ./wgles2test1
    Compiling program '/usr/share/pvr/shaders/glsltest1_vertshader.txt', 269 bytes long
    Compiling program '/usr/share/pvr/shaders/glsltest1_fragshaderA.txt', 81 bytes long
    Compiling program '/usr/share/pvr/shaders/glsltest1_fragshaderB.txt', 214 bytes long

    ^Croot@j7-evm:/usr/bin#

    Even my code is working fine.

    Thanks for your guidance, support and time.

    Thanks,

    Chaitanya Prakash Uppala