On Sun, May 30, 2010 at 6:35 AM, Chia-I Wu <[email protected]> wrote:
> But it is less flexible IMHO.  Also, I am not convinced that EGLImageKHR to be
> queryable, which is stemmed from using EGLImageKHR to represent pipe_resource.
> Using an EGLImageKHR also implies that an implementation must implement
> EGLImage in EGL/GLES/VG, where the latter seems to still miss a way to render
> into an EGLImage.  Therefore, my idea is to use pbuffer to represent
> pipe_resource.  This is in line with eglCreatePbufferFromClientBuffer.  To be
> precise,
>
>  * use EGLSurface to represent the pipe_resource
>  * Use attrib_list of eglCreatePbufferSurface to describe the resource
>    template (same tokens as defined by EGL_MESA_image_system_use).  Use
>    EGLConfig to describe the pipe_format.
>  * use eglQuerySuface to query the pipe_resource.  Borrow the tokens from
>    glGetFramebufferAttachmentParameteriv in GL 3.0 to query the exact pixel
>    format
>
> And for EGL_MESA_drm_image substitute,
>
>  * use eglCreatePbufferFromClientBuffer to create a pipe_resource from a
>    winsys_handle.  Describe the winsys_handle using the attrib_list.
>    (Or personally, I prefer to add eglCreatePbufferFromBO)
>  * use eglQuerySurface again to query the pipe_resource.
>
> This allows the DRM BO to be drawn without using FBO (OpenVG!), provides more
> flexibility in describing the pixel format, and remove the dependency on
> EGLImage.  Another extension similar to EGL_KHR_image_pixmap may be added to
> support creation of an EGLImageKHR from a pbuffer.  All color/depth buffer
> issues are resolved as they are in eglCreatePbufferFromClientBuffer or
> EGL_KHR_image_pixmap.
This patch series demonstrates the said functions.  It adds "system pbuffer"
that can be queried for the BO handle.  A system pbuffer can also be created
from a BO handle using eglCreatePbufferFromClientBuffer, and can be used to
create an EGLImageKHR.

The last patch is a modified version of Krisitian's eglkms demo.

 include/EGL/eglext.h                                  |   26 ++++++++++
 src/egl/main/egldisplay.h                             |    3 +
 src/egl/main/eglmisc.c                                |    3 +
 src/egl/main/eglsurface.c                             |   25 ++++++++++
 src/egl/main/eglsurface.h                             |    7 ++
 src/gallium/state_trackers/egl/common/egl_g3d.c       |    7 ++
 src/gallium/state_trackers/egl/common/egl_g3d.h       |    1
 src/gallium/state_trackers/egl/common/egl_g3d_api.c   |   16 ++++++
 src/gallium/state_trackers/egl/common/egl_g3d_image.c |   17 ++++++
 src/gallium/state_trackers/egl/common/egl_g3d_st.c    |   44 ++++++++++++++++--
 10 files changed, 146 insertions(+), 3 deletions(-)

-- 
[email protected]
From 18301457500114f5cab3ebf7490e176bc57a4385 Mon Sep 17 00:00:00 2001
From: Chia-I Wu <[email protected]>
Date: Sun, 30 May 2010 07:31:12 +0800
Subject: [PATCH 1/3] egl: Add EGL_MESA_system_pbuffer and EGL_MESA_drm_pbuffer.

---
 include/EGL/eglext.h      |   26 ++++++++++++++++++++++++++
 src/egl/main/egldisplay.h |    3 +++
 src/egl/main/eglmisc.c    |    3 +++
 src/egl/main/eglsurface.c |   25 +++++++++++++++++++++++++
 src/egl/main/eglsurface.h |    7 +++++++
 5 files changed, 64 insertions(+), 0 deletions(-)

