Git Product home page Git Product logo

Comments (20)

matusnovak avatar matusnovak commented on May 23, 2024

I don't see a reason why it should not work, but I have not tested it yet, because I don't have a Raspberry Pi 4. I should have one this week and will give it a try.

from rpi-opengl-without-x.

ArtArt0 avatar ArtArt0 commented on May 23, 2024

I do not see neither, but i have and i think it wont work, because of my code - similar to yours - uses dispmanx with egl and pi4 has no full kms driver...

from rpi-opengl-without-x.

matusnovak avatar matusnovak commented on May 23, 2024

I am not losing hope yet.

Unfortunately it seems that I won't receive my Raspberry Pi 4 before this weekend, so I'll get back to you the following next week.

from rpi-opengl-without-x.

ArtArt0 avatar ArtArt0 commented on May 23, 2024

Me neither :)

from rpi-opengl-without-x.

matusnovak avatar matusnovak commented on May 23, 2024

@ArtArt0 Raspberry Pi 4 is already here, but it does not like my older SD card for some reason, need to buy a new one. I should be able to finally test it tomorrow.

from rpi-opengl-without-x.

ArtArt0 avatar ArtArt0 commented on May 23, 2024

Ok, thanx, I am still waiting... :)

from rpi-opengl-without-x.

matusnovak avatar matusnovak commented on May 23, 2024

@ArtArt0

I wasn't able to get anywhere, there is no full kms and I can't find any more info on that. I have tried following many different posts about running EGL via DRM/GBM library. There is some discussion about it here: https://www.raspberrypi.org/forums/viewtopic.php

Could you try the code below? You might have a better luck than me. Try also chaing the /dev/dri/card1 to /dev/dri/card0, maybe it will do something, but it didn't work for me though.

The code is from this post: https://www.raspberrypi.org/forums/viewtopic.php?t=243707#p1499181 I have copy pasted the code below with an extra NULL check so you don't get segmentation fault.

Additionally, someone has said that they had success with https://gitlab.freedesktop.org/mesa/kmscube (I have tried it, no luck).

The code:

// Compile as:
// gcc -o drm-gbm drm-gbm-mod.c -g -O0 -ldrm -lgbm -lEGL -lGL -I/usr/include/libdrm

// Extra dependencies needed:
// sudo apt-get install libegl1-mesa-dev libgbm-dev

//----------------------------------------------------------------------
//--------  Trying to get OpenGL ES screen on RPi4 without X
//--------  based on drm-gbm https://github.com/eyelash/tutorials/blob/master/drm-gbm.c
//--------  and kmscube https://github.com/robclark/kmscube
//--------  [email protected]
//----------------------------------------------------------------------

#include <xf86drm.h>
#include <xf86drmMode.h>
#include <gbm.h>
#include <EGL/egl.h>
#include <GL/gl.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>

#define EXIT(msg) { fputs (msg, stderr); exit (EXIT_FAILURE); }

// global variables declarations

static int device;
static drmModeRes *resources;
static drmModeConnector *connector;
static uint32_t connector_id;
static drmModeEncoder *encoder;
static drmModeModeInfo mode_info;
static drmModeCrtc *crtc;
static struct gbm_device *gbm_device;
static EGLDisplay display;
static EGLContext context;
static struct gbm_surface *gbm_surface;
static EGLSurface egl_surface;
       EGLConfig config;
       EGLint num_config;
       EGLint count=0;
       EGLConfig *configs;
       int config_index;
       int i;
       
static struct gbm_bo *previous_bo = NULL;
static uint32_t previous_fb;       

static EGLint attributes[] = {
    EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
    EGL_RED_SIZE, 8,
    EGL_GREEN_SIZE, 8,
    EGL_BLUE_SIZE, 8,
    EGL_ALPHA_SIZE, 0,
    EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
    EGL_NONE
};

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

struct gbm_bo *bo;	
uint32_t handle;
uint32_t pitch;
int32_t fb;
uint64_t modifier;


