The python gallium state tracker is an excellent debugging tool, but one
drawback I noticed on people around me is that it is quite hard to setup
and use. The only thing that the python state tracker needs to be told
is how to create a pipe_screen/pipe_context for the hardware being
debugged, but that implies quite a lot: code changes, rebuilding the
python module, messing up with PYTHONPATHs, etc.

Attached is a quick hack that enourmously simplifies using the python
state tracker by:

- exporting two functions from the GL driver

    struct pipe_screen * glGetGalliumScreen(void);
    struct pipe_context *glCreateGalliumContext(void);

- resolving and using these functions in runtime from the python module

In pratice, what it does is replace the static linking with dynamic
linking. The patch is for windows, but the same thing can easily be done
for Linux.

I think it is too soon for promising a stable binary interface so I only
enable this on DEBUG builds, as it is meant for development only. But
this extension might be useful for more things in the future.

A good addition would be a function to present a surface to a drawable:

  void wglGalliumPresent(struct pipe_surface *surface, HWND hwnd);

  void glXGalliumPresent(struct pipe_surface *surface, Window win);

Jose
diff --git a/src/gallium/state_trackers/python/st_hardpipe_winsys.c b/src/gallium/state_trackers/python/st_hardpipe_winsys.c
index 8b33c70..326caa2 100644
--- a/src/gallium/state_trackers/python/st_hardpipe_winsys.c
+++ b/src/gallium/state_trackers/python/st_hardpipe_winsys.c
@@ -28,31 +28,103 @@
 
 /**
  * @file
- * Stub for hardware pipe driver support.
+ * Get a hardware accelerated Gallium screen/context from the OpenGL driver.
  */
 
 
 #include "pipe/p_compiler.h"
 
+#ifdef PIPE_OS_WINDOWS
+#include <windows.h>
+#endif
+#include <GL/gl.h>
+
 #include "st_winsys.h"
 
 
+typedef struct pipe_screen * (GLAPIENTRY *PFNGLGETGALLIUMSCREENPROC) (void);
+typedef struct pipe_context * (GLAPIENTRY* PFNGLCREATEGALLIUMCONTEXTPROC) (void);
+
+static PFNGLGETGALLIUMSCREENPROC pfnglGetGalliumScreen = NULL;
+static PFNGLCREATEGALLIUMCONTEXTPROC pfnglCreateGalliumContext = NULL;
+
+
 /* XXX: Force init_gallium symbol to be linked */
 extern void init_gallium(void);
 void (*force_init_gallium_linkage)(void) = &init_gallium;
 
 
+#ifdef PIPE_OS_WINDOWS
+
+static HMODULE hOpenGLDll = NULL;
+
+typedef PROC (GLAPIENTRY * PFNWGLGETPROCADDRESSPROC)(const char * lpszProc);
+
+static PFNWGLGETPROCADDRESSPROC pwglGetProcAddress = NULL;
+
+static INLINE boolean
+st_hardpipe_load(void)
+{
+   if(!hOpenGLDll) {
+      hOpenGLDll = LoadLibraryA("opengl32");
+      if(!hOpenGLDll)
+         return FALSE;
+   }
+
+   if(!pwglGetProcAddress) {
+       pwglGetProcAddress = (PFNWGLGETPROCADDRESSPROC)GetProcAddress(hOpenGLDll, "wglGetProcAddress");
+       if(!pwglGetProcAddress)
+           return FALSE;
+   }
+
+   if(!pfnglGetGalliumScreen) {
+      pfnglGetGalliumScreen = (PFNGLGETGALLIUMSCREENPROC)pwglGetProcAddress("glGetGalliumScreen");
+      if(!pfnglGetGalliumScreen)
+         return FALSE;
+   }
+
+   if(!pfnglCreateGalliumContext) {
+      pfnglCreateGalliumContext = (PFNGLCREATEGALLIUMCONTEXTPROC)pwglGetProcAddress("glCreateGalliumContext");
+      if(!pfnglCreateGalliumContext)
+         return FALSE;
+   }
+
+   return TRUE;
+}
+
+#else
+
+static INLINE boolean
+st_hardpipe_load(void)
+{
+   /* FIXME: do the some on Unices with dlopen. */
+   return FALSE;
+}
+
+#endif
+
+
 static struct pipe_screen *
 st_hardpipe_screen_create(void)
 {
-   return st_softpipe_winsys.screen_create();
+   if(st_hardpipe_load())
+      return pfnglGetGalliumScreen();
+   else
+      return st_softpipe_winsys.screen_create();
 }
 
 
 static struct pipe_context *
 st_hardpipe_context_create(struct pipe_screen *screen)
 {
-   return st_softpipe_winsys.context_create(screen);
+   if(st_hardpipe_load()) {
+      if(screen == pfnglGetGalliumScreen())
+         return pfnglCreateGalliumContext();
+      else
+         return NULL;
+   }
+   else
+      return st_softpipe_winsys.context_create(screen);
 }
 
 