diff --git a/include/EGL/eglext.h b/include/EGL/eglext.h
index ce1dca3..d17ecf4 100644
--- a/include/EGL/eglext.h
+++ b/include/EGL/eglext.h
@@ -246,6 +246,32 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGIONNOK) (EGLDisplay dpy, EG
 #endif /* EGL_NOK_texture_from_pixmap */
 
 
+#ifndef EGL_MESA_system_pbuffer
+#define EGL_MESA_system_pbuffer 1
+
+#define EGL_PBUFFER_USES_MESA 0x3200 /* eglCreatePbufferSurface attribute */
+#define EGL_SYSTEM_HANDLE_MESA 0x3201 /* eglQuerySurface attribute */
+#define EGL_SYSTEM_PBUFFER_MESA 0x3202 /* eglCreateImageKHR target */
+
+#define EGL_PBUFFER_SYSTEM_BIT_MESA 0x0001 /* EGL_PBUFFER_USES_MESA bitfield */
+
+#endif /* EGL_MESA_system_pbuffer */
+
+
+#ifndef EGL_MESA_drm_pbuffer
+#define EGL_MESA_drm_pbuffer 1
+
+/* when the buftype is EGL_SYSTEM_HANDLE_MESA, the client buffer is casted from a DRM handle */
+typedef khronos_uint32_t EGLDRMHandleMESA;
+
+#define EGL_DRM_BPP_MESA 0x3203 /* eglQuerySurface attribute */
+#define EGL_DRM_STRIDE_MESA 0x3204 /* eglQuerySurface and eglCreatePbufferFromClientBuffer attribute */
+
+#define EGL_PBUFFER_SCANOUT_BIT_MESA 0x0002 /* EGL_PBUFFER_USES_MESA bitfield */
+
+#endif /* EGL_MESA_drm_pbuffer */
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h
index 42e305f..5c91408 100644
--- a/src/egl/main/egldisplay.h
+++ b/src/egl/main/egldisplay.h
@@ -49,6 +49,9 @@ struct _egl_extensions
    EGLBoolean NOK_swap_region;
    EGLBoolean NOK_texture_from_pixmap;
 
+   EGLBoolean MESA_system_pbuffer;
+   EGLBoolean MESA_drm_pbuffer;
+
    char String[_EGL_MAX_EXTENSIONS_LEN];
 };
 
diff --git a/src/egl/main/eglmisc.c b/src/egl/main/eglmisc.c
index 4652969..1d93677 100644
--- a/src/egl/main/eglmisc.c
+++ b/src/egl/main/eglmisc.c
@@ -98,6 +98,9 @@ _eglUpdateExtensionsString(_EGLDisplay *dpy)
 
    _EGL_CHECK_EXTENSION(NOK_swap_region);
    _EGL_CHECK_EXTENSION(NOK_texture_from_pixmap);
+
+   _EGL_CHECK_EXTENSION(MESA_system_pbuffer);
+   _EGL_CHECK_EXTENSION(MESA_drm_pbuffer);
 #undef _EGL_CHECK_EXTENSION
 }
 
diff --git a/src/egl/main/eglsurface.c b/src/egl/main/eglsurface.c
index d46bdb0..6d896d6 100644
--- a/src/egl/main/eglsurface.c
+++ b/src/egl/main/eglsurface.c
@@ -171,6 +171,15 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
          }
          surf->MipmapTexture = !!val;
          break;
+#ifdef EGL_MESA_system_pbuffer
+      case EGL_PBUFFER_USES_MESA:
+         if (type != EGL_PBUFFER_BIT) {
+            err = EGL_BAD_ATTRIBUTE;
+            break;
+         }
+         surf->PbufferUses = val;
+         break;
+#endif /* EGL_MESA_system_pbuffer */
       /* no pixmap surface specific attributes */
       default:
          err = EGL_BAD_ATTRIBUTE;
@@ -335,6 +344,22 @@ _eglQuerySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
    case EGL_VG_COLORSPACE:
       *value = surface->VGColorspace;
       break;
+#ifdef EGL_MESA_system_pbuffer
+   case EGL_SYSTEM_HANDLE_MESA:
+      if (surface->Type == EGL_PBUFFER_BIT)
+         *value = surface->SystemHandle;
+      break;
+#endif /* EGL_MESA_system_pbuffer */
+#ifdef EGL_MESA_drm_pbuffer
+   case EGL_DRM_BPP_MESA:
+      if (surface->Type == EGL_PBUFFER_BIT)
+         *value = surface->DRMBpp;
+      break;
+   case EGL_DRM_STRIDE_MESA:
+      if (surface->Type == EGL_PBUFFER_BIT)
+         *value = surface->DRMStride;
+      break;
+#endif /* EGL_MESA_drm_pbuffer */
    default:
       _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
       return EGL_FALSE;
diff --git a/src/egl/main/eglsurface.h b/src/egl/main/eglsurface.h
index 8f520dc..d81be3b 100644
--- a/src/egl/main/eglsurface.h
+++ b/src/egl/main/eglsurface.h
@@ -31,6 +31,13 @@ struct _egl_surface
    EGLenum VGAlphaFormat;
    EGLenum VGColorspace;
 
