Raylib: [core] RPI4 without X11

Created on 11 Feb 2020  Β·  136Comments  Β·  Source: raysan5/raylib

In init device core.c

define RPI4

Initrpi4();

else

Normal init rpi 2 3 bla bla

endif

//////////////////////
RPI4InitDevice.h
// gcc -o drm-gbm drm-gbm-mod.c -ldrm -lgbm -lEGL -lGL -I/usr/include/libdrm

//----------------------------------------------------------------------
//-------- 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

include

include

include

include

include

include

include

include

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; icount_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;
}

Bool initrpi4 () {

device = open ("/dev/dri/card1", O_RDWR);
resources = drmModeGetResources (device);
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);

Return here...

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;
}

new feature raspberrypi

Most helpful comment

@gen2brain PLATFORM_DRM doesn't work when X is on the screen. You can switch from a graphical console running X to a text console and then start a raylib PLATFORM_DRM program. You can also switch between the two, but only one of them can draw at the screen at the same time.
Exactly, any board supporting GBM, DRM and OpenGL ES 2 (currently, this could be changed when you build raylib) should work. If no hardware acceleration is available then a software acceleration is used - of course only when available. If you don't have access rights to the hardware then also software rendering may apply.

All 136 comments

image

@dginu85 sorry, what is the issue about? Maybe related to https://github.com/raysan5/raylib/issues/1041

image

i build with "make PLATFORM=PLATFORM_DESKTOP GRAPHICS=GRAPHICS_API_OPENGL_21"

Ok, last time I tested, about 2 weeks ago, it worked ok RPI4 desktop mode with OpenGL 2.1... I'll try to review it at some point, I have no RPI4 for testing.

I try this for test
I make file "EGL_FIX."
////////////////////////////////////////////////////////////

#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;
}

static int IniTRpi4() {

    device = open("/dev/dri/card1", O_RDWR);
    resources = drmModeGetResources(device);
    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);
    swap_buffers();
    return 1;

}

static void CloseSurface()
{
    close(device);
    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);


}

In core.c
////////////////////////////////////////////////////////////////////////////////////////

static bool InitGraphicsDevice(int width, int height)
{
    CORE.Window.screen.width = width;            // User desired width
    CORE.Window.screen.height = height;          // User desired height
    CORE.Window.display.width = width;            // User desired width
    CORE.Window.display.height = height;          // User desired height
    CORE.Window.render.width = width;            // User desired width
    CORE.Window.render.height = height;          // User desired height
    CORE.Window.screenScale = MatrixIdentity();  // No draw scaling required by default
    CORE.Window.fullscreen = true;


#pragma region EGLFIX

    IniTRpi4();

    CORE.Window.config = configs;
    CORE.Window.device = display;
    CORE.Window.surface = egl_surface;
    CORE.Window.context = context;
    SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height);

#pragma endregion EGLFIX



        TRACELOG(LOG_INFO, "Display device initialized successfully");
        TRACELOG(LOG_INFO, "Display size: %i x %i", CORE.Window.display.width, CORE.Window.display.height);
        TRACELOG(LOG_INFO, "Render size: %i x %i", CORE.Window.render.width, CORE.Window.render.height);
        TRACELOG(LOG_INFO, "Screen size: %i x %i", CORE.Window.screen.width, CORE.Window.screen.height);
        TRACELOG(LOG_INFO, "Viewport offsets: %i, %i", CORE.Window.renderOffset.x, CORE.Window.renderOffset.y);




    rlglInit(CORE.Window.screen.width, CORE.Window.screen.height);
    SetupViewport(CORE.Window.screen.width, CORE.Window.screen.height);
    CORE.Window.currentFbo.width = CORE.Window.screen.width;
    CORE.Window.currentFbo.height = CORE.Window.screen.height;
    ClearBackground(RAYWHITE);      
    CORE.Window.ready = true;
    return true;
}

Result work but paint only BLACK
why?

OK FIX
void BeginDrawing(void)
{
//add this
swap_buffers();
work perfect :-)
}

Just for reference, here another RPI4-native implementation for raylib: https://github.com/jonlidgard/raylib/tree/rpi4

Is there any chance of a single binary that would work on all versions of the PI? My understanding is to make a native CLI binary that works on the 4 you need to

"make PLATFORM=PLATFORM_RPI RPI_VERSION=RPI_VERSION_4"

precluding use on earlier PIs.

@alanbork Actually those changes have not been integrated on raylib, at the moment raylib does not support RaspberryPi 4 officially.

Unfortunately, it's not possible to have a single binary for all the RPi, RPI4 dratically changed the required libraries for native GPU access and old libraries do not work anymore.

I see. The main website does say you can compile to support the pi 4 - am I
misunderstanding this? From the webpage it sure looks like it's CLI not
x11:

On Raspberry Pi platform (native mode), Videocore API and EGL libraries
are used for window/context management. Inputs are processed
using evdev Linux libraries. To build for the Raspberry Pi 4:

cd src
make PLATFORM=PLATFORM_RPI RPI_VERSION=RPI_VERSION_4

On Fri, Jun 19, 2020 at 3:13 AM Ray notifications@github.com wrote:

@alanbork https://github.com/alanbork Actually those changes have not
been integrated on raylib, at the moment raylib does not support
RaspberryPi 4 officially.

Unfortunately, it's not possible to have a single binary for all the RPi,
RPI4 dratically changed the required libraries for native GPU access and
old libraries do not work anymore.

β€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/raysan5/raylib/issues/1096#issuecomment-646555493,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/ANPGZ5PSP7V7BOBIQHEHFWDRXM24LANCNFSM4KTHYJMA
.

never-mind, I see that the website in question is a fork of the current raylib for supporting rpi4.

Has anybody else working on getting raylib for the pi4 gotten this error?

FATAL: kms: Unable to access GPU via DRM

(this is using the rpi4 branch contributed by jonlidgard). I'd file an issue with his branch but it doesn't seem possible?!

ok, I figured that out on my own: I need to enable DRM in the boot/config.txt overlay:

dtoverlay=vc4-fkms-v3d

there's still other issues, but at least it runs now.