static drmModeConnector *find_connector (drmModeRes *resources) {
    for (i=0; i<resources->count_connectors; i++) {
        drmModeConnector *connector = drmModeGetConnector (device, resources->connectors[i]);
        if (connector->connection == DRM_MODE_CONNECTED) {return connector;}
            drmModeFreeConnector (connector);
        }
        return NULL; // if no connector found
    }

    static drmModeEncoder *find_encoder (drmModeRes *resources, drmModeConnector *connector) {

    if (connector->encoder_id) {
        return drmModeGetEncoder (device, connector->encoder_id);
    }
    return NULL; // if no encoder found
}

static void swap_buffers () {
    eglSwapBuffers (display, egl_surface);
    bo = gbm_surface_lock_front_buffer (gbm_surface);
    handle = gbm_bo_get_handle (bo).u32;
    pitch = gbm_bo_get_stride (bo);
    drmModeAddFB (device, mode_info.hdisplay, mode_info.vdisplay, 24, 32, pitch, handle, &fb);
    drmModeSetCrtc (device, crtc->crtc_id, fb, 0, 0, &connector_id, 1, &mode_info);
    if (previous_bo) {
        drmModeRmFB (device, previous_fb);
        gbm_surface_release_buffer (gbm_surface, previous_bo);
    }
    previous_bo = bo;
    previous_fb = fb;
}

static void draw (float progress) {
    glClearColor (1.0f-progress, progress, 0.0, 1.0);
    glClear (GL_COLOR_BUFFER_BIT);
    swap_buffers ();
}

static int match_config_to_visual(EGLDisplay egl_display, EGLint visual_id, EGLConfig *configs, int count) {
    EGLint id;
    for (i = 0; i < count; ++i) {
        if (!eglGetConfigAttrib(egl_display, configs[i], EGL_NATIVE_VISUAL_ID,&id)) continue;
        if (id == visual_id) return i;
    }
    return -1;
}

int main () {
    device = open ("/dev/dri/card1", O_RDWR);
    resources = drmModeGetResources (device);
    if (resources == NULL) {
        printf("drmModeGetResources returned NULL\n");
        return 1;
    }
    connector = find_connector (resources);
    connector_id = connector->connector_id;
    mode_info = connector->modes[0];
    encoder = find_encoder (resources, connector);
    crtc = drmModeGetCrtc (device, encoder->crtc_id);
    drmModeFreeEncoder (encoder);
    drmModeFreeConnector (connector);
    drmModeFreeResources (resources);
    gbm_device = gbm_create_device (device);
    gbm_surface = gbm_surface_create (gbm_device, mode_info.hdisplay, mode_info.vdisplay, GBM_FORMAT_XRGB8888, GBM_BO_USE_SCANOUT|GBM_BO_USE_RENDERING);
    display = eglGetDisplay (gbm_device);
    eglInitialize (display, NULL ,NULL);
    eglBindAPI (EGL_OPENGL_API);
    eglGetConfigs(display, NULL, 0, &count);
    configs = malloc(count * sizeof *configs);
    eglChooseConfig (display, attributes, configs, count, &num_config);
    config_index = match_config_to_visual(display,GBM_FORMAT_XRGB8888,configs,num_config);
    context = eglCreateContext (display, configs[config_index], EGL_NO_CONTEXT, context_attribs);
    egl_surface = eglCreateWindowSurface (display, configs[config_index], gbm_surface, NULL);
    free(configs);
    eglMakeCurrent (display, egl_surface, egl_surface, context);

    for (i = 0; i < 600; i++) draw (i / 600.0f);
        
    drmModeSetCrtc (device, crtc->crtc_id, crtc->buffer_id, crtc->x, crtc->y, &connector_id, 1, &crtc->mode);
    drmModeFreeCrtc (crtc);
    if (previous_bo) {
        drmModeRmFB (device, previous_fb);
        gbm_surface_release_buffer (gbm_surface, previous_bo);
    }
    eglDestroySurface (display, egl_surface);
    gbm_surface_destroy (gbm_surface);
    eglDestroyContext (display, context);
    eglTerminate (display);
    gbm_device_destroy (gbm_device);

    close (device);
    return 0;
}

from rpi-opengl-without-x.

naluhh avatar naluhh commented on May 23, 2024

Jumping on this. @matusnovak Your code run without any issue.

from rpi-opengl-without-x.

matusnovak avatar matusnovak commented on May 23, 2024

@naluhh Thank you for testing it out. I am probably doing something wrong on my side (maybe because I am using it in a headless mode with no screen output). Once I figure it out, I will create a new triangle_rpi4.c file on the master branch with the necessary changes.

from rpi-opengl-without-x.

matusnovak avatar matusnovak commented on May 23, 2024

@ArtArt0 Done.

See the triangle_rpi4.c file in this repository and the relevant instructions in the README file.

from rpi-opengl-without-x.

ArtArt0 avatar ArtArt0 commented on May 23, 2024

Thanks! - I just did it in my code using your and your used codes, and I found an interesting thing:

If I try to use (just link the corresponded lib directory) bcm_host.h, the pi4 code just does not work anymore, even if I am not call bcm_host_init()...

What is happening?

from rpi-opengl-without-x.

matusnovak avatar matusnovak commented on May 23, 2024

@ArtArt0

I don't exactly know what bcm_host.h does but I think it sets some variables specific to the Broadcom (BCM = Broadcom) processor that Raspberry Pi 1, 2, and 3 use.

The Raspberry Pi 4 uses a different CPU, therefore a different GPU, so the triangle_rpi4.c code uses the GBM and DRM libraries.

I assume using bcm_host.h causes hardware compatibility issues.

If you need to import bcm_host.h I would suggest to do that after any relevant EGL code.

from rpi-opengl-without-x.

ArtArt0 avatar ArtArt0 commented on May 23, 2024

I dont use bcm_host.h, just linked the corresponded lib path in!

from rpi-opengl-without-x.

matusnovak avatar matusnovak commented on May 23, 2024

@ArtArt0 What does your gcc linking command look like?

from rpi-opengl-without-x.

ArtArt0 avatar ArtArt0 commented on May 23, 2024

Add gcc the following: -L/opt/vc/lib

The result is: * failed to add service - already in use?

from rpi-opengl-without-x.

matusnovak avatar matusnovak commented on May 23, 2024

@ArtArt0

You should be not using /opt/vc/lib on Raspberry Pi 4. The vc stands for VideoCore library which is used only in Raspberry Pi 1, 2, and 3.

Previous Pi's used a non-standard mechanism of getting EGL onto a display (dispmanx).
When using kms/fkms (pi4 only supports fkms) you can't use that and need do this the standard linux way.

This is a useful thread where these methods are discussed:
https://www.raspberrypi.org/forums/viewtopic.php?f=68&t=243611

Source: raspberrypi/firmware#1171 (comment)

There is more about that also here: libretro/RetroArch#9727

So, to get the triangle_rpi4.c code running, you need to compile it as:

gcc -o triangle_rpi4 triangle_rpi4.c -ldrm -lgbm -lEGL -lGLESv2 \
  -I/usr/include/libdrm -I/usr/include/GLES2

Without using the /opt/vc/lib directory. The /opt/vc/lib contains EGL and GLESv2 that are specific to the Broadcom CPU/GPU and VideoCore. You need to link to the correct EGL and GLESv2 libraries installed via sudo apt-get install libegl1-mesa-dev libgbm-dev libgles2-mesa-dev. I assume that when you add -L/opt/vc/lib the GCC will link to the incorrect libraries.

And you may need to ensure that /boot/config.txt contains dtoverlay=vc4-fkms-v3d.

from rpi-opengl-without-x.

matusnovak avatar matusnovak commented on May 23, 2024

Also, similar issue to the failed to ass service - already in use? error is here: #1 (But that's Raspberry Pi 3 related).

from rpi-opengl-without-x.

ArtArt0 avatar ArtArt0 commented on May 23, 2024

Ok, but on Pi4 I can not use bcm_host.h, can I?

from rpi-opengl-without-x.

matusnovak avatar matusnovak commented on May 23, 2024

No you should not, it's not compatible with Pi4.

from rpi-opengl-without-x.

ArtArt0 avatar ArtArt0 commented on May 23, 2024

Thanks Matus! :)

from rpi-opengl-without-x.

Related Issues (12)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.