+   /* system pbuffer */
+   EGLint PbufferUses;
+   EGLint SystemHandle;
+   /* DRM pbuffer */
+   EGLint DRMBpp;
+   EGLint DRMStride;
+
    /* attributes set by eglSurfaceAttrib */
    EGLint MipmapLevel;
    EGLenum MultisampleResolve;
-- 
1.7.1

From ce99014546d229d6c1edad9feb04d8c13501fd12 Mon Sep 17 00:00:00 2001
From: Chia-I Wu <[email protected]>
Date: Sun, 30 May 2010 07:53:41 +0800
Subject: [PATCH 2/3] st/egl: Support EGL_MESA_system_pbuffer and EGL_MESA_drm_pbuffer.

---
 src/gallium/state_trackers/egl/common/egl_g3d.c    |    7 +++
 src/gallium/state_trackers/egl/common/egl_g3d.h    |    1 +
 .../state_trackers/egl/common/egl_g3d_api.c        |   16 +++++++
 .../state_trackers/egl/common/egl_g3d_image.c      |   17 ++++++++
 src/gallium/state_trackers/egl/common/egl_g3d_st.c |   44 ++++++++++++++++++-
 5 files changed, 82 insertions(+), 3 deletions(-)

diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c
index 361cc79..4c7eabc 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.c
@@ -510,6 +510,13 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy,
    if (gdpy->native->get_param(gdpy->native, NATIVE_PARAM_USE_NATIVE_BUFFER))
       dpy->Extensions.KHR_image_pixmap = EGL_TRUE;
 
