Module: Demos Branch: master Commit: 5ed40f47466aad8fd21889cb905ab429d111b086 URL: http://cgit.freedesktop.org/mesa/demos/commit/?id=5ed40f47466aad8fd21889cb905ab429d111b086
Author: Kristian Høgsberg <[email protected]> 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; +} _______________________________________________ mesa-commit mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/mesa-commit
