Hello everyone
I just flushed my AGX Xavier with Jetpack 5.1.2. First thing I like to point out that after installing eglinfo (mesa-utils-extra) and running it I get core dump.
apex@agx-xavier:$ eglinfo
EGL client extensions string:
EGL_EXT_platform_base EGL_EXT_device_base EGL_EXT_device_enumeration
EGL_EXT_device_query EGL_KHR_client_get_all_proc_addresses
EGL_EXT_client_extensions EGL_KHR_debug EGL_KHR_platform_x11
EGL_EXT_platform_x11 EGL_EXT_platform_device
EGL_MESA_platform_surfaceless EGL_KHR_platform_gbm
EGL_MESA_platform_gbm EGL_KHR_platform_wayland
EGL_EXT_platform_wayland EGL_MESA_platform_xcb
Segmentation fault (core dumped)
Is anyone also getting core dump? There has been no system modifications since installation. Just installing some packages using apt.
Now to my main issue: I am trying to write a simple full screen app in C++.
Please note that I like to run without desktop running. For that reason, I did run:
sudo systemctl set-default multi-user
sudo reboot
Now that I am booted in level 3, I started writing a simple app to do double buffering that initializes EGL and displays background color red., just to keep it simple.
My user was added to video group and rebooted.
sudo usermod -a -G video $USER
sudo reboot
First thing I checked available devices in /dev folder. I see following:
crw-rw---- 1 root video 29, 0 Mar 27 12:54 fb0
crw-rw---- 1 root video 29, 1 Mar 27 12:54 fb1
crw-rw---- 1 root video 29, 2 Mar 27 12:54 fb2
Checking each /dev/fb0 device, I see the following:
cat /sys/class/graphics/fb0/mode
U:1920x1080p-60
cat /sys/class/graphics/fb0/name
tegra_fb
cat /sys/class/graphics/fb0/virtual_size
1920,1080
fb1 and fb2 in /sys/class/graphics/fbX/name shows tegra_fb.
cat /sys/class/graphics/fbX/mode for 1 and 2 is empty.
cat /sys/class/graphics/fbX/virtual_size for 1 and 2 is 4096,2160.
First I did create a simple FB app which is working without EGL. After compiling, executing it filled the screen with green color and finish without any errors.
#include <signal.h>
#include <iostream>
#include <vector>
#include <cstdio>
#include <fcntl.h>
#include <unistd.h>
#include <linux/fb.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <sys/mman.h>
int main(int argc, char* argv[])
{
if(argc < 2) {
std::cout << "ERROR: Missing FB device" << std::endl;
return -1;
}
std::cout << "Initializing " << argv[1] << " ..." << std::endl;
int fb = open(argv[1], O_RDWR);
if (fb == -1) {
perror("Error opening framebuffer device");
return 1;
}
struct fb_var_screeninfo vinfo;
if (ioctl(fb, FBIOGET_VSCREENINFO, &vinfo)) {
perror("Error reading variable screen info");
close(fb);
return 1;
}
int screensize = vinfo.yres_virtual * vinfo.xres_virtual * vinfo.bits_per_pixel / 8;
char* framebuffer = (char*)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fb, 0);
if (framebuffer == MAP_FAILED) {
perror("Error mapping framebuffer to memory");
close(fb);
return 1;
}
// Fill the screen with green
for (int i = 0; i < screensize; i += 4) {
framebuffer[i] = 0; // Blue
framebuffer[i + 1] = 255; // Green
framebuffer[i + 2] = 0; // Red
framebuffer[i + 3] = 0; // Transparency (might not be used)
}
// Cleanup
munmap(framebuffer, screensize);
close(fb);
return 0;
}
Next I did try to modify it and add EGL. Here is my test source.
g++ egl_sample.cpp -o egl_sample -lEGL -lGLESv2
#include <EGL/egl.h>
#include <GLES2/gl2.h>
#include <signal.h>
#include <iostream>
#include <vector>
#include <cstdio>
#include <fcntl.h>
EGLDisplay eglDisplay;
EGLContext eglContext;
EGLSurface eglSurface;
EGLConfig eglConfig;
bool keepRunning(true);
bool initEGL(const std::string& framebufferDevice);
void printInformation();
extern "C" {
void abSigHandler(int sig)
{
std::cout << "Signal: " << sig << " received" << std::endl;
if(sig == SIGINT)
keepRunning = false;
}
}
void printInformation()
{
std::cout << (const char*)glGetString(GL_VENDOR) << std::endl;
std::cout << (const char*)glGetString(GL_RENDERER) << std::endl;
std::cout << (const char*)glGetString(GL_VERSION) << std::endl;
}
bool initEGL() {
// 1. Initialize EGL
eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (eglDisplay == EGL_NO_DISPLAY) {
return false;
}
if (!eglInitialize(eglDisplay, nullptr, nullptr)) {
return false;
}
// 2. Choose an appropriate EGL config
EGLint numConfigs;
EGLint configAttribs[] = {
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
EGL_BLUE_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_RED_SIZE, 8,
EGL_DEPTH_SIZE, 8,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_NONE
};
if (!eglChooseConfig(eglDisplay, configAttribs, &eglConfig, 1, &numConfigs)) {
return false;
}
// 3. Create an EGL context
EGLint contextAttribs[] = {
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
eglContext = eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, contextAttribs);
if (eglContext == EGL_NO_CONTEXT) {
return false;
}
// 4. Create a PBuffer surface
EGLint pbufferAttribs[] = {
EGL_WIDTH, 640,
EGL_HEIGHT, 480,
EGL_NONE
};
eglSurface = eglCreatePbufferSurface(eglDisplay, eglConfig, pbufferAttribs);
if (eglSurface == EGL_NO_SURFACE) {
return false;
}
// 5. Make the context and surface current
if (!eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext)) {
return false;
}
return true;
}
int main() {
if (!initEGL()) {
std::cerr << "Failed to initialize EGL!" << std::endl;
return 1;
}
// Main rendering loop
bool running = true;
while (running) {
// Clear the buffer to green
glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// Swap the front and back buffers
eglSwapBuffers(eglDisplay, eglSurface);
// std::cout << ".";
}
// Cleanup: destroy the EGL objects
eglDestroySurface(eglDisplay, eglSurface);
eglDestroyContext(eglDisplay, eglContext);
eglTerminate(eglDisplay);
return 0;
}
Interesting thing is that is running and no errors. I added a ** std::cout << “.”; ** in the loop which is commented out in above sample, but when uncommented out it prints “…” continuously.
But I do not see anything just my terminal vs. color like I did with above “fb” example.
I did try to modify last example initEGL() to pass /dev/fb0. But I get error running.
bool initEGL(const std::string& framebufferDevice)
{
int fb = open(framebufferDevice.c_str(), O_RDWR);
if (fb == -1)
throw std::runtime_error(std::string("Failed to open ") + framebufferDevice + " device");
// 1. Initialize EGL
eglDisplay = eglGetDisplay((EGLNativeDisplayType)fb);
if (eglDisplay == EGL_NO_DISPLAY) {
close(fb);
throw std::runtime_error("Failed calling eglGetDisplay");
}
if (!eglInitialize(eglDisplay, nullptr, nullptr)) {
close(fb);
throw std::runtime_error("Failed calling eglInitialize");
}
// 2. Choose an appropriate EGL config
EGLint numConfigs;
EGLint configAttribs[] = {
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, // Use PBuffer for off-screen rendering
EGL_BLUE_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_RED_SIZE, 8,
EGL_DEPTH_SIZE, 8,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, // Assuming ES2
EGL_NONE
};
if (!eglChooseConfig(eglDisplay, configAttribs, &eglConfig, 1, &numConfigs)) {
close(fb);
throw std::runtime_error("Failed calling eglChooseConfig");
}
struct fb_var_screeninfo vinfo;
if (ioctl(fb, FBIOGET_VSCREENINFO, &vinfo)) {
close(fb);
throw std::runtime_error("Failed reading variable screen info");
}
EGLint windowAttribs[] = {
EGL_WIDTH, static_cast<EGLint>(vinfo.xres),
EGL_HEIGHT, static_cast<EGLint>(vinfo.yres),
EGL_NONE
};
eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, (EGLNativeWindowType)fb, windowAttribs);
if (eglSurface == EGL_NO_SURFACE) {
close(fb);
throw std::runtime_error("Failed calling eglCreateWindowSurface");
}
// 3. Create an EGL context
EGLint contextAttribs[] = {
EGL_CONTEXT_CLIENT_VERSION, 2, // Assuming ES2
EGL_NONE
};
eglContext = eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, contextAttribs);
if (eglContext == EGL_NO_CONTEXT) {
close(fb);
throw std::runtime_error("Failed calling eglCreateContext");
}
if (!eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext)) {
eglDestroyContext(eglDisplay, eglContext);
eglDestroySurface(eglDisplay, eglSurface);
close(fb);
throw std::runtime_error("Failed calling eglMakeCurrent");
}
// Close the fb device now, EGL maintains its own reference
close(fb);
return true;
}
Anyone knows what I am doing wrong or missing? I do not see /dev/dri on my device eather to use DRI.
There are also other nv devices in /dev like:
/dev/nvhost-as-gpu
/dev/nvhost-ctrl
/dev/nvhost-ctrl-gpu
/dev/nvhost-ctrl-isp
/dev/nvhost-ctrl-nvdec
/dev/nvhost-ctrl-nvdec1
/dev/nvhost-ctrl-nvdla0
/dev/nvhost-ctrl-nvdla1
/dev/nvhost-ctrl-pva0
/dev/nvhost-ctrl-pva1
/dev/nvhost-ctxsw-gpu
/dev/nvhost-dbg-gpu
/dev/nvhost-gpu
/dev/nvhost-isp
/dev/nvhost-isp-thi
/dev/nvhost-msenc
/dev/nvhost-nvcsi
/dev/nvhost-nvdec
/dev/nvhost-nvdec1
/dev/nvhost-nvdla0
/dev/nvhost-nvdla1
/dev/nvhost-nvenc1
/dev/nvhost-nvjpg
/dev/nvhost-nvsched-gpu
/dev/nvhost-power-gpu
/dev/nvhost-prof-ctx-gpu
/dev/nvhost-prof-dev-gpu
/dev/nvhost-prof-gpu
/dev/nvhost-pva0
/dev/nvhost-pva1
/dev/nvhost-sched-gpu
/dev/nvhost-slvs-ec
/dev/nvhost-tsec
/dev/nvhost-tsecb
/dev/nvhost-tsg-gpu
/dev/nvhost-vi
/dev/nvhost-vic
/dev/nvhost-vi-thi
/dev/nvmap
/dev/nvme0
/dev/nvme0n1
/dev/nvsciipc
Should I be using one of them?
Any help is greatly appriciated.