On Mon, Mar 29, 2010 at 1:51 AM, Keith Whitwell
<keith.whitw...@googlemail.com> wrote:
> I've just pushed a variation on a theme a couple of people have
> explored in the past, ie. an interface to gallium without an
> intervening state-tracker.
> The purpose of this is for writing minimal test programs to exercise
> new gallium drivers in isolation from the rest of the codebase.
> In fact it doesn't really make sense to say "without a state tracker",
> unless you don't mind creating test programs which are specific to the
> windowing system you're currently working with.  Some similar work has
> avoided window-system issues altogether by dumping bitmaps to files,
> or using eg. python to abstract over window systems.
> This approach is a little different - I've defined a super-minimal api
> for creating/destroying windows, currently calling this "graw", and we
> have a tiny little co-state-tracker that each implementation provides.
>  This is similar to the glut approach of abstracting over window
> systems, though much less complete.
> It currently consists of three calls:
>   struct pipe_screen *graw_init( void );
>   void *graw_create_window(...);
>   void graw_destroy_window( void *handle );
> which are sufficient to build simple demos on top of.  A future
> enhancement would be to add a glut-style input handling facility.
> Right now there's a single demo, "clear.c" which displays an ugly
> purple box.  Builds so far only with scons, using winsys=graw-xlib.
I happened to be playing with the idea yesterday.  My take is to define an EGL
extension, EGL_MESA_gallium.  The extension defines Gallium as a rendering API
of EGL.  The downside of this approach is that it depends on st/egl.  The
upside is that, it will work on whatever platform st/egl supports.

I've cleaned up my work a little bit.  You can find it in the attachments.
There is a port of "clear" raw demo to use EGL_MESA_gallium.  The demo supports
window resizing, and is accelerated if a hardware EGL driver is used.

The demo renders into a X11 window.  It is worth noting that, when there is no
need to render into an EGLSurface, eglCreateWindowSurface or eglMakeCurrent is
not required.  To interface with X11, I've also borrowed some code from OpenVG
demos and renamed it to EGLUT.

-- 
o...@lunarg.com
From 8b40fe56be030b19281971ac7db0a19625ae734e Mon Sep 17 00:00:00 2001
From: Chia-I Wu <o...@lunarg.com>
Date: Mon, 29 Mar 2010 01:46:16 +0800
Subject: [PATCH 1/4] egl: Export _eglCheckDisplayHandle.

---
 src/egl/main/egldisplay.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h
index 21bf22b..57e7132 100644
--- a/src/egl/main/egldisplay.h
+++ b/src/egl/main/egldisplay.h
@@ -101,7 +101,7 @@ PUBLIC void
 _eglCleanupDisplay(_EGLDisplay *disp);
 
 
-extern EGLBoolean
+PUBLIC EGLBoolean
 _eglCheckDisplayHandle(EGLDisplay dpy);
 
 
-- 
1.7.0

From 636480770965187ce09d8b59a2c6bdec572dd52d Mon Sep 17 00:00:00 2001
From: Chia-I Wu <o...@lunarg.com>
Date: Mon, 29 Mar 2010 00:26:50 +0800
Subject: [PATCH 2/4] egl: Define EGL_MESA_gallium.

---
 include/EGL/eglext.h                               |    8 ++++++++
 src/egl/main/eglconfig.c                           |    3 +++
 src/egl/main/eglcurrent.h                          |    6 ++++++
 src/gallium/include/state_tracker/st_api.h         |    3 +++
 src/gallium/state_trackers/egl/common/egl_g3d.c    |    5 +++++
 src/gallium/state_trackers/egl/common/egl_g3d_st.c |    3 +++
 src/gallium/state_trackers/egl/common/egl_g3d_st.h |    5 +++++
 7 files changed, 33 insertions(+), 0 deletions(-)

diff --git a/include/EGL/eglext.h b/include/EGL/eglext.h
index a9e598d..e797523 100644
--- a/include/EGL/eglext.h
+++ b/include/EGL/eglext.h
@@ -197,6 +197,14 @@ typedef const char * (EGLAPIENTRYP PFNEGLQUERYMODESTRINGMESA) (EGLDisplay dpy, E
 #endif /* EGL_MESA_screen_surface */
 
 
+/* EGL_MESA_gallium extension  >>> PRELIMINARY <<< */
+#ifndef EGL_MESA_gallium
+#define EGL_MESA_gallium 1
+#define EGL_GALLIUM_API_MESA			0x30A3
+#define EGL_GALLIUM_BIT_MESA			0x0010	/* EGL_RENDERABLE_TYPE mask bits */
+#endif /* EGL_MESA_gallium */
+
+
 #ifndef EGL_MESA_copy_context
 #define EGL_MESA_copy_context 1
 
diff --git a/src/egl/main/eglconfig.c b/src/egl/main/eglconfig.c
index 21d13cb..9a4de7e 100644
--- a/src/egl/main/eglconfig.c
+++ b/src/egl/main/eglconfig.c
@@ -332,6 +332,9 @@ _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching)
                    EGL_OPENVG_BIT |
                    EGL_OPENGL_ES2_BIT |
                    EGL_OPENGL_BIT;