You can also try with :

  • PLATFORM_DESKTOP
  • USE_WAYLAND_DISPLAY = TRUE
  • GRAPHICS_API_OPENGL_21 if OpenGL 3.3 is not supported
    (GRAPHICS_API_OPENGL_ES2 may be interesting but it's currently not supported with PLATFORM_DESKTOP)

and run executables using cage

cage ./core_basic_window

There are some issues with renderer size (as cage forces fullscreen) but aside that, it works perfectly.

After a lot of work I have gotten the unofficial port (https://github.com/jonlidgard/raylib/tree/rpi4) to work on my pi4. It is, however fragile. it's sensitive to how the resolution is configured; using tvservice + fbset doesn't work right or at least it doesn't work like it did in the pie zero. But if you set the resolution using rasp-config the result looks good - so long as your code isn't very demanding. As soon as you try to do anything very complex inside your render loop, however, it seems to act very strange, with frames getting rendered out of order. I think the issue is that it seems to be double buffered instead of triple buffered, and sometimes it doesn't flip the buffer when it's supposed to? Or maybe there's only 1 single buffer? It's very hard to diagnose. In any case, other people have remarked on the vsync being broken, and although I didn't see any torn frames the weirdness I saw may well be due to incorrect measurement of sync, causing buffer flips to occur at odd times. Just FYI.

You can also try with :

  • PLATFORM_DESKTOP
  • USE_WAYLAND_DISPLAY = TRUE
  • GRAPHICS_API_OPENGL_21 if OpenGL 3.3 is not supported
    (GRAPHICS_API_OPENGL_ES2 may be interesting but it's currently not supported with PLATFORM_DESKTOP)

and run executables using cage

cage ./core_basic_window

There are some issues with renderer size (as cage forces fullscreen) but aside that, it works perfectly.

FYI this can be done with X11 too:

https://linuxconfig.org/how-to-run-x-applications-without-a-desktop-or-a-wm

(tested, and working with version 3.0 of raylib).

Admittedly, this thread is about running without X11, but I'm not sure wayland is going to be more lightweight? I have determined that using xinit/no wm does give better latency than using whatever the default Rpi4 desktop X11 environment is that you get with startx.

I modified the Raspberry Pi portions of core.c for VideoCore VI (which is supported by the V3D driver and which is in hardware in the Raspberry Pi 4) when a preprocessor definition V3D is set and I added a build-rpi4.sh script. Other makefiles, CMake files or project files aren't modified because I currently don't know the best way to integrate this new option into the current build system of PLATFORM etc. You can see my changes at https://github.com/kernelkinetic/raylib, actually only core.c and build-rpi4.sh are changed. My intension was to get raylib working without X but hardware acceleration on Raspberry Pi 4, I currently didn't test how this works with X11, but because I used the "proper linux way" to initialize the DRM/GBM/OpenGL ES stuff (as it is to be done for the new V3D driver as stated by the Raspberry Pi Foundation), I think it also may work using X if added appropriately.

From the raylib code I assume that raylib on VideoCore IV doesn't support the V3D drivers (kms and fake kms) but only the legacy graphics using the bcm libs. If this is right, my code could also be used on Raspberry Pi 1-3 with the kms/fkms drivers with just one line changed. Is it possible then to build one binary running on all Raspberry Pis without X using the kms or fkms V3D driver (again, I didn't test how it works with X). But all of this needs testing, I only tested the successfull initialization of the OpenGL ES context and some basic examples like core_basic_window and core_2d_camera but not all raylib graphics possibilities.

I modified the Raspberry Pi portions of core.c for VideoCore VI (which is supported by the V3D driver and which is in hardware in the Raspberry Pi 4) when a preprocessor definition V3D is set and I added a build-rpi4.sh script. Other makefiles, CMake files or project files aren't modified because I currently don't know the best way to integrate this new option into the current build system of PLATFORM etc. You can see my changes at https://github.com/kernelkinetic/raylib, actually only core.c and build-rpi4.sh are changed. My intension was to get raylib working without X but hardware acceleration on Raspberry Pi 4, I currently didn't test how this works with X11, but because I used the "proper linux way" to initialize the DRM/GBM/OpenGL ES stuff (as it is to be done for the new V3D driver as stated by the Raspberry Pi Foundation), I think it also may work using X if added appropriately.

So this is interesting and I'd be happy to test it out some but you've left out a lot of details here. Which drivers (kms/fkms, or nothing) should be loaded? what's the proper command line call to make that would build the raylib examples?

@alanbork You need to use the V3D driver which you can setup using raspi-config and selecting GL (Fake KMS) or by adding dtoverlay=vc4-fkms-v3d to your/boot/config.txt (that's the same what raspi-config is doing).
I didn't commit the Makefiles for lib and examples because I don't know how it is "the raylib way" to support all of the Raspberry Pi versions. Anyways, I pushed to my repository these modified versions of the two Makefiles: https://github.com/kernelkinetic/raylib/commit/ea9360c68efef1df4d7f8741aff3c34d01522f09

@kernelkinetic current V3D driver replaces the old Broadcom driver? Does it work for RPI 0,1,2,3 in native mode? In that case, what is the performance of V3D in comparison to the old Broadcom?

@raysan5 V3D is since Raspberry Pi 4 the current driver (see https://www.raspberrypi.org/blog/raspberry-pi-4-on-sale-now-from-35/), the previous non-GL VideoCore IV "bcm..." stuff is considered "legacy" on Raspberry Pi 4. V3D is public available since 02/2016 as experimental driver and the announcement says it's only available from Pi 2 because of memory requirements (https://www.raspberrypi.org/blog/another-new-raspbian-release/). and as far as I tested the only difference to get my code running on a Raspberry Pi 3 (beneath enabling the V3D kms or fkms driver) is to open "card0" instead of "card1" as dri device (https://github.com/kernelkinetic/raylib/blob/ea9360c68efef1df4d7f8741aff3c34d01522f09/src/core.c#L2975).
V3D is in active development (https://www.raspberrypi.org/blog/vc4-and-v3d-opengl-drivers-for-raspberry-pi-an-update/) and supports hardware acceleration as well as software rendering (if you don't have permissions the software renderer is selected automatically, for example). In my few tests I came to the assesment that V3D and Broadcom drivers doesn't have noticeable performance differences, but I didn't measure anything. The previous link shows also many already reached and further planned enhancements of the V3D driver.
As far as I understood, V3D also supports hardware accelerated rendering __in__ __X__ but I didn't investigated this further.
Maybe I also need to state that I wrote this code to get raylib to work on a Pi 4 just for fun, I didn't used this raylib version currently for more than testing and all informations I used are taken from different public sources and express my understanding of these.

@kernelkinetic I'm not sure what I was doing wrong but your code is working fine now. perhaps the firmware I had installed was causing intermittent issues. I've deleted my earlier comments since they were in essence wrong.

So here's the only issue I do see: in regular raylib accepts InitWindow(0,0, "name") to make a full-screen window. your code instead makes a 0,0 window. Which is why I was having problems earlier.

if I give it a smaller window I get something strange:

INFO: DISPLAY: Device initialized successfully
INFO: > Display size: 1920 x 1080
INFO: > Render size: 1280 x 720
INFO: > Screen size: 1280 x 720

with the Render window in the lower right corner, and horizontal lines everywhere that's not inside the render window. I don't get 1280x720 resolution, just 1920 x 1080 no matter what I send to initwindow.

if I pass the actual resolution, I get a properly functioning full screen window.

performance seems good - buffer flips happen when I expect them to, and there are no dropped frames as measured with a photodiode.

ps it is definitely possible to get a lower resolution properly - using the code at

https://www.raspberrypi.org/forums/viewtopic.php?f=68&t=243707&hilit=pi4#p1499181

I can select different modes from the mode array and they come up just fine. So this is a fixable problem in your code.

@alanbork Wow, thanks for your obviously deep analysis. I'm happy that it works so far and I'll look into my code and your link the next days to fix this. I'll notice here when it's finished.

@alanbork Different resolutions should now work as expected. https://github.com/kernelkinetic/raylib/commit/25a687b275ecfe9416b52380c1c5818ceede74d4

@alanbork Different resolutions should now work as expected. kernelkinetic@25a687b

Excellent work! 720x480, 1280x720 and 1920x1080 result in the desired resolution. still some more to go, however.

Calling InitWindow(0,0, "name") gives a segfault, rather than using whatever the current video mode is (set at boot with config.txt or via tvservice at runtime). Raylib on pi0..3 get this right, including matching the interlacing of the current mode, which can be important if used with a TV.

@alanbork Thanks, and thanks again for testing, get ready for the next session :) https://github.com/kernelkinetic/raylib/commit/b1f3d8ab27cdef6a5fc6cdb0cc61c6ac5e2d4888 contains the screen size security check from PLATFORM_DESKTOP and PLATFORM_RPI to support also InitWindow(0, 0, ...). I'm not sure if this uses the current video mode because I don't know if I can get this information via DRM. At the moment I use the first available mode like any example I found is doing. Maybe you are so kind to check if this works as expected. If it doesn't work I'll look deeper into DRM.

By the way, I didn't implement this before because I didn't find documentation about the InitWindow function. Is there any I can use and overlooked so far (maybe @raysan5)?

@kernelkinetic

not sure if this is relevant, but the 0,0 thing is officially supported:

https://github.com/raysan5/raylib/issues/1186

@alanbork Thanks, so I expect my already mentioned commit to work the same way as mentioned in this issue.

current raylib on pi0.3 it uses the current mode set by
config.txt/tvservice , which makes sense i think.

user chose that mode for a reason. for instance on my tv 0th mode is
an interlaced mode that doesn't actually match tv's native resolution.
not a great solution :-(

On Sat, Sep 5, 2020 at 12:03 PM kernelkinetic notifications@github.com wrote:
>

@alanbork Thanks, so I expect my already mentioned commit to work the same way as mentioned in this issue.

β€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or unsubscribe.

@kernelkinetic , see if this works. for me it shows 1280x720, as expected

cat /sys/kernel/debug/dri/1/*

@kernelkinetic , see if this works. for me it shows 1280x720, as expected

cat /sys/kernel/debug/dri/1/*

sorry I should have checked - that seems to be constant independent of calls to tvservice. maybe it's the boot resolution?

@alanbork You lead me to an idea: I think I could use the same function to get the current display size as for Raspberry Pi 0..3. I'll check that tomorrow πŸ‘πŸΌ

@kernelkinetic there's this option:

https://blog.weghos.com/userland/PiUserland/host_applications/linux/apps/tvservice/tvservice.c.html#451

but that seems to use non-drm methods to get the current mode. Since we are talking about supporting he the pi4 that wouldn't be the end of the world, but certainly not elegant.

@alanbork Thanks for your hints, I also thought to use graphics_get_display_size() from bcm, but I think we should stick to DRM because that's what should be available on every Linux system and so we may build a base for other embedded linux boards already. I was going a little bit deeper into DRM: According to https://manpages.debian.org/testing/libdrm-dev/drmModeGetResources.3.en.html the correct way seems to be to find the connector of the display we want to use and then get the current display setting from the connector's crt controller and mode. That leads to another question: Raspberry Pi 4 has two HDMI connectors _and_ the LCD connector as third option, how to say to raylib which one to use?

@alanbork Beside we should also answer the previous question, I added that the current screen settings are used if InitWindow() isn't called with two positive size values in https://github.com/kernelkinetic/raylib/commit/926f6f7b1f8eb3deaaa434a18b3e62a652a545c4

@kernelkinetic you shouldn't name this support "V3D", the API you use is supported on most (if not all) DRI supported platforms.
So nouveau, r200/r300/r600, radeonsi, iris, i965, lima, panfrost, and many others are supported with your code.

Maybe name it PLATFORM_DRM ?

Thanks for the hint, @TSnake41. This touches the (still not answered) question how to integrate this into the current raylib build system. Since I'm currently not aware wether and how DRM and X11 works together and I'm concentrating on raylib's "native mode" only, I'm not able to answer this question. Of course I'm open to suggestions or decisions how to integrate this into raylib the proper way and then it will get the name whatever it should have. But to be honest I'm not sure if its a new platform and so I didn't build it as PLATFORM_DRM so far. I think someone with more knowledge of raylib should answer this.

I can run your fork with -DPLATFORM_RPI and -DV3D fine on my Linux laptop (i5-5300U, HD 5500) and should work as long as you have "Open Source drivers" (got the same idea working on a Orange Pi One and my desktop (i5-4670k, GTX 750-Ti (nouveau driver)).
Just compile it, and it runs (almost) properly, only having display issues with big screens or multi screen (probably a issue of actual size vs requested size).

About project integration, making a PLATFORM_DRM platform looks fine with shared parts between PLATFORM_RPI and PLATFORM_DRM, there is already EGL stuff shared between all these platforms.

OpenGL ES is needed, but it's already provided by Mesa, even for desktop/laptops (I have OpenGL ES 3.2 on HD 5500/GTX 750-Ti).

@TSnake41 Okay, sounds reasonable to me. So I'll change my implementation to a new PLATFORM_DRM :)

wrt to getting the current mode, from another forum post:

The current mode is a setting on the crtc (the thing that applies the video timings), so you'll find the current mode in "drmModeCrtc" as "mode".

It gets tricky fast when you consider multiple monitors/outputs, but as long as there's only one attached it's possible to do the right thing without having to guess. IMHO if there's more than one display just punt and use the first, as raylib doesn't have any API for this anyway. A more general option would be to support a .rayrc file in the same directory that override initwindow or resolution, monitor, etc, but going that way is up to ray.

I've updated my repo to https://github.com/kernelkinetic/raylib/commit/f900a4017e02f5c86fd47e3a19d05d5662d89c22 containing my implementation as new PLATFORM_DRM and I also modified the Makefiles in src and in examples for first test builds.

@kernelkinetic Ah, ok. I just downloaded your newest release and it's working great. Even potentially tricky bits like 480p vs 480i are maintained properly! FYI things start to go south once you use tvservice to set to current display mode; but this is because tvservice is deprecated for fkms. IMHO, at least from the users side of things this is functionally ready for consideration of a merge with the official raylib. The only thing I could suggest is perhaps a more informative error message in the case that a user tries to run your code when fkms is not loaded; plus there's the question of what to with pi0...3 - the original vc4/dispmanx api's are really better suited for that hardware, so the holy grail here would be to support both in a single binary.

@kernelkinetic great work! I need to see how to integrate it in raylib properly...
@alanbork I'm afraid RPI0-3 and RPI4 paths should be separated in some way and users need to recompile raylib with the proper libraries for every platform... I'm considering splitting PLATFORM_RPI into:

  • PLATFORM_RPI_NATIVE_VC4
  • PLATFORM_RPI_NATIVE_V3D or PLATFORM_NATIVE_DRM

Is this implementation supported in other embedded platforms other than RPI? could it be easily adapated? I don't know what's the state of DRM driver between platforms... any info?

Thanks a lot @alanbork and @raysan5, I'm glad to read this! I didn't check input et. al., only the graphic part. Because I only updated the PLATFORM_RPI defines to also be included on PLATFORM_DRM, I didn't expect any flaws there.

I mentioned earlier that my implementation should also work with V3D (f)kms driver on Raspberry Pi 2 and above. If we want to support both APIs in one binary, the only solution I can imagine is to dynamically load the corresponding libraries - which could also be used if the (f)kms driver is not available. Let me check the necessary effort of such an implementation. The only drawback with this would be that we loose link-time checks for these dependencies.

@raysan5 As @TSnake41 already mentioned, the DRM implementation is "the Linux standard" as native base to EGL. It should also work on most Linux distributions, even on desktops. The only difference that my implementation uses OpenGL ES while desktops often use OpenGL profile.

I'm glad to read this! I didn't check input et. al., only the graphic part. Because I only updated the PLATFORM_RPI defines to also be included on PLATFORM_DRM, I didn't expect any flaws there.

FYI the current raylib implementation of keyboard input works fine on the pi4. I have not tested usb gamepads but I would expect it to work.

@raysan5 @kernelkinetic
I can confirm raylib with DRM working on desktop and other ARM platforms (Orange Pi One).
I could try to test on a Raspberry Pi Zero, but I need to find a micro sd card for it.

@TSnake41 thank you very much for testing! Did you also test native mode? Some RPI0 testing would be great...

@TSnake41 thank you very much for testing! Did you also test native mode? Some RPI0 testing would be great...

are you talking about testing pi0 with platform_rpi or platform_drm? I could be wrong but I vaguely recall fkms not supporting pi0.

from the firmware developers:

  1. Does FKMS work on every Pi model?
    Yes, although it'll be very slow on the 0/1, and you'll be very short of memory.

Just a thought guys - an option to run without X on desktop could be nice...

@chriscamacho Just a thought guys - an option to run without X on desktop could be nice...

what do you mean, exactly?

the ability to run a Linux Raylib application without X running.

@chriscamacho the ability to run a Linux Raylib application without X running.

that's exactly what we are doing here, at least for the raspberry pi hardware. feel free to try the platform_drm code being tested here to see if it can be run under desktop x86 linux (I assume that's what you are talking about?) to see if that works - it might.

@alanbork Is there a reason that you focus on x86 Linux only? I don't see why it shouldn't work on x64, too.

@kernelkinetic, sorry for the confusion I still think of x86 as
encompassing both 32 and 64 bit ISAs.

On Mon, Sep 7, 2020 at 10:44 AM kernelkinetic notifications@github.com
wrote:

@alanbork https://github.com/alanbork Is there a reason that you focus
on x86 Linux only? I don't see why it shouldn't work on x64, too.

β€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/raysan5/raylib/issues/1096#issuecomment-688453592,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/ANPGZ5NY5RVHV3VXT6UA6GDSEULYJANCNFSM4KTHYJMA
.

@alanbork do you have some code, that actually compiles, stuff missing on
the 1st post...

happy to test it out and get it working, on desktop too...

On Mon, 7 Sep 2020 at 18:30, alanbork notifications@github.com wrote:

@chriscamacho https://github.com/chriscamacho the ability to run a
Linux Raylib application without X running.

that's exactly what we are doing here, at least for the raspberry pi
hardware. feel free to try the platform_drm code being tested here to see
if it can be run under desktop x86 linux (I assume that's what you are
talking about?) to see if that works - it might.

β€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/raysan5/raylib/issues/1096#issuecomment-688448455,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAFO4SJNWC77MOU6PBT5AFDSEUKC5ANCNFSM4KTHYJMA
.

--

blog bedroomcoders.co.uk http://bedroomcoders.co.uk

Disclaimer:
By sending an email to ANY of my addresses you are agreeing that:

  1. I am by definition, "the intended recipient"

  2. All information in the email is mine to do with as I see fit and make
    such financial profit, political mileage, or good joke as it lends itself
    to. In particular, I may quote it where I please.

  3. I may take the contents as representing the views of your company.

  4. This overrides any disclaimer or statement of confidentiality that
    may be included on your message.

@chriscamacho https://github.com/kernelkinetic/raylib and using PLATFORM_DRM, currently only the src/Makefile and examples/Makefile are modified

I got the examples compiled! forgot the PLATFORM define for them....

however I now see
shaders_fog: core.c:3923: SwapBuffers: Assertion `bo' failed.

I'll test further and get back....

@TSnake41 got it work on his linux laptop... Is this a regression, or something else?

@chriscamacho That's a hint that raylib can't lock the front buffer because it's not available (headless) or someone already locked it, e. g. a running X server or another running raylib instance.

@kernelkinetic So... just to clarify... not sure if I understood it correctly... PLATFORM_NATIVE_DRM can allow raylib running on any Linux distribution with no X required? That sounds too awesome to me...

@raysan5 That's the case (and it may also work for some Android devices: https://www.collabora.com/news-and-blog/blog/2018/12/17/a-dream-come-true-android-finally-using-drm/kms/), as long as the graphic system supports:

  • OpenGL ES 2.0 (we could change this to OpenGL 2.0 for example, but OpenGL ES 2.0 is the current setting for raylib on Raspberry Pi)
  • DRM, which should be the case for most systems, because it's part of the Linux kernel (https://www.kernel.org/doc/html/latest/gpu/introduction.html)
  • GBM, which is the buffer management API used for most free graphic drivers - there may some issues with proprietary drivers, I found an article from October 2019 that NVIDIA _plans but at this point don't uses_ it for its proprietary driver, for example.

By the way, the Raspberry Linux Foundation switched away from its proprietary API to DRM and GBM because it wants to support this "standard Linux way".

ran it from the command line without X running, really i need just the
egl/gbm/drm stuff without the raylib.... to get something working...

On Tue, 8 Sep 2020 at 04:48, kernelkinetic notifications@github.com wrote:

@chriscamacho https://github.com/chriscamacho That's a hint that raylib
can't lock the front buffer because it's not available (headless) or
someone already locked it, e. g. a running X server or another running
raylib instance.

β€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/raysan5/raylib/issues/1096#issuecomment-688602125,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAFO4SOE2IUVPBGNELQQODLSEWSPLANCNFSM4KTHYJMA
.

--

blog bedroomcoders.co.uk http://bedroomcoders.co.uk

Disclaimer:
By sending an email to ANY of my addresses you are agreeing that:

  1. I am by definition, "the intended recipient"

  2. All information in the email is mine to do with as I see fit and make
    such financial profit, political mileage, or good joke as it lends itself
    to. In particular, I may quote it where I please.

  3. I may take the contents as representing the views of your company.

  4. This overrides any disclaimer or statement of confidentiality that
    may be included on your message.

@chriscamacho I'm not sure if I get you right, but you need to clone https://github.com/kernelkinetic/raylib and build raylib using the Makefile in src with the option PLATFORM=PLATFORM_DRM. If you want to build the examples then use the Makefile in examples again with the option PLATFORM=PLATFORM_DRM. If you want to link the built raylib.a with your own sources, you need to link to libGLESv2, libEGL, libdrm and libgbm.

There may be one caveat for compiling: Because raylib defines a Font structure and X11 does so, too, you need to define EGL_NO_X11, otherwise egl.h tears in the X11 headers and the second Font structure.

yeah i got it to compile and run, it just doesn't open a context - even
without x running... in order to debug what is going on I need a minimal
example of opening a valid context so I can debug it without the confusion
of all the various ifdef's in the raylib code base, I've looked at a number
of different ways to do this no found a working method just yet (at least
on my hardware i7-10510U) I did have some code that rendered to a buffer
(missing proper flipping) but that stopped working after a mesa update.

On Tue, 8 Sep 2020 at 12:54, kernelkinetic notifications@github.com wrote:

@chriscamacho https://github.com/chriscamacho I'm not sure if I get you
right, but you need to clone https://github.com/kernelkinetic/raylib and
build raylib using the Makefile in src with the option
PLATFORM=PLATFORM_DRM. If you want to use build the examples then use the
Makefile in examples again with the option PLATFORM=PLATFORM_DRM. If you
want to link the built raylib.a with your own sources, you need to link to
libGLESv2, libEGL, libdrm and libgbm.

There may be one caveat for compiling: Because raylib defines a Font
structure and X11 does so, too, you need to define EGL_NO_X11, otherwise
egl.h tears in the X11 headers and the second Font structure.

β€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/raysan5/raylib/issues/1096#issuecomment-688817931,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAFO4SMCCZOKDHCDTPDFI6TSEYLQNANCNFSM4KTHYJMA
.

--

blog bedroomcoders.co.uk http://bedroomcoders.co.uk

Disclaimer:
By sending an email to ANY of my addresses you are agreeing that:

  1. I am by definition, "the intended recipient"

  2. All information in the email is mine to do with as I see fit and make
    such financial profit, political mileage, or good joke as it lends itself
    to. In particular, I may quote it where I please.

  3. I may take the contents as representing the views of your company.

  4. This overrides any disclaimer or statement of confidentiality that
    may be included on your message.

@chriscamacho At least for my code there should be an error message or a failing assertion if it doesn't work properly. Otherwise I'll consider this to be a bug. I'll try this in a virtual machine, too.
According your specific problem: DRM and GBM needs to be supported by your graphic card driver, maybe you can check that. And DRM and GBM is implemented by mesa, so maybe an update breaks something between driver and mesa and you also need to update your graphics driver.

@chriscamacho I can successfully compile and run raylib and the core_basic_window example on a current Ubuntu 20.04 in a current VMware Player machine. But again: It is necessary to switch from the graphical login screen to a console window to allow raylib to aquire the graphics buffer.

@alanbork If you want to build one binary for both Raspberry Pi implementations, you can replace the calls to the external functions by function pointers, dynamic load the necessary libraries and set the function calls. For the (to be fair really easy) bcm_host_init() call it could be like:

#include <assert.h>
#include <dlfcn.h>

void rl_bcm_host_init() {
    assert(prl_bcm_host_init);
    prl_bcm_host_init();
}

void *bcm_host = 0;
void (*prl_bcm_host_init)() = 0;

void libs_init() {
    bcm_host = dlopen("bcm_host.so", RTLD_NOW);
    if (bcm_host) {
        prl_bcm_host_init = dlsym(bcm_host, "bcm_host_init");
    }
}

void libs_destroy() {
    if (bcm_host) {
        dlclose(bcm_host);
    }
}

You need to decide which library to load by checking the available driver for example.

on an unrealed project I have been using exact technique - it works well,
ends up transparent to the end user...

On Tue, 8 Sep 2020 at 19:31, kernelkinetic notifications@github.com wrote:

@alanbork https://github.com/alanbork If you want to build one binary
for both Raspberry Pi implementations, you can replace the calls to the
external functions by function pointers, dynamic load the necessary
libraries and set the function calls. For the (to be fair really easy)
bcm_host_init() call it could be like:

include

include

void rl_bcm_host_init() {
assert(prl_bcm_host_init);
prl_bcm_host_init();
}

void bcm_host = 0;
void (
prl_bcm_host_init)() = 0;

void libs_init() {
bcm_host = dlopen("bcm_host.so", RTLD_NOW);
if (bcm_host) {
prl_bcm_host_init = dlsym(bcm_host, "bcm_host_init");
}
}

void libs_destroy() {
if (bcm_host) {
dlclose(bcm_host);
}
}

You need to decide which library to load by checking the available driver
for example.

β€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/raysan5/raylib/issues/1096#issuecomment-689058238,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAFO4SKLYP5TTU4WBYF3T5LSEZZ7DANCNFSM4KTHYJMA
.

--

blog bedroomcoders.co.uk http://bedroomcoders.co.uk

Disclaimer:
By sending an email to ANY of my addresses you are agreeing that:

  1. I am by definition, "the intended recipient"

  2. All information in the email is mine to do with as I see fit and make
    such financial profit, political mileage, or good joke as it lends itself
    to. In particular, I may quote it where I please.

  3. I may take the contents as representing the views of your company.

  4. This overrides any disclaimer or statement of confidentiality that
    may be included on your message.

@kernelkinetic As commented on Discord, I prefer letting the users compile the right version for their needs but thanks for saring the code snipped, very interesting!

@kernelkinetic can you open "issues" on your github I'm still looking at this - would be very useful to make it none PI specific! (but still automagically detect pi2/3/4 desktop without X....

when testing I was not running X !

I see this output

[chris@chris-N150CU core]$ ./core_basic_window 
INFO: Initializing raylib 3.1-dev
WARNING: DISPLAY: Failed to create EGL window surface: 0x3009
INFO: TIMER: Target time per frame: 16.667 milliseconds
INFO: TEXTURE: [ID 0] Unloaded default texture data from VRAM (GPU)
Segmentation fault
[chris@chris-N150CU core]$ grep 0x3009 /usr/include/EGL/* 
/usr/include/EGL/egl.h:#define EGL_BAD_MATCH                     0x3009

the seg fault is caused by CloseWindow - I haven't bothered looking into this - going to see if I can see what configs and mismatches there are - you never know I might even get it working....

@chriscamacho Issues are open πŸ‘

I'm pretty sure we'll get this to work, we need just to see which of your available configs matches the raylib requirements. But maybe we discuss this in an issue you file at https://github.com/kernelkinetic/raylib/issues.

:+1: done!

@alanbork @chriscamacho I want to provide a clean fork with branches for DRM etc. After fiddeling with too much trouble with this github thing πŸ˜€ I'll start again and will commit the already done code in a new branch at https://github.com/kernelkinetic/raylib, please be patient.

ok, let us know. seems like all the filed issues got deleted whatever it was you did

@kernelkinetic @chriscamacho @alanbork @TSnake41 @dginu85 Thank you very much to you all for working on this improvement! Now we got three implementation: @dginu85 one, @TSnake41 one and @kernelkinetic one. It seems that last one is the most promising.

@kernelkinetic feel free to send a PR with PLATFORM_DRM for review.

@raysan5 Thanks. I'm currently working out an issue with @alanbork about progressive and interlaced mode selection. I think this should go into the DRM implementation. If this is finished I'll send the PR, if this is okay.

the @kernelkinetic/raylib
reply@reply.github.com one is
very good, but still has at least one bug to be fixed before it's ready.

On Sat, Sep 19, 2020 at 10:27 AM Ray notifications@github.com wrote:

@kernelkinetic https://github.com/kernelkinetic @chriscamacho
https://github.com/chriscamacho @alanbork https://github.com/alanbork
@TSnake41 https://github.com/TSnake41 @dginu85
https://github.com/dginu85 Thank you very much to you all for working
on this improvement! Now I got three implementation: @dginu85 one
https://github.com/raysan5/raylib/issues/1096#issue-563451616, @TSnake41
one https://github.com/raysan5/raylib/pull/1293 and @kernelkinetic one
https://github.com/kernelkinetic/raylib. It seems that last one is the
most promissing.

@kernelkinetic https://github.com/kernelkinetic feel free to send a PR
with PLATFORM_DRM for review.

β€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/raysan5/raylib/issues/1096#issuecomment-695335108,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/ANPGZ5L3AAC6FYCVBIRAK5LSGTSZ7ANCNFSM4KTHYJMA
.

@alanbork I just wanted to contribute some code and not to manage a github repo, sorry for the inconvenience 😬 Anyways, I added branch https://github.com/kernelkinetic/raylib/tree/platform-drm with the well-known code and modified mode selection. Finding the right mode in the list of modes isn't an easy thing, so now first an exactly matching (according width and height) mode is searched (interlaced if flag is set, progressive is choosen if no interlaced found) and if there is nothing found then the next bigger one is choosen (again interlaced if flag is set, progressive is choosen if no interlaced found). You can see the modes and the choice if you set logTypeLevel in utils.c to LOG_TRACE.
Additionally I modified the CMakeLists.txt to allow building and especially debugging in Visual Studio Code with CMake Tools extension. The many (necessary) #ifdefs make the sources hard to read, but in Visual Studio Code the active #ifdefs are easy to see.

I'll take a look. is there a way to see if you got the requested
interlacing? (I don't mind looking inside the CORE data structure).

On Sat, Sep 19, 2020 at 11:32 AM kernelkinetic notifications@github.com wrote:
>

@alanbork I just wanted to contribute some code and not to manage a github repo, sorry for the inconvenience Anyways, I added branch https://github.com/kernelkinetic/raylib/tree/platform-drm with the well-known code and modified mode selection. Finding the right mode in the list of modes isn't an easy thing, so now first an exactly matching (according width and height) mode is searched (interlaced if flag is set, progressive is choosen if no interlaced found) and if there is nothing found then the next bigger one is choosen (again interlaced if flag is set, progressive is choosen if no interlaced found). You can see the modes and the choice if you set logTypeLevel in utils.c to LOG_TRACE.
Additionally I modified the CMakeLists.txt to allow building and especially debugging in Visual Studio Code with CMake Tools extension. The many (necessary) #ifdefs make the sources hard to read, but in Visual Studio Code the active #ifdefs are easy to see.

β€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or unsubscribe.

Set logTypeLevel in utils.c to LOG_TRACE before building raylib to see the available modes and the selected mode.

bug is less nasty but still there when asking for 1080 (no interlace flag
set) on a display that only does 1080i:

INFO: DISPLAY: no graphic card set, trying card1
TRACE: DISPLAY: 1 connectors found
TRACE: DISPLAY: connector index 0
TRACE: DISPLAY: there are 11 connector modes
TRACE: DRM mode connected
TRACE: selecting for (res 1920x1080)
TRACE: mode 10 h=640 v=480
TRACE: progressive mode
TRACE: mode 9 h=640 v=480
TRACE: progressive mode
TRACE: mode 8 h=720 v=480
TRACE: interlaced mode
TRACE: but shouldn't choose an interlaced mode
TRACE: mode 7 h=720 v=480
TRACE: interlaced mode
TRACE: but shouldn't choose an interlaced mode
TRACE: mode 6 h=720 v=480
TRACE: progressive mode
TRACE: mode 5 h=720 v=480
TRACE: progressive mode
TRACE: mode 4 h=1440 v=480
TRACE: interlaced mode
TRACE: but shouldn't choose an interlaced mode
TRACE: mode 3 h=1280 v=720
TRACE: progressive mode
TRACE: mode 2 h=1280 v=720
TRACE: progressive mode
TRACE: mode 1 h=1920 v=1080
TRACE: interlaced mode
TRACE: but shouldn't choose an interlaced mode
TRACE: mode 0 h=1920 v=1080
TRACE: interlaced mode
TRACE: but shouldn't choose an interlaced mode
TRACE: selecting for (res 1920x1080)
TRACE: mode 10 h=640 v=480
TRACE: progressive mode
TRACE: mode 9 h=640 v=480
TRACE: progressive mode
TRACE: mode 8 h=720 v=480
TRACE: interlaced mode
TRACE: but shouldn't choose an interlaced mode
TRACE: mode 7 h=720 v=480
TRACE: interlaced mode
TRACE: but shouldn't choose an interlaced mode
TRACE: mode 6 h=720 v=480
TRACE: progressive mode
TRACE: mode 5 h=720 v=480
TRACE: progressive mode
TRACE: mode 4 h=1440 v=480
TRACE: interlaced mode
TRACE: but shouldn't choose an interlaced mode
TRACE: mode 3 h=1280 v=720
TRACE: progressive mode
TRACE: mode 2 h=1280 v=720
TRACE: progressive mode
TRACE: mode 1 h=1920 v=1080
TRACE: interlaced mode
TRACE: but shouldn't choose an interlaced mode
TRACE: mode 0 h=1920 v=1080
TRACE: interlaced mode
TRACE: but shouldn't choose an interlaced mode
WARNING: no suitable DRM connector mode found

On Sat, Sep 19, 2020 at 11:46 AM kernelkinetic notifications@github.com
wrote:

Set logTypeLevel in utils.c to LOG_TRACE before building raylib to see
the available modes and the selected mode.

β€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/raysan5/raylib/issues/1096#issuecomment-695343415,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/ANPGZ5N75VSGMGUSA7OIAM3SGT4BFANCNFSM4KTHYJMA
.

Set logTypeLevel in utils.c to LOG_TRACE before building raylib to see the available modes and the selected mode.

I meant programmatically .

so as I suspected the refresh rates are an issue - on a tv you can have anything from 25 to 75hz supported, and gamers have 144hz screens... currently it chooses randomly. 25hz is probably not what we want in any situation.

raylib already has a framerate function, SetTargetFPS, so you could use that. 60hz would be a reasonable default, or you could go for max.

@alanbork
Thanks for testing! I found a way to test DRM mode selection without proper hardware and so it should work now as expected.
Thanks for your hint about the framerate, I modified the frame rate selection to respect target fps if set and to try 60 Hz otherwise. InitWindow() fails if no requested or higher screen refresh rate is found. Of course SetTargetFPS() must be called before InitWindow().
The actual commit https://github.com/kernelkinetic/raylib/commit/8319537e3fe76262a9be9975331c06f4b5d7bbf8 contains both.

this is looking very good. I tried asking for 480i on a display that didn't
have 480i and it gave me 1080i, which is maybe not ideal but there's no
ideal option in that case so I'd call it good enough. Everything else
worked right: 50 and 24hz refresh rates were selectable, correctly, for
both 1080i and 1080p. And with the hardware I'm using I can confirm that
the pi even was producing those modes properly.

I plan to make a local copy that allows floating point target refresh rates
so that I can select 59.94hz vs 60hz but I think that's outside the scope
of this project. relatedly the refresh variable returned in the drm_mode
structure is an integer, so you have to calculate the actual refresh rate
from the dot clock. definitely beyond the scope of raylib, I'd leave it as
is in your code..

you might update the get monitor refresh rate code though, to reflect
what's chosen by your code. Currently that function returns 0 for all
platforms other than desktop.

On Sun, Sep 20, 2020 at 2:57 AM kernelkinetic notifications@github.com
wrote:

@alanbork https://github.com/alanbork
Thanks for testing! I found a way to test DRM mode selection without
proper hardware and so it should work now as expected.
Thanks for your hint about the framerate, I modified the frame rate
selection to respect target fps if set and to try 60 Hz otherwise.
InitWindow() fails if no requested or higher screen refresh rate is
found. Of course SetTargetFPS() must be called before InitWindow().
The actual commit kernelkinetic@8319537
https://github.com/kernelkinetic/raylib/commit/8319537e3fe76262a9be9975331c06f4b5d7bbf8
contains both.

β€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/raysan5/raylib/issues/1096#issuecomment-695767973,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/ANPGZ5MF7HZJAQXF3ONBH6DSGXGY3ANCNFSM4KTHYJMA
.

in case anybody wants to support fractional refresh rates (necessary if you need to select NTSC aka 59.97hz), here's the relevant bit of changes. As I said this is probably beyond what anybody else is using raylib for so I'm not submitting an official patch, just an FYI for anybody with unusual needs like mine.

allow setTargetFPS to take a float, and:

static float mode_vrefresh(drmModeModeInfo *mode)
{
        return  mode->clock * (mode->flags & DRM_MODE_FLAG_INTERLACE ? 2000.00 : 1000.00)
                        / (mode->htotal * mode->vtotal);
}


static bool InitGraphicsDevice(int width, int height) {

.....

TRACELOG(LOG_TRACE, "selecting for (res %ux%u@%f)", CORE.Window.screen.width, CORE.Window.screen.height, fps);
        // Get closest video mode to desired CORE.Window.screen.width/CORE.Window.screen.height
        for (int i = CORE.Window.connector->count_modes - 1; i >= 0; i--)
        {
            TRACELOG(LOG_TRACE, "checking mode %d h=%u v=%u %s refresh=%f", i, CORE.Window.connector->modes[i].hdisplay, CORE.Window.connector->modes[i].vdisplay,
               IS_INTERLACED(CORE.Window.connector->modes[i]) ? "interlaced" : "progressive", mode_vrefresh(& CORE.Window.connector->modes[i]));

            if (IS_PROGRESSIVE(CORE.Window.connector->modes[i]))
            {
                TRACELOG(LOG_TRACE, "progressive mode");
                if (avoidProgressive)
                {
                    TRACELOG(LOG_TRACE, "but shouldn't choose an progressive mode");
                    continue;
                }
            }
            else
            {
                TRACELOG(LOG_TRACE, "interlaced mode");
            }

            bool found = false;
            if (findExactly) {
                found = (CORE.Window.connector->modes[i].hdisplay == CORE.Window.screen.width) &&
                    (CORE.Window.connector->modes[i].vdisplay == CORE.Window.screen.height);
            }
            else
            {
                found = (CORE.Window.connector->modes[i].hdisplay >= CORE.Window.screen.width) &&
                    (CORE.Window.connector->modes[i].vdisplay >= CORE.Window.screen.height) &&
                    (CORE.Window.connector->modes[i].vrefresh >= fps);
            }
            if (found)
            {
                double tr = mode_vrefresh(& CORE.Window.connector->modes[i]);
                double newError = fabs(tr  - fps);

                TRACELOG(LOG_TRACE, "wanted %f, found %f, diff: %f",fps, tr, newError);
                if (newError < bestError)
                    {
                    TRACELOG(LOG_TRACE, "%f is less error, using %f", newError, tr);    
                    bestError = newError;
                    CORE.Window.display.width = CORE.Window.connector->modes[i].hdisplay;
                    CORE.Window.display.height = CORE.Window.connector->modes[i].vdisplay;
                    CORE.Window.modeIndex = i;
                    selectedRefreshRate = tr;
                    }


            }
        }
    }

@alanbork Thanks again for testing! I'm glad to see that it's working now πŸ˜€ I'll update GetMonitorRefreshRate(), thanks for the hint. Is there anything more I should implement before we will consider PLATFORM_DRM ready to send a pull request, @alanbork and @chriscamacho?
@chriscamacho I didn't forget your two issues but I think they don't belong to PLATFORM_DRM so I'll handle them later.

@kernelkinetic at the moment it seems very PI specific, I wonder if some
things like default /dev/drm/cardX settings and a few other things could go
in config.h or maybe set before calling initWindow() ???

Consider adding switch to tty-1 automagically if a lock can't be achieved
(or have you already)

look at removing down scaling code, we only ever upscale to letterbox, a
smaller screen is never selected.

add comments!

On Mon, 21 Sep 2020 at 13:15, kernelkinetic notifications@github.com
wrote:

@alanbork https://github.com/alanbork Thanks again for testing! I'm
glad to see that it's working now πŸ˜€ I'll update GetMonitorRefreshRate(),
thanks for the hint. Is there anything more I should implement before we
will consider PLATFORM_DRM ready to send a pull request, @alanbork
https://github.com/alanbork and @chriscamacho
https://github.com/chriscamacho?
@chriscamacho https://github.com/chriscamacho I didn't forget your two
issues but I think they don't belong to PLATFORM_DRM so I'll handle them
later.

β€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/raysan5/raylib/issues/1096#issuecomment-696075549,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAFO4SJBUJOJE6RZS2CVM7TSG47VZANCNFSM4KTHYJMA
.

--

blog bedroomcoders.co.uk http://bedroomcoders.co.uk

Disclaimer:
By sending an email to ANY of my addresses you are agreeing that:

  1. I am by definition, "the intended recipient"

  2. All information in the email is mine to do with as I see fit and make
    such financial profit, political mileage, or good joke as it lends itself
    to. In particular, I may quote it where I please.

  3. I may take the contents as representing the views of your company.

  4. This overrides any disclaimer or statement of confidentiality that
    may be included on your message.

above not withstanding this is great work btw, adds greatly to the utility of raylib

@alanbork Thanks again for testing! I'm glad to see that it's working now πŸ˜€ I'll update GetMonitorRefreshRate(), thanks for the hint. Is there anything more I should implement before we will consider PLATFORM_DRM ready to send a pull request,

I think it's ready. There's maybe a few issues raised about how raylib in general should support multiple monitors, finer grained control over refresh rates, etc, but as is what you have adds significant value to the current iteration of raylib.

at the moment it seems very PI specific, I wonder if some
things like default /dev/drm/cardX settings and a few other things could go
in config.h or maybe set before calling initWindow() ???

that's a very tricky issue - I think that kind of reworking of the raylib API is up to @raysan5 and may well be necessary. But at the same time part of the joy of raylib is it's simplicity. Intelligently choosing defaults might be the best way to go. I mean, I need control over raylib's initwindow in a way that the current code base does not provide and so I have to modify the source. But 99% of users probably don't need what I do. The only thing I really wish is that the functions and data structures of core.c were exported so that I could write my own implementation of initwindow and EndDrawing, rather than having to hack core.c directly. My core.c is always 4 months or more behind because of the re-hacking work required to be up to date.

@kernelkinetic one last thought:

instead of hint interlaced = avoid progressive you might think instead of hint allow interlaced, (unset= avoid interlaced). Because most people will probably prefer to get progressive even if it means not getting the exact resolution requested. but if getting the resolution you want is more important, then allow interlaced to get it. make sense?

@chriscamacho Thanks for your view. The card1/card0 thing is indeed Raspberry Pi specific to support Raspberry Pi 4 and the previous ones. For Linux in general I've implemented a SetGraphicDeviceName() as you suggested to set any card name. I currently don't get what you mean with "downscaling code", but maybe you can add a note to the PR 😊 I like your idea to switch to console but I'm not sure if the user wants this and if yes to which one, so I think as @alanbork that may need some structural change of raylib and so I let this up to @raysan5 for a later discussion.

@alanbork Thanks for your opinion and the hint. As I already said I'm absolutely with you. And I modified the interlaced hint just the way you proposed. I spent some days thinking about this because my solution doesn't make me happy, but I didn't see this obviously one πŸ˜€

Now I've just some cleanup to do, maybe to put some code into functions to get it clean and readabble and last but not least to check it against the coding conventions.

You never select a buffer that is smaller than the requested screen size - so you only ever need to down scale to a letterbox, never do you need to upscale yet you are checking for both cases...

@chriscamacho The mode list isn't necessarily sorted so I had some trouble with it. Maybe I fixed this already and maybe you are so kind to check this in https://github.com/raysan5/raylib/pull/1388.

I can't checkin PRs on this repo!

once the PR is in I will test again

@chriscamacho Oh, sorry. I've PRed my https://github.com/kernelkinetic/raylib/tree/platform-drm

@kernelkinetic Excuse for the late response! Thank you very much for the PR, it looks really good! Just two concerns out-of-curiosity:

  1. Would it be possible to avoid the drm_mouse_img.h? Just asking, I'll think about it more carefully...
  2. About the new set of variables for PLATFORM_DRM, are all of them required to be stored?

I'll review the PR more carefully after merging (maybe doing some renaming) but in general I looks really good and following raylib convention!

Congratulations to all of you for such a great work! πŸ‘

@raysan5 Thanks πŸ˜€ drm_mouse_img.h contains a good looking mouse pointer contributed by @chriscamacho, so maybe he can say more about this.

I carefully selected to store only the variables that are really necessary, but I will double check that again πŸ‘

I'm not a fan of the cursor addition actually - way too big on low
resolution screens and too small on high ones.

On Thu, Sep 24, 2020, 9:46 AM kernelkinetic notifications@github.com
wrote:

@raysan5 https://github.com/raysan5 Thanks πŸ˜€ drm_mouse_img.h contains
a good looking mouse pointer contributed by @chriscamacho
https://github.com/chriscamacho, so maybe he can say more about this.

I carefully selected to store only the variables that are really
necessary, but I will double check that again πŸ‘

β€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/raysan5/raylib/issues/1096#issuecomment-698460923,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/ANPGZ5PTALHE3QILOHQWYG3SHNZVDANCNFSM4KTHYJMA
.

@raysan5 I've checked the variables I introduced into CORE.Window and I'm afraid they are all necessary as long as the window exists:

const char *card;                   // /dev/dri/... file name

is set using SetGraphicDeviceName(...) before calling InitWindow(...).

int fd;                             // /dev/dri/... file descriptor
drmModeConnector *connector;        // Direct Rendering Manager (DRM) mode connector
int modeIndex;                      // index of the used mode of connector->modes
drmModeCrtc *crtc;                  // crt controller
struct gbm_bo *prevBO;              // previous used GBM buffer object (during frame swapping)
uint32_t prevFB;                    // previous used GBM framebufer (during frame swapping)

are necessary in consecutive calls to SwapBuffers(...).

struct gbm_device *gbmDevice;       // device of Generic Buffer Management (GBM, native platform for EGL on DRM)
struct gbm_surface *gbmSurface;     // surface of GBM

are the native display and surface on which EGL relies as long as it uses the window.

According to the mouse pointer: Currently it is optional and replaces the small square which I personally found a little bit to small 😁 But anyways, I can also remove it and let the small square come in again. It's up to you, @raysan5.

btw I have a question raised by

struct gbm_bo *prevBO; // previous used GBM buffer object
(during frame swapping)

uint32_t prevFB; // previous used GBM framebufer
(during frame swapping)

I'm measuring output with a photometer, and it looks like what's
happening is that the display outputs the frame as soon as you call
swap buffer, and blocks if it hasn't finished scanning out the last
buffer (double buffering, right?). Is there an option to do triple
buffering under DRM? In the previous incarnation of raylib with
pi3...0 the default was triple buffering. It would be nice to have the
choice, at least.

On Thu, Sep 24, 2020 at 10:57 AM kernelkinetic notifications@github.com
wrote:

@raysan5 https://github.com/raysan5 I've checked the variables I
introduced into CORE.Window and I'm afraid they are all necessary as long
as the window exists:

const char *card; // /dev/dri/... file name

is set using SetGraphicDeviceName(...) before calling InitWindow(...).

int fd; // /dev/dri/... file descriptor

drmModeConnector *connector; // Direct Rendering Manager (DRM) mode connector

int modeIndex; // index of the used mode of connector->modes

drmModeCrtc *crtc; // crt controller

struct gbm_bo *prevBO; // previous used GBM buffer object (during frame swapping)

uint32_t prevFB; // previous used GBM framebufer (during frame swapping)

are necessary in consecutive calls to SwapBuffers(...).

struct gbm_device *gbmDevice; // device of Generic Buffer Management (GBM, native platform for EGL on DRM)

struct gbm_surface *gbmSurface; // surface of GBM

are the native display and surface on which EGL relies as long as it uses
the window.

According to the mouse pointer: Currently it is optional and replaces the
small square which I personally found a little bit to small 😁 But
anyways, I can also remove it and let the small square come in again. It's
up to you, @raysan5 https://github.com/raysan5.

β€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/raysan5/raylib/issues/1096#issuecomment-698496794,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/ANPGZ5LB62SXQO3RX6SKZITSHOCAJANCNFSM4KTHYJMA
.

@kernelkinetic thanks for the detailed explanation.

About the SetGraphicDeviceName() before InitWindow(), it seems a bit cumbersome solution to me, I believe most users probably don't want to worry about that, I'd would prefer to use (if possible) a default #define DRM_DEVICE_NAME and let the advance users re-define it when required (despite having to recompile the library).

About drm_mouse_img.h I prefer to avoid it. It's 4096 bytes in size permanently loaded into memory, default raylib font is 512 bytes (supporting European charset) and it already worries me... A square placeholder looks ok to me, actually, raylib users could replace it for a custom one if desired. I even considered removing that square, so the define...

@alanbork Interesting question. Yes, there are two buffers used in SwapBuffers() and as far as I know I it can be extended to three buffers if hardware supports it. I'll investigate further.

@raysan5 Both sounds reasonable to me. I'll change this and and commit to the PR when it's ready πŸ‘ Should I remove the two checks for Raspberry Pi and use just one defined device name or should this stay as it is?

@kernelkinetic Sorry, could you point me to the specific code line?

Also considering using PLATFORM_NATIVE_DRM and rename PLATFORM_NATIVE_RPI, what do you thing? defines would be longer but maybe more descriptive for future users... in any case, this change could be applied after merging.

are there any platform_unative's planned? cuz otherwise it seems
unnecessarily long.

On Thu, Sep 24, 2020 at 11:45 AM Ray notifications@github.com wrote:
>

@kernelkinetic Sorry, could you point me to the specific code line?

Also considering using PLATFORM_NATIVE_DRM and rename PLATFORM_NATIVE_RPI, what do you thing? defines would be longer but maybe more descriptive for future users... in any case, this change could be applied after merging.

β€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or unsubscribe.

@raysan5 I mean lines 3086..3092 in core.c.

I'm not sure about the platform names, on the one hand RPI and DRM are a little bit misleading because DRM is the new RPI, otherwise on the other hand DRM works also on Linux as native mode πŸ€”

I corrected my previous post.

@alanbork Additional to the native platforms there is PLATFORM_DESKTOP which is incorporating X and also work on Raspberry Pi and Linux and which is another way of using raylib on these systems beside PLATFORM_DRM.

@raysan5 I have new information to clarify this /dev/dri/card* thing a little bit to find a proper solution for your #define DRM_DEVICE_NAME proposal, that I really like btw.

On Raspberry Pi the default situation /dev/dri/card0 exposes the older VC4 driver interface and /dev/dri/card1 the V3D interface that Platform DRM supports. But sometimes (maybe because you can switch the drives on Raspberry 1-3, but I don't know the reason) /dev/dri/card0 is the V3D interface. So I decided to try the default card1 first and card0 on failure. Of course it's possible that any other card* is the right one, but I've never seen this on a Raspberry Pi.

On a generic Linux device the /dev/dri/card* should rely on the installed graphic cards, but the name may differ, I've already seen something like /dev/dri/nvidia or /dev/dri/nvidia. We could check all available devices if they support rendering capabilities and choose one automatically, but many computers have two graphic cards which both may render but one is the cheap card that uses only software rendering and one is game card that supports fast hardware rendering. So it seems not to be an easy task to select a card automatically.

I originally embedded the image directly in the code - purposely to avoid
an include !

@alanbork nothing stopping you contributing a scaled mouse pointer!, even a fixed size one is better than a single red dot, if you really don't like it you can always hideCursor() and provide your own

you can access V3d on /dev/card0 just fine, in the very early days of pi4
it was better to use /dev/card1 and the secondary display connector.

I can't remember why exactly this was, but afaik /dev/card0 should be fine.

On Fri, 25 Sep 2020 at 08:37, kernelkinetic notifications@github.com
wrote:

@raysan5 https://github.com/raysan5 I have new information to clarify
this /dev/dri/card* thing a little bit to find a proper solution for your #define
DRM_DEVICE_NAME proposal, that I really like btw.

On Raspberry Pi the default situation /dev/dri/card0 exposes the older
VC4 driver interface and /dev/dri/card1 the V3D interface that Platform
DRM supports. But sometimes (maybe because you can switch the drives on
Raspberry 1-3, but I don't know the reason) /dev/dri/card0 is the V3D
interface. So I decided to try the default card1 first and card0 on
failure. Of course it's possible that any other card* is the right one,
but I've never seen this on a Raspberry Pi.

On a generic Linux device the /dev/dri/card* should rely on the installed
graphic cards, but the name may differ, I've already seen something like
/dev/dri/nvidia or /dev/dri/nvidia. We could check all available devices
if they support rendering capabilities and choose one automatically, but
many computers have two graphic cards which both may render but one is the
cheap card that uses only software rendering and one is game card that
supports fast hardware rendering. So it seems not to be an easy task to
select a card automatically.

β€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/raysan5/raylib/issues/1096#issuecomment-698774787,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAFO4SJSHAUB4TGH2M6GAQDSHRCCTANCNFSM4KTHYJMA
.

--

blog bedroomcoders.co.uk http://bedroomcoders.co.uk

Disclaimer:
By sending an email to ANY of my addresses you are agreeing that:

  1. I am by definition, "the intended recipient"

  2. All information in the email is mine to do with as I see fit and make
    such financial profit, political mileage, or good joke as it lends itself
    to. In particular, I may quote it where I please.

  3. I may take the contents as representing the views of your company.

  4. This overrides any disclaimer or statement of confidentiality that
    may be included on your message.

@chriscamacho At least on my up-to-date Raspberry Pi 4 Raspbian here I can open /dev/dri/card0 but I can't get DRM resources for it.

@alanbork I'm not a professional for graphics, but if the hardware supports it then triple buffering and vsync is possible with DRM because others already implemented it. Maybe if my current implementation is successully tested by some people in real world we could go to triple buffering.

@kernelkinetic - interesting, I was using custom, butchered image last on PI4 so probably some wrinkles with RPI OS ?

in any case obviously - if you can't get it on /dev/dri/card0 it'll have to be card1 !

@kernelkinetic Excuse the late resposne, about checking for /dev/dri/card1 and fallback to /dev/dri/card0 looks perfect for me.

Not sure if there is any tweak left, let me know and I'll merge. PLATFORM_ flag names can be renamed later on.

@raysan5 No problem, everything fine here πŸ˜€ I've currently nothing to add so you can merge πŸ‘

@alanbork Additional to the native platforms there is PLATFORM_DESKTOP which is incorporating X and also work on Raspberry Pi and Linux and which is another way of using raylib on these systems beside PLATFORM_DRM.

I'm not sure PLATFORM_DRM is any more native than PLATFORM_DESKTOP though. In the end both use the same fkms drivers, right?

@alanbork The fkms driver is the native option at least on Raspberry Pi 4, there the framebuffer is emulated only. And PLATFORM_DRM goes fullscreen without any other program allowed on the screen while PLATFORM_DESKTOP uses a window on X.

Sorry for the intrusion, but can PLATFORM_DRM work while in X? And as I understand, since there is no window, it will always be fullscreen or it can be borderless square or something like that? And nothing is needed for input, it is all native Linux, very nice.
So any board with support for Linux, even if not supported in libdrm (intel,amdgpu,exynos,freedreno,nouveau,omap,radeon,tegra,vc4,vivante,vmware) can work via software, slower of course?

@gen2brain PLATFORM_DRM doesn't work when X is on the screen. You can switch from a graphical console running X to a text console and then start a raylib PLATFORM_DRM program. You can also switch between the two, but only one of them can draw at the screen at the same time.
Exactly, any board supporting GBM, DRM and OpenGL ES 2 (currently, this could be changed when you build raylib) should work. If no hardware acceleration is available then a software acceleration is used - of course only when available. If you don't have access rights to the hardware then also software rendering may apply.

Pull Request has been finally merged! Thanks to all the contributors for this big and amazing addition to raylib!

It still requires some testing but hopefully PLATFORM_DRM will open the door to a broad set of embedded platforms. Please, let me know if you test it with some platforms other than Raspberry Pi 4!

:D

@kernelkinetic About the Travis CI issue:

Building raylib static library
CMake Error at src/CMakeLists.txt:195 (target_link_libraries):
  The keyword signature for target_link_libraries has already been used with
  the target "raylib_static".  All uses of target_link_libraries with a
  target must be either all-keyword or all-plain.
  The uses of the keyword signature are here:
   * src/CMakeLists.txt:188 (target_link_libraries)

Would it be possible to review that? Maybe @a3f could take a look?

I've added lines 187..189 for all platforms which conflicts with line 194 which is only active for PLATFORM_DESKTOP. In my opinion the CMake files need some updates in general. A quick solution could be to activate lines 187..189 only if it's not PLATFORM_DESKTOP.

@raysan5 Beside my previous message about TravisCI, I'll also test PLATFORM_DRM on a beaglebone black embedded system πŸ˜‰

@kernelkinetic Nice! Let me know how it works on a BeagleBone Black!

About CMake, let's wait for @a3f opinion on that but for me a PLATFORM_DESKTOP check sounds good.

I'm curious about if PLATFORM_DRM works on ClockworkPi GameShell... I'll ask in Discord if anyone could try it...

@a3f https://github.com/raysan5/raylib/issues/1391 may be related to CMake quirks.

@kernelkinetic About the Travis CI issue:

Building raylib static library
CMake Error at src/CMakeLists.txt:195 (target_link_libraries):
  The keyword signature for target_link_libraries has already been used with
  the target "raylib_static".  All uses of target_link_libraries with a
  target must be either all-keyword or all-plain.
  The uses of the keyword signature are here:
   * src/CMakeLists.txt:188 (target_link_libraries)

Would it be possible to review that? Maybe @a3f could take a look?

The problem here is that target_link_libraries for raylib_static is called once with keyword "PUBLIC" (line 189) and once without keyword (line 195). Cmake does not allow mixing these signatures. Either have both calls without keyword or both with.

A fix could look like this https://gist.github.com/tjammer/ec0ed7fabd701fe3387cacf2aaaf6a75

edit: I opened a PR #1395

I think it's time to close this issue. Thanks to you all for your time an effort implementing this new amazing feature! :)

Does that mean it's been merged?

On Sat, Oct 10, 2020 at 11:41 AM Ray notifications@github.com wrote:

Closed #1096 https://github.com/raysan5/raylib/issues/1096.

β€”
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/raysan5/raylib/issues/1096#event-3863013848, or
unsubscribe
https://github.com/notifications/unsubscribe-auth/ANPGZ5P4PT5K3HALP5CUEXLSKCTERANCNFSM4KTHYJMA
.

@alanbork yes

I just got to say, speaking for myself, that the fantastic end results from this issue, are really useful and appreciated !

Was this page helpful?
0 / 5 - 0 ratings

Related issues

carlsmith picture carlsmith  Β·  8Comments

SethArchambault picture SethArchambault  Β·  7Comments

williamfjm picture williamfjm  Β·  3Comments

ianpan870102 picture ianpan870102  Β·  6Comments

raysan5 picture raysan5  Β·  4Comments