+#ifdef EGL_MESA_system_pbuffer
+   dpy->Extensions.MESA_system_pbuffer = EGL_TRUE;
+#endif
+#ifdef EGL_MESA_drm_pbuffer
+   dpy->Extensions.MESA_drm_pbuffer = EGL_TRUE;
+#endif
+
    if (egl_g3d_add_configs(drv, dpy, 1) == 1) {
       _eglError(EGL_NOT_INITIALIZED, "eglInitialize(unable to add configs)");
       goto fail;
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.h b/src/gallium/state_trackers/egl/common/egl_g3d.h
index d516d8f..c23aef5 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.h
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.h
@@ -77,6 +77,7 @@ struct egl_g3d_surface {
 
    EGLenum client_buffer_type;
    EGLClientBuffer client_buffer;
+   EGLint drm_stride;
 
    unsigned int sequence_number;
 };
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_api.c b/src/gallium/state_trackers/egl/common/egl_g3d_api.c
index 255a1fb..ce4832b 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_api.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_api.c
@@ -331,9 +331,13 @@ egl_g3d_create_pbuffer_from_client_buffer(_EGLDriver *drv, _EGLDisplay *dpy,
    struct pipe_resource *ptex = NULL;
    EGLint pbuffer_attribs[32];
    EGLint count, i;
+   EGLint drm_stride = 0;
 
    switch (buftype) {
    case EGL_OPENVG_IMAGE:
+#ifdef EGL_MESA_drm_pbuffer
+   case EGL_SYSTEM_HANDLE_MESA:
+#endif
       break;
    default:
       _eglError(EGL_BAD_PARAMETER, "eglCreatePbufferFromClientBuffer");
@@ -355,6 +359,17 @@ egl_g3d_create_pbuffer_from_client_buffer(_EGLDriver *drv, _EGLDisplay *dpy,
          pbuffer_attribs[count++] = attr;
          pbuffer_attribs[count++] = val;
          break;
+#ifdef EGL_MESA_system_pbuffer
+      case EGL_PBUFFER_USES_MESA:
+         pbuffer_attribs[count++] = attr;
+         pbuffer_attribs[count++] = val;
+         break;
+#endif
+#ifdef EGL_MESA_drm_pbuffer
+      case EGL_DRM_STRIDE_MESA:
+         drm_stride = val;
+         break;
+#endif
       default:
          err = EGL_BAD_ATTRIBUTE;
          break;
@@ -375,6 +390,7 @@ egl_g3d_create_pbuffer_from_client_buffer(_EGLDriver *drv, _EGLDisplay *dpy,
 
    gsurf->client_buffer_type = buftype;
    gsurf->client_buffer = buffer;
+   gsurf->drm_stride = drm_stride;
 
    if (!gsurf->stfbi->validate(gsurf->stfbi,
             &gsurf->stvis.render_buffer, 1, &ptex)) {
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_image.c b/src/gallium/state_trackers/egl/common/egl_g3d_image.c
index b1fe30a..6020299 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_image.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_image.c
@@ -67,6 +67,17 @@ egl_g3d_reference_native_pixmap(_EGLDisplay *dpy, EGLNativePixmapType pix)
    return textures[natt];
 }
 
+#ifdef EGL_MESA_system_pbuffer
+static struct pipe_resource *
+egl_g3d_reference_system_pbuffer(_EGLDisplay *dpy, EGLSurface surface)
+{
+   _EGLSurface *surf = _eglLookupSurface(surface, dpy);
+   struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
+
+   return (gsurf) ? gsurf->render_texture : NULL;
+}
+#endif /* EGL_MESA_system_pbuffer */
+
 _EGLImage *
 egl_g3d_create_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx,
                      EGLenum target, EGLClientBuffer buffer,
@@ -92,6 +103,12 @@ egl_g3d_create_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx,
       ptex = egl_g3d_reference_native_pixmap(dpy,
             (EGLNativePixmapType) buffer);
       break;
+#ifdef EGL_MESA_system_pbuffer
+   case EGL_SYSTEM_PBUFFER_MESA:
+      ptex = egl_g3d_reference_system_pbuffer(dpy,
+            (EGLSurface) buffer);
+      break;
+#endif
    default:
       ptex = NULL;
       break;
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_st.c b/src/gallium/state_trackers/egl/common/egl_g3d_st.c
index e2217b3..ecf0277 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_st.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_st.c
@@ -295,12 +295,16 @@ pbuffer_reference_openvg_image(struct egl_g3d_surface *gsurf)
    /* TODO */
 }
 
+/* TODO use native.h instead of winsys_handle */
+#include "state_tracker/drm_api.h"
 static void
-pbuffer_allocate_render_texture(struct egl_g3d_surface *gsurf)
+pbuffer_allocate_render_texture(struct egl_g3d_surface *gsurf,
+                                boolean from_handle)
 {
    struct egl_g3d_display *gdpy =
       egl_g3d_display(gsurf->base.Resource.Display);
    struct pipe_screen *screen = gdpy->native->screen;
+   struct winsys_handle whandle;
    struct pipe_resource templ, *ptex;
 
    memset(&templ, 0, sizeof(templ));
@@ -311,8 +315,37 @@ pbuffer_allocate_render_texture(struct egl_g3d_surface *gsurf)
    templ.depth0 = 1;
    templ.format = gsurf->stvis.color_format;
    templ.bind = PIPE_BIND_RENDER_TARGET;
+#ifdef EGL_MESA_system_pbuffer
+   if (gsurf->base.PbufferUses & EGL_PBUFFER_SYSTEM_BIT_MESA)
+      templ.bind |= PIPE_BIND_SHARED;
+#endif
+#ifdef EGL_MESA_drm_pbuffer
+   if (gsurf->base.PbufferUses & EGL_PBUFFER_SCANOUT_BIT_MESA)
+      templ.bind |= PIPE_BIND_SCANOUT;
+#endif
+
+   memset(&whandle, 0, sizeof(whandle));
+   whandle.type = DRM_API_HANDLE_TYPE_SHARED;
+
+   if (from_handle) {
+      whandle.handle =
+         (unsigned) pointer_to_uintptr((void *) gsurf->client_buffer);
+      whandle.stride = gsurf->drm_stride;
+
+      ptex = screen->resource_from_handle(screen, &templ, &whandle);
+   }
+   else {
+      ptex = screen->resource_create(screen, &templ);
+      if (ptex && gsurf->base.PbufferUses)
+         screen->resource_get_handle(screen, ptex, &whandle);
+   }
+
+   if (ptex) {
+      gsurf->base.SystemHandle = whandle.handle;
+      gsurf->base.DRMStride = whandle.stride;
+      gsurf->base.DRMBpp = util_format_get_blocksizebits(ptex->format);
+   }
 
-   ptex = screen->resource_create(screen, &templ);
    gsurf->render_texture = ptex;
 }
 
@@ -335,11 +368,16 @@ egl_g3d_st_framebuffer_validate_pbuffer(struct st_framebuffer_iface *stfbi,
       if (!gsurf->render_texture) {
          switch (gsurf->client_buffer_type) {
          case EGL_NONE:
-            pbuffer_allocate_render_texture(gsurf);
+            pbuffer_allocate_render_texture(gsurf, FALSE);
             break;
          case EGL_OPENVG_IMAGE:
             pbuffer_reference_openvg_image(gsurf);
             break;
+#ifdef EGL_MESA_drm_pbuffer
+         case EGL_SYSTEM_HANDLE_MESA:
+            pbuffer_allocate_render_texture(gsurf, TRUE);
+            break;
+#endif
          default:
             break;
          }
-- 
1.7.1

From 2c96380471b9425a9cb8cd8e07d89a62f456760b Mon Sep 17 00:00:00 2001
From: Chia-I Wu <[email protected]>
Date: Wed, 2 Jun 2010 09:57:35 +0800
Subject: [PATCH 3/3] progs: Add eglkms.

---
 progs/eglkms.c |  221 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 221 insertions(+), 0 deletions(-)
 create mode 100644 progs/eglkms.c

diff --git a/progs/eglkms.c b/progs/eglkms.c
new file mode 100644
index 0000000..86d3971
--- /dev/null
+++ b/progs/eglkms.c
@@ -0,0 +1,221 @@
+/*
+ * Compile with
+ *
+ *   $ gcc -o eglkms eglkms.c -I/usr/include/drm -lEGL -lGL -ldrm
+ */
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <GL/gl.h>
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <drm.h>
+#include <xf86drmMode.h>
+#include <fcntl.h>
+#include <unistd.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;
+   EGLConfig config;
+   EGLContext ctx;
+   EGLint major, minor;
+   const char *ver;
+   EGLint handle, pitch, bpp, count;
+   struct kms kms;
+   int ret, fd;
+   EGLSurface pbuffer;
+
+   EGLint config_attribs[] = {
+      EGL_SURFACE_TYPE,		EGL_PBUFFER_BIT,
+      EGL_RED_SIZE,		1,
+      EGL_GREEN_SIZE,		1,
+      EGL_BLUE_SIZE,		1,
+      EGL_DEPTH_SIZE,		0,
+      EGL_RENDERABLE_TYPE,	EGL_OPENGL_BIT,
+      EGL_NONE
+   };
+
+   EGLint pbuffer_attribs[] = {
+      EGL_WIDTH,		0,
+      EGL_HEIGHT,		0,
+      EGL_PBUFFER_USES_MESA,	EGL_PBUFFER_SYSTEM_BIT_MESA | EGL_PBUFFER_SCANOUT_BIT_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 = eglGetDisplay((EGLNativeDisplayType) 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);
+
+   if (!setup_kms(fd, &kms))
+      return -1;
+
+   if (!eglChooseConfig(dpy, config_attribs, &config, 1, &count) ||
+       count == 0) {
+      fprintf(stderr, "eglChooseConfig() failed\n");
+      return -1;
+   }
+
+   pbuffer_attribs[1] = kms.mode.hdisplay;
+   pbuffer_attribs[3] = kms.mode.vdisplay;
+   pbuffer = eglCreatePbufferSurface(dpy, config, pbuffer_attribs);
+   if (pbuffer == EGL_NO_SURFACE) {
+      fprintf(stderr, "eglCreatePbufferSurface() failed\n");
+      return -1;
+   }
+
+   eglBindAPI(EGL_OPENGL_API);
+   ctx = eglCreateContext(dpy, config, EGL_NO_CONTEXT, NULL);
+
+   eglMakeCurrent(dpy, pbuffer, pbuffer, ctx);
+   render_stuff(kms.mode.hdisplay, kms.mode.vdisplay);
+
+   eglQuerySurface(dpy, pbuffer, EGL_SYSTEM_HANDLE_MESA, &handle);
+   eglQuerySurface(dpy, pbuffer, EGL_DRM_STRIDE_MESA, &pitch);
+   eglQuerySurface(dpy, pbuffer, EGL_DRM_BPP_MESA, &bpp);
+   printf("handle=%d, pitch=%d, bpp=%d\n", handle, pitch, bpp);
+
+   ret = drmModeAddFB(fd,
+		      kms.mode.hdisplay, kms.mode.vdisplay,
+		      bpp, bpp, pitch, 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;
+}
-- 
1.7.1

_______________________________________________
mesa-dev mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to