+#ifdef EGL_MESA_gallium
+            mask |= EGL_GALLIUM_BIT_MESA;
+#endif
             break;
          default:
             assert(0);
diff --git a/src/egl/main/eglcurrent.h b/src/egl/main/eglcurrent.h
index e5c94ce..5bd11ae 100644
--- a/src/egl/main/eglcurrent.h
+++ b/src/egl/main/eglcurrent.h
@@ -13,7 +13,13 @@
 
 
 #define _EGL_API_FIRST_API EGL_OPENGL_ES_API
+
+#ifdef EGL_MESA_gallium
+#define _EGL_API_LAST_API EGL_GALLIUM_API_MESA
+#else
 #define _EGL_API_LAST_API EGL_OPENGL_API
+#endif
+
 #define _EGL_API_NUM_APIS (_EGL_API_LAST_API - _EGL_API_FIRST_API + 1)
 
 
diff --git a/src/gallium/include/state_tracker/st_api.h b/src/gallium/include/state_tracker/st_api.h
index 70ad215..83cefdf 100644
--- a/src/gallium/include/state_tracker/st_api.h
+++ b/src/gallium/include/state_tracker/st_api.h
@@ -49,6 +49,7 @@
 #define ST_MODULE_OPENGL_ES1_SYMBOL  "st_module_OpenGL_ES1"
 #define ST_MODULE_OPENGL_ES2_SYMBOL  "st_module_OpenGL_ES2"
 #define ST_MODULE_OPENVG_SYMBOL      "st_module_OpenVG"
+#define ST_MODULE_GALLIUM_SYMBOL     "st_module_Gallium"
 
 /**
  * The supported rendering API of a state tracker.
@@ -58,6 +59,7 @@ enum st_api_type {
    ST_API_OPENGL_ES1,
    ST_API_OPENGL_ES2,
    ST_API_OPENVG,
+   ST_API_GALLIUM,
 
    ST_API_COUNT
 };
@@ -403,5 +405,6 @@ extern PUBLIC const struct st_module st_module_OpenGL;
 extern PUBLIC const struct st_module st_module_OpenGL_ES1;
 extern PUBLIC const struct st_module st_module_OpenGL_ES2;
 extern PUBLIC const struct st_module st_module_OpenVG;
+extern PUBLIC const struct st_module st_module_Gallium;
 
 #endif /* _ST_API_H_ */
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c
index 5eabe10..a5a3651 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.c
@@ -70,6 +70,11 @@ egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx)
    case EGL_OPENGL_API:
       idx = ST_API_OPENGL;
       break;
+#ifdef EGL_MESA_gallium
+   case EGL_GALLIUM_API_MESA:
+      idx = ST_API_GALLIUM;
+      break;
+#endif
    default:
       _eglLog(_EGL_WARNING, "unknown client API 0x%04x", ctx->ClientAPI);
       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 3609409..1daa07a 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_st.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_st.c
@@ -65,6 +65,9 @@ egl_g3d_create_st_api(enum st_api_type api)
    case ST_API_OPENVG:
       stmod_name = ST_MODULE_OPENVG_SYMBOL;
       break;
+   case ST_API_GALLIUM:
+      stmod_name = ST_MODULE_GALLIUM_SYMBOL;
+      break;
    default:
       stmod_name = NULL;
       break;
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_st.h b/src/gallium/state_trackers/egl/common/egl_g3d_st.h
index ea8b406..485db68 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_st.h
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_st.h
@@ -68,6 +68,11 @@ egl_g3d_st_api_bit(enum st_api_type api)
    case ST_API_OPENVG:
       bit = EGL_OPENVG_BIT;
       break;
+#ifdef EGL_MESA_gallium
+   case ST_API_GALLIUM:
+      bit = EGL_GALLIUM_BIT_MESA;
+      break;
+#endif
    default:
       bit = 0;
       break;
-- 
1.7.0

From 884d41de8aabefc18e48ef4b28aba996b37991fd Mon Sep 17 00:00:00 2001
From: Chia-I Wu <o...@lunarg.com>
Date: Mon, 29 Mar 2010 00:39:00 +0800
Subject: [PATCH 3/4] gallium: Add libG3D.

