Demos (master): egl: Add eglkms demo
Kristian Høgsberg
krh at kemper.freedesktop.org
Mon Jan 10 14:47:51 UTC 2011
Module: Demos
Branch: master
Commit: 5ed40f47466aad8fd21889cb905ab429d111b086
URL: http://cgit.freedesktop.org/mesa/demos/commit/?id=5ed40f47466aad8fd21889cb905ab429d111b086
Author: Kristian Høgsberg <krh at bitplanet.net>
Date: Thu May 27 21:37:15 2010 -0400
egl: Add eglkms demo
---
src/egl/opengl/eglkms.c | 237 +++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 237 insertions(+), 0 deletions(-)
diff --git a/src/egl/opengl/eglkms.c b/src/egl/opengl/eglkms.c
new file mode 100644
index 0000000..4e398b7
--- /dev/null
+++ b/src/egl/opengl/eglkms.c
@@ -0,0 +1,237 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#define EGL_EGLEXT_PROTOTYPES
+#define GL_GLEXT_PROTOTYPES
+
+#include <GL/gl.h>
+#include <GL/glext.h>
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <drm.h>
+#include <xf86drmMode.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+
+struct kms {
+ drmModeConnector *connector;
+ drmModeEncoder *encoder;
+ drmModeModeInfo mode;
+ uint32_t fb_id;
+};
+
+static EGLBoolean
+setup_kms(int fd, struct kms *kms)
+{
+ drmModeRes *resources;
+ drmModeConnector *connector;
+ drmModeEncoder *encoder;
+ int i;
+
+ resources = drmModeGetResources(fd);
+ if (!resources) {
+ fprintf(stderr, "drmModeGetResources failed\n");
+ return EGL_FALSE;
+ }
+
+ for (i = 0; i < resources->count_connectors; i++) {
+ connector = drmModeGetConnector(fd, resources->connectors[i]);
+ if (connector == NULL)
+ continue;
+
+ if (connector->connection == DRM_MODE_CONNECTED &&
+ connector->count_modes > 0)
+ break;
+
+ drmModeFreeConnector(connector);
+ }
+
+ if (i == resources->count_connectors) {
+ fprintf(stderr, "No currently active connector found.\n");
+ return EGL_FALSE;
+ }
+
+ for (i = 0; i < resources->count_encoders; i++) {
+ encoder = drmModeGetEncoder(fd, resources->encoders[i]);
+
+ if (encoder == NULL)
+ continue;
+
+ if (encoder->encoder_id == connector->encoder_id)
+ break;
+
+ drmModeFreeEncoder(encoder);
+ }
+
+ kms->connector = connector;
+ kms->encoder = encoder;
+ kms->mode = connector->modes[0];
+
+ return EGL_TRUE;
+}
+
+static void
+render_stuff(int width, int height)
+{
+ GLfloat view_rotx = 0.0, view_roty = 0.0, view_rotz = 0.0;
+ static const GLfloat verts[3][2] = {
+ { -1, -1 },
+ { 1, -1 },
+ { 0, 1 }
+ };
+ static const GLfloat colors[3][3] = {
+ { 1, 0, 0 },
+ { 0, 1, 0 },
+ { 0, 0, 1 }
+ };
+ GLfloat ar = (GLfloat) width / (GLfloat) height;
+
+ glViewport(0, 0, (GLint) width, (GLint) height);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(-ar, ar, -1, 1, 5.0, 60.0);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0.0, 0.0, -10.0);
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glClearColor(0.4, 0.4, 0.4, 0.0);
+
+ glPushMatrix();
+ glRotatef(view_rotx, 1, 0, 0);
+ glRotatef(view_roty, 0, 1, 0);
+ glRotatef(view_rotz, 0, 0, 1);
+
+ glVertexPointer(2, GL_FLOAT, 0, verts);
+ glColorPointer(3, GL_FLOAT, 0, colors);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_COLOR_ARRAY);
+
+ glDrawArrays(GL_TRIANGLES, 0, 3);
+
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
+
+ glPopMatrix();
+
+ glFinish();
+}
+
+static const char device_name[] = "/dev/dri/card0";
+
+int main(int argc, char *argv[])
+{
+ EGLDisplay dpy;
+ EGLContext ctx;
+ EGLImageKHR image;
+ EGLint major, minor;
+ const char *ver, *extensions;
+ GLuint fb, color_rb, depth_rb;
+ EGLint handle, stride;
+ struct kms kms;
+ int ret, fd;
+
+ EGLint image_attribs[] = {
+ EGL_WIDTH, 0,
+ EGL_HEIGHT, 0,
+ EGL_DRM_BUFFER_FORMAT_MESA, EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
+ EGL_DRM_BUFFER_USE_MESA, EGL_DRM_BUFFER_USE_SCANOUT_MESA,
+ EGL_NONE
+ };
+
+ fd = open(device_name, O_RDWR);
+ if (fd < 0) {
+ /* Probably permissions error */
+ fprintf(stderr, "couldn't open %s, skipping\n", device_name);
+ return -1;
+ }
+
+ dpy = eglGetDRMDisplayMESA(fd);
+ if (dpy == EGL_NO_DISPLAY) {
+ fprintf(stderr, "eglGetDisplay() failed\n");
+ return -1;
+ }
+
+ if (!eglInitialize(dpy, &major, &minor)) {
+ printf("eglInitialize() failed\n");
+ return -1;
+ }
+
+ ver = eglQueryString(dpy, EGL_VERSION);
+ printf("EGL_VERSION = %s\n", ver);
+
+ extensions = eglQueryString(dpy, EGL_EXTENSIONS);
+ printf("EGL_EXTENSIONS: %s\n", extensions);
+
+ if (!strstr(extensions, "EGL_KHR_surfaceless_opengl")) {
+ printf("No support for EGL_KHR_surfaceless_opengl\n");
+ return -1;
+ }
+
+ if (!setup_kms(fd, &kms))
+ return -1;
+
+ eglBindAPI(EGL_OPENGL_API);
+ ctx = eglCreateContext(dpy, NULL, EGL_NO_CONTEXT, NULL);
+
+ eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, ctx);
+
+ glGenFramebuffers(1, &fb);
+ glBindFramebuffer(GL_FRAMEBUFFER_EXT, fb);
+
+ image_attribs[1] = kms.mode.hdisplay;
+ image_attribs[3] = kms.mode.vdisplay;
+ image = eglCreateDRMImageMESA (dpy, image_attribs);
+
+ eglExportDRMImageMESA(dpy, image, NULL, &handle, &stride);
+
+ glGenRenderbuffers(1, &color_rb);
+ glBindRenderbuffer(GL_RENDERBUFFER_EXT, color_rb);
+ glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, image);
+ glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
+ GL_COLOR_ATTACHMENT0_EXT,
+ GL_RENDERBUFFER_EXT,
+ color_rb);
+
+ glGenRenderbuffers(1, &depth_rb);
+ glBindRenderbuffer(GL_RENDERBUFFER_EXT, depth_rb);
+ glRenderbufferStorage(GL_RENDERBUFFER_EXT,
+ GL_DEPTH_COMPONENT,
+ kms.mode.hdisplay, kms.mode.vdisplay);
+ glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
+ GL_DEPTH_ATTACHMENT_EXT,
+ GL_RENDERBUFFER_EXT,
+ depth_rb);
+
+ if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) !=
+ GL_FRAMEBUFFER_COMPLETE) {
+ printf("framebuffer not complete\n");
+ exit(1);
+ }
+
+ render_stuff(kms.mode.hdisplay, kms.mode.vdisplay);
+
+ printf("handle=%d, stride=%d\n", handle, stride);
+
+ ret = drmModeAddFB(fd,
+ kms.mode.hdisplay, kms.mode.vdisplay,
+ 32, 32, stride, handle, &kms.fb_id);
+ if (ret) {
+ fprintf(stderr, "failed to create fb\n");
+ return -1;
+ }
+
+ ret = drmModeSetCrtc(fd, kms.encoder->crtc_id, kms.fb_id, 0, 0,
+ &kms.connector->connector_id, 1, &kms.mode);
+ if (ret) {
+ fprintf(stderr, "failed to set mode: %m\n");
+ return -1;
+ }
+
+ getchar();
+
+ return 0;
+}
More information about the mesa-commit
mailing list