diff --git a/src/gallium/state_trackers/wgl/shared/stw_getprocaddress.c b/src/gallium/state_trackers/wgl/shared/stw_getprocaddress.c
index 54cc038..497dde9 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_getprocaddress.c
+++ b/src/gallium/state_trackers/wgl/shared/stw_getprocaddress.c
@@ -33,7 +33,16 @@
 #include <GL/wglext.h>
 
 #include "glapi/glapi.h"
+#include "pipe/p_screen.h"
 #include "stw_public.h"
+#include "stw_device.h"
+#include "stw_winsys.h"
+
+#ifdef DEBUG
+#include "trace/tr_screen.h"
+#include "trace/tr_context.h"
+#endif
+
 
 struct stw_extension_entry
 {
@@ -63,6 +72,52 @@ static const struct stw_extension_entry stw_extension_entries[] = {
    { NULL, NULL }
 };
 
+
+#ifdef DEBUG
+
+static INLINE struct pipe_screen *
+glGetGalliumScreen(void)
+{
+   return stw_dev ? stw_dev->screen : NULL;
+}
+
+/* XXX: Unify with stw_create_layer_context */
+static INLINE struct pipe_context *
+glCreateGalliumContext(void)
+{
+   struct pipe_screen *screen = NULL;
+   struct pipe_context *pipe = NULL;
+
+   if(!stw_dev)
+      return NULL;
+
+   screen = stw_dev->screen;
+
+#ifdef DEBUG
+   /* Unwrap screen */
+   if(stw_dev->trace_running)
+      screen = trace_screen(screen)->screen;
+#endif
+
+   pipe = stw_dev->stw_winsys->create_context( screen );
+   if (pipe == NULL)
+      goto no_pipe;
+
+#ifdef DEBUG
+   /* Wrap context */
+   if(stw_dev->trace_running)
+      pipe = trace_context_create(stw_dev->screen, pipe);
+#endif
+
+   return pipe;
+
+no_pipe:
+   return NULL;
+}
+
+#endif
+
+
 PROC
 stw_get_proc_address(
    LPCSTR lpszProc )
@@ -74,8 +129,17 @@ stw_get_proc_address(
          if (strcmp( lpszProc, entry->name ) == 0)
             return entry->proc;
 
-   if (lpszProc[0] == 'g' && lpszProc[1] == 'l')
-        return (PROC) _glapi_get_proc_address( lpszProc );
+   if (lpszProc[0] == 'g' && lpszProc[1] == 'l') {
+
+#ifdef DEBUG
+      if (strcmp(lpszProc, "glGetGalliumScreen") == 0)
+         return (PROC) &glGetGalliumScreen;
+      if (strcmp(lpszProc, "glCreateGalliumContext") == 0)
+         return (PROC) &glCreateGalliumContext;
+#endif
+
+      return (PROC) _glapi_get_proc_address( lpszProc );
+   }
 
    return NULL;
 }
------------------------------------------------------------------------------
Enter the BlackBerry Developer Challenge  
This is your chance to win up to $100,000 in prizes! For a limited time, 
vendors submitting new applications to BlackBerry App World(TM) will have
the opportunity to enter the BlackBerry Developer Challenge. See full prize  
details at: http://p.sf.net/sfu/Challenge
_______________________________________________
Mesa3d-dev mailing list
Mesa3d-dev@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mesa3d-dev

Reply via email to