---
 src/gallium/include/state_tracker/g3d.h   |   49 ++++++
 src/gallium/targets/g3d-egl/Makefile      |   45 +++++
 src/gallium/targets/g3d-egl/g3d.c         |   92 ++++++++++
 src/gallium/targets/g3d-egl/g3d_manager.c |  260 +++++++++++++++++++++++++++++
 src/gallium/targets/g3d-egl/g3d_manager.h |   56 ++++++
 5 files changed, 502 insertions(+), 0 deletions(-)
 create mode 100644 src/gallium/include/state_tracker/g3d.h
 create mode 100644 src/gallium/targets/g3d-egl/Makefile
 create mode 100644 src/gallium/targets/g3d-egl/g3d.c
 create mode 100644 src/gallium/targets/g3d-egl/g3d_manager.c
 create mode 100644 src/gallium/targets/g3d-egl/g3d_manager.h

diff --git a/src/gallium/include/state_tracker/g3d.h b/src/gallium/include/state_tracker/g3d.h
new file mode 100644
index 0000000..5b0fd54
--- /dev/null
+++ b/src/gallium/include/state_tracker/g3d.h
@@ -0,0 +1,49 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <o...@lunarg.com>
+ */
+
+#ifndef _G3D_H_
+#define _G3D_H_
+
+#include "pipe/p_compiler.h"
+
+#define G3DAPI PUBLIC
+
+struct pipe_context;
+struct pipe_texture;
+struct pipe_fence_handle;
+
+G3DAPI struct pipe_context *
+g3dGetPipeContext(void *manager_display, void *manager_context);
+
+G3DAPI struct pipe_texture *
+g3dValidatePipeTexture(struct pipe_context *pipe);
+
+G3DAPI void
+g3dFlush(struct pipe_context *pipe, unsigned flags,
+         struct pipe_fence_handle **fence);
+
+#endif /* _G3D_H_ */
diff --git a/src/gallium/targets/g3d-egl/Makefile b/src/gallium/targets/g3d-egl/Makefile
new file mode 100644
index 0000000..1b3fa57
--- /dev/null
+++ b/src/gallium/targets/g3d-egl/Makefile
@@ -0,0 +1,45 @@
+TOP = ../../../..
+include $(TOP)/configs/current
+
+LIBNAME = G3D
+
+INCLUDES = \
+	-I$(TOP)/include \
+	-I$(TOP)/src/gallium/include \
+	-I$(TOP)/src/gallium/auxiliary \
+	-I$(TOP)/src/egl/main \
+	-I$(TOP)/src/gallium/state_trackers/egl
+
+C_SOURCES = \
+	g3d_manager.c \
+	g3d.c
+
+TARGET_PATH = $(TOP)/$(LIB_DIR)/gallium
+
+
+OBJECTS = $(C_SOURCES:.c=.o)
+TARGET = $(TARGET_PATH)/lib$(LIBNAME).so
+
+%.o: %.c
+	$(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
+
+
+default: depend $(TARGET)
+
+$(TARGET): $(OBJECTS) Makefile
+	@mkdir -p $(TARGET_PATH)
+	$(MKLIB) -o $(LIBNAME) -install $(TARGET_PATH) $(OBJECTS)
+
+depend: $(C_SOURCES)
+	rm -f depend
+	touch depend
+	$(MKDEP) $(MKDEP_OPTIONS) $(INCLUDES) $(C_SOURCES) 2> /dev/null
+
+clean:
+	rm -f $(OBJECTS) lib$(LIBNAME).a depend depend.bak
+
+# Dummy target
+install:
+	@echo -n ""
+
+sinclude depend
diff --git a/src/gallium/targets/g3d-egl/g3d.c b/src/gallium/targets/g3d-egl/g3d.c
new file mode 100644
index 0000000..2a8fcf3
--- /dev/null
+++ b/src/gallium/targets/g3d-egl/g3d.c
@@ -0,0 +1,92 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <o...@lunarg.com>
+ */
+
+#include "util/u_inlines.h"
+#include "state_tracker/g3d.h"
+
+#include "g3d_manager.h"
+
+/**
+ * The returned pipe_context is valid only until the context is destroyed.
+ */
+struct pipe_context *
+g3dGetPipeContext(void *manager_display, void *manager_context)
+{
+   struct g3d_context *ctx;
+   struct pipe_context *pipe;
+   
+   ctx = g3d_manager_lookup_context(manager_display, manager_context);
+   if (!ctx)
+      return NULL;
+
+   pipe_mutex_lock(ctx->mutex);
+
+   pipe = ctx->pipe;
+
+   pipe_mutex_unlock(ctx->mutex);
+
+   return pipe;
+}
+
+/**
+ * Return the pipe_texture of the binding surface of the context.  The binding
+ * surface and its pipe_texture may change asynchronously and the caller should
+ * call this function periodically, usually at the beginning of a frame.
+ */
+struct pipe_texture *
+g3dValidatePipeTexture(struct pipe_context *pipe)
+{
+   struct g3d_context *ctx = (struct g3d_context *) pipe->priv;
+   struct pipe_texture *ptex = NULL;
+
+   pipe_mutex_lock(ctx->mutex);
+
+   g3d_manager_validate_framebuffer(ctx);
+   pipe_texture_reference(&ptex, ctx->texture);
+
+   pipe_mutex_unlock(ctx->mutex);
+
+   return ptex;
+}
+
+/**
+ * Flush the context.
+ */
+void
+g3dFlush(struct pipe_context *pipe, unsigned flags,
+         struct pipe_fence_handle **fence)
+{
+   struct g3d_context *ctx = (struct g3d_context *) pipe->priv;
+
+   pipe->flush(pipe, flags, fence);
+
+   pipe_mutex_lock(ctx->mutex);
+
+   g3d_manager_flush_framebuffer(ctx);
+
+   pipe_mutex_unlock(ctx->mutex);
+}
diff --git a/src/gallium/targets/g3d-egl/g3d_manager.c b/src/gallium/targets/g3d-egl/g3d_manager.c
new file mode 100644
index 0000000..b77a6a7
--- /dev/null
+++ b/src/gallium/targets/g3d-egl/g3d_manager.c
@@ -0,0 +1,260 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <o...@lunarg.com>
+ */
+
+#include "pipe/p_screen.h"
+#include "pipe/p_context.h"
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+#include "os/os_thread.h"
+#include "state_tracker/st_api.h"
+#include "state_tracker/g3d.h"
+
+#include "g3d_manager.h"
+
+static pipe_tsd g3d_tsd;
+
+/**
+ * Cast and lock a g3d_context.
+ */
+static INLINE struct g3d_context *
+g3d_context_lock(struct st_context_iface *stctxi)
+{
+   struct g3d_context *ctx = (struct g3d_context *) stctxi;
+
+   pipe_mutex_lock(ctx->mutex);
+
+   return ctx;
+}
+
+static void
+g3d_context_notify_invalid_framebuffer(struct st_context_iface *stctxi,
+                                       struct st_framebuffer_iface *stfbi)
+{
+   struct g3d_context *ctx = g3d_context_lock(stctxi);
+
+   assert(ctx->fb == stfbi);
+   pipe_texture_reference(&ctx->texture, NULL);
+
+   pipe_mutex_unlock(ctx->mutex);
+}
+
+static void
+g3d_context_flush(struct st_context_iface *stctxi, unsigned flags,
+                  struct pipe_fence_handle **fence)
+{
+   struct g3d_context *ctx = g3d_context_lock(stctxi);
+
+   ctx->pipe->flush(ctx->pipe, flags, fence);
+
+   if (flags & PIPE_FLUSH_FRAME)
+      g3d_manager_flush_framebuffer(ctx);
+
+   pipe_mutex_unlock(ctx->mutex);
+}
+
+static void
+g3d_context_destroy(struct st_context_iface *stctxi)
+{
+   struct g3d_context *ctx = (struct g3d_context *) stctxi;
+
+   ctx->pipe->destroy(ctx->pipe);
+   FREE(ctx);
+}
+
+static struct st_context_iface *
+g3d_api_create_context(struct st_api *stapi, struct st_manager *smapi,
+                       const struct st_visual *visual,
+                       struct st_context_iface *shared_stctxi)
+{
+   struct g3d_context *ctx;
+   struct pipe_context *pipe;
+
+   ctx = CALLOC_STRUCT(g3d_context);
+   if (!ctx)
+      return NULL;
+
+   pipe = smapi->screen->context_create(smapi->screen, (void *) ctx);
+   if (!pipe) {
+      FREE(ctx);
+      return NULL;
+   }
+
+   ctx->pipe = pipe;
+
+   ctx->iface.destroy = g3d_context_destroy;
+
+   ctx->iface.notify_invalid_framebuffer =
+      g3d_context_notify_invalid_framebuffer;
+   ctx->iface.flush = g3d_context_flush;
+
+   ctx->iface.teximage = NULL;
+   ctx->iface.copy = NULL;
+
+   return &ctx->iface;
+}
+
+static boolean
+g3d_api_make_current(struct st_api *stapi, struct st_context_iface *stctxi,
+                     struct st_framebuffer_iface *stdrawi,
+                     struct st_framebuffer_iface *streadi)
+{
+   struct st_context_iface *target = stctxi;
+   struct g3d_context *ctx;
+   
+   if (!target) {
+      target = (struct st_context_iface *) pipe_tsd_get(&g3d_tsd);
+      if (!target)
+         return TRUE;
+   }
+
+   if (stdrawi != streadi)
+      return FALSE;
+
+   ctx = g3d_context_lock(target);
+
+   /* do nothing but bind the framebuffer */
+   if (ctx->fb != stdrawi) {
+      ctx->fb = stdrawi;
+      pipe_texture_reference(&ctx->texture, NULL);
+   }
+
+   pipe_mutex_unlock(ctx->mutex);
+
+   pipe_tsd_set(&g3d_tsd, (void *) stctxi);
+
+   return TRUE;
+}
+
+static struct st_context_iface *
+g3d_api_get_current(struct st_api *stapi)
+{
+   return (struct st_context_iface *) pipe_tsd_get(&g3d_tsd);
+}
+
+static boolean
+g3d_api_is_visual_supported(struct st_api *stapi,
+                            const struct st_visual *visual)
+{
+   return TRUE;
+}
+
+static st_proc_t
+g3d_api_get_proc_address(struct st_api *stapi, const char *procname)
+{
+   return (st_proc_t) NULL;
+}
+
+static void
+g3d_api_destroy(struct st_api *stapi)
+{
+   free(stapi);
+}
+
+static struct st_api *
+g3d_module_create_api(void)
+{
+   struct st_api *stapi;
+
+   stapi = CALLOC_STRUCT(st_api);
+   if (stapi) {
+      stapi->destroy = g3d_api_destroy;
+      stapi->get_proc_address = g3d_api_get_proc_address;
+      stapi->is_visual_supported = g3d_api_is_visual_supported;
+
+      stapi->create_context = g3d_api_create_context;
+      stapi->make_current = g3d_api_make_current;
+      stapi->get_current = g3d_api_get_current;
+   }
+
+   return stapi;
+}
+
+PUBLIC const struct st_module st_module_Gallium = {
+   .api = ST_API_GALLIUM,
+   .create_api = g3d_module_create_api,
+};
+
+
+/**
+ * Validate the framebuffer of the context.
+ */
+void
+g3d_manager_validate_framebuffer(struct g3d_context *ctx)
+{
+   if (!ctx->texture && ctx->fb) {
+      enum st_attachment_type statt = ctx->fb->visual->render_buffer;
+
+      if (statt != ST_ATTACHMENT_INVALID) {
+         if (!ctx->fb->validate(ctx->fb, &statt, 1, &ctx->texture))
+            ctx->texture = NULL;
+      }
+   }
+}
+
+void
+g3d_manager_flush_framebuffer(struct g3d_context *ctx)
+{
+   if (ctx->fb) {
+      switch (ctx->fb->visual->render_buffer) {
+      case ST_ATTACHMENT_FRONT_LEFT:
+      case ST_ATTACHMENT_FRONT_RIGHT:
+         ctx->fb->flush_front(ctx->fb, ctx->fb->visual->render_buffer);
+         break;
+      default:
+         break;
+      }
+   }
+}
+/**
+ * This is the ugly part of libG3D.  It can be done right by moving this
+ * functionality to st_api.h and chage it to another form.  But for now, let's
+ * assume st/egl is used.
+ */
+#include "util/u_string.h"
+#include "common/egl_g3d.h"
+struct g3d_context *
+g3d_manager_lookup_context(void *manager_display, void *manager_context)
+{
+   _EGLDisplay *dpy = _eglLookupDisplay((EGLDisplay) manager_display);
+   _EGLContext *ctx;
+   struct st_context_iface *stctxi = NULL;
+
+   if (dpy) {
+      _eglLockMutex(&dpy->Mutex);
+
+      /* make sure st/egl is in use */
+      if (dpy->Driver && !util_strncmp(dpy->Driver->Name, "Gallium/", 8))
+         ctx = _eglLookupContext((EGLContext) manager_context, dpy);
+
+      if (ctx)
+         stctxi = egl_g3d_context(ctx)->stctxi;
+
+      _eglUnlockMutex(&dpy->Mutex);
+   }
+
+   return (struct g3d_context *) stctxi;
+}
diff --git a/src/gallium/targets/g3d-egl/g3d_manager.h b/src/gallium/targets/g3d-egl/g3d_manager.h
new file mode 100644
index 0000000..f1c18ed
--- /dev/null
+++ b/src/gallium/targets/g3d-egl/g3d_manager.h
@@ -0,0 +1,56 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <o...@lunarg.com>
+ */
+
+#ifndef _G3D_MANAGER_H_
+#define _G3D_MANAGER_H_
+
+#include "pipe/p_context.h"
+#include "pipe/p_state.h"
+#include "os/os_thread.h"
+
+#include "state_tracker/st_api.h"
+
+struct g3d_context {
+   struct st_context_iface iface;
+
+   pipe_mutex mutex;
+
+   struct pipe_context *pipe;
+   struct st_framebuffer_iface *fb;
+   struct pipe_texture *texture;
+};
+
+void
+g3d_manager_validate_framebuffer(struct g3d_context *ctx);
+
+void
+g3d_manager_flush_framebuffer(struct g3d_context *ctx);
+
+struct g3d_context *
+g3d_manager_lookup_context(void *manager_display, void *manager_context);
+
+#endif /* _G3D_MANAGER_H_ */
-- 
1.7.0

From c7df1d481a31d8c2f4d297228c283c5c412c7080 Mon Sep 17 00:00:00 2001
From: Chia-I Wu <o...@lunarg.com>
Date: Mon, 29 Mar 2010 13:58:58 +0800
Subject: [PATCH 4/4] progs/gallium: Add libG3D demos.

---
 progs/gallium/g3d/Makefile |   37 ++++++
 progs/gallium/g3d/clear.c  |   65 ++++++++++
 progs/gallium/g3d/eglut.c  |  293 ++++++++++++++++++++++++++++++++++++++++++++
 progs/gallium/g3d/eglut.h  |   31 +++++
 4 files changed, 426 insertions(+), 0 deletions(-)
 create mode 100644 progs/gallium/g3d/Makefile
 create mode 100644 progs/gallium/g3d/clear.c
 create mode 100644 progs/gallium/g3d/eglut.c
 create mode 100644 progs/gallium/g3d/eglut.h

diff --git a/progs/gallium/g3d/Makefile b/progs/gallium/g3d/Makefile
new file mode 100644
index 0000000..77b226b
--- /dev/null
+++ b/progs/gallium/g3d/Makefile
@@ -0,0 +1,37 @@
+# progs/gallium/raw/Makefile
+
+TOP = ../../..
+include $(TOP)/configs/current
+
+INCLUDES = \
+	-I. \
+	-I$(TOP)/include \
+	-I$(TOP)/src/gallium/include \
+	-I$(TOP)/src/gallium/auxiliary
+
+SOURCES = \
+	clear.c
+
+OBJECTS = $(SOURCES:.c=.o)
+
+EGLUT_OBJECTS = eglut.o
+EGLUT_LIBS =  -lEGL -lX11 -L$(TOP)/$(LIB_DIR)/gallium -Wl,-rpath,$(TOP)/$(LIB_DIR)/gallium -lG3D
+
+PROGS = $(OBJECTS:.o=)
+
+##### TARGETS #####
+
+default: $(PROGS)
+
+clean:
+	-rm -f $(PROGS)
+	-rm -f *.o
+	-rm -f result.bmp
+
+##### RULES #####
+
+$(OBJECTS) $(EGLUT_OBJECTS): %.o: %.c
+	$(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $(PROG_DEFINES) $< -o $@
+
+$(PROGS): %: %.o $(EGLUT_OBJECTS)
+	$(CC) $(LDFLAGS) $< $(EGLUT_OBJECTS) $(LINKS) $(EGLUT_LIBS) -lm -o $@
diff --git a/progs/gallium/g3d/clear.c b/progs/gallium/g3d/clear.c
new file mode 100644
index 0000000..62cee12
--- /dev/null
+++ b/progs/gallium/g3d/clear.c
@@ -0,0 +1,65 @@
+/* Display a cleared blue window.  This demo has no dependencies on
+ * any utility code, just the graw interface and gallium.
+ */
+
+#include "pipe/p_screen.h"
+#include "pipe/p_context.h"
+#include "pipe/p_state.h"
+#include "pipe/p_defines.h"
+
+#include "eglut.h"
+
+static const int WIDTH = 300;
+static const int HEIGHT = 300;
+
+static void
+init(void)
+{
+}
+
+/* new window size or exposure */
+static void
+reshape(int w, int h)
+{
+   struct pipe_context *pipe;
+   struct pipe_texture *tex;
+   struct pipe_surface *surf;
+   struct pipe_framebuffer_state fb;
+
+   pipe = get_pipe_context();
+   tex = get_display_texture(pipe);
+
+   surf = pipe->screen->get_tex_surface(pipe->screen, tex, 0, 0, 0,
+                                  PIPE_TEXTURE_USAGE_RENDER_TARGET |
+                                  PIPE_TEXTURE_USAGE_DISPLAY_TARGET);
+   if (surf == NULL)
+      exit(5);
+
+   memset(&fb, 0, sizeof fb);
+   fb.nr_cbufs = 1;
+   fb.width = w;
+   fb.height = h;
+   fb.cbufs[0] = surf;
+
+   pipe->set_framebuffer_state(pipe, &fb);
+
+   put_display_texture(pipe, tex);
+}
+
+static void
+draw(void)
+{
+   struct pipe_context *pipe;
+   float clear_color[4] = {1,0,1,1};
+
+   pipe = get_pipe_context();
+
+   pipe->clear(pipe, PIPE_CLEAR_COLOR, clear_color, 0, 0);
+}
+
+int main( int argc, char *argv[] )
+{
+   set_window_size(WIDTH, HEIGHT);
+   return run(argc, argv, init, reshape,
+         draw, 0);
+}
diff --git a/progs/gallium/g3d/eglut.c b/progs/gallium/g3d/eglut.c
new file mode 100644
index 0000000..5f0c710
--- /dev/null
+++ b/progs/gallium/g3d/eglut.c
@@ -0,0 +1,293 @@
+#include "eglut.h"
+
+#include "state_tracker/g3d.h"
+#include "util/u_inlines.h" /* for pipe_texture_reference */
+
+#include <assert.h>
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/keysym.h>
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+
+static init_func    init = 0;
+static draw_func    draw = 0;
+static reshape_func reshape = 0;
+static key_func     keyPress = 0;
+static EGLint width = 300, height = 300;
+
+
+void set_window_size(int w, int h)
+{
+   width = w;
+   height = h;
+}
+
+/*
+ * Create an RGB, double-buffered X window.
+ * Return the window and context handles.
+ */
+static void
+make_x_window(Display *x_dpy, EGLDisplay egl_dpy,
+              const char *name,
+              int x, int y, int width, int height,
+              Window *winRet,
+              EGLContext *ctxRet,
+              EGLSurface *surfRet)
+{
+   static const EGLint attribs[] = {
+      EGL_RED_SIZE, 1,
+      EGL_GREEN_SIZE, 1,
+      EGL_BLUE_SIZE, 1,
+      EGL_RENDERABLE_TYPE, EGL_GALLIUM_BIT_MESA,
+      EGL_NONE
+   };
+
+   int scrnum;
+   XSetWindowAttributes attr;
+   unsigned long mask;
+   Window root;
+   Window win;
+   XVisualInfo *visInfo, visTemplate;
+   int num_visuals;
+   EGLContext ctx;
+   EGLConfig config;
+   EGLint num_configs;
+   EGLint vid;
+
+   scrnum = DefaultScreen( x_dpy );
+   root = RootWindow( x_dpy, scrnum );
+
+   if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs) ||
+       !num_configs) {
+      printf("Error: couldn't get an EGL visual config\n");
+      exit(1);
+   }
+
+   assert(config);
+
+   if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) {
+      printf("Error: eglGetConfigAttrib() failed\n");
+      exit(1);
+   }
+
+   /* The X window visual must match the EGL config */
+   visTemplate.visualid = vid;
+   visInfo = XGetVisualInfo(x_dpy, VisualIDMask, &visTemplate, &num_visuals);
+   if (!visInfo) {
+      printf("Error: couldn't get X visual\n");
+      exit(1);
+   }
+
+   /* window attributes */
+   attr.background_pixel = 0;
+   attr.border_pixel = 0;
+   attr.colormap = XCreateColormap( x_dpy, root, visInfo->visual, AllocNone);
+   attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
+   mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
+
+   win = XCreateWindow( x_dpy, root, 0, 0, width, height,
+		        0, visInfo->depth, InputOutput,
+		        visInfo->visual, mask, &attr );
+
+   /* set hints and properties */
+   {
+      XSizeHints sizehints;
+      sizehints.x = x;
+      sizehints.y = y;
+      sizehints.width  = width;
+      sizehints.height = height;
+      sizehints.flags = USSize | USPosition;
+      XSetNormalHints(x_dpy, win, &sizehints);
+      XSetStandardProperties(x_dpy, win, name, name,
+                              None, (char **)NULL, 0, &sizehints);
+   }
+
+   eglBindAPI(EGL_GALLIUM_API_MESA);
+
+   ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, NULL );
+   if (!ctx) {
+      printf("Error: eglCreateContext failed\n");
+      exit(1);
+   }
+
+   *surfRet = eglCreateWindowSurface(egl_dpy, config, win, NULL);
+
+   if (!*surfRet) {
+      printf("Error: eglCreateWindowSurface failed\n");
+      exit(1);
+   }
+
+   XFree(visInfo);
+
+   *winRet = win;
+   *ctxRet = ctx;
+}
+
+static void
+event_loop(Display *dpy, Window win,
+           EGLDisplay egl_dpy, EGLSurface egl_surf)
+{
+   while (1) {
+      int redraw = 0;
+      XEvent event;
+
+      XNextEvent(dpy, &event);
+
+      switch (event.type) {
+      case Expose:
+         redraw = 1;
+         break;
+      case ConfigureNotify:
+         if (reshape) {
+            width = event.xconfigure.width;
+            height = event.xconfigure.height;
+            reshape(event.xconfigure.width, event.xconfigure.height);
+         }
+         break;
+      case KeyPress:
+      {
+         char buffer[10];
+         int r, code;
+         code = XLookupKeysym(&event.xkey, 0);
+         if (!keyPress || !keyPress(code)) {
+            r = XLookupString(&event.xkey, buffer, sizeof(buffer),
+                              NULL, NULL);
+            if (buffer[0] == 27) {
+               /* escape */
+               return;
+            }
+         }
+      }
+      redraw = 1;
+      break;
+      default:
+         ; /*no-op*/
+      }
+
+      if (redraw) {
+         draw();
+         eglSwapBuffers(egl_dpy, egl_surf);
+      }
+   }
+}
+
+int window_width(void)
+{
+   return width;
+}
+
+int window_height(void)
+{
+   return height;
+}
+
+int run(int argc, char **argv,
+        init_func init_f,
+        reshape_func resh_f,
+        draw_func draw_f,
+        key_func key_f)
+{
+   const int winWidth = width, winHeight = height;
+   Display *x_dpy;
+   Window win;
+   EGLSurface egl_surf;
+   EGLContext egl_ctx;
+   EGLDisplay egl_dpy;
+   char *dpyName = NULL;
+   EGLint egl_major, egl_minor;
+   int i;
+   const char *s;
+
+   init = init_f;
+   draw = draw_f;
+   reshape = resh_f;
+   keyPress = key_f;
+
+   for (i = 1; i < argc; i++) {
+      if (strcmp(argv[i], "-display") == 0) {
+         dpyName = argv[i+1];
+         i++;
+      }
+   }
+
+   x_dpy = XOpenDisplay(dpyName);
+   if (!x_dpy) {
+      printf("Error: couldn't open display %s\n",
+	     dpyName ? dpyName : getenv("DISPLAY"));
+      return -1;
+   }
+
+   egl_dpy = eglGetDisplay(x_dpy);
+   if (!egl_dpy) {
+      printf("Error: eglGetDisplay() failed\n");
+      return -1;
+   }
+
+   if (!eglInitialize(egl_dpy, &egl_major, &egl_minor)) {
+      printf("Error: eglInitialize() failed\n");
+      return -1;
+   }
+
+   s = eglQueryString(egl_dpy, EGL_VERSION);
+   printf("EGL_VERSION = %s\n", s);
+
+   make_x_window(x_dpy, egl_dpy,
+                 "OpenVG Example", 0, 0, winWidth, winHeight,
+                 &win, &egl_ctx, &egl_surf);
+
+   XMapWindow(x_dpy, win);
+   if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) {
+      printf("Error: eglMakeCurrent() failed\n");
+      return -1;
+   }
+
+   if (init)
+      init();
+
+   /* Set initial projection/viewing transformation.
+    * We can't be sure we'll get a ConfigureNotify event when the window
+    * first appears.
+    */
+   if (reshape)
+      reshape(winWidth, winHeight);
+
+   event_loop(x_dpy, win, egl_dpy, egl_surf);
+
+   eglMakeCurrent(egl_dpy, 0, 0, 0);
+   eglDestroyContext(egl_dpy, egl_ctx);
+   eglDestroySurface(egl_dpy, egl_surf);
+   eglTerminate(egl_dpy);
+
+
+   XDestroyWindow(x_dpy, win);
+   XCloseDisplay(x_dpy);
+
+   return 0;
+}
+
+struct pipe_context *
+get_pipe_context(void)
+{
+   EGLDisplay dpy = eglGetCurrentDisplay();
+   EGLContext ctx = eglGetCurrentContext();
+
+   return g3dGetPipeContext((void *) dpy, (void *) ctx);
+}
+
+struct pipe_texture *
+get_display_texture(struct pipe_context *ctx)
+{
+   return g3dValidatePipeTexture(ctx);
+}
+
+void
+put_display_texture(struct pipe_context *ctx, struct pipe_texture *ptex)
+{
+   pipe_texture_reference(&ptex, NULL);
+}
diff --git a/progs/gallium/g3d/eglut.h b/progs/gallium/g3d/eglut.h
new file mode 100644
index 0000000..b103987
--- /dev/null
+++ b/progs/gallium/g3d/eglut.h
@@ -0,0 +1,31 @@
+#ifndef EGLCOMMON_H
+#define EGLCOMMON_H
+
+typedef void (*init_func)();
+typedef void (*reshape_func)(int, int);
+typedef void (*draw_func)();
+typedef int  (*key_func)(unsigned key);
+
+struct pipe_context;
+struct pipe_texture;
+
+void set_window_size(int width, int height);
+int window_width(void);
+int window_height(void);
+
+int run(int argc, char **argv,
+        init_func init,
+        reshape_func resh,
+        draw_func draw,
+        key_func key);
+
+struct pipe_context *
+get_pipe_context(void);
+
+struct pipe_texture *
+get_display_texture(struct pipe_context *ctx);
+
+void
+put_display_texture(struct pipe_context *ctx, struct pipe_texture *ptex);
+
+#endif
-- 
1.7.0

------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Mesa3d-dev mailing list
Mesa3d-dev@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mesa3d-dev

Reply via email to