Merge branch 'gallium-drm-driver-drescriptor'

Conflicts:
	src/gallium/state_trackers/egl/x11/native_dri2.c
	src/gallium/state_trackers/egl/x11/native_x11.c
	src/gallium/state_trackers/egl/x11/native_x11.h
	src/gallium/state_trackers/xorg/xorg_driver.c
	src/gallium/winsys/radeon/drm/radeon_drm.c
diff --git a/configure.ac b/configure.ac
index 5cfdd45..0992117 100644
--- a/configure.ac
+++ b/configure.ac
@@ -486,7 +486,7 @@
 dri)
     SRC_DIRS="$SRC_DIRS glx"
     DRIVER_DIRS="dri"
-    GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS sw/xlib sw/dri sw/drm"
+    GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS sw/xlib sw/dri"
     ;;
 osmesa)
     DRIVER_DIRS="osmesa"
diff --git a/src/gallium/auxiliary/target-helpers/inline_debug_helper.h b/src/gallium/auxiliary/target-helpers/inline_debug_helper.h
new file mode 100644
index 0000000..1bc329c
--- /dev/null
+++ b/src/gallium/auxiliary/target-helpers/inline_debug_helper.h
@@ -0,0 +1,36 @@
+
+#ifndef INLINE_DEBUG_HELPER_H
+#define INLINE_DEBUG_HELPER_H
+
+#include "pipe/p_compiler.h"
+#include "util/u_debug.h"
+
+
+/* Helper function to wrap a screen with
+ * one or more debug driver: rbug, trace.
+ */
+
+#ifdef GALLIUM_TRACE
+#include "trace/tr_public.h"
+#endif
+
+#ifdef GALLIUM_RBUG
+#include "rbug/rbug_public.h"
+#endif
+
+static INLINE struct pipe_screen *
+debug_screen_wrap(struct pipe_screen *screen)
+{
+
+#if defined(GALLIUM_RBUG)
+   screen = rbug_screen_create(screen);
+#endif
+
+#if defined(GALLIUM_TRACE)
+   screen = trace_screen_create(screen);
+#endif
+
+   return screen;
+}
+
+#endif
diff --git a/src/gallium/auxiliary/target-helpers/inline_sw_helper.h b/src/gallium/auxiliary/target-helpers/inline_sw_helper.h
new file mode 100644
index 0000000..036c1ee
--- /dev/null
+++ b/src/gallium/auxiliary/target-helpers/inline_sw_helper.h
@@ -0,0 +1,63 @@
+
+#ifndef INLINE_SW_HELPER_H
+#define INLINE_SW_HELPER_H
+
+#include "pipe/p_compiler.h"
+#include "util/u_debug.h"
+#include "state_tracker/sw_winsys.h"
+
+
+/* Helper function to choose and instantiate one of the software rasterizers:
+ * cell, llvmpipe, softpipe.
+ */
+
+#ifdef GALLIUM_SOFTPIPE
+#include "softpipe/sp_public.h"
+#endif
+
+#ifdef GALLIUM_LLVMPIPE
+#include "llvmpipe/lp_public.h"
+#endif
+
+#ifdef GALLIUM_CELL
+#include "cell/ppu/cell_public.h"
+#endif
+
+static INLINE struct pipe_screen *
+sw_screen_create(struct sw_winsys *winsys)
+{
+   const char *default_driver;
+   const char *driver;
+   struct pipe_screen *screen = NULL;
+
+#if defined(GALLIUM_CELL)
+   default_driver = "cell";
+#elif defined(GALLIUM_LLVMPIPE)
+   default_driver = "llvmpipe";
+#elif defined(GALLIUM_SOFTPIPE)
+   default_driver = "softpipe";
+#else
+   default_driver = "";
+#endif
+
+   driver = debug_get_option("GALLIUM_DRIVER", default_driver);
+
+#if defined(GALLIUM_CELL)
+   if (screen == NULL && strcmp(driver, "cell") == 0)
+      screen = cell_create_screen(winsys);
+#endif
+
+#if defined(GALLIUM_LLVMPIPE)
+   if (screen == NULL && strcmp(driver, "llvmpipe") == 0)
+      screen = llvmpipe_create_screen(winsys);
+#endif
+
+#if defined(GALLIUM_SOFTPIPE)
+   if (screen == NULL)
+      screen = softpipe_create_screen(winsys);
+#endif
+
+   return screen;
+}
+
+#endif
diff --git a/src/gallium/auxiliary/target-helpers/inline_wrapper_sw_helper.h b/src/gallium/auxiliary/target-helpers/inline_wrapper_sw_helper.h
new file mode 100644
index 0000000..0b4e740
--- /dev/null
+++ b/src/gallium/auxiliary/target-helpers/inline_wrapper_sw_helper.h
@@ -0,0 +1,34 @@
+
+#ifndef INLINE_WRAPPER_SW_HELPER_H
+#define INLINE_WRAPPER_SW_HELPER_H
+
+#include "target-helpers/inline_sw_helper.h"
+#include "sw/wrapper/wrapper_sw_winsys.h"
+
+/**
+ * Try to wrap a hw screen with a software screen.
+ * On failure will return given screen.
+ */
+static INLINE struct pipe_screen *
+sw_screen_wrap(struct pipe_screen *screen)
+{
+   struct sw_winsys *sws;
+   struct pipe_screen *sw_screen;
+
+   sws = wrapper_sw_winsys_warp_pipe_screen(screen);
+   if (!sws)
+      goto err;
+
+   sw_screen = sw_screen_create(sws);
+   if (sw_screen == screen)
+      goto err_winsys;
+
+   return sw_screen;
+
+err_winsys:
+   sws->destroy(sws);
+err:
+  return screen;
+}
+
+#endif
diff --git a/src/gallium/drivers/galahad/Makefile b/src/gallium/drivers/galahad/Makefile
index 67d0874..e9c4f7e 100644
--- a/src/gallium/drivers/galahad/Makefile
+++ b/src/gallium/drivers/galahad/Makefile
@@ -6,7 +6,6 @@
 C_SOURCES = \
 	glhd_objects.c \
 	glhd_context.c \
-	glhd_screen.c \
-	glhd_drm.c
+	glhd_screen.c
 
 include ../../Makefile.template
diff --git a/src/gallium/drivers/galahad/SConscript b/src/gallium/drivers/galahad/SConscript
index fc668fa..ca6213c 100644
--- a/src/gallium/drivers/galahad/SConscript
+++ b/src/gallium/drivers/galahad/SConscript
@@ -6,7 +6,6 @@
 	target = 'identity',
 	source = [
 		'glhd_context.c',
-		'glhd_drm.c',
 		'glhd_objects.c',
 		'glhd_screen.c',
 	])
diff --git a/src/gallium/drivers/galahad/glhd_drm.c b/src/gallium/drivers/galahad/glhd_drm.c
deleted file mode 100644
index d62f6f4..0000000
--- a/src/gallium/drivers/galahad/glhd_drm.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2009 VMware, Inc.
- * All Rights Reserved.
- *
- * 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, sub license, 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 (including the
- * next paragraph) 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 NON-INFRINGEMENT.
- * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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.
- *
- **************************************************************************/
-
-#include "state_tracker/drm_api.h"
-
-#include "util/u_memory.h"
-#include "glhd_drm.h"
-#include "glhd_screen.h"
-#include "glhd_public.h"
-
-struct galahad_drm_api
-{
-   struct drm_api base;
-
-   struct drm_api *api;
-};
-
-static INLINE struct galahad_drm_api *
-galahad_drm_api(struct drm_api *_api)
-{
-   return (struct galahad_drm_api *)_api;
-}
-
-static struct pipe_screen *
-galahad_drm_create_screen(struct drm_api *_api, int fd)
-{
-   struct galahad_drm_api *glhd_api = galahad_drm_api(_api);
-   struct drm_api *api = glhd_api->api;
-   struct pipe_screen *screen;
-
-   screen = api->create_screen(api, fd);
-
-   return galahad_screen_create(screen);
-}
-
-static void
-galahad_drm_destroy(struct drm_api *_api)
-{
-   struct galahad_drm_api *glhd_api = galahad_drm_api(_api);
-   struct drm_api *api = glhd_api->api;
-   api->destroy(api);
-
-   FREE(glhd_api);
-}
-
-struct drm_api *
-galahad_drm_create(struct drm_api *api)
-{
-   struct galahad_drm_api *glhd_api;
-
-   if (!api)
-      goto error;
-
-   if (!debug_get_option("GALAHAD", FALSE))
-      goto error;
-
-   glhd_api = CALLOC_STRUCT(galahad_drm_api);
-
-   if (!glhd_api)
-      goto error;
-
-   glhd_api->base.name = api->name;
-   glhd_api->base.driver_name = api->driver_name;
-   glhd_api->base.create_screen = galahad_drm_create_screen;
-   glhd_api->base.destroy = galahad_drm_destroy;
-   glhd_api->api = api;
-
-   return &glhd_api->base;
-
-error:
-   return api;
-}
diff --git a/src/gallium/drivers/i915/i915_public.h b/src/gallium/drivers/i915/i915_public.h
new file mode 100644
index 0000000..588654d
--- /dev/null
+++ b/src/gallium/drivers/i915/i915_public.h
@@ -0,0 +1,13 @@
+
+#ifndef I915_PUBLIC_H
+#define I915_PUBLIC_H
+
+struct i915_winsys;
+struct pipe_screen;
+
+/**
+ * Create i915 pipe_screen.
+ */
+struct pipe_screen * i915_screen_create(struct i915_winsys *iws);
+
+#endif
diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c
index 255538e..77345d5 100644
--- a/src/gallium/drivers/i915/i915_screen.c
+++ b/src/gallium/drivers/i915/i915_screen.c
@@ -37,6 +37,7 @@
 #include "i915_surface.h"
 #include "i915_resource.h"
 #include "i915_winsys.h"
+#include "i915_public.h"
 
 
 /*
diff --git a/src/gallium/drivers/i915/i915_winsys.h b/src/gallium/drivers/i915/i915_winsys.h
index 3aba19f..5385e40 100644
--- a/src/gallium/drivers/i915/i915_winsys.h
+++ b/src/gallium/drivers/i915/i915_winsys.h
@@ -222,11 +222,4 @@
    void (*destroy)(struct i915_winsys *iws);
 };
 
-
-/**
- * Create i915 pipe_screen.
- */
-struct pipe_screen *i915_screen_create(struct i915_winsys *iws);
-
-
 #endif
diff --git a/src/gallium/drivers/i965/brw_public.h b/src/gallium/drivers/i965/brw_public.h
new file mode 100644
index 0000000..be2cd6b
--- /dev/null
+++ b/src/gallium/drivers/i965/brw_public.h
@@ -0,0 +1,13 @@
+
+#ifndef BRW_PUBLIC_H
+#define BRW_PUBLIC_H
+
+struct brw_winsys_screen;
+struct pipe_screen;
+
+/**
+ * Create brw AKA i965 pipe_screen.
+ */
+struct pipe_screen * brw_screen_create(struct brw_winsys_screen *bws);
+
+#endif
diff --git a/src/gallium/drivers/i965/brw_screen.c b/src/gallium/drivers/i965/brw_screen.c
index 50a446d..bdfead7 100644
--- a/src/gallium/drivers/i965/brw_screen.c
+++ b/src/gallium/drivers/i965/brw_screen.c
@@ -34,6 +34,7 @@
 #include "brw_context.h"
 #include "brw_screen.h"
 #include "brw_winsys.h"
+#include "brw_public.h"
 #include "brw_debug.h"
 #include "brw_resource.h"
 
@@ -350,7 +351,7 @@
  * Create a new brw_screen object
  */
 struct pipe_screen *
-brw_create_screen(struct brw_winsys_screen *sws, uint pci_id)
+brw_screen_create(struct brw_winsys_screen *sws)
 {
    struct brw_screen *bscreen;
    struct brw_chipset chipset;
@@ -365,9 +366,9 @@
 
    memset(&chipset, 0, sizeof chipset);
 
-   chipset.pci_id = pci_id;
+   chipset.pci_id = sws->pci_id;
 
-   switch (pci_id) {
+   switch (chipset.pci_id) {
    case PCI_CHIP_I965_G:
    case PCI_CHIP_I965_Q:
    case PCI_CHIP_I965_G_1:
@@ -393,7 +394,7 @@
 
    default:
       debug_printf("%s: unknown pci id 0x%x, cannot create screen\n", 
-                   __FUNCTION__, pci_id);
+                   __FUNCTION__, chipset.pci_id);
       return NULL;
    }
 
diff --git a/src/gallium/drivers/i965/brw_winsys.h b/src/gallium/drivers/i965/brw_winsys.h
index f30c7f1..a06f8bb 100644
--- a/src/gallium/drivers/i965/brw_winsys.h
+++ b/src/gallium/drivers/i965/brw_winsys.h
@@ -147,6 +147,7 @@
 
 struct brw_winsys_screen {
 
+   unsigned pci_id;
 
    /**
     * Buffer functions.
@@ -261,12 +262,6 @@
 }
 
 
-/**
- * Create brw pipe_screen.
- */
-struct pipe_screen *brw_create_screen(struct brw_winsys_screen *iws, unsigned pci_id);
-
-
 
 /*************************************************************************
  * Cooperative dumping between winsys and driver.  TODO: make this
diff --git a/src/gallium/drivers/identity/Makefile b/src/gallium/drivers/identity/Makefile
index e32b910..74692d9 100644
--- a/src/gallium/drivers/identity/Makefile
+++ b/src/gallium/drivers/identity/Makefile
@@ -6,7 +6,6 @@
 C_SOURCES = \
 	id_objects.c \
 	id_context.c \
-	id_screen.c \
-	id_drm.c
+	id_screen.c
 
 include ../../Makefile.template
diff --git a/src/gallium/drivers/identity/SConscript b/src/gallium/drivers/identity/SConscript
index 2a68891..b364e0a 100644
--- a/src/gallium/drivers/identity/SConscript
+++ b/src/gallium/drivers/identity/SConscript
@@ -6,7 +6,6 @@
 	target = 'identity',
 	source = [
 		'id_context.c',
-		'id_drm.c',
 		'id_objects.c',
 		'id_screen.c',
 	])
diff --git a/src/gallium/drivers/identity/id_drm.c b/src/gallium/drivers/identity/id_drm.c
deleted file mode 100644
index 15d0151..0000000
--- a/src/gallium/drivers/identity/id_drm.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2009 VMware, Inc.
- * All Rights Reserved.
- *
- * 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, sub license, 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 (including the
- * next paragraph) 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 NON-INFRINGEMENT.
- * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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.
- *
- **************************************************************************/
-
-#include "state_tracker/drm_api.h"
-
-#include "util/u_memory.h"
-#include "id_drm.h"
-#include "id_screen.h"
-#include "id_public.h"
-
-struct identity_drm_api
-{
-   struct drm_api base;
-
-   struct drm_api *api;
-};
-
-static INLINE struct identity_drm_api *
-identity_drm_api(struct drm_api *_api)
-{
-   return (struct identity_drm_api *)_api;
-}
-
-static struct pipe_screen *
-identity_drm_create_screen(struct drm_api *_api, int fd)
-{
-   struct identity_drm_api *id_api = identity_drm_api(_api);
-   struct drm_api *api = id_api->api;
-   struct pipe_screen *screen;
-
-   screen = api->create_screen(api, fd);
-
-   return identity_screen_create(screen);
-}
-
-static void
-identity_drm_destroy(struct drm_api *_api)
-{
-   struct identity_drm_api *id_api = identity_drm_api(_api);
-   struct drm_api *api = id_api->api;
-   api->destroy(api);
-
-   FREE(id_api);
-}
-
-struct drm_api *
-identity_drm_create(struct drm_api *api)
-{
-   struct identity_drm_api *id_api;
-
-   if (!api)
-      goto error;
-
-   id_api = CALLOC_STRUCT(identity_drm_api);
-
-   if (!id_api)
-      goto error;
-
-   id_api->base.name = api->name;
-   id_api->base.driver_name = api->driver_name;
-   id_api->base.create_screen = identity_drm_create_screen;
-   id_api->base.destroy = identity_drm_destroy;
-   id_api->api = api;
-
-   return &id_api->base;
-
-error:
-   return api;
-}
diff --git a/src/gallium/drivers/identity/id_drm.h b/src/gallium/drivers/identity/id_drm.h
deleted file mode 100644
index cf2ad2c..0000000
--- a/src/gallium/drivers/identity/id_drm.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2009 VMware, Inc.
- * All Rights Reserved.
- *
- * 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, sub license, 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 (including the
- * next paragraph) 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 NON-INFRINGEMENT.
- * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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.
- *
- **************************************************************************/
-
-#ifndef ID_DRM_H
-#define ID_DRM_H
-
-struct drm_api;
-
-struct drm_api* identity_drm_create(struct drm_api *api);
-
-#endif /* ID_DRM_H */
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c
index 60bdd72..6fe1eb6 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.c
+++ b/src/gallium/drivers/nouveau/nouveau_screen.c
@@ -15,7 +15,7 @@
 #include "nouveau_screen.h"
 
 /* XXX this should go away */
-#include "state_tracker/drm_api.h"
+#include "state_tracker/drm_driver.h"
 #include "util/u_simple_screen.h"
 
 static const char *
diff --git a/src/gallium/drivers/r300/r300_public.h b/src/gallium/drivers/r300/r300_public.h
new file mode 100644
index 0000000..8e7a963
--- /dev/null
+++ b/src/gallium/drivers/r300/r300_public.h
@@ -0,0 +1,9 @@
+
+#ifndef R300_PUBLIC_H
+#define R300_PUBLIC_H
+
+struct r300_winsys_screen;
+
+struct pipe_screen* r300_screen_create(struct r300_winsys_screen *rws);
+
+#endif
diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
index d3d36a7..5bba559 100644
--- a/src/gallium/drivers/r300/r300_screen.c
+++ b/src/gallium/drivers/r300/r300_screen.c
@@ -30,6 +30,7 @@
 #include "r300_screen_buffer.h"
 #include "r300_state_inlines.h"
 #include "r300_winsys.h"
+#include "r300_public.h"
 
 /* Return the identifier behind whom the brave coders responsible for this
  * amalgamation of code, sweat, and duct tape, routinely obscure their names.
@@ -381,7 +382,7 @@
     return 0; /* 0 == success */
 }
 
-struct pipe_screen* r300_create_screen(struct r300_winsys_screen *rws)
+struct pipe_screen* r300_screen_create(struct r300_winsys_screen *rws)
 {
     struct r300_screen *r300screen = CALLOC_STRUCT(r300_screen);
 
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
index ddb6600..6206570 100644
--- a/src/gallium/drivers/r300/r300_texture.c
+++ b/src/gallium/drivers/r300/r300_texture.c
@@ -36,7 +36,9 @@
 #include "util/u_memory.h"
 
 #include "pipe/p_screen.h"
-#include "state_tracker/drm_api.h"
+
+/* XXX NO! just no! */
+#include "state_tracker/drm_driver.h"
 
 enum r300_dim {
     DIM_WIDTH  = 0,
@@ -1081,6 +1083,7 @@
         return NULL;
     }
 
+    /* XXX make the winsys return the stride_override, see i915_resource_texture.c:830 */
     buffer = rws->buffer_from_handle(rws, whandle->handle);
     if (!buffer) {
         return NULL;
diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h
index 77c1c13..3b5e9ee 100644
--- a/src/gallium/drivers/r300/r300_winsys.h
+++ b/src/gallium/drivers/r300/r300_winsys.h
@@ -162,7 +162,4 @@
 struct r300_winsys_screen *
 r300_winsys_screen(struct pipe_screen *screen);
 
-/* Creates a new r300 screen. */
-struct pipe_screen* r300_create_screen(struct r300_winsys_screen *rws);
-
 #endif /* R300_WINSYS_H */
diff --git a/src/gallium/drivers/r600/r600_buffer.c b/src/gallium/drivers/r600/r600_buffer.c
index 272f4dd..bc6e336 100644
--- a/src/gallium/drivers/r600/r600_buffer.c
+++ b/src/gallium/drivers/r600/r600_buffer.c
@@ -29,7 +29,7 @@
 #include <util/u_math.h>
 #include <util/u_inlines.h>
 #include <util/u_memory.h>
-#include "state_tracker/drm_api.h"
+#include "state_tracker/drm_driver.h"
 #include "r600_screen.h"
 #include "r600_context.h"
 
diff --git a/src/gallium/drivers/r600/r600_public.h b/src/gallium/drivers/r600/r600_public.h
new file mode 100644
index 0000000..1d89c9f
--- /dev/null
+++ b/src/gallium/drivers/r600/r600_public.h
@@ -0,0 +1,9 @@
+
+#ifndef R600_PUBLIC_H
+#define R600_PUBLIC_H
+
+struct radeon;
+
+struct pipe_screen* r600_screen_create(struct radeon *rw);
+
+#endif
diff --git a/src/gallium/drivers/r600/r600_screen.c b/src/gallium/drivers/r600/r600_screen.c
index 1d83383..20758b0 100644
--- a/src/gallium/drivers/r600/r600_screen.c
+++ b/src/gallium/drivers/r600/r600_screen.c
@@ -31,6 +31,7 @@
 #include "r600_screen.h"
 #include "r600_texture.h"
 #include "r600_context.h"
+#include "r600_public.h"
 #include <stdio.h>
 
 static const char* r600_get_vendor(struct pipe_screen* pscreen)
@@ -240,7 +241,7 @@
 	FREE(rscreen);
 }
 
-struct pipe_screen *radeon_create_screen(struct radeon *rw)
+struct pipe_screen *r600_screen_create(struct radeon *rw)
 {
 	struct r600_screen* rscreen;
 
diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c
index 7d94bbe..903cfad 100644
--- a/src/gallium/drivers/r600/r600_texture.c
+++ b/src/gallium/drivers/r600/r600_texture.c
@@ -29,7 +29,7 @@
 #include <util/u_math.h>
 #include <util/u_inlines.h>
 #include <util/u_memory.h>
-#include "state_tracker/drm_api.h"
+#include "state_tracker/drm_driver.h"
 #include "r600_screen.h"
 #include "r600_texture.h"
 
diff --git a/src/gallium/drivers/r600/radeon.h b/src/gallium/drivers/r600/radeon.h
index ec94b11..2a82aad 100644
--- a/src/gallium/drivers/r600/radeon.h
+++ b/src/gallium/drivers/r600/radeon.h
@@ -28,8 +28,6 @@
 
 struct radeon;
 
-struct pipe_screen *radeon_create_screen(struct radeon *rw);
-
 enum radeon_family {
 	CHIP_UNKNOWN,
 	CHIP_R100,
diff --git a/src/gallium/winsys/sw/drm/sw_drm_api.h b/src/gallium/drivers/svga/svga_public.h
similarity index 78%
copy from src/gallium/winsys/sw/drm/sw_drm_api.h
copy to src/gallium/drivers/svga/svga_public.h
index ce90a04..ded2e24 100644
--- a/src/gallium/winsys/sw/drm/sw_drm_api.h
+++ b/src/gallium/drivers/svga/svga_public.h
@@ -23,12 +23,20 @@
  *
  **********************************************************/
 
+/**
+ * @file
+ * VMware SVGA public interface. Used by targets to create a stack.
+ *
+ * @author Jakob Bornecrantz Fonseca <jakob@vmware.com>
+ */
 
-#ifndef SW_DRM_API_H
-#define SW_DRM_API_H
+#ifndef SVGA_PUBLIC_H_
+#define SVGA_PUBLIC_H_
 
-struct drm_api;
+struct pipe_screen;
+struct svga_winsys_screen;
 
-struct drm_api * sw_drm_api_create(struct drm_api *api);
+struct pipe_screen *
+svga_screen_create(struct svga_winsys_screen *sws);
 
-#endif
+#endif /* SVGA_PUBLIC_H_ */
diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c
index 54d9fae..077ff9a 100644
--- a/src/gallium/drivers/svga/svga_screen.c
+++ b/src/gallium/drivers/svga/svga_screen.c
@@ -29,6 +29,7 @@
 #include "util/u_math.h"
 
 #include "svga_winsys.h"
+#include "svga_public.h"
 #include "svga_context.h"
 #include "svga_screen.h"
 #include "svga_resource_texture.h"
diff --git a/src/gallium/drivers/svga/svga_winsys.h b/src/gallium/drivers/svga/svga_winsys.h
index a2dcc84..5e4bdef 100644
--- a/src/gallium/drivers/svga/svga_winsys.h
+++ b/src/gallium/drivers/svga/svga_winsys.h
@@ -288,9 +288,6 @@
 };
 
 
-struct pipe_screen *
-svga_screen_create(struct svga_winsys_screen *sws);
-
 struct svga_winsys_screen *
 svga_winsys_screen(struct pipe_screen *screen);
 
diff --git a/src/gallium/drivers/trace/Makefile b/src/gallium/drivers/trace/Makefile
index 1b0c087..99e5fb8 100644
--- a/src/gallium/drivers/trace/Makefile
+++ b/src/gallium/drivers/trace/Makefile
@@ -8,7 +8,6 @@
 	tr_dump.c \
 	tr_dump_state.c \
 	tr_screen.c \
-	tr_drm.c \
 	tr_texture.c
 
 include ../../Makefile.template
diff --git a/src/gallium/drivers/trace/SConscript b/src/gallium/drivers/trace/SConscript
index 0dc43a9..06b0c48 100644
--- a/src/gallium/drivers/trace/SConscript
+++ b/src/gallium/drivers/trace/SConscript
@@ -6,7 +6,6 @@
     target = 'trace',
     source = [
         'tr_context.c',
-        'tr_drm.c',
         'tr_dump.c',
         'tr_dump_state.c',
         'tr_screen.c',
diff --git a/src/gallium/drivers/trace/tr_drm.c b/src/gallium/drivers/trace/tr_drm.c
deleted file mode 100644
index e685033..0000000
--- a/src/gallium/drivers/trace/tr_drm.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2009 VMware, Inc.
- * All Rights Reserved.
- *
- * 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, sub license, 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 (including the
- * next paragraph) 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 NON-INFRINGEMENT.
- * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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.
- *
- **************************************************************************/
-
-#include "state_tracker/drm_api.h"
-
-#include "util/u_memory.h"
-#include "rbug/rbug_public.h"
-#include "tr_drm.h"
-#include "tr_screen.h"
-#include "tr_public.h"
-
-struct trace_drm_api
-{
-   struct drm_api base;
-
-   struct drm_api *api;
-};
-
-static INLINE struct trace_drm_api *
-trace_drm_api(struct drm_api *_api)
-{
-   return (struct trace_drm_api *)_api;
-}
-
-static struct pipe_screen *
-trace_drm_create_screen(struct drm_api *_api, int fd)
-{
-   struct trace_drm_api *tr_api = trace_drm_api(_api);
-   struct drm_api *api = tr_api->api;
-   struct pipe_screen *screen;
-
-   /* TODO trace call */
-
-   screen = api->create_screen(api, fd);
-
-   return trace_screen_create(rbug_screen_create(screen));
-}
-
-static void
-trace_drm_destroy(struct drm_api *_api)
-{
-   struct trace_drm_api *tr_api = trace_drm_api(_api);
-   struct drm_api *api = tr_api->api;
-
-   if (api->destroy)
-      api->destroy(api);
-
-   FREE(tr_api);
-}
-
-struct drm_api *
-trace_drm_create(struct drm_api *api)
-{
-   struct trace_drm_api *tr_api;
-
-   if (!api)
-      goto error;
-
-   if (!trace_enabled() && !rbug_enabled())
-      goto error;
-
-   tr_api = CALLOC_STRUCT(trace_drm_api);
-
-   if (!tr_api)
-      goto error;
-
-   tr_api->base.name = api->name;
-   tr_api->base.driver_name = api->driver_name;
-   tr_api->base.create_screen = trace_drm_create_screen;
-   tr_api->base.destroy = trace_drm_destroy;
-   tr_api->api = api;
-
-   return &tr_api->base;
-
-error:
-   return api;
-}
diff --git a/src/gallium/drivers/trace/tr_drm.h b/src/gallium/drivers/trace/tr_drm.h
deleted file mode 100644
index 845c66a..0000000
--- a/src/gallium/drivers/trace/tr_drm.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2009 VMware, Inc.
- * All Rights Reserved.
- *
- * 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, sub license, 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 (including the
- * next paragraph) 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 NON-INFRINGEMENT.
- * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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.
- *
- **************************************************************************/
-
-#ifndef TR_DRM_H
-#define TR_DRM_H
-
-struct drm_api;
-
-struct drm_api* trace_drm_create(struct drm_api *api);
-
-#endif /* ID_DRM_H */
diff --git a/src/gallium/include/state_tracker/drm_api.h b/src/gallium/include/state_tracker/drm_api.h
deleted file mode 100644
index 4572c7e..0000000
--- a/src/gallium/include/state_tracker/drm_api.h
+++ /dev/null
@@ -1,57 +0,0 @@
-
-#ifndef _DRM_API_H_
-#define _DRM_API_H_
-
-#include "pipe/p_compiler.h"
-
-struct pipe_screen;
-struct pipe_winsys;
-struct pipe_context;
-struct pipe_resource;
-
-#define DRM_API_HANDLE_TYPE_SHARED 0
-#define DRM_API_HANDLE_TYPE_KMS    1
-
-/**
- * For use with pipe_screen::{texture_from_handle|texture_get_handle}.
- */
-struct winsys_handle
-{
-	/**
-	 * Unused for texture_from_handle, always
-	 * DRM_API_HANDLE_TYPE_SHARED.  Input to texture_get_handle,
-	 * use TEXTURE_USAGE to select handle for kms or ipc.
-	 */
-	unsigned type;
-	/**
-	 * Input to texture_from_handle.
-	 * Output for texture_get_handle.
-	 */
-	unsigned handle;
-	/**
-	 * Input to texture_from_handle.
-	 * Output for texture_get_handle.
-	 */
-	unsigned stride;
-};
-
-struct drm_api
-{
-	void (*destroy)(struct drm_api *api);
-
-        const char *name;
-
-	/**
-	 * Kernel driver name, as accepted by drmOpenByName.
-	 */
-	const char *driver_name;
-
-	/**
-	 * Create a pipe srcreen.
-	 */
-	struct pipe_screen* (*create_screen)(struct drm_api *api, int drm_fd);
-};
-
-extern struct drm_api * drm_api_create(void);
-
-#endif
diff --git a/src/gallium/include/state_tracker/drm_driver.h b/src/gallium/include/state_tracker/drm_driver.h
new file mode 100644
index 0000000..d94c1e6
--- /dev/null
+++ b/src/gallium/include/state_tracker/drm_driver.h
@@ -0,0 +1,71 @@
+
+#ifndef _DRM_DRIVER_H_
+#define _DRM_DRIVER_H_
+
+#include "pipe/p_compiler.h"
+
+struct pipe_screen;
+struct pipe_winsys;
+struct pipe_context;
+struct pipe_resource;
+
+#define DRM_API_HANDLE_TYPE_SHARED 0
+#define DRM_API_HANDLE_TYPE_KMS    1
+
+/**
+ * For use with pipe_screen::{texture_from_handle|texture_get_handle}.
+ */
+struct winsys_handle
+{
+   /**
+    * Unused for texture_from_handle, always
+    * DRM_API_HANDLE_TYPE_SHARED.  Input to texture_get_handle,
+    * use TEXTURE_USAGE to select handle for kms or ipc.
+    */
+   unsigned type;
+   /**
+    * Input to texture_from_handle.
+    * Output for texture_get_handle.
+    */
+   unsigned handle;
+   /**
+    * Input to texture_from_handle.
+    * Output for texture_get_handle.
+    */
+   unsigned stride;
+};
+
+struct drm_driver_descriptor
+{
+   /**
+    * Identifying sufix/prefix of the binary, used by egl.
+    */
+   const char *name;
+
+   /**
+    * Kernel driver name, as accepted by drmOpenByName.
+    */
+   const char *driver_name;
+
+   /**
+    * Create a pipe srcreen.
+    *
+    * This function does any wrapping of the screen.
+    * For example wrapping trace or rbug debugging drivers around it.
+    */
+   struct pipe_screen* (*create_screen)(int drm_fd);
+};
+
+extern struct drm_driver_descriptor driver_descriptor;
+
+/**
+ * Instantiate a drm_driver_descriptor struct.
+ */
+#define DRM_DRIVER_DESCRIPTOR(name_str, driver_name_str, func) \
+struct drm_driver_descriptor driver_descriptor = {             \
+   .name = name_str,                                           \
+   .driver_name = driver_name_str,                             \
+   .create_screen = func,                                      \
+};
+
+#endif
diff --git a/src/gallium/state_trackers/dri/common/dri_screen.h b/src/gallium/state_trackers/dri/common/dri_screen.h
index 9ff925d..087ae8d 100644
--- a/src/gallium/state_trackers/dri/common/dri_screen.h
+++ b/src/gallium/state_trackers/dri/common/dri_screen.h
@@ -39,7 +39,6 @@
 #include "pipe/p_context.h"
 #include "pipe/p_state.h"
 #include "state_tracker/st_api.h"
-#include "state_tracker/drm_api.h"
 
 struct dri_context;
 struct dri_drawable;
@@ -75,7 +74,6 @@
                              enum st_attachment_type statt);
 
    /* gallium */
-   struct drm_api *api;
    boolean d_depth_bits_last;
    boolean sd_depth_bits_last;
    boolean auto_fake_front;
diff --git a/src/gallium/state_trackers/dri/drm/dri2.c b/src/gallium/state_trackers/dri/drm/dri2.c
index f4cc8d7..b3bf21f 100644
--- a/src/gallium/state_trackers/dri/drm/dri2.c
+++ b/src/gallium/state_trackers/dri/drm/dri2.c
@@ -33,7 +33,7 @@
 #include "util/u_inlines.h"
 #include "util/u_format.h"
 #include "util/u_debug.h"
-#include "state_tracker/drm_api.h"
+#include "state_tracker/drm_driver.h"
 
 #include "dri_screen.h"
 #include "dri_context.h"
@@ -508,7 +508,6 @@
    if (!screen)
       return NULL;
 
-   screen->api = drm_api_create();
    screen->sPriv = sPriv;
    screen->fd = sPriv->fd;
    screen->lookup_egl_image = dri2_lookup_egl_image;
@@ -518,7 +517,7 @@
    sPriv->private = (void *)screen;
    sPriv->extensions = dri_screen_extensions;
 
-   pscreen = screen->api->create_screen(screen->api, screen->fd);
+   pscreen = driver_descriptor.create_screen(screen->fd);
    /* dri_init_screen_helper checks pscreen for us */
 
    configs = dri_init_screen_helper(screen, pscreen, 32);
diff --git a/src/gallium/state_trackers/dri/sw/drisw.c b/src/gallium/state_trackers/dri/sw/drisw.c
index dcf6455..23e99aa 100644
--- a/src/gallium/state_trackers/dri/sw/drisw.c
+++ b/src/gallium/state_trackers/dri/sw/drisw.c
@@ -255,7 +255,6 @@
    if (!screen)
       return NULL;
 
-   screen->api = NULL; /* not needed */
    screen->sPriv = sPriv;
    screen->fd = -1;
    screen->allocate_textures = drisw_allocate_textures;
diff --git a/src/gallium/state_trackers/egl/kms/native_kms.c b/src/gallium/state_trackers/egl/kms/native_kms.c
index f90b871..09a08f3 100644
--- a/src/gallium/state_trackers/egl/kms/native_kms.c
+++ b/src/gallium/state_trackers/egl/kms/native_kms.c
@@ -33,6 +33,7 @@
 #include "egllog.h"
 
 #include "native_kms.h"
+#include "state_tracker/drm_driver.h"
 
 static boolean
 kms_surface_validate(struct native_surface *nsurf, uint attachment_mask,
@@ -657,8 +658,6 @@
    if (kdpy->fd >= 0)
       drmClose(kdpy->fd);
 
-   if (kdpy->api && kdpy->api->destroy)
-      kdpy->api->destroy(kdpy->api);
    FREE(kdpy);
 }
 
@@ -674,7 +673,7 @@
    fd = kdpy->fd;
    if (fd >= 0) {
       drmVersionPtr version = drmGetVersion(fd);
-      if (!version || strcmp(version->name, kdpy->api->driver_name)) {
+      if (!version || strcmp(version->name, driver_descriptor.driver_name)) {
          if (version) {
             _eglLog(_EGL_WARNING, "unknown driver name %s", version->name);
             drmFreeVersion(version);
@@ -689,7 +688,7 @@
       drmFreeVersion(version);
    }
    else {
-      fd = drmOpen(kdpy->api->driver_name, NULL);
+      fd = drmOpen(driver_descriptor.driver_name, NULL);
    }
 
    if (fd < 0) {
@@ -704,7 +703,7 @@
    }
 #endif
 
-   kdpy->base.screen = kdpy->api->create_screen(kdpy->api, fd);
+   kdpy->base.screen = driver_descriptor.create_screen(fd);
    if (!kdpy->base.screen) {
       _eglLog(_EGL_WARNING, "failed to create DRM screen");
       drmClose(fd);
@@ -724,8 +723,7 @@
 };
 
 static struct native_display *
-kms_create_display(int fd, struct native_event_handler *event_handler,
-                   struct drm_api *api)
+kms_create_display(int fd, struct native_event_handler *event_handler)
 {
    struct kms_display *kdpy;
 
@@ -734,14 +732,6 @@
       return NULL;
 
    kdpy->event_handler = event_handler;
-
-   kdpy->api = api;
-   if (!kdpy->api) {
-      _eglLog(_EGL_WARNING, "failed to create DRM API");
-      FREE(kdpy);
-      return NULL;
-   }
-
    kdpy->fd = fd;
    if (!kms_display_init_screen(&kdpy->base)) {
       kms_display_destroy(&kdpy->base);
@@ -790,21 +780,13 @@
    return NATIVE_PROBE_UNKNOWN;
 }
 
-/* the api is destroyed with the native display */
-static struct drm_api *drm_api;
-
 const char *
 native_get_name(void)
 {
    static char kms_name[32];
 
-   if (!drm_api)
-      drm_api = drm_api_create();
 
-   if (drm_api)
-      util_snprintf(kms_name, sizeof(kms_name), "KMS/%s", drm_api->name);
-   else
-      util_snprintf(kms_name, sizeof(kms_name), "KMS");
+   util_snprintf(kms_name, sizeof(kms_name), "KMS/%s", driver_descriptor.name);
 
    return kms_name;
 }
@@ -815,15 +797,8 @@
    struct native_display *ndpy = NULL;
    int fd;
 
-   if (!drm_api)
-      drm_api = drm_api_create();
-
-   if (drm_api) {
-      /* well, this makes fd 0 being ignored */
-      fd = (dpy != EGL_DEFAULT_DISPLAY) ?
-         (int) pointer_to_intptr((void *) dpy) : -1;
-      ndpy = kms_create_display(fd, event_handler, drm_api);
-   }
+   fd = (dpy != EGL_DEFAULT_DISPLAY) ? (int) pointer_to_intptr((void *) dpy) : -1;
+   ndpy = kms_create_display(fd, event_handler);
 
    return ndpy;
 }
diff --git a/src/gallium/state_trackers/egl/kms/native_kms.h b/src/gallium/state_trackers/egl/kms/native_kms.h
index d69c8d3..14cf5a6 100644
--- a/src/gallium/state_trackers/egl/kms/native_kms.h
+++ b/src/gallium/state_trackers/egl/kms/native_kms.h
@@ -32,7 +32,6 @@
 #include "pipe/p_compiler.h"
 #include "util/u_format.h"
 #include "pipe/p_state.h"
-#include "state_tracker/drm_api.h"
 
 #include "common/native.h"
 #include "common/native_helper.h"
@@ -53,7 +52,6 @@
    struct native_event_handler *event_handler;
 
    int fd;
-   struct drm_api *api;
    drmModeResPtr resources;
    struct kms_config *config;
 
diff --git a/src/gallium/state_trackers/egl/x11/native_dri2.c b/src/gallium/state_trackers/egl/x11/native_dri2.c
index e90c33b..7464354 100644
--- a/src/gallium/state_trackers/egl/x11/native_dri2.c
+++ b/src/gallium/state_trackers/egl/x11/native_dri2.c
@@ -32,7 +32,7 @@
 #include "pipe/p_screen.h"
 #include "pipe/p_context.h"
 #include "pipe/p_state.h"
-#include "state_tracker/drm_api.h"
+#include "state_tracker/drm_driver.h"
 #include "egllog.h"
 
 #include "native_x11.h"
@@ -50,7 +50,6 @@
 
    struct native_event_handler *event_handler;
 
-   struct drm_api *api;
    struct x11_screen *xscr;
    int xscr_number;
    const char *dri_driver;
@@ -662,8 +661,6 @@
       x11_screen_destroy(dri2dpy->xscr);
    if (dri2dpy->own_dpy)
       XCloseDisplay(dri2dpy->dpy);
-   if (dri2dpy->api && dri2dpy->api->destroy)
-      dri2dpy->api->destroy(dri2dpy->api);
    FREE(dri2dpy);
 }
 
@@ -695,7 +692,7 @@
 dri2_display_init_screen(struct native_display *ndpy)
 {
    struct dri2_display *dri2dpy = dri2_display(ndpy);
-   const char *driver = dri2dpy->api->name;
+   const char *driver = driver_descriptor.name;
    int fd;
 
    if (!x11_screen_support(dri2dpy->xscr, X11_SCREEN_EXTENSION_DRI2) ||
@@ -709,7 +706,7 @@
    if (!dri2dpy->dri_driver || !driver ||
        strcmp(dri2dpy->dri_driver, driver) != 0) {
       _eglLog(_EGL_WARNING, "Driver mismatch: %s != %s",
-            dri2dpy->dri_driver, dri2dpy->api->name);
+            dri2dpy->dri_driver, driver);
       return FALSE;
    }
 
@@ -718,7 +715,7 @@
    if (fd < 0)
       return FALSE;
 
-   dri2dpy->base.screen = dri2dpy->api->create_screen(dri2dpy->api, fd);
+   dri2dpy->base.screen = driver_descriptor.create_screen(fd);
    if (!dri2dpy->base.screen) {
       _eglLog(_EGL_WARNING, "failed to create DRM screen");
       return FALSE;
@@ -742,8 +739,7 @@
 
 struct native_display *
 x11_create_dri2_display(Display *dpy,
-                        struct native_event_handler *event_handler,
-                        struct drm_api *api)
+                        struct native_event_handler *event_handler)
 {
    struct dri2_display *dri2dpy;
 
@@ -752,7 +748,6 @@
       return NULL;
 
    dri2dpy->event_handler = event_handler;
-   dri2dpy->api = api;
 
    dri2dpy->dpy = dpy;
    if (!dri2dpy->dpy) {
diff --git a/src/gallium/state_trackers/egl/x11/native_x11.c b/src/gallium/state_trackers/egl/x11/native_x11.c
index bfa12b2..6f1e599 100644
--- a/src/gallium/state_trackers/egl/x11/native_x11.c
+++ b/src/gallium/state_trackers/egl/x11/native_x11.c
@@ -27,15 +27,14 @@
 #include "util/u_debug.h"
 #include "util/u_memory.h"
 #include "util/u_string.h"
-#include "state_tracker/drm_api.h"
 #include "egllog.h"
 
 #include "native_x11.h"
 #include "x11_screen.h"
 
-#define X11_PROBE_MAGIC 0x11980BE /* "X11PROBE" */
+#include "state_tracker/drm_driver.h"
 
-static struct drm_api *api;
+#define X11_PROBE_MAGIC 0x11980BE /* "X11PROBE" */
 
 static void
 x11_probe_destroy(struct native_probe *nprobe)
@@ -96,15 +95,12 @@
    if (!nprobe || nprobe->magic != X11_PROBE_MAGIC)
       return NATIVE_PROBE_UNKNOWN;
 
-   if (!api)
-      api = drm_api_create();
-
    /* this is a software driver */
-   if (!api)
+   if (!driver_descriptor.create_screen)
       return NATIVE_PROBE_SUPPORTED;
 
    /* the display does not support DRI2 or the driver mismatches */
-   if (!nprobe->data || strcmp(api->name, (const char *) nprobe->data) != 0)
+   if (!nprobe->data || strcmp(driver_descriptor.name, (const char *) nprobe->data) != 0)
       return NATIVE_PROBE_FALLBACK;
 
    return NATIVE_PROBE_EXACT;
@@ -115,13 +111,7 @@
 {
    static char x11_name[32];
 
-   if (!api)
-      api = drm_api_create();
-
-   if (api)
-      util_snprintf(x11_name, sizeof(x11_name), "X11/%s", api->name);
-   else
-      util_snprintf(x11_name, sizeof(x11_name), "X11");
+   util_snprintf(x11_name, sizeof(x11_name), "X11/%s", driver_descriptor.name);
 
    return x11_name;
 }
@@ -132,12 +122,12 @@
    struct native_display *ndpy = NULL;
    boolean force_sw;
 
-   if (!api)
-      api = drm_api_create();
-
    force_sw = debug_get_bool_option("EGL_SOFTWARE", FALSE);
-   if (api && !force_sw) {
-      ndpy = x11_create_dri2_display((Display *) dpy, event_handler, api);
+   if (!driver_descriptor.create_screen)
+      force_sw = TRUE;
+
+   if (!force_sw) {
+      ndpy = x11_create_dri2_display((Display *) dpy, event_handler);
    }
 
    if (!ndpy) {
diff --git a/src/gallium/state_trackers/egl/x11/native_x11.h b/src/gallium/state_trackers/egl/x11/native_x11.h
index f1fea7f..a1c32c3 100644
--- a/src/gallium/state_trackers/egl/x11/native_x11.h
+++ b/src/gallium/state_trackers/egl/x11/native_x11.h
@@ -26,7 +26,6 @@
 #ifndef _NATIVE_X11_H_
 #define _NATIVE_X11_H_
 
-#include "state_tracker/drm_api.h"
 #include "common/native.h"
 
 struct native_display *
@@ -35,7 +34,6 @@
 
 struct native_display *
 x11_create_dri2_display(Display *dpy,
-                        struct native_event_handler *event_handler,
-                        struct drm_api *api);
+                        struct native_event_handler *event_handler);
 
 #endif /* _NATIVE_X11_H_ */
diff --git a/src/gallium/state_trackers/xorg/xorg_crtc.c b/src/gallium/state_trackers/xorg/xorg_crtc.c
index f1a07bd..627754a 100644
--- a/src/gallium/state_trackers/xorg/xorg_crtc.c
+++ b/src/gallium/state_trackers/xorg/xorg_crtc.c
@@ -50,6 +50,7 @@
 #include <X11/extensions/dpms.h>
 #endif
 
+#include "state_tracker/drm_driver.h"
 #include "util/u_inlines.h"
 #include "util/u_rect.h"
 
diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c
index 4e01bd1..704aed6 100644
--- a/src/gallium/state_trackers/xorg/xorg_dri2.c
+++ b/src/gallium/state_trackers/xorg/xorg_dri2.c
@@ -42,6 +42,8 @@
 
 #include "util/u_format.h"
 
+#include "state_tracker/drm_driver.h"
+
 /* Make all the #if cases in the code esier to read */
 #ifndef DRI2INFOREC_VERSION
 #define DRI2INFOREC_VERSION 1
diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c
index a7e5763..c69d75e 100644
--- a/src/gallium/state_trackers/xorg/xorg_driver.c
+++ b/src/gallium/state_trackers/xorg/xorg_driver.c
@@ -51,6 +51,7 @@
 
 #include <pciaccess.h>
 
+#include "state_tracker/drm_driver.h"
 #include "pipe/p_context.h"
 #include "xorg_tracker.h"
 #include "xorg_winsys.h"
@@ -269,18 +270,12 @@
 	    );
 
 
-	ms->api = drm_api_create();
-	ms->fd = drmOpen(ms->api ? ms->api->driver_name : NULL, BusID);
+	ms->fd = drmOpen(driver_descriptor.driver_name, BusID);
 	xfree(BusID);
 
 	if (ms->fd >= 0)
 	    return TRUE;
 
-	if (ms->api && ms->api->destroy)
-	    ms->api->destroy(ms->api);
-
-	ms->api = NULL;
-
 	return FALSE;
     }
 
@@ -292,10 +287,6 @@
 {
     modesettingPtr ms = modesettingPTR(pScrn);
 
-    if (ms->api && ms->api->destroy)
-	ms->api->destroy(ms->api);
-    ms->api = NULL;
-
     drmClose(ms->fd);
     ms->fd = -1;
 
@@ -316,18 +307,11 @@
     if (ms->screen || ms->kms)
 	return TRUE;
 
-    if (ms->api) {
-	ms->screen = ms->no3D ? NULL :
-	    ms->api->create_screen(ms->api, ms->fd);
+    if (!ms->no3D)
+	ms->screen = driver_descriptor.create_screen(ms->fd);
 
-	if (ms->screen)
-	    return TRUE;
-
-	if (ms->api->destroy)
-	    ms->api->destroy(ms->api);
-
-	ms->api = NULL;
-    }
+    if (ms->screen)
+	return TRUE;
 
 #ifdef HAVE_LIBKMS
     if (!kms_create(ms->fd, &ms->kms))
@@ -433,7 +417,6 @@
     }
 
     ms->fd = -1;
-    ms->api = NULL;
     if (!drv_init_drm(pScrn))
 	return FALSE;
 
diff --git a/src/gallium/state_trackers/xorg/xorg_tracker.h b/src/gallium/state_trackers/xorg/xorg_tracker.h
index df56ad1..a5178ef 100644
--- a/src/gallium/state_trackers/xorg/xorg_tracker.h
+++ b/src/gallium/state_trackers/xorg/xorg_tracker.h
@@ -49,7 +49,6 @@
 #include "pipe/p_screen.h"
 #include "util/u_inlines.h"
 #include "util/u_debug.h"
-#include "state_tracker/drm_api.h"
 
 #define DRV_ERROR(msg)	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, msg);
 
@@ -125,7 +124,6 @@
     struct kms_bo *root_bo;
 
     /* gallium */
-    struct drm_api *api;
     struct pipe_screen *screen;
     struct pipe_context *ctx;
     boolean d_depth_bits_last;
diff --git a/src/gallium/targets/SConscript.dri b/src/gallium/targets/SConscript.dri
index 74b53e5..e5981c2 100644
--- a/src/gallium/targets/SConscript.dri
+++ b/src/gallium/targets/SConscript.dri
@@ -13,6 +13,7 @@
 	'#src/gallium/include',
 	'#src/gallium/auxiliary',
 	'#src/gallium/drivers',
+	'#src/gallium/winsys',
 	'#src/mesa',
 	'#src/mesa/main',
 	'#src/mesa/glapi',
diff --git a/src/gallium/targets/dri-i915/Makefile b/src/gallium/targets/dri-i915/Makefile
index fdcfd08..26726b2 100644
--- a/src/gallium/targets/dri-i915/Makefile
+++ b/src/gallium/targets/dri-i915/Makefile
@@ -13,9 +13,13 @@
 	$(TOP)/src/gallium/drivers/i915/libi915.a
 
 C_SOURCES = \
+	target.c \
 	$(COMMON_GALLIUM_SOURCES) \
 	$(DRIVER_SOURCES)
 
+DRIVER_DEFINES = \
+	-DGALLIUM_RBUG -DGALLIUM_TRACE
+
 include ../Makefile.dri
 
 DRI_LIB_DEPS += -ldrm_intel
diff --git a/src/gallium/targets/dri-i915/SConscript b/src/gallium/targets/dri-i915/SConscript
index 65c4239..5659bc8 100644
--- a/src/gallium/targets/dri-i915/SConscript
+++ b/src/gallium/targets/dri-i915/SConscript
@@ -8,6 +8,8 @@
 
 env.ParseConfig('pkg-config --cflags --libs libdrm_intel')
 
+env.Append(CPPDEFINES = ['GALLIUM_RBUG', 'GALLIUM_TRACE'])
+
 env.Prepend(LIBS = [
     st_dri,
     i915drm,
@@ -22,6 +24,6 @@
 
 env.LoadableModule(
     target = 'i915_dri.so',
-    source = 'dummy.c',
+    source = 'target.c',
     SHLIBPREFIX = '',
 )
diff --git a/src/gallium/targets/dri-i915/dummy.c b/src/gallium/targets/dri-i915/dummy.c
deleted file mode 100644
index e69de29..0000000
--- a/src/gallium/targets/dri-i915/dummy.c
+++ /dev/null
diff --git a/src/gallium/targets/dri-i915/target.c b/src/gallium/targets/dri-i915/target.c
new file mode 100644
index 0000000..8c8ef7e
--- /dev/null
+++ b/src/gallium/targets/dri-i915/target.c
@@ -0,0 +1,26 @@
+
+#include "state_tracker/drm_driver.h"
+#include "target-helpers/inline_debug_helper.h"
+#include "i915/drm/i915_drm_public.h"
+#include "i915/i915_public.h"
+
+static struct pipe_screen *
+create_screen(int fd)
+{
+   struct i915_winsys *iws;
+   struct pipe_screen *screen;
+
+   iws = i915_drm_winsys_create(fd);
+   if (!iws)
+      return NULL;
+
+   screen = i915_screen_create(iws);
+   if (!screen)
+      return NULL;
+
+   screen = debug_screen_wrap(screen);
+
+   return screen;
+}
+
+DRM_DRIVER_DESCRIPTOR("i915", "i915", create_screen)
diff --git a/src/gallium/targets/dri-i965/Makefile b/src/gallium/targets/dri-i965/Makefile
index 13987c6..3679c07 100644
--- a/src/gallium/targets/dri-i965/Makefile
+++ b/src/gallium/targets/dri-i965/Makefile
@@ -8,16 +8,18 @@
 	$(TOP)/src/gallium/winsys/i965/drm/libi965drm.a \
 	$(TOP)/src/gallium/drivers/trace/libtrace.a \
 	$(TOP)/src/gallium/drivers/rbug/librbug.a \
-	$(TOP)/src/gallium/winsys/sw/drm/libswdrm.a \
 	$(TOP)/src/gallium/winsys/sw/wrapper/libwsw.a \
 	$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
-	$(TOP)/src/gallium/drivers/identity/libidentity.a \
 	$(TOP)/src/gallium/drivers/i965/libi965.a
 
 C_SOURCES = \
+	target.c \
 	$(COMMON_GALLIUM_SOURCES) \
 	$(DRIVER_SOURCES)
 
+DRIVER_DEFINES = \
+	-DGALLIUM_SOFTPIPE -DGALLIUM_RBUG -DGALLIUM_TRACE
+
 include ../Makefile.dri
 
 DRI_LIB_DEPS += -ldrm_intel
diff --git a/src/gallium/targets/dri-i965/SConscript b/src/gallium/targets/dri-i965/SConscript
index 13ac5a2..7eb3c43 100644
--- a/src/gallium/targets/dri-i965/SConscript
+++ b/src/gallium/targets/dri-i965/SConscript
@@ -8,6 +8,12 @@
 
 env.ParseConfig('pkg-config --cflags --libs libdrm_intel')
 
+env.Append(CPPDEFINES = [
+    'GALLIUM_SOFTPIPE',
+    'GALLIUM_RBUG',
+    'GALLIUM_TRACE'
+])
+
 env.Prepend(LIBS = [
     st_dri,
     i965drm,
@@ -24,6 +30,6 @@
 
 env.LoadableModule(
     target = 'i965_dri.so',
-    source = 'dummy.c',
+    source = 'target.c',
     SHLIBPREFIX = '',
 )
diff --git a/src/gallium/targets/dri-i965/dummy.c b/src/gallium/targets/dri-i965/dummy.c
deleted file mode 100644
index e69de29..0000000
--- a/src/gallium/targets/dri-i965/dummy.c
+++ /dev/null
diff --git a/src/gallium/targets/dri-i965/target.c b/src/gallium/targets/dri-i965/target.c
new file mode 100644
index 0000000..ce97f82
--- /dev/null
+++ b/src/gallium/targets/dri-i965/target.c
@@ -0,0 +1,30 @@
+
+#include "target-helpers/inline_wrapper_sw_helper.h"
+#include "target-helpers/inline_debug_helper.h"
+#include "state_tracker/drm_driver.h"
+#include "i965/drm/i965_drm_public.h"
+#include "i965/brw_public.h"
+
+static struct pipe_screen *
+create_screen(int fd)
+{
+   struct brw_winsys_screen *bws;
+   struct pipe_screen *screen;
+
+   bws = i965_drm_winsys_screen_create(fd);
+   if (!bws)
+      return NULL;
+
+   screen = brw_screen_create(bws);
+   if (!screen)
+      return NULL;
+
+   if (debug_get_bool_option("BRW_SOFTPIPE", FALSE))
+      screen = sw_screen_wrap(screen);
+
+   screen = debug_screen_wrap(screen);
+
+   return screen;
+}
+
+DRM_DRIVER_DESCRIPTOR("i915", "i965", create_screen)
diff --git a/src/gallium/targets/dri-nouveau/Makefile b/src/gallium/targets/dri-nouveau/Makefile
index 74d352c..2f64f31 100644
--- a/src/gallium/targets/dri-nouveau/Makefile
+++ b/src/gallium/targets/dri-nouveau/Makefile
@@ -6,14 +6,20 @@
 PIPE_DRIVERS = \
 	$(TOP)/src/gallium/state_trackers/dri/drm/libdridrm.a \
 	$(TOP)/src/gallium/winsys/nouveau/drm/libnouveaudrm.a \
+	$(TOP)/src/gallium/drivers/trace/libtrace.a \
+	$(TOP)/src/gallium/drivers/rbug/librbug.a \
 	$(TOP)/src/gallium/drivers/nvfx/libnvfx.a \
 	$(TOP)/src/gallium/drivers/nv50/libnv50.a \
 	$(TOP)/src/gallium/drivers/nouveau/libnouveau.a
 
 C_SOURCES = \
+	target.c \
 	$(COMMON_GALLIUM_SOURCES) \
 	$(DRIVER_SOURCES)
 
+DRIVER_DEFINES = \
+	-DGALLIUM_RBUG -DGALLIUM_TRACE
+
 include ../Makefile.dri
 
 DRI_LIB_DEPS += $(shell pkg-config libdrm_nouveau --libs)
diff --git a/src/gallium/targets/dri-nouveau/target.c b/src/gallium/targets/dri-nouveau/target.c
new file mode 100644
index 0000000..e725a4d
--- /dev/null
+++ b/src/gallium/targets/dri-nouveau/target.c
@@ -0,0 +1,20 @@
+
+#include "target-helpers/inline_debug_helper.h"
+#include "state_tracker/drm_driver.h"
+#include "nouveau/drm/nouveau_drm_public.h"
+
+static struct pipe_screen *
+create_screen(int fd)
+{
+   struct pipe_screen *screen;
+
+   screen = nouveau_drm_screen_create(fd);
+   if (!screen)
+      return NULL;
+
+   screen = debug_screen_wrap(screen);
+
+   return screen;
+}
+
+DRM_DRIVER_DESCRIPTOR("nouveau", "nouveau", create_screen)
diff --git a/src/gallium/targets/dri-r600/Makefile b/src/gallium/targets/dri-r600/Makefile
index 0213200..932303d 100644
--- a/src/gallium/targets/dri-r600/Makefile
+++ b/src/gallium/targets/dri-r600/Makefile
@@ -12,9 +12,13 @@
 	$(TOP)/src/gallium/drivers/r600/libr600.a
 
 C_SOURCES = \
+	target.c \
 	$(COMMON_GALLIUM_SOURCES) \
 	$(DRIVER_SOURCES)
 
+DRIVER_DEFINES = \
+	-DGALLIUM_RBUG -DGALLIUM_TRACE
+
 include ../Makefile.dri
 
 DRI_LIB_DEPS += -ldrm_radeon
diff --git a/src/gallium/targets/dri-r600/SConscript b/src/gallium/targets/dri-r600/SConscript
index 6c23c05..97c5df0 100644
--- a/src/gallium/targets/dri-r600/SConscript
+++ b/src/gallium/targets/dri-r600/SConscript
@@ -8,6 +8,8 @@
 
 env.ParseConfig('pkg-config --cflags --libs libdrm_radeon')
 
+env.Append(CPPDEFINES = ['GALLIUM_RBUG', 'GALLIUM_TRACE'])
+
 env.Prepend(LIBS = [
     st_dri,
     r600drm,
@@ -22,6 +24,6 @@
 
 env.SharedLibrary(
     target ='r600_dri.so',
-    source = 'dummy.c',
+    source = 'target.c',
     SHLIBPREFIX = '',
 )
diff --git a/src/gallium/targets/dri-r600/dummy.c b/src/gallium/targets/dri-r600/dummy.c
deleted file mode 100644
index e69de29..0000000
--- a/src/gallium/targets/dri-r600/dummy.c
+++ /dev/null
diff --git a/src/gallium/targets/dri-r600/target.c b/src/gallium/targets/dri-r600/target.c
new file mode 100644
index 0000000..a01f4ed
--- /dev/null
+++ b/src/gallium/targets/dri-r600/target.c
@@ -0,0 +1,26 @@
+
+#include "state_tracker/drm_driver.h"
+#include "target-helpers/inline_debug_helper.h"
+#include "r600/drm/r600_drm_public.h"
+#include "r600/r600_public.h"
+
+static struct pipe_screen *
+create_screen(int fd)
+{
+   struct radeon *rw;
+   struct pipe_screen *screen;
+
+   rw = r600_drm_winsys_create(fd);
+   if (!rw)
+      return NULL;
+
+   screen = r600_screen_create(rw);
+   if (!screen)
+      return NULL;
+
+   screen = debug_screen_wrap(screen);
+
+   return screen;
+}
+
+DRM_DRIVER_DESCRIPTOR("r600", "radeon", create_screen)
diff --git a/src/gallium/targets/dri-radeong/Makefile b/src/gallium/targets/dri-radeong/Makefile
index 8ba1972..a0ee9f1 100644
--- a/src/gallium/targets/dri-radeong/Makefile
+++ b/src/gallium/targets/dri-radeong/Makefile
@@ -13,9 +13,13 @@
 	$(TOP)/src/gallium/drivers/r300/libr300.a
 
 C_SOURCES = \
+	target.c \
 	$(COMMON_GALLIUM_SOURCES) \
 	$(DRIVER_SOURCES)
 
+DRIVER_DEFINES = \
+	-DGALLIUM_RBUG -DGALLIUM_TRACE
+
 include ../Makefile.dri
 
 DRI_LIB_DEPS += -ldrm_radeon
diff --git a/src/gallium/targets/dri-radeong/SConscript b/src/gallium/targets/dri-radeong/SConscript
index 4c6cfb8..ffac73a 100644
--- a/src/gallium/targets/dri-radeong/SConscript
+++ b/src/gallium/targets/dri-radeong/SConscript
@@ -8,6 +8,8 @@
 
 env.ParseConfig('pkg-config --cflags --libs libdrm_radeon')
 
+env.Append(CPPDEFINES = ['GALLIUM_RBUG', 'GALLIUM_TRACE'])
+
 env.Prepend(LIBS = [
     st_dri,
     radeonwinsys,
@@ -22,6 +24,6 @@
 
 env.SharedLibrary(
     target ='radeon_dri.so',
-    source = 'dummy.c',
+    source = 'target.c',
     SHLIBPREFIX = '',
 )
diff --git a/src/gallium/targets/dri-radeong/dummy.c b/src/gallium/targets/dri-radeong/dummy.c
deleted file mode 100644
index e69de29..0000000
--- a/src/gallium/targets/dri-radeong/dummy.c
+++ /dev/null
diff --git a/src/gallium/targets/dri-radeong/target.c b/src/gallium/targets/dri-radeong/target.c
new file mode 100644
index 0000000..5a0a8dc
--- /dev/null
+++ b/src/gallium/targets/dri-radeong/target.c
@@ -0,0 +1,26 @@
+
+#include "target-helpers/inline_debug_helper.h"
+#include "state_tracker/drm_driver.h"
+#include "radeon/drm/radeon_drm_public.h"
+#include "r300/r300_public.h"
+
+static struct pipe_screen *
+create_screen(int fd)
+{
+   struct r300_winsys_screen *sws;
+   struct pipe_screen *screen;
+
+   sws = r300_drm_winsys_screen_create(fd);
+   if (!sws)
+      return NULL;
+
+   screen = r300_screen_create(sws);
+   if (!screen)
+      return NULL;
+
+   screen = debug_screen_wrap(screen);
+
+   return screen;
+}
+
+DRM_DRIVER_DESCRIPTOR("radeon", "radeon", create_screen)
diff --git a/src/gallium/targets/dri-swrast/Makefile b/src/gallium/targets/dri-swrast/Makefile
index 0a53eb5..948c45a 100644
--- a/src/gallium/targets/dri-swrast/Makefile
+++ b/src/gallium/targets/dri-swrast/Makefile
@@ -3,7 +3,9 @@
 
 LIBNAME = swrastg_dri.so
 
-DRIVER_DEFINES = -D__NOT_HAVE_DRM_H -DGALLIUM_SOFTPIPE
+DRIVER_DEFINES = \
+	-D__NOT_HAVE_DRM_H -DGALLIUM_SOFTPIPE \
+	-DGALLIUM_RBUG -DGALLIUM_TRACE
 
 PIPE_DRIVERS = \
 	$(TOP)/src/gallium/state_trackers/dri/sw/libdrisw.a \
diff --git a/src/gallium/targets/dri-swrast/SConscript b/src/gallium/targets/dri-swrast/SConscript
index 679afab..d814347 100644
--- a/src/gallium/targets/dri-swrast/SConscript
+++ b/src/gallium/targets/dri-swrast/SConscript
@@ -18,7 +18,11 @@
 ])
 
 if True:
-    env.Append(CPPDEFINES = 'GALLIUM_SOFTPIPE')
+    env.Append(CPPDEFINES = [
+        'GALLIUM_SOFTPIPE',
+        'GALLIUM_RBUG',
+        'GALLIUM_TRACE',
+    ])
     env.Prepend(LIBS = [softpipe])
 
 if env['llvm']:
diff --git a/src/gallium/targets/dri-swrast/swrast_drm_api.c b/src/gallium/targets/dri-swrast/swrast_drm_api.c
index 84142be..8d741c6 100644
--- a/src/gallium/targets/dri-swrast/swrast_drm_api.c
+++ b/src/gallium/targets/dri-swrast/swrast_drm_api.c
@@ -28,61 +28,11 @@
 
 #include "pipe/p_compiler.h"
 #include "util/u_memory.h"
-#include "state_tracker/drm_api.h"
-#include "state_tracker/sw_winsys.h"
 #include "dri_sw_winsys.h"
-#include "trace/tr_public.h"
 
-/* Copied from targets/libgl-xlib */
+#include "target-helpers/inline_debug_helper.h"
+#include "target-helpers/inline_sw_helper.h"
 
-#ifdef GALLIUM_SOFTPIPE
-#include "softpipe/sp_public.h"
-#endif
-
-#ifdef GALLIUM_LLVMPIPE
-#include "llvmpipe/lp_public.h"
-#endif
-
-#ifdef GALLIUM_CELL
-#include "cell/ppu/cell_public.h"
-#endif
-
-static struct pipe_screen *
-swrast_create_screen(struct sw_winsys *winsys)
-{
-   const char *default_driver;
-   const char *driver;
-   struct pipe_screen *screen = NULL;
-
-#if defined(GALLIUM_CELL)
-   default_driver = "cell";
-#elif defined(GALLIUM_LLVMPIPE)
-   default_driver = "llvmpipe";
-#elif defined(GALLIUM_SOFTPIPE)
-   default_driver = "softpipe";
-#else
-   default_driver = "";
-#endif
-
-   driver = debug_get_option("GALLIUM_DRIVER", default_driver);
-
-#if defined(GALLIUM_CELL)
-   if (screen == NULL && strcmp(driver, "cell") == 0)
-      screen = cell_create_screen( winsys );
-#endif
-
-#if defined(GALLIUM_LLVMPIPE)
-   if (screen == NULL && strcmp(driver, "llvmpipe") == 0)
-      screen = llvmpipe_create_screen( winsys );
-#endif
-
-#if defined(GALLIUM_SOFTPIPE)
-   if (screen == NULL)
-      screen = softpipe_create_screen( winsys );
-#endif
-
-   return trace_screen_create(screen);;
-}
 
 struct pipe_screen *
 drisw_create_screen(struct drisw_loader_funcs *lf)
@@ -94,10 +44,12 @@
    if (winsys == NULL)
       return NULL;
 
-   screen = swrast_create_screen(winsys);
+   screen = sw_screen_create(winsys);
    if (!screen)
       goto fail;
 
+   screen = debug_screen_wrap(screen);
+
    return screen;
 
 fail:
diff --git a/src/gallium/targets/dri-vmwgfx/Makefile b/src/gallium/targets/dri-vmwgfx/Makefile
index b5b679f..97c703b 100644
--- a/src/gallium/targets/dri-vmwgfx/Makefile
+++ b/src/gallium/targets/dri-vmwgfx/Makefile
@@ -11,8 +11,12 @@
 	$(TOP)/src/gallium/drivers/svga/libsvga.a
 
 C_SOURCES = \
+	target.c \
 	$(COMMON_GALLIUM_SOURCES)
 
+DRIVER_DEFINES = \
+	-DGALLIUM_RBUG -DGALLIUM_TRACE
+
 include ../Makefile.dri
 
 symlinks:
diff --git a/src/gallium/targets/dri-vmwgfx/SConscript b/src/gallium/targets/dri-vmwgfx/SConscript
index 09a0c25..7afabc7 100644
--- a/src/gallium/targets/dri-vmwgfx/SConscript
+++ b/src/gallium/targets/dri-vmwgfx/SConscript
@@ -6,6 +6,8 @@
 
 env = drienv.Clone()
 
+env.Append(CPPDEFINES = ['GALLIUM_RBUG', 'GALLIUM_TRACE'])
+
 env.Prepend(LIBS = [
     st_dri,
     svgadrm,
@@ -20,6 +22,6 @@
 
 env.LoadableModule(
     target = 'vmwgfx_dri.so',
-    source = 'dummy.c',
+    source = 'target.c',
     SHLIBPREFIX = '',
 )
diff --git a/src/gallium/targets/dri-vmwgfx/dummy.c b/src/gallium/targets/dri-vmwgfx/dummy.c
deleted file mode 100644
index e69de29..0000000
--- a/src/gallium/targets/dri-vmwgfx/dummy.c
+++ /dev/null
diff --git a/src/gallium/targets/dri-vmwgfx/target.c b/src/gallium/targets/dri-vmwgfx/target.c
new file mode 100644
index 0000000..15089d6
--- /dev/null
+++ b/src/gallium/targets/dri-vmwgfx/target.c
@@ -0,0 +1,26 @@
+
+#include "target-helpers/inline_debug_helper.h"
+#include "state_tracker/drm_driver.h"
+#include "svga/drm/svga_drm_public.h"
+#include "svga/svga_public.h"
+
+static struct pipe_screen *
+create_screen(int fd)
+{
+   struct svga_winsys_screen *sws;
+   struct pipe_screen *screen;
+
+   sws = svga_drm_winsys_screen_create(fd);
+   if (!sws)
+      return NULL;
+
+   screen = svga_screen_create(sws);
+   if (!screen)
+      return NULL;
+
+   screen = debug_screen_wrap(screen);
+
+   return screen;
+}
+
+DRM_DRIVER_DESCRIPTOR("vmwgfx", "vmwgfx", create_screen)
diff --git a/src/gallium/targets/egl-i915/Makefile b/src/gallium/targets/egl-i915/Makefile
index a4b4184..c3ffe78 100644
--- a/src/gallium/targets/egl-i915/Makefile
+++ b/src/gallium/targets/egl-i915/Makefile
@@ -2,9 +2,12 @@
 include $(TOP)/configs/current
 
 EGL_DRIVER_NAME = i915
-EGL_DRIVER_SOURCES = dummy.c
+EGL_DRIVER_SOURCES = target.c
 EGL_DRIVER_LIBS = -ldrm_intel
 
+EGL_DRIVER_DEFINES = \
+	-DGALLIUM_RBUG -DGALLIUM_TRACE
+
 EGL_DRIVER_PIPES = \
 	$(TOP)/src/gallium/winsys/i915/drm/libi915drm.a \
 	$(TOP)/src/gallium/drivers/trace/libtrace.a \
diff --git a/src/gallium/targets/egl-i915/dummy.c b/src/gallium/targets/egl-i915/dummy.c
deleted file mode 100644
index 3181d0b..0000000
--- a/src/gallium/targets/egl-i915/dummy.c
+++ /dev/null
@@ -1,3 +0,0 @@
-/* A poor man's --whole-archive for EGL drivers */
-void *_eglMain(void *);
-void *_eglWholeArchive = (void *) _eglMain;
diff --git a/src/gallium/targets/egl-i915/target.c b/src/gallium/targets/egl-i915/target.c
new file mode 100644
index 0000000..070e2c0
--- /dev/null
+++ b/src/gallium/targets/egl-i915/target.c
@@ -0,0 +1,30 @@
+
+#include "state_tracker/drm_driver.h"
+#include "target-helpers/inline_debug_helper.h"
+#include "i915/drm/i915_drm_public.h"
+#include "i915/i915_public.h"
+
+static struct pipe_screen *
+create_screen(int fd)
+{
+   struct i915_winsys *iws;
+   struct pipe_screen *screen;
+
+   iws = i915_drm_winsys_create(fd);
+   if (!iws)
+      return NULL;
+
+   screen = i915_screen_create(iws);
+   if (!screen)
+      return NULL;
+
+   screen = debug_screen_wrap(screen);
+
+   return screen;
+}
+
+DRM_DRIVER_DESCRIPTOR("i915", "i915", create_screen)
+
+/* A poor man's --whole-archive for EGL drivers */
+void *_eglMain(void *);
+void *_eglWholeArchive = (void *) _eglMain;
diff --git a/src/gallium/targets/egl-i965/Makefile b/src/gallium/targets/egl-i965/Makefile
index d473082..44e4354 100644
--- a/src/gallium/targets/egl-i965/Makefile
+++ b/src/gallium/targets/egl-i965/Makefile
@@ -2,15 +2,17 @@
 include $(TOP)/configs/current
 
 EGL_DRIVER_NAME = i965
-EGL_DRIVER_SOURCES = dummy.c
+EGL_DRIVER_SOURCES = target.c
 EGL_DRIVER_LIBS = -ldrm_intel
 
+EGL_DRIVER_DEFINES = \
+	-DGALLIUM_SOFTPIPE -DGALLIUM_RBUG -DGALLIUM_TRACE
+
 EGL_DRIVER_PIPES = \
 	$(TOP)/src/gallium/winsys/i965/drm/libi965drm.a \
 	$(TOP)/src/gallium/drivers/trace/libtrace.a \
 	$(TOP)/src/gallium/drivers/rbug/librbug.a \
 	$(TOP)/src/gallium/drivers/i965/libi965.a \
-	$(TOP)/src/gallium/winsys/sw/drm/libswdrm.a \
 	$(TOP)/src/gallium/winsys/sw/wrapper/libwsw.a \
 	$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a
 
diff --git a/src/gallium/targets/egl-i965/dummy.c b/src/gallium/targets/egl-i965/dummy.c
deleted file mode 100644
index 3181d0b..0000000
--- a/src/gallium/targets/egl-i965/dummy.c
+++ /dev/null
@@ -1,3 +0,0 @@
-/* A poor man's --whole-archive for EGL drivers */
-void *_eglMain(void *);
-void *_eglWholeArchive = (void *) _eglMain;
diff --git a/src/gallium/targets/egl-i965/target.c b/src/gallium/targets/egl-i965/target.c
new file mode 100644
index 0000000..1195b51
--- /dev/null
+++ b/src/gallium/targets/egl-i965/target.c
@@ -0,0 +1,34 @@
+
+#include "target-helpers/inline_wrapper_sw_helper.h"
+#include "target-helpers/inline_debug_helper.h"
+#include "state_tracker/drm_driver.h"
+#include "i965/drm/i965_drm_public.h"
+#include "i965/brw_public.h"
+
+static struct pipe_screen *
+create_screen(int fd)
+{
+   struct brw_winsys_screen *bws;
+   struct pipe_screen *screen;
+
+   bws = i965_drm_winsys_screen_create(fd);
+   if (!bws)
+      return NULL;
+
+   screen = brw_screen_create(bws);
+   if (!screen)
+      return NULL;
+
+   if (debug_get_bool_option("BRW_SOFTPIPE", FALSE))
+      screen = sw_screen_wrap(screen);
+
+   screen = debug_screen_wrap(screen);
+
+   return screen;
+}
+
+DRM_DRIVER_DESCRIPTOR("i915", "i965", create_screen)
+
+/* A poor man's --whole-archive for EGL drivers */
+void *_eglMain(void *);
+void *_eglWholeArchive = (void *) _eglMain;
diff --git a/src/gallium/targets/egl-nouveau/Makefile b/src/gallium/targets/egl-nouveau/Makefile
index e3fa893..0e16f11 100644
--- a/src/gallium/targets/egl-nouveau/Makefile
+++ b/src/gallium/targets/egl-nouveau/Makefile
@@ -2,11 +2,16 @@
 include $(TOP)/configs/current
 
 EGL_DRIVER_NAME = nouveau
-EGL_DRIVER_SOURCES = dummy.c
+EGL_DRIVER_SOURCES = target.c
 EGL_DRIVER_LIBS = -ldrm_nouveau
 
+EGL_DRIVER_DEFINES = \
+	-DGALLIUM_RBUG -DGALLIUM_TRACE
+
 EGL_DRIVER_PIPES = \
 	$(TOP)/src/gallium/winsys/nouveau/drm/libnouveaudrm.a \
+	$(TOP)/src/gallium/drivers/trace/libtrace.a \
+	$(TOP)/src/gallium/drivers/rbug/librbug.a \
 	$(TOP)/src/gallium/drivers/nvfx/libnvfx.a \
 	$(TOP)/src/gallium/drivers/nv50/libnv50.a \
 	$(TOP)/src/gallium/drivers/nouveau/libnouveau.a
diff --git a/src/gallium/targets/egl-nouveau/dummy.c b/src/gallium/targets/egl-nouveau/dummy.c
deleted file mode 100644
index 3181d0b..0000000
--- a/src/gallium/targets/egl-nouveau/dummy.c
+++ /dev/null
@@ -1,3 +0,0 @@
-/* A poor man's --whole-archive for EGL drivers */
-void *_eglMain(void *);
-void *_eglWholeArchive = (void *) _eglMain;
diff --git a/src/gallium/targets/egl-nouveau/target.c b/src/gallium/targets/egl-nouveau/target.c
new file mode 100644
index 0000000..cf569ea
--- /dev/null
+++ b/src/gallium/targets/egl-nouveau/target.c
@@ -0,0 +1,24 @@
+
+#include "target-helpers/inline_debug_helper.h"
+#include "state_tracker/drm_driver.h"
+#include "nouveau/drm/nouveau_drm_public.h"
+
+static struct pipe_screen *
+create_screen(int fd)
+{
+   struct pipe_screen *screen;
+
+   screen = nouveau_drm_screen_create(fd);
+   if (!screen)
+      return NULL;
+
+   screen = debug_screen_wrap(screen);
+
+   return screen;
+}
+
+DRM_DRIVER_DESCRIPTOR("nouveau", "nouveau", create_screen)
+
+/* A poor man's --whole-archive for EGL drivers */
+void *_eglMain(void *);
+void *_eglWholeArchive = (void *) _eglMain;
diff --git a/src/gallium/targets/egl-radeon/Makefile b/src/gallium/targets/egl-radeon/Makefile
index 64c20af..7942683 100644
--- a/src/gallium/targets/egl-radeon/Makefile
+++ b/src/gallium/targets/egl-radeon/Makefile
@@ -2,9 +2,12 @@
 include $(TOP)/configs/current
 
 EGL_DRIVER_NAME = radeon
-EGL_DRIVER_SOURCES = dummy.c
+EGL_DRIVER_SOURCES = target.c
 EGL_DRIVER_LIBS = -ldrm_radeon
 
+EGL_DRIVER_DEFINES = \
+	-DGALLIUM_RBUG -DGALLIUM_TRACE
+
 EGL_DRIVER_PIPES = \
 	$(TOP)/src/gallium/winsys/radeon/drm/libradeonwinsys.a \
 	$(TOP)/src/gallium/drivers/galahad/libgalahad.a \
diff --git a/src/gallium/targets/egl-radeon/dummy.c b/src/gallium/targets/egl-radeon/dummy.c
deleted file mode 100644
index 3181d0b..0000000
--- a/src/gallium/targets/egl-radeon/dummy.c
+++ /dev/null
@@ -1,3 +0,0 @@
-/* A poor man's --whole-archive for EGL drivers */
-void *_eglMain(void *);
-void *_eglWholeArchive = (void *) _eglMain;
diff --git a/src/gallium/targets/egl-radeon/target.c b/src/gallium/targets/egl-radeon/target.c
new file mode 100644
index 0000000..ce07327
--- /dev/null
+++ b/src/gallium/targets/egl-radeon/target.c
@@ -0,0 +1,30 @@
+
+#include "target-helpers/inline_debug_helper.h"
+#include "state_tracker/drm_driver.h"
+#include "radeon/drm/radeon_drm_public.h"
+#include "r300/r300_public.h"
+
+static struct pipe_screen *
+create_screen(int fd)
+{
+   struct r300_winsys_screen *sws;
+   struct pipe_screen *screen;
+
+   sws = r300_drm_winsys_screen_create(fd);
+   if (!sws)
+      return NULL;
+
+   screen = r300_screen_create(sws);
+   if (!screen)
+      return NULL;
+
+   screen = debug_screen_wrap(screen);
+
+   return screen;
+}
+
+DRM_DRIVER_DESCRIPTOR("radeon", "radeon", create_screen)
+
+/* A poor man's --whole-archive for EGL drivers */
+void *_eglMain(void *);
+void *_eglWholeArchive = (void *) _eglMain;
diff --git a/src/gallium/targets/egl-swrast/swrast_glue.c b/src/gallium/targets/egl-swrast/swrast_glue.c
index defd11c..24f7782 100644
--- a/src/gallium/targets/egl-swrast/swrast_glue.c
+++ b/src/gallium/targets/egl-swrast/swrast_glue.c
@@ -1,10 +1,11 @@
-#include "state_tracker/drm_api.h"
 
-struct drm_api *
-drm_api_create()
-{
-   return NULL;
-}
+#include "state_tracker/drm_driver.h"
+
+struct drm_driver_descriptor drm_driver = {
+   .name = "swrast",
+   .driver_name = NULL,
+   .create_screen = NULL,
+};
 
 /* A poor man's --whole-archive for EGL drivers */
 void *_eglMain(void *);
diff --git a/src/gallium/targets/egl-vmwgfx/Makefile b/src/gallium/targets/egl-vmwgfx/Makefile
index a9f6874..92ec4cb 100644
--- a/src/gallium/targets/egl-vmwgfx/Makefile
+++ b/src/gallium/targets/egl-vmwgfx/Makefile
@@ -2,9 +2,12 @@
 include $(TOP)/configs/current
 
 EGL_DRIVER_NAME = vmwgfx
-EGL_DRIVER_SOURCES = dummy.c
+EGL_DRIVER_SOURCES = target.c
 EGL_DRIVER_LIBS =
 
+EGL_DRIVER_DEFINES = \
+	-DGALLIUM_RBUG -DGALLIUM_TRACE
+
 EGL_DRIVER_PIPES = \
 	$(TOP)/src/gallium/winsys/svga/drm/libsvgadrm.a \
 	$(TOP)/src/gallium/drivers/trace/libtrace.a \
diff --git a/src/gallium/targets/egl-vmwgfx/dummy.c b/src/gallium/targets/egl-vmwgfx/dummy.c
deleted file mode 100644
index 3181d0b..0000000
--- a/src/gallium/targets/egl-vmwgfx/dummy.c
+++ /dev/null
@@ -1,3 +0,0 @@
-/* A poor man's --whole-archive for EGL drivers */
-void *_eglMain(void *);
-void *_eglWholeArchive = (void *) _eglMain;
diff --git a/src/gallium/targets/egl-vmwgfx/target.c b/src/gallium/targets/egl-vmwgfx/target.c
new file mode 100644
index 0000000..4e9f51c
--- /dev/null
+++ b/src/gallium/targets/egl-vmwgfx/target.c
@@ -0,0 +1,30 @@
+
+#include "target-helpers/inline_debug_helper.h"
+#include "state_tracker/drm_driver.h"
+#include "svga/drm/svga_drm_public.h"
+#include "svga/svga_public.h"
+
+static struct pipe_screen *
+create_screen(int fd)
+{
+   struct svga_winsys_screen *sws;
+   struct pipe_screen *screen;
+
+   sws = svga_drm_winsys_screen_create(fd);
+   if (!sws)
+      return NULL;
+
+   screen = svga_screen_create(sws);
+   if (!screen)
+      return NULL;
+
+   screen = debug_screen_wrap(screen);
+
+   return screen;
+}
+
+DRM_DRIVER_DESCRIPTOR("vmwgfx", "vmwgfx", create_screen)
+
+/* A poor man's --whole-archive for EGL drivers */
+void *_eglMain(void *);
+void *_eglWholeArchive = (void *) _eglMain;
diff --git a/src/gallium/targets/xorg-i915/Makefile b/src/gallium/targets/xorg-i915/Makefile
index 18f07d6..3ab7285 100644
--- a/src/gallium/targets/xorg-i915/Makefile
+++ b/src/gallium/targets/xorg-i915/Makefile
@@ -4,10 +4,11 @@
 LIBNAME = modesetting_drv.so
 
 C_SOURCES = \
+	intel_target.c \
 	intel_xorg.c
 
 DRIVER_DEFINES = \
-	-DHAVE_CONFIG_H
+	-DHAVE_CONFIG_H -DGALLIUM_RBUG -DGALLIUM_TRACE
 
 DRIVER_LINKS = \
 	$(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \
diff --git a/src/gallium/targets/xorg-i915/intel_target.c b/src/gallium/targets/xorg-i915/intel_target.c
new file mode 100644
index 0000000..8c8ef7e
--- /dev/null
+++ b/src/gallium/targets/xorg-i915/intel_target.c
@@ -0,0 +1,26 @@
+
+#include "state_tracker/drm_driver.h"
+#include "target-helpers/inline_debug_helper.h"
+#include "i915/drm/i915_drm_public.h"
+#include "i915/i915_public.h"
+
+static struct pipe_screen *
+create_screen(int fd)
+{
+   struct i915_winsys *iws;
+   struct pipe_screen *screen;
+
+   iws = i915_drm_winsys_create(fd);
+   if (!iws)
+      return NULL;
+
+   screen = i915_screen_create(iws);
+   if (!screen)
+      return NULL;
+
+   screen = debug_screen_wrap(screen);
+
+   return screen;
+}
+
+DRM_DRIVER_DESCRIPTOR("i915", "i915", create_screen)
diff --git a/src/gallium/targets/xorg-i965/Makefile b/src/gallium/targets/xorg-i965/Makefile
index 2b0c7d6..9bb8252 100644
--- a/src/gallium/targets/xorg-i965/Makefile
+++ b/src/gallium/targets/xorg-i965/Makefile
@@ -4,10 +4,12 @@
 LIBNAME = i965g_drv.so
 
 C_SOURCES = \
+	intel_target.c \
 	intel_xorg.c
 
 DRIVER_DEFINES = \
-	-DHAVE_CONFIG_H
+	-DHAVE_CONFIG_H -DGALLIUM_SOFTPIPE \
+	-DGALLIUM_RBUG -DGALLIUM_TRACE
 
 DRIVER_LINKS = \
 	$(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \
@@ -15,6 +17,7 @@
 	$(TOP)/src/gallium/drivers/i965/libi965.a \
 	$(TOP)/src/gallium/drivers/trace/libtrace.a \
 	$(TOP)/src/gallium/drivers/rbug/librbug.a \
+	$(TOP)/src/gallium/winsys/sw/wrapper/libwsw.a \
 	$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
 	$(GALLIUM_AUXILIARIES) \
 	$(shell pkg-config --libs libdrm libdrm_intel)
diff --git a/src/gallium/targets/xorg-i965/intel_target.c b/src/gallium/targets/xorg-i965/intel_target.c
new file mode 100644
index 0000000..ce97f82
--- /dev/null
+++ b/src/gallium/targets/xorg-i965/intel_target.c
@@ -0,0 +1,30 @@
+
+#include "target-helpers/inline_wrapper_sw_helper.h"
+#include "target-helpers/inline_debug_helper.h"
+#include "state_tracker/drm_driver.h"
+#include "i965/drm/i965_drm_public.h"
+#include "i965/brw_public.h"
+
+static struct pipe_screen *
+create_screen(int fd)
+{
+   struct brw_winsys_screen *bws;
+   struct pipe_screen *screen;
+
+   bws = i965_drm_winsys_screen_create(fd);
+   if (!bws)
+      return NULL;
+
+   screen = brw_screen_create(bws);
+   if (!screen)
+      return NULL;
+
+   if (debug_get_bool_option("BRW_SOFTPIPE", FALSE))
+      screen = sw_screen_wrap(screen);
+
+   screen = debug_screen_wrap(screen);
+
+   return screen;
+}
+
+DRM_DRIVER_DESCRIPTOR("i915", "i965", create_screen)
diff --git a/src/gallium/targets/xorg-nouveau/Makefile b/src/gallium/targets/xorg-nouveau/Makefile
index f508723..93f53e6 100644
--- a/src/gallium/targets/xorg-nouveau/Makefile
+++ b/src/gallium/targets/xorg-nouveau/Makefile
@@ -4,14 +4,17 @@
 LIBNAME = modesetting_drv.so
 
 C_SOURCES = \
+	nouveau_target.c \
 	nouveau_xorg.c
 
 DRIVER_DEFINES = \
-	-DHAVE_CONFIG_H
+	-DHAVE_CONFIG_H -DGALLIUM_RBUG -DGALLIUM_TRACE
 
 DRIVER_LINKS = \
 	$(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \
 	$(TOP)/src/gallium/winsys/nouveau/drm/libnouveaudrm.a \
+	$(TOP)/src/gallium/drivers/trace/libtrace.a \
+	$(TOP)/src/gallium/drivers/rbug/librbug.a \
 	$(TOP)/src/gallium/drivers/nvfx/libnvfx.a \
 	$(TOP)/src/gallium/drivers/nv50/libnv50.a \
 	$(TOP)/src/gallium/drivers/nouveau/libnouveau.a \
diff --git a/src/gallium/targets/xorg-nouveau/nouveau_target.c b/src/gallium/targets/xorg-nouveau/nouveau_target.c
new file mode 100644
index 0000000..e725a4d
--- /dev/null
+++ b/src/gallium/targets/xorg-nouveau/nouveau_target.c
@@ -0,0 +1,20 @@
+
+#include "target-helpers/inline_debug_helper.h"
+#include "state_tracker/drm_driver.h"
+#include "nouveau/drm/nouveau_drm_public.h"
+
+static struct pipe_screen *
+create_screen(int fd)
+{
+   struct pipe_screen *screen;
+
+   screen = nouveau_drm_screen_create(fd);
+   if (!screen)
+      return NULL;
+
+   screen = debug_screen_wrap(screen);
+
+   return screen;
+}
+
+DRM_DRIVER_DESCRIPTOR("nouveau", "nouveau", create_screen)
diff --git a/src/gallium/targets/xorg-radeon/Makefile b/src/gallium/targets/xorg-radeon/Makefile
index 6cbc61e..caf2ac9 100644
--- a/src/gallium/targets/xorg-radeon/Makefile
+++ b/src/gallium/targets/xorg-radeon/Makefile
@@ -4,10 +4,11 @@
 LIBNAME = radeon_drv.so
 
 C_SOURCES = \
+	radeon_target.c \
 	radeon_xorg.c
 
 DRIVER_DEFINES = \
-	-DHAVE_CONFIG_H
+	-DHAVE_CONFIG_H -DGALLIUM_RBUG -DGALLIUM_TRACE
 
 DRIVER_LINKS = \
         $(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \
diff --git a/src/gallium/targets/xorg-radeon/radeon_target.c b/src/gallium/targets/xorg-radeon/radeon_target.c
new file mode 100644
index 0000000..5a0a8dc
--- /dev/null
+++ b/src/gallium/targets/xorg-radeon/radeon_target.c
@@ -0,0 +1,26 @@
+
+#include "target-helpers/inline_debug_helper.h"
+#include "state_tracker/drm_driver.h"
+#include "radeon/drm/radeon_drm_public.h"
+#include "r300/r300_public.h"
+
+static struct pipe_screen *
+create_screen(int fd)
+{
+   struct r300_winsys_screen *sws;
+   struct pipe_screen *screen;
+
+   sws = r300_drm_winsys_screen_create(fd);
+   if (!sws)
+      return NULL;
+
+   screen = r300_screen_create(sws);
+   if (!screen)
+      return NULL;
+
+   screen = debug_screen_wrap(screen);
+
+   return screen;
+}
+
+DRM_DRIVER_DESCRIPTOR("radeon", "radeon", create_screen)
diff --git a/src/gallium/targets/xorg-vmwgfx/Makefile b/src/gallium/targets/xorg-vmwgfx/Makefile
index c0ff999..73a2cea 100644
--- a/src/gallium/targets/xorg-vmwgfx/Makefile
+++ b/src/gallium/targets/xorg-vmwgfx/Makefile
@@ -8,6 +8,7 @@
 	vmw_video.c \
 	vmw_ioctl.c \
 	vmw_ctrl.c \
+	vmw_target.c \
 	vmw_screen.c
 
 DRIVER_INCLUDES = \
@@ -15,8 +16,11 @@
 
 DRIVER_DEFINES = \
 	-std=gnu99 \
+	-DGALLIUM_RBUG \
+	-DGALLIUM_TRACE \
 	-DHAVE_CONFIG_H
 
+
 DRIVER_LINKS = \
 	$(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \
 	$(TOP)/src/gallium/winsys/svga/drm/libsvgadrm.a \
diff --git a/src/gallium/targets/xorg-vmwgfx/vmw_target.c b/src/gallium/targets/xorg-vmwgfx/vmw_target.c
new file mode 100644
index 0000000..15089d6
--- /dev/null
+++ b/src/gallium/targets/xorg-vmwgfx/vmw_target.c
@@ -0,0 +1,26 @@
+
+#include "target-helpers/inline_debug_helper.h"
+#include "state_tracker/drm_driver.h"
+#include "svga/drm/svga_drm_public.h"
+#include "svga/svga_public.h"
+
+static struct pipe_screen *
+create_screen(int fd)
+{
+   struct svga_winsys_screen *sws;
+   struct pipe_screen *screen;
+
+   sws = svga_drm_winsys_screen_create(fd);
+   if (!sws)
+      return NULL;
+
+   screen = svga_screen_create(sws);
+   if (!screen)
+      return NULL;
+
+   screen = debug_screen_wrap(screen);
+
+   return screen;
+}
+
+DRM_DRIVER_DESCRIPTOR("vmwgfx", "vmwgfx", create_screen)
diff --git a/src/gallium/winsys/SConscript b/src/gallium/winsys/SConscript
index 907ac90..65b1228 100644
--- a/src/gallium/winsys/SConscript
+++ b/src/gallium/winsys/SConscript
@@ -17,7 +17,6 @@
 
 if env['dri']:
 	SConscript([
-		'sw/drm/SConscript',
 		'sw/dri/SConscript',
 	])
 
diff --git a/src/gallium/winsys/i915/drm/i915_drm_buffer.c b/src/gallium/winsys/i915/drm/i915_drm_buffer.c
index 3bd8502..6b06e7a 100644
--- a/src/gallium/winsys/i915/drm/i915_drm_buffer.c
+++ b/src/gallium/winsys/i915/drm/i915_drm_buffer.c
@@ -1,5 +1,5 @@
 
-#include "state_tracker/drm_api.h"
+#include "state_tracker/drm_driver.h"
 #include "i915_drm_winsys.h"
 #include "util/u_memory.h"
 
diff --git a/src/gallium/winsys/i915/drm/i915_drm_public.h b/src/gallium/winsys/i915/drm/i915_drm_public.h
new file mode 100644
index 0000000..b828d8d
--- /dev/null
+++ b/src/gallium/winsys/i915/drm/i915_drm_public.h
@@ -0,0 +1,9 @@
+
+#ifndef I915_DRM_PUBLIC_H
+#define I915_DRM_PUBLIC_H
+
+struct i915_winsys;
+
+struct i915_winsys * i915_drm_winsys_create(int drmFD);
+
+#endif
diff --git a/src/gallium/winsys/i915/drm/i915_drm_winsys.c b/src/gallium/winsys/i915/drm/i915_drm_winsys.c
index 5a6b45e..83651b4 100644
--- a/src/gallium/winsys/i915/drm/i915_drm_winsys.c
+++ b/src/gallium/winsys/i915/drm/i915_drm_winsys.c
@@ -1,14 +1,11 @@
 #include <stdio.h>
 
-#include "state_tracker/drm_api.h"
+#include "state_tracker/drm_driver.h"
 
 #include "i915_drm_winsys.h"
+#include "i915_drm_public.h"
 #include "util/u_memory.h"
 
-#include "i915/i915_context.h"
-#include "i915/i915_screen.h"
-
-#include "trace/tr_drm.h"
 
 /*
  * Helper functions
@@ -48,8 +45,8 @@
    FREE(idws);
 }
 
-static struct pipe_screen *
-i915_drm_create_screen(struct drm_api *api, int drmFD)
+struct i915_winsys *
+i915_drm_winsys_create(int drmFD)
 {
    struct i915_drm_winsys *idws;
    unsigned int deviceID;
@@ -75,19 +72,5 @@
 
    idws->dump_cmd = debug_get_bool_option("INTEL_DUMP_CMD", FALSE);
 
-   return i915_screen_create(&idws->base);
-}
-
-static struct drm_api i915_drm_api =
-{
-   .name = "i915",
-   .driver_name = "i915",
-   .create_screen = i915_drm_create_screen,
-   .destroy = NULL,
-};
-
-struct drm_api *
-drm_api_create()
-{
-   return trace_drm_create(&i915_drm_api);
+   return &idws->base;
 }
diff --git a/src/gallium/winsys/i915/drm/i915_drm_winsys.h b/src/gallium/winsys/i915/drm/i915_drm_winsys.h
index 99667bd..1b93ddc 100644
--- a/src/gallium/winsys/i915/drm/i915_drm_winsys.h
+++ b/src/gallium/winsys/i915/drm/i915_drm_winsys.h
@@ -34,7 +34,6 @@
    return (struct i915_drm_winsys *)iws;
 }
 
-struct i915_drm_winsys * i915_drm_winsys_create(int fd, unsigned pci_id);
 struct pipe_fence_handle * i915_drm_fence_create(drm_intel_bo *bo);
 
 void i915_drm_winsys_init_batchbuffer_functions(struct i915_drm_winsys *idws);
diff --git a/src/gallium/winsys/i915/sw/i915_sw_public.h b/src/gallium/winsys/i915/sw/i915_sw_public.h
new file mode 100644
index 0000000..e951a32
--- /dev/null
+++ b/src/gallium/winsys/i915/sw/i915_sw_public.h
@@ -0,0 +1,9 @@
+
+#ifndef I915_SW_PUBLIC_H
+#define I915_SW_PUBLIC_H
+
+struct i915_winsys;
+
+struct i915_winsys * i915_sw_winsys_create(void);
+
+#endif
diff --git a/src/gallium/winsys/i915/sw/i915_sw_winsys.c b/src/gallium/winsys/i915/sw/i915_sw_winsys.c
index bb1c107..058ddc4 100644
--- a/src/gallium/winsys/i915/sw/i915_sw_winsys.c
+++ b/src/gallium/winsys/i915/sw/i915_sw_winsys.c
@@ -1,5 +1,6 @@
 
 #include "i915_sw_winsys.h"
+#include "i915_sw_public.h"
 #include "util/u_memory.h"
 
 
@@ -28,8 +29,8 @@
  */
 
 
-struct pipe_screen *
-i915_sw_create_screen()
+struct i915_winsys *
+i915_sw_winsys_create()
 {
    struct i915_sw_winsys *isws;
    unsigned int deviceID;
@@ -51,6 +52,5 @@
 
    isws->dump_cmd = debug_get_bool_option("INTEL_DUMP_CMD", FALSE);
 
-   /* XXX so this will leak winsys:es */
-   return i915_screen_create(&isws->base);
+   return &isws->base;
 }
diff --git a/src/gallium/winsys/i915/sw/i915_sw_winsys.h b/src/gallium/winsys/i915/sw/i915_sw_winsys.h
index b8aa9ef..b7b4366 100644
--- a/src/gallium/winsys/i915/sw/i915_sw_winsys.h
+++ b/src/gallium/winsys/i915/sw/i915_sw_winsys.h
@@ -25,7 +25,6 @@
    return (struct i915_sw_winsys *)iws;
 }
 
-struct pipe_screen* i915_sw_create_screen(void);
 struct pipe_fence_handle * i915_sw_fence_create(void);
 
 void i915_sw_winsys_init_batchbuffer_functions(struct i915_sw_winsys *idws);
diff --git a/src/gallium/winsys/i965/drm/Makefile b/src/gallium/winsys/i965/drm/Makefile
index bbb71e2..46f98d7 100644
--- a/src/gallium/winsys/i965/drm/Makefile
+++ b/src/gallium/winsys/i965/drm/Makefile
@@ -5,7 +5,7 @@
 
 C_SOURCES = \
 	i965_drm_buffer.c \
-	i965_drm_api.c
+	i965_drm_winsys.c
 
 LIBRARY_INCLUDES = $(shell pkg-config libdrm --cflags-only-I)
 
diff --git a/src/gallium/winsys/i965/drm/SConscript b/src/gallium/winsys/i965/drm/SConscript
index abf9aac..785be44 100644
--- a/src/gallium/winsys/i965/drm/SConscript
+++ b/src/gallium/winsys/i965/drm/SConscript
@@ -5,8 +5,8 @@
 env.ParseConfig('pkg-config --cflags libdrm')
 
 i965drm_sources = [
-    'i965_drm_api.c',
     'i965_drm_buffer.c',
+    'i965_drm_winsys.c',
 ]
 
 i965drm = env.ConvenienceLibrary(
diff --git a/src/gallium/winsys/i965/drm/i965_drm_api.c b/src/gallium/winsys/i965/drm/i965_drm_api.c
deleted file mode 100644
index 87ee807..0000000
--- a/src/gallium/winsys/i965/drm/i965_drm_api.c
+++ /dev/null
@@ -1,104 +0,0 @@
-
-#include <stdio.h>
-#include "state_tracker/drm_api.h"
-
-#include "i965_drm_winsys.h"
-#include "util/u_memory.h"
-
-#include "i965/brw_context.h"        /* XXX: shouldn't be doing this */
-#include "i965/brw_screen.h"         /* XXX: shouldn't be doing this */
-
-#include "trace/tr_drm.h"
-
-#include "../../sw/drm/sw_drm_api.h"
-
-/*
- * Helper functions
- */
-
-
-static void
-i965_libdrm_get_device_id(unsigned int *device_id)
-{
-   char path[512];
-   FILE *file;
-   void *shutup_gcc;
-
-   /*
-    * FIXME: Fix this up to use a drm ioctl or whatever.
-    */
-
-   snprintf(path, sizeof(path), "/sys/class/drm/card0/device/device");
-   file = fopen(path, "r");
-   if (!file) {
-      return;
-   }
-
-   shutup_gcc = fgets(path, sizeof(path), file);
-   sscanf(path, "%x", device_id);
-   fclose(file);
-}
-
-static void
-i965_libdrm_winsys_destroy(struct brw_winsys_screen *iws)
-{
-   struct i965_libdrm_winsys *idws = i965_libdrm_winsys(iws);
-
-   if (BRW_DUMP)
-      debug_printf("%s\n", __FUNCTION__);
-
-   drm_intel_bufmgr_destroy(idws->gem);
-
-   FREE(idws);
-}
-
-static struct pipe_screen *
-i965_libdrm_create_screen(struct drm_api *api, int drmFD)
-{
-   struct i965_libdrm_winsys *idws;
-   unsigned int deviceID;
-
-   debug_printf("%s\n", __FUNCTION__);
-
-   idws = CALLOC_STRUCT(i965_libdrm_winsys);
-   if (!idws)
-      return NULL;
-
-   i965_libdrm_get_device_id(&deviceID);
-
-   i965_libdrm_winsys_init_buffer_functions(idws);
-
-   idws->fd = drmFD;
-   idws->id = deviceID;
-
-   idws->base.destroy = i965_libdrm_winsys_destroy;
-
-   idws->gem = drm_intel_bufmgr_gem_init(idws->fd, BRW_BATCH_SIZE);
-   drm_intel_bufmgr_gem_enable_reuse(idws->gem);
-
-   idws->send_cmd = !debug_get_bool_option("BRW_NO_HW", FALSE);
-
-   return brw_create_screen(&idws->base, deviceID);
-}
-
-struct drm_api i965_libdrm_api =
-{
-   .name = "i965",
-   .driver_name = "i915",
-   .create_screen = i965_libdrm_create_screen,
-   .destroy = NULL,
-};
-
-struct drm_api *
-drm_api_create()
-{
-   struct drm_api *api = NULL;
-
-   if (api == NULL && debug_get_bool_option("BRW_SOFTPIPE", FALSE))
-      api = sw_drm_api_create(&i965_libdrm_api);
-
-   if (api == NULL)
-      api = &i965_libdrm_api;
-
-   return trace_drm_create(api);
-}
diff --git a/src/gallium/winsys/i965/drm/i965_drm_buffer.c b/src/gallium/winsys/i965/drm/i965_drm_buffer.c
index fb5e50c..ed62db6 100644
--- a/src/gallium/winsys/i965/drm/i965_drm_buffer.c
+++ b/src/gallium/winsys/i965/drm/i965_drm_buffer.c
@@ -1,5 +1,5 @@
 
-#include "state_tracker/drm_api.h"
+#include "state_tracker/drm_driver.h"
 #include "i965_drm_winsys.h"
 #include "util/u_memory.h"
 #include "util/u_inlines.h"
@@ -322,7 +322,7 @@
 		   nr_reloc);
 
    if (BRW_DUMP)
-      brw_dump_data( idws->id,
+      brw_dump_data( idws->base.pci_id,
 		     data_type,
 		     buf->bo->offset + offset, 
 		     data, size );
@@ -460,7 +460,7 @@
 		   offset, length);
 
    if (BRW_DUMP)
-      brw_dump_data( idws->id,
+      brw_dump_data( idws->base.pci_id,
 		     buf->data_type,
 		     buf->bo->offset + offset, 
 		     (char*)buf->bo->virtual + offset, 
diff --git a/src/gallium/winsys/i965/drm/i965_drm_public.h b/src/gallium/winsys/i965/drm/i965_drm_public.h
new file mode 100644
index 0000000..2913b07
--- /dev/null
+++ b/src/gallium/winsys/i965/drm/i965_drm_public.h
@@ -0,0 +1,9 @@
+
+#ifndef I965_DRM_PUBLIC_H
+#define I965_DRM_PUBLIC_H
+
+struct brw_winsys_screen;
+
+struct brw_winsys_screen * i965_drm_winsys_screen_create(int drmFD);
+
+#endif
diff --git a/src/gallium/winsys/i965/drm/i965_drm_winsys.c b/src/gallium/winsys/i965/drm/i965_drm_winsys.c
new file mode 100644
index 0000000..b08e622
--- /dev/null
+++ b/src/gallium/winsys/i965/drm/i965_drm_winsys.c
@@ -0,0 +1,74 @@
+
+#include <stdio.h>
+#include "state_tracker/drm_driver.h"
+
+#include "i965_drm_winsys.h"
+#include "i965_drm_public.h"
+#include "util/u_memory.h"
+
+/*
+ * Helper functions
+ */
+
+
+static void
+i965_libdrm_get_device_id(unsigned int *device_id)
+{
+   char path[512];
+   FILE *file;
+   void *shutup_gcc;
+
+   /*
+    * FIXME: Fix this up to use a drm ioctl or whatever.
+    */
+
+   snprintf(path, sizeof(path), "/sys/class/drm/card0/device/device");
+   file = fopen(path, "r");
+   if (!file) {
+      return;
+   }
+
+   shutup_gcc = fgets(path, sizeof(path), file);
+   sscanf(path, "%x", device_id);
+   fclose(file);
+}
+
+static void
+i965_libdrm_winsys_destroy(struct brw_winsys_screen *iws)
+{
+   struct i965_libdrm_winsys *idws = i965_libdrm_winsys(iws);
+
+   if (BRW_DUMP)
+      debug_printf("%s\n", __FUNCTION__);
+
+   drm_intel_bufmgr_destroy(idws->gem);
+
+   FREE(idws);
+}
+
+struct brw_winsys_screen *
+i965_drm_winsys_screen_create(int drmFD)
+{
+   struct i965_libdrm_winsys *idws;
+
+   debug_printf("%s\n", __FUNCTION__);
+
+   idws = CALLOC_STRUCT(i965_libdrm_winsys);
+   if (!idws)
+      return NULL;
+
+   i965_libdrm_get_device_id(&idws->base.pci_id);
+
+   i965_libdrm_winsys_init_buffer_functions(idws);
+
+   idws->fd = drmFD;
+
+   idws->base.destroy = i965_libdrm_winsys_destroy;
+
+   idws->gem = drm_intel_bufmgr_gem_init(idws->fd, BRW_BATCH_SIZE);
+   drm_intel_bufmgr_gem_enable_reuse(idws->gem);
+
+   idws->send_cmd = !debug_get_bool_option("BRW_NO_HW", FALSE);
+
+   return &idws->base;
+}
diff --git a/src/gallium/winsys/i965/drm/i965_drm_winsys.h b/src/gallium/winsys/i965/drm/i965_drm_winsys.h
index c6a7d4a..82dbe61 100644
--- a/src/gallium/winsys/i965/drm/i965_drm_winsys.h
+++ b/src/gallium/winsys/i965/drm/i965_drm_winsys.h
@@ -22,8 +22,6 @@
    boolean send_cmd;
 
    int fd; /**< Drm file discriptor */
-
-   unsigned id;
 };
 
 static INLINE struct i965_libdrm_winsys *
@@ -32,8 +30,6 @@
    return (struct i965_libdrm_winsys *)iws;
 }
 
-struct i965_libdrm_winsys *i965_libdrm_winsys_create(int fd, unsigned pci_id);
-
 void i965_libdrm_winsys_init_buffer_functions(struct i965_libdrm_winsys *idws);
 
 
diff --git a/src/gallium/winsys/i965/xlib/xlib_i965.c b/src/gallium/winsys/i965/xlib/xlib_i965.c
index 063e9f6..baadd6e 100644
--- a/src/gallium/winsys/i965/xlib/xlib_i965.c
+++ b/src/gallium/winsys/i965/xlib/xlib_i965.c
@@ -395,6 +395,7 @@
       return NULL;
 
    ws->used = 0;
+   ws->base.pci_id = PCI_CHIP_GM45_GM;
 
    ws->base.destroy              = xlib_brw_winsys_destroy;
    ws->base.bo_alloc             = xlib_brw_bo_alloc;
@@ -452,7 +453,7 @@
    if (winsys == NULL)
       return NULL;
 
-   screen = brw_create_screen(winsys, PCI_CHIP_GM45_GM);
+   screen = brw_create_screen(winsys);
    if (screen == NULL)
       goto fail;
 
diff --git a/src/gallium/winsys/nouveau/drm/Makefile b/src/gallium/winsys/nouveau/drm/Makefile
index 7102985..74a3c6a 100644
--- a/src/gallium/winsys/nouveau/drm/Makefile
+++ b/src/gallium/winsys/nouveau/drm/Makefile
@@ -3,7 +3,7 @@
 
 LIBNAME = nouveaudrm
 
-C_SOURCES = nouveau_drm_api.c
+C_SOURCES = nouveau_drm_winsys.c
 
 LIBRARY_INCLUDES = $(shell pkg-config libdrm libdrm_nouveau --cflags-only-I)
 LIBRARY_DEFINES = $(shell pkg-config libdrm libdrm_nouveau --cflags-only-other)
diff --git a/src/gallium/winsys/nouveau/drm/nouveau_drm_public.h b/src/gallium/winsys/nouveau/drm/nouveau_drm_public.h
new file mode 100644
index 0000000..67b7c44
--- /dev/null
+++ b/src/gallium/winsys/nouveau/drm/nouveau_drm_public.h
@@ -0,0 +1,9 @@
+
+#ifndef __NOUVEAU_DRM_PUBLIC_H__
+#define __NOUVEAU_DRM_PUBLIC_H__
+
+struct pipe_screen;
+
+struct pipe_screen *nouveau_drm_screen_create(int drmFD);
+
+#endif
diff --git a/src/gallium/winsys/nouveau/drm/nouveau_drm_api.c b/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c
similarity index 79%
rename from src/gallium/winsys/nouveau/drm/nouveau_drm_api.c
rename to src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c
index 2f24431..660dbd0 100644
--- a/src/gallium/winsys/nouveau/drm/nouveau_drm_api.c
+++ b/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c
@@ -4,7 +4,8 @@
 #include "util/u_memory.h"
 #include "util/u_inlines.h"
 
-#include "nouveau_drm_api.h"
+#include "nouveau_drm_winsys.h"
+#include "nouveau_drm_public.h"
 
 #include "nouveau_drmif.h"
 #include "nouveau_channel.h"
@@ -22,8 +23,8 @@
 	FREE(nv_winsys);
 }
 
-static struct pipe_screen *
-nouveau_drm_create_screen(struct drm_api *api, int fd)
+struct pipe_screen *
+nouveau_drm_screen_create(int fd)
 {
 	struct nouveau_winsys *nvws;
 	struct pipe_winsys *ws;
@@ -70,16 +71,3 @@
 
 	return nvws->pscreen;
 }
-
-static struct drm_api nouveau_drm_api_hooks = {
-	.name = "nouveau",
-	.driver_name = "nouveau",
-	.create_screen = nouveau_drm_create_screen,
-	.destroy = NULL,
-};
-
-struct drm_api *
-drm_api_create() {
-	return &nouveau_drm_api_hooks;
-}
-
diff --git a/src/gallium/winsys/nouveau/drm/nouveau_drm_api.h b/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.h
similarity index 81%
rename from src/gallium/winsys/nouveau/drm/nouveau_drm_api.h
rename to src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.h
index ba6305c..9e529ec 100644
--- a/src/gallium/winsys/nouveau/drm/nouveau_drm_api.h
+++ b/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.h
@@ -1,7 +1,5 @@
-#ifndef __NOUVEAU_DRM_API_H__
-#define __NOUVEAU_DRM_API_H__
-
-#include "state_tracker/drm_api.h"
+#ifndef __NOUVEAU_DRM_WINSYS_H__
+#define __NOUVEAU_DRM_WINSYS_H__
 
 #include "util/u_simple_screen.h"
 
diff --git a/src/gallium/winsys/r600/drm/r600_drm.c b/src/gallium/winsys/r600/drm/r600_drm.c
index 803049d..3d87a99 100644
--- a/src/gallium/winsys/r600/drm/r600_drm.c
+++ b/src/gallium/winsys/r600/drm/r600_drm.c
@@ -26,21 +26,18 @@
  *      Joakim Sindholt <opensource@zhasha.com>
  */
 #include <sys/ioctl.h>
-#include "trace/tr_drm.h"
 #include "util/u_inlines.h"
 #include "util/u_debug.h"
-#include "state_tracker/drm_api.h"
 #include "radeon_priv.h"
 #include "r600_screen.h"
 #include "r600_texture.h"
+#include "r600_public.h"
+#include "r600_drm_public.h"
+#include "state_tracker/drm_driver.h"
 
-static struct pipe_screen *r600_drm_create_screen(struct drm_api* api, int drmfd)
+struct radeon *r600_drm_winsys_create(int drmfd)
 {
-	struct radeon *rw = radeon_new(drmfd, 0);
-
-	if (rw == NULL)
-		return NULL;
-	return radeon_create_screen(rw);
+	return radeon_new(drmfd, 0);
 }
 
 boolean r600_buffer_get_handle(struct radeon *rw,
@@ -66,24 +63,3 @@
 	}
 	return TRUE;
 }
-
-static void r600_drm_api_destroy(struct drm_api *api)
-{
-	return;
-}
-
-struct drm_api drm_api_hooks = {
-	.name = "r600",
-	.driver_name = "r600",
-	.create_screen = r600_drm_create_screen,
-	.destroy = r600_drm_api_destroy,
-};
-
-struct drm_api* drm_api_create()
-{
-#ifdef DEBUG
-	return trace_drm_create(&drm_api_hooks);
-#else
-	return &drm_api_hooks;
-#endif
-}
diff --git a/src/gallium/winsys/r600/drm/r600_drm_public.h b/src/gallium/winsys/r600/drm/r600_drm_public.h
new file mode 100644
index 0000000..84f2dce
--- /dev/null
+++ b/src/gallium/winsys/r600/drm/r600_drm_public.h
@@ -0,0 +1,9 @@
+
+#ifndef R600_DRM_PUBLIC_H
+#define R600_DRM_PUBLIC_H
+
+struct radeon;
+
+struct radeon *r600_drm_winsys_create(int drmFD);
+
+#endif
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm.c b/src/gallium/winsys/radeon/drm/radeon_drm.c
index a9ae09c..e9a2763 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm.c
@@ -32,12 +32,10 @@
 #include "radeon_drm.h"
 #include "radeon_r300.h"
 #include "radeon_buffer.h"
+#include "radeon_drm_public.h"
 
 #include "r300_winsys.h"
 
-#include "galahad/glhd_drm.h"
-#include "trace/tr_drm.h"
-
 #include "util/u_memory.h"
 
 #include "xf86drm.h"
@@ -155,7 +153,7 @@
 }
 
 /* Create a pipe_screen. */
-struct pipe_screen* radeon_create_screen(struct drm_api* api, int drmFB)
+struct r300_winsys_screen* r300_drm_winsys_screen_create(int drmFB)
 {
     struct radeon_libdrm_winsys* rws; 
     boolean ret;
@@ -173,22 +171,10 @@
         ret = radeon_setup_winsys(drmFB, rws);
 	if (ret == FALSE)
 	    goto fail;
-        return r300_create_screen(&rws->base);
+        return &rws->base;
     }
 
 fail:
     FREE(rws);
     return NULL;
 }
-
-static struct drm_api radeon_drm_api_hooks = {
-    .name = "radeon",
-    .driver_name = "radeon",
-    .create_screen = radeon_create_screen,
-    .destroy = NULL,
-};
-
-struct drm_api* drm_api_create()
-{
-    return galahad_drm_create(trace_drm_create(&radeon_drm_api_hooks));
-}
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm.h b/src/gallium/winsys/radeon/drm/radeon_drm.h
index 3544c92..df6dd91 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm.h
+++ b/src/gallium/winsys/radeon/drm/radeon_drm.h
@@ -30,12 +30,7 @@
 #ifndef RADEON_DRM_H
 #define RADEON_DRM_H
 
-#include "state_tracker/drm_api.h"
-
-
-struct pipe_screen* radeon_create_screen(struct drm_api* api, int drmFB);
-
-void radeon_destroy_drm_api(struct drm_api* api);
+#include "state_tracker/drm_driver.h"
 
 /* Guess at whether this chipset should use r300g.
  *
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_public.h b/src/gallium/winsys/radeon/drm/radeon_drm_public.h
new file mode 100644
index 0000000..0d96ae8c
--- /dev/null
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_public.h
@@ -0,0 +1,9 @@
+
+#ifndef RADEON_DRM_PUBLIC_H
+#define RADEON_DRM_PUBLIC_H
+
+struct r300_winsys_screen;
+
+struct r300_winsys_screen *r300_drm_winsys_screen_create(int drmFD);
+
+#endif
diff --git a/src/gallium/winsys/radeon/drm/radeon_r300.c b/src/gallium/winsys/radeon/drm/radeon_r300.c
index d2d317d..cb26447 100644
--- a/src/gallium/winsys/radeon/drm/radeon_r300.c
+++ b/src/gallium/winsys/radeon/drm/radeon_r300.c
@@ -25,7 +25,7 @@
 
 #include "radeon_bo_gem.h"
 #include "radeon_cs_gem.h"
-#include "state_tracker/drm_api.h"
+#include "state_tracker/drm_driver.h"
 
 static struct r300_winsys_buffer *
 radeon_r300_winsys_buffer_create(struct r300_winsys_screen *rws,
diff --git a/src/gallium/winsys/sw/drm/sw_drm_api.h b/src/gallium/winsys/svga/drm/svga_drm_public.h
similarity index 78%
rename from src/gallium/winsys/sw/drm/sw_drm_api.h
rename to src/gallium/winsys/svga/drm/svga_drm_public.h
index ce90a04..e98c89d 100644
--- a/src/gallium/winsys/sw/drm/sw_drm_api.h
+++ b/src/gallium/winsys/svga/drm/svga_drm_public.h
@@ -23,12 +23,19 @@
  *
  **********************************************************/
 
+/**
+ * @file
+ * VMware SVGA DRM winsys public interface. Used by targets to create a stack.
+ *
+ * @author Jakob Bornecrantz Fonseca <jakob@vmware.com>
+ */
 
-#ifndef SW_DRM_API_H
-#define SW_DRM_API_H
+#ifndef SVGA_DRM_PUBLIC_H_
+#define SVGA_DRM_PUBLIC_H_
 
-struct drm_api;
+struct svga_winsys_screen;
 
-struct drm_api * sw_drm_api_create(struct drm_api *api);
+struct svga_winsys_screen *
+svga_drm_winsys_screen_create(int fd);
 
-#endif
+#endif /* SVGA_PUBLIC_H_ */
diff --git a/src/gallium/winsys/svga/drm/vmw_screen_dri.c b/src/gallium/winsys/svga/drm/vmw_screen_dri.c
index fe28522..1b0d10f 100644
--- a/src/gallium/winsys/svga/drm/vmw_screen_dri.c
+++ b/src/gallium/winsys/svga/drm/vmw_screen_dri.c
@@ -30,14 +30,14 @@
 #include "util/u_format.h"
 #include "vmw_screen.h"
 
-#include "trace/tr_drm.h"
-
 #include "vmw_screen.h"
 #include "vmw_surface.h"
 #include "vmw_fence.h"
 #include "vmw_context.h"
+#include "svga_drm_public.h"
 
-#include <state_tracker/drm_api.h>
+#include "state_tracker/drm_driver.h"
+
 #include "vmwgfx_drm.h"
 #include <xf86drm.h>
 
@@ -84,15 +84,13 @@
    return FALSE;
 }
 
-/* This is actually the entrypoint to the entire driver, called by the
- * libGL (or EGL, or ...) code via the drm_api_hooks table at the
- * bottom of the file.
+/* This is actually the entrypoint to the entire driver,
+ * called by the target bootstrap code.
  */
-static struct pipe_screen *
-vmw_drm_create_screen(struct drm_api *drm_api, int fd)
+struct svga_winsys_screen *
+svga_drm_winsys_screen_create(int fd)
 {
    struct vmw_winsys_screen *vws;
-   struct pipe_screen *screen;
    boolean use_old_scanout_flag = FALSE;
 
    struct dri1_api_version drm_ver;
@@ -123,16 +121,7 @@
    vws->base.surface_from_handle = vmw_drm_surface_from_handle;
    vws->base.surface_get_handle = vmw_drm_surface_get_handle;
 
-   screen = svga_screen_create( &vws->base );
-   if (!screen)
-      goto out_no_screen;
-
-   return screen;
-
-   /* Failure cases:
-    */
-out_no_screen:
-   vmw_winsys_destroy( vws );
+   return &vws->base;
 
 out_no_vws:
    return NULL;
@@ -253,15 +242,3 @@
 
     return TRUE;
 }
-
-static struct drm_api vmw_drm_api_hooks = {
-   .name = "vmwgfx",
-   .driver_name = "vmwgfx",
-   .create_screen = vmw_drm_create_screen,
-   .destroy = NULL,
-};
-
-struct drm_api* drm_api_create()
-{
-   return trace_drm_create(&vmw_drm_api_hooks);
-}
diff --git a/src/gallium/winsys/sw/drm/Makefile b/src/gallium/winsys/sw/drm/Makefile
deleted file mode 100644
index 7966453..0000000
--- a/src/gallium/winsys/sw/drm/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-TOP = ../../../../..
-include $(TOP)/configs/current
-
-LIBNAME = swdrm
-
-C_SOURCES = sw_drm_api.c
-
-LIBRARY_INCLUDES =
-
-LIBRARY_DEFINES =
-
-include ../../../Makefile.template
diff --git a/src/gallium/winsys/sw/drm/SConscript b/src/gallium/winsys/sw/drm/SConscript
deleted file mode 100644
index 15a2e05..0000000
--- a/src/gallium/winsys/sw/drm/SConscript
+++ /dev/null
@@ -1,21 +0,0 @@
-#######################################################################
-# SConscript for xlib winsys
-
-
-Import('*')
-
-env = env.Clone()
-
-env.Append(CPPPATH = [
-    '#/src/gallium/include',
-    '#/src/gallium/auxiliary',
-    '#/src/gallium/drivers',
-])
-
-ws_drm = env.ConvenienceLibrary(
-    target = 'ws_drm',
-    source = [
-       'sw_drm_api.c',
-    ]
-)
-Export('ws_drm')
diff --git a/src/gallium/winsys/sw/drm/sw_drm_api.c b/src/gallium/winsys/sw/drm/sw_drm_api.c
deleted file mode 100644
index 7b86382..0000000
--- a/src/gallium/winsys/sw/drm/sw_drm_api.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/**********************************************************
- * Copyright 2010 VMware, Inc.  All rights reserved.
- *
- * 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 THE AUTHORS OR COPYRIGHT HOLDERS
- * 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.
- *
- **********************************************************/
-
-
-#include "util/u_memory.h"
-#include "softpipe/sp_public.h"
-#include "state_tracker/drm_api.h"
-#include "../../sw/wrapper/wrapper_sw_winsys.h"
-#include "sw_drm_api.h"
-
-
-/*
- * Defines
- */
-
-
-struct sw_drm_api
-{
-   struct drm_api base;
-   struct drm_api *api;
-   struct sw_winsys *sw;
-};
-
-static INLINE struct sw_drm_api *
-sw_drm_api(struct drm_api *api)
-{
-   return (struct sw_drm_api *)api;
-}
-
-
-/*
- * Exported functions
- */
-
-
-static struct pipe_screen *
-sw_drm_create_screen(struct drm_api *_api, int drmFD)
-{
-   struct sw_drm_api *swapi = sw_drm_api(_api);
-   struct drm_api *api = swapi->api;
-   struct sw_winsys *sww;
-   struct pipe_screen *screen;
-
-   screen = api->create_screen(api, drmFD);
-   if (!screen)
-      return NULL;
-
-   sww = wrapper_sw_winsys_warp_pipe_screen(screen);
-   if (!sww)
-      return NULL;
-
-   return softpipe_create_screen(sww);
-}
-
-static void
-sw_drm_destroy(struct drm_api *api)
-{
-   struct sw_drm_api *swapi = sw_drm_api(api);
-   if (swapi->api->destroy)
-      swapi->api->destroy(swapi->api);
-
-   FREE(swapi);
-}
-
-struct drm_api *
-sw_drm_api_create(struct drm_api *api)
-{
-   struct sw_drm_api *swapi = CALLOC_STRUCT(sw_drm_api);
-
-   if (!swapi)
-      return api;
-
-   swapi->base.name = api->name;
-   swapi->base.driver_name = api->driver_name;
-   swapi->base.create_screen = sw_drm_create_screen;
-   swapi->base.destroy = sw_drm_destroy;
-
-   swapi->api = api;
-
-   return &swapi->base;
-}