I am going to use CM3+ module. I am planning to attach display using DSI (not a standard display - the same as CutiePi use). As far as I know I need vc4-kms-v3d driver to do it. So, I decided to try how it performs with RPi 3A+ and HDMI display I had by hand. I need OpenGL ES 2.0 full screen rendering without X. But first of all I need just to initialize all the things.
So, here is the simple test program (it is from this topic viewtopic.php?t=243707 with minimal changes):
Code: Select all
// 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
//-------- pik33@o2.pl
//----------------------------------------------------------------------
#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>
#include <assert.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 */1)
{
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/card0", O_RDWR);
assert(device != 0);
resources = drmModeGetResources(device);
assert(resources != NULL);
connector = find_connector(resources);
assert(connector != NULL);
printf("Modes list:\n------------------\n");
for(int i = 0; i < connector->count_modes; i++)
{
printf("Mode %d: %s\n", i, connector->modes[i].name);
}
printf("\nSelect mode (0..%d):", connector->count_modes);
int mode_num;
scanf("%d", &mode_num);
connector_id = connector->connector_id;
mode_info = connector->modes[mode_num];
encoder = find_encoder(resources, connector);
assert(encoder != NULL);
crtc = drmModeGetCrtc(device, encoder->crtc_id);
assert(crtc != 0);
drmModeFreeEncoder(encoder);
drmModeFreeConnector(connector);
drmModeFreeResources(resources);
gbm_device = gbm_create_device(device);
assert(gbm_device != 0);
gbm_surface = gbm_surface_create(gbm_device, mode_info.hdisplay, mode_info.vdisplay, GBM_FORMAT_XRGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
assert(gbm_surface != NULL);
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;
}Another wrong thing is the reported modes list - using the vc4-fkms-v3d there are 1920x1200 (the resolution of the connected display) and 1600x1200 modes additionally to the 21 similar (with the vc4-kms-v3d) lower resolution modes.
Does anybody have any ideas?
Here is the output of some command (do not know if it will be usefull)
Code: Select all
ls /dev/dri
by-path card0 renderD128
Code: Select all
uname -a
Linux raspberrypi 4.19.102-v7+ #1295 SMP Thu Feb 6 15:43:59 GMT 2020 armv7l GNU/Linux
Code: Select all
vcgencmd version
Feb 12 2020 12:38:08
Copyright (c) 2012 Broadcom
version 53a54c770c493957d99bf49762dfabc4eee00e45 (clean) (release) (start)
Oleg