Last active
April 21, 2023 14:09
-
-
Save JohnnyonFlame/a79d7c0758e0145daf619204c4e20840 to your computer and use it in GitHub Desktop.
eglconfig for owl/rg35xx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stddef.h> | |
#include <string.h> | |
#include <EGL/egl.h> | |
#include <EGL/eglext.h> | |
#include <GLES2/gl2.h> | |
#include <GLES2/gl2ext.h> | |
#include <GLES2/gl2platform.h> | |
#include <sys/ioctl.h> | |
#include <linux/ioctl.h> | |
#include <linux/fb.h> | |
#include <math.h> | |
#include <fcntl.h> | |
#include <unistd.h> | |
#define MAX_MODES 256 | |
#define MAX_CONFIGS 256 | |
struct owlfb_sync_info { | |
__u8 enabled; | |
__u8 disp_id; | |
__u16 reserved2; | |
}; | |
#define OWL_IOW(num, dtype) _IOW('O', num, dtype) | |
#define OWLFB_WAITFORVSYNC OWL_IOW(57,long long) | |
#define OWLFB_VSYNC_EVENT_EN OWL_IOW(67, struct owlfb_sync_info) | |
int main(int argc, char *argv[]) | |
{ | |
int egl_maj, egl_min; | |
EGLContext ctx; | |
EGLSurface surface; | |
EGLConfig configs[MAX_CONFIGS]; | |
EGLint config_count, i; | |
EGLDisplay display; | |
EGLint screen_attribs[] = { | |
EGL_RED_SIZE, 8, | |
EGL_GREEN_SIZE, 8, | |
EGL_BLUE_SIZE, 8, | |
EGL_ALPHA_SIZE, 0, | |
EGL_SURFACE_TYPE, EGL_PIXMAP_BIT | EGL_WINDOW_BIT, | |
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, | |
EGL_NONE | |
}; | |
EGLint window_attribs[] = { | |
EGL_NONE, | |
}; | |
EGLint context_attribs[] = { | |
EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR, | |
EGL_NONE | |
}; | |
EGLint mode[MAX_MODES]; | |
EGLint screen; | |
EGLint count, config_chosen; | |
EGLint width = 0, height = 0; | |
int fbdev_fd = open("/dev/fb0", O_RDWR, 0); | |
if (fbdev_fd < 0) { | |
printf("failed to open /dev/fb0.\n"); | |
return -1; | |
} | |
// Grab the display information | |
struct fb_var_screeninfo vinfo = {}; | |
ioctl(fbdev_fd, FBIOGET_VSCREENINFO, &vinfo); | |
// Setup for double-buffered rendering | |
vinfo.yres_virtual = vinfo.yres * 2; | |
ioctl(fbdev_fd, FBIOPUT_VSCREENINFO, &vinfo); | |
ioctl(fbdev_fd, FBIOGET_VSCREENINFO, &vinfo); | |
printf("Display: %d x %d\n", vinfo.xres, vinfo.yres); | |
printf("Virtual Display: %d x %d\n", vinfo.xres_virtual, vinfo.yres_virtual); | |
// Enable RG35XX vsync | |
struct owlfb_sync_info sinfo; | |
sinfo.enabled = 1; | |
if (ioctl(fbdev_fd, OWLFB_VSYNC_EVENT_EN, &sinfo)) { | |
printf("OWLFB_VSYNC_EVENT_EN failed\n"); | |
} | |
display = eglGetDisplay(EGL_DEFAULT_DISPLAY); | |
if (!eglInitialize(display, &egl_maj, &egl_min)) | |
{ | |
printf("eglgears: eglInitialize failed: 0x%04X\n", eglGetError()); | |
return -1; | |
} | |
printf("EGL version = %d.%d\n", egl_maj, egl_min); | |
printf("EGL_VENDOR = %s\n", eglQueryString(display, EGL_VENDOR)); | |
eglBindAPI(EGL_OPENGL_ES_API); | |
if (eglGetConfigs(display, configs, MAX_CONFIGS, &config_count) == EGL_FALSE) { | |
printf("eglGetConfigs failed: 0x%04X\n", eglGetError()); | |
return 0; | |
} else { | |
printf("eglGetConfigs: %d configs\n", config_count); | |
} | |
if (!eglChooseConfig(display, screen_attribs, configs, MAX_CONFIGS, &config_chosen)) | |
{ | |
printf("eglChooseConfig failed!\n"); | |
return 0; | |
} | |
ctx = eglCreateContext(display, configs[config_chosen], EGL_NO_CONTEXT, context_attribs); | |
if (ctx == EGL_NO_CONTEXT) | |
{ | |
printf("failed to create context: 0x%04X\n", eglGetError()); | |
return 0; | |
} | |
surface = eglCreateWindowSurface(display, configs[config_chosen], 0, window_attribs); | |
if (surface == EGL_NO_SURFACE) { | |
printf("failed to create window surface: 0x%04X\n", eglGetError()); | |
return 0; | |
} | |
eglQuerySurface(display, surface, EGL_WIDTH, &width); | |
eglQuerySurface(display, surface, EGL_HEIGHT, &height); | |
printf("Using screen mode %d x %d.\n", width, height); | |
if (!eglMakeCurrent(display, surface, surface, ctx)) | |
{ | |
printf("make current failed\n"); | |
return 0; | |
} | |
printf("GL_RENDERER = %s\n", (char *)glGetString(GL_RENDERER)); | |
printf("GL_VERSION = %s\n", (char *)glGetString(GL_VERSION)); | |
printf("GL_VENDOR = %s\n", (char *)glGetString(GL_VENDOR)); | |
printf("GL_EXTENSIONS: \n"); | |
const char *exts = glGetString(GL_EXTENSIONS); | |
if (!exts) { | |
printf(" ?\n"); | |
} | |
else { | |
do { | |
const char *end = strchr(exts, ' '); | |
if (end == NULL) { | |
end = exts + strlen(exts); // use end of string if no space is found | |
} | |
printf(" * %.*s\n", (int)(end - exts), exts); | |
exts = (*end == ' ') ? end + 1 : end; // move past space if found, otherwise stay at end of string | |
} while (*exts != '\0'); | |
} | |
long long _arg = 0; | |
for (int i = 0; i < 600; i++) { | |
// Obnoxious pattern to make vsync issues apparent | |
glClearColor(((i % 3) == 0) * 1.f, ((i % 3) == 1) * 1.f, ((i % 3) == 2) * 1.f, 1.0f); | |
glClear(GL_COLOR_BUFFER_BIT); | |
/* necessary for proper VSYNC */ | |
ioctl(fbdev_fd, OWLFB_WAITFORVSYNC, &_arg); | |
eglSwapBuffers(display, surface); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment