vl: Get softpipe working again.
authorYounes Manton <younes.m@gmail.com>
Sun, 23 May 2010 23:56:12 +0000 (19:56 -0400)
committerYounes Manton <younes.m@gmail.com>
Sun, 23 May 2010 23:56:12 +0000 (19:56 -0400)
Still segfaults on softpipe->destroy() in the draw module when
freeing a vertex buffer.

src/gallium/auxiliary/vl/vl_compositor.c
src/gallium/auxiliary/vl/vl_compositor.h
src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c
src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h
src/gallium/state_trackers/xorg/xvmc/surface.c
src/gallium/targets/Makefile.xvmc [new file with mode: 0644]
src/gallium/targets/xvmc-softpipe/Makefile [new file with mode: 0644]
src/gallium/winsys/g3dvl/vl_winsys.h
src/gallium/winsys/g3dvl/xlib/xsp_winsys.c

index 8f21eb68d641aa5a9b7f1ce7aef53eaaac0cb5c2..b128af19ba351693c25694f3ad70c15a344dc7fd 100644 (file)
@@ -30,6 +30,8 @@
 #include <pipe/p_context.h>
 #include <util/u_inlines.h>
 #include <util/u_memory.h>
+#include <util/u_keymap.h>
+#include <util/u_sampler.h>
 #include <tgsi/tgsi_ureg.h>
 #include "vl_csc.h"
 
@@ -251,6 +253,21 @@ cleanup_buffers(struct vl_compositor *c)
    pipe_resource_reference(&c->fs_const_buf, NULL);
 }
 
+static void
+texview_map_delete(const struct keymap *map,
+                   const void *key, void *data,
+                   void *user)
+{
+   struct pipe_context *pipe = (struct pipe_context*)user;
+
+   assert(map);
+   assert(key);
+   assert(data);
+   assert(user);
+
+   pipe->sampler_view_destroy(pipe, data);
+}
+
 bool vl_compositor_init(struct vl_compositor *compositor, struct pipe_context *pipe)
 {
    unsigned i;
@@ -261,13 +278,22 @@ bool vl_compositor_init(struct vl_compositor *compositor, struct pipe_context *p
 
    compositor->pipe = pipe;
 
-   if (!init_pipe_state(compositor))
+   compositor->texview_map = util_new_keymap(sizeof(struct pipe_surface*), -1,
+                                             texview_map_delete);
+   if (!compositor->texview_map)
       return false;
+
+   if (!init_pipe_state(compositor)) {
+      util_delete_keymap(compositor->texview_map, compositor->pipe);
+      return false;
+   }
    if (!init_shaders(compositor)) {
+      util_delete_keymap(compositor->texview_map, compositor->pipe);
       cleanup_pipe_state(compositor);
       return false;
    }
    if (!init_buffers(compositor)) {
+      util_delete_keymap(compositor->texview_map, compositor->pipe);
       cleanup_shaders(compositor);
       cleanup_pipe_state(compositor);
       return false;
@@ -288,6 +314,7 @@ void vl_compositor_cleanup(struct vl_compositor *compositor)
 {
    assert(compositor);
 
+   util_delete_keymap(compositor->texview_map, compositor->pipe);
    cleanup_buffers(compositor);
    cleanup_shaders(compositor);
    cleanup_pipe_state(compositor);
@@ -459,8 +486,28 @@ static void draw_layers(struct vl_compositor *c,
    num_rects = gen_data(c, src_surface, src_rect, dst_rect, src_surfaces);
 
    for (i = 0; i < num_rects; ++i) {
-      //c->pipe->set_fragment_sampler_views(c->pipe, 1, &src_surfaces[i]->texture);
+      boolean delete_view = FALSE;
+      struct pipe_sampler_view *surface_view = (struct pipe_sampler_view*)util_keymap_lookup(c->texview_map,
+                                                                                             &src_surfaces[i]);
+      if (!surface_view) {
+         struct pipe_sampler_view templat;
+         u_sampler_view_default_template(&templat, src_surfaces[i]->texture,
+                                         src_surfaces[i]->texture->format);
+         surface_view = c->pipe->create_sampler_view(c->pipe, src_surfaces[i]->texture,
+                                                     &templat);
+         if (!surface_view)
+            return;
+
+         delete_view = !util_keymap_insert(c->texview_map, &src_surfaces[i],
+                                           surface_view, c->pipe);
+      }
+
+      c->pipe->set_fragment_sampler_views(c->pipe, 1, &surface_view);
       c->pipe->draw_arrays(c->pipe, PIPE_PRIM_TRIANGLES, i * 6, 6);
+
+      if (delete_view) {
+         c->pipe->sampler_view_destroy(c->pipe, surface_view);
+      }
    }
 }
 
index 4b0cdd6be5f832b831099b0ac26c5d0df078528d..026ae559ed7b96d5af2168f911dc6440523171a4 100644 (file)
@@ -34,6 +34,7 @@
 #include "vl_types.h"
 
 struct pipe_context;
+struct keymap;
 
 #define VL_COMPOSITOR_MAX_LAYERS 16
 
@@ -59,6 +60,8 @@ struct vl_compositor
    struct pipe_video_rect layer_src_rects[VL_COMPOSITOR_MAX_LAYERS];
    struct pipe_video_rect layer_dst_rects[VL_COMPOSITOR_MAX_LAYERS];
    unsigned dirty_layers;
+
+   struct keymap *texview_map;
 };
 
 bool vl_compositor_init(struct vl_compositor *compositor, struct pipe_context *pipe);
index a4a9320d6675e8ef8f925d8b827bf85e6be3c0f2..1e9a02c270dc7fed7f1f8adbcf2c239086c54020 100644 (file)
@@ -32,6 +32,7 @@
 #include <util/u_format.h>
 #include <util/u_math.h>
 #include <util/u_memory.h>
+#include <util/u_keymap.h>
 #include <util/u_sampler.h>
 #include <tgsi/tgsi_ureg.h>
 
@@ -1004,6 +1005,33 @@ gen_macroblock_stream(struct vl_mpeg12_mc_renderer *r,
       pipe_buffer_unmap(r->pipe, r->vertex_bufs.individual.ref[i].buffer, buf_transfer[i + 1]);
 }
 
+static struct pipe_sampler_view
+*find_or_create_sampler_view(struct vl_mpeg12_mc_renderer *r, struct pipe_surface *surface)
+{
+   struct pipe_sampler_view *sampler_view;
+   assert(r);
+   assert(surface);
+
+   sampler_view = (struct pipe_sampler_view*)util_keymap_lookup(r->texview_map, &surface);
+   if (!sampler_view) {
+      struct pipe_sampler_view templat;
+      boolean added_to_map;
+
+      u_sampler_view_default_template(&templat, surface->texture,
+                                      surface->texture->format);
+      sampler_view = r->pipe->create_sampler_view(r->pipe, surface->texture,
+                                                  &templat);
+      if (!sampler_view)
+         return NULL;
+
+      added_to_map = util_keymap_insert(r->texview_map, &surface,
+                                        sampler_view, r->pipe);
+      assert(added_to_map);
+   }
+
+   return sampler_view;
+}
+
 static void
 flush(struct vl_mpeg12_mc_renderer *r)
 {
@@ -1051,10 +1079,11 @@ flush(struct vl_mpeg12_mc_renderer *r)
       vb_start += num_macroblocks[MACROBLOCK_TYPE_INTRA] * 24;
    }
 
-   if (false /*num_macroblocks[MACROBLOCK_TYPE_FWD_FRAME_PRED] > 0*/) {
+   if (num_macroblocks[MACROBLOCK_TYPE_FWD_FRAME_PRED] > 0) {
       r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all);
       r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems_state.individual.p);
       r->textures.individual.ref[0] = r->past->texture;
+      r->sampler_views.individual.ref[0] = find_or_create_sampler_view(r, r->past);
       r->pipe->set_fragment_sampler_views(r->pipe, 4, r->sampler_views.all);
       r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all);
       r->pipe->bind_vs_state(r->pipe, r->p_vs[0]);
@@ -1069,6 +1098,7 @@ flush(struct vl_mpeg12_mc_renderer *r)
       r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all);
       r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems_state.individual.p);
       r->textures.individual.ref[0] = r->past->texture;
+      r->sampler_views.individual.ref[0] = find_or_create_sampler_view(r, r->past);
       r->pipe->set_fragment_sampler_views(r->pipe, 4, r->sampler_views.all);
       r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all);
       r->pipe->bind_vs_state(r->pipe, r->p_vs[1]);
@@ -1079,10 +1109,11 @@ flush(struct vl_mpeg12_mc_renderer *r)
       vb_start += num_macroblocks[MACROBLOCK_TYPE_FWD_FIELD_PRED] * 24;
    }
 
-   if (false /*num_macroblocks[MACROBLOCK_TYPE_BKWD_FRAME_PRED] > 0*/) {
+   if (num_macroblocks[MACROBLOCK_TYPE_BKWD_FRAME_PRED] > 0) {
       r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all);
       r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems_state.individual.p);
       r->textures.individual.ref[0] = r->future->texture;
+      r->sampler_views.individual.ref[0] = find_or_create_sampler_view(r, r->future);
       r->pipe->set_fragment_sampler_views(r->pipe, 4, r->sampler_views.all);
       r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all);
       r->pipe->bind_vs_state(r->pipe, r->p_vs[0]);
@@ -1097,6 +1128,7 @@ flush(struct vl_mpeg12_mc_renderer *r)
       r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all);
       r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems_state.individual.p);
       r->textures.individual.ref[0] = r->future->texture;
+      r->sampler_views.individual.ref[0] = find_or_create_sampler_view(r, r->future);
       r->pipe->set_fragment_sampler_views(r->pipe, 4, r->sampler_views.all);
       r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all);
       r->pipe->bind_vs_state(r->pipe, r->p_vs[1]);
@@ -1107,11 +1139,13 @@ flush(struct vl_mpeg12_mc_renderer *r)
       vb_start += num_macroblocks[MACROBLOCK_TYPE_BKWD_FIELD_PRED] * 24;
    }
 
-   if (false /*num_macroblocks[MACROBLOCK_TYPE_BI_FRAME_PRED] > 0*/) {
+   if (num_macroblocks[MACROBLOCK_TYPE_BI_FRAME_PRED] > 0) {
       r->pipe->set_vertex_buffers(r->pipe, 3, r->vertex_bufs.all);
       r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems_state.individual.b);
       r->textures.individual.ref[0] = r->past->texture;
       r->textures.individual.ref[1] = r->future->texture;
+      r->sampler_views.individual.ref[0] = find_or_create_sampler_view(r, r->past);
+      r->sampler_views.individual.ref[1] = find_or_create_sampler_view(r, r->future);
       r->pipe->set_fragment_sampler_views(r->pipe, 5, r->sampler_views.all);
       r->pipe->bind_fragment_sampler_states(r->pipe, 5, r->samplers.all);
       r->pipe->bind_vs_state(r->pipe, r->b_vs[0]);
@@ -1127,6 +1161,8 @@ flush(struct vl_mpeg12_mc_renderer *r)
       r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems_state.individual.b);
       r->textures.individual.ref[0] = r->past->texture;
       r->textures.individual.ref[1] = r->future->texture;
+      r->sampler_views.individual.ref[0] = find_or_create_sampler_view(r, r->past);
+      r->sampler_views.individual.ref[1] = find_or_create_sampler_view(r, r->future);
       r->pipe->set_fragment_sampler_views(r->pipe, 5, r->sampler_views.all);
       r->pipe->bind_fragment_sampler_states(r->pipe, 5, r->samplers.all);
       r->pipe->bind_vs_state(r->pipe, r->b_vs[1]);
@@ -1270,6 +1306,21 @@ grab_macroblock(struct vl_mpeg12_mc_renderer *r,
    ++r->num_macroblocks;
 }
 
+static void
+texview_map_delete(const struct keymap *map,
+                   const void *key, void *data,
+                   void *user)
+{
+   struct pipe_context *pipe = (struct pipe_context*)user;
+
+   assert(map);
+   assert(key);
+   assert(data);
+   assert(user);
+
+   pipe->sampler_view_destroy(pipe, data);
+}
+
 bool
 vl_mpeg12_mc_renderer_init(struct vl_mpeg12_mc_renderer *renderer,
                            struct pipe_context *pipe,
@@ -1302,13 +1353,22 @@ vl_mpeg12_mc_renderer_init(struct vl_mpeg12_mc_renderer *renderer,
    renderer->eb_handling = eb_handling;
    renderer->pot_buffers = pot_buffers;
 
-   if (!init_pipe_state(renderer))
+   renderer->texview_map = util_new_keymap(sizeof(struct pipe_surface*), -1,
+                                           texview_map_delete);
+   if (!renderer->texview_map)
+      return false;
+
+   if (!init_pipe_state(renderer)) {
+      util_delete_keymap(renderer->texview_map, renderer->pipe);
       return false;
+   }
    if (!init_shaders(renderer)) {
+      util_delete_keymap(renderer->texview_map, renderer->pipe);
       cleanup_pipe_state(renderer);
       return false;
    }
    if (!init_buffers(renderer)) {
+      util_delete_keymap(renderer->texview_map, renderer->pipe);
       cleanup_shaders(renderer);
       cleanup_pipe_state(renderer);
       return false;
@@ -1333,6 +1393,7 @@ vl_mpeg12_mc_renderer_cleanup(struct vl_mpeg12_mc_renderer *renderer)
 
    xfer_buffers_unmap(renderer);
 
+   util_delete_keymap(renderer->texview_map, renderer->pipe);
    cleanup_pipe_state(renderer);
    cleanup_shaders(renderer);
    cleanup_buffers(renderer);
index 2e37efbc3cd9853e96e2ebdcf93b15fce12545e6..85191cf6b02e42b25827d8a5837a78908560f624 100644 (file)
@@ -35,6 +35,7 @@
 
 struct pipe_context;
 struct pipe_macroblock;
+struct keymap;
 
 /* A slice is video-width (rounded up to a multiple of macroblock width) x macroblock height */
 enum VL_MPEG12_MC_RENDERER_BUFFER_MODE
@@ -105,6 +106,8 @@ struct vl_mpeg12_mc_renderer
    short *texels[3];
    struct vertex2f surface_tex_inv_size;
    struct vertex2f zero_block[3];
+
+   struct keymap *texview_map;
 };
 
 bool vl_mpeg12_mc_renderer_init(struct vl_mpeg12_mc_renderer *renderer,
index 9340744fa361c5e76d0c6ed70845f217ab36703c..985cc1a97a693e853a9b0462e7874477714bf50a 100644 (file)
@@ -121,7 +121,7 @@ CreateOrResizeBackBuffer(struct vl_context *vctx, unsigned int width, unsigned i
    template.height0 = height;
    template.depth0 = 1;
    template.usage = PIPE_USAGE_DEFAULT;
-   template.bind = PIPE_BIND_RENDER_TARGET;
+   template.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_BLIT_SOURCE;
    template.flags = 0;
 
    tex = vpipe->screen->resource_create(vpipe->screen, &template);
@@ -129,7 +129,7 @@ CreateOrResizeBackBuffer(struct vl_context *vctx, unsigned int width, unsigned i
       return false;
 
    *backbuffer = vpipe->screen->get_tex_surface(vpipe->screen, tex, 0, 0, 0,
-                                                PIPE_BIND_RENDER_TARGET | PIPE_BIND_BLIT_SOURCE);
+                                                template.bind);
    pipe_resource_reference(&tex, NULL);
 
    if (!*backbuffer)
@@ -366,11 +366,6 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable,
                       short destx, short desty, unsigned short destw, unsigned short desth,
                       int flags)
 {
-   Window root;
-   int x, y;
-   unsigned int width, height;
-   unsigned int border_width;
-   unsigned int depth;
    struct pipe_video_context *vpipe;
    XvMCSurfacePrivate *surface_priv;
    XvMCContextPrivate *context_priv;
@@ -378,6 +373,8 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable,
    XvMCContext *context;
    struct pipe_video_rect src_rect = {srcx, srcy, srcw, srch};
    struct pipe_video_rect dst_rect = {destx, desty, destw, desth};
+   void *displaytarget;
+   unsigned width, height;
 
    XVMC_MSG(XVMC_TRACE, "[XvMC] Displaying surface %p.\n", surface);
 
@@ -386,7 +383,12 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable,
    if (!surface || !surface->privData)
       return XvMCBadSurface;
 
-   if (XGetGeometry(dpy, drawable, &root, &x, &y, &width, &height, &border_width, &depth) == BadDrawable)
+   surface_priv = surface->privData;
+   context = surface_priv->context;
+   context_priv = context->privData;
+
+   displaytarget = vl_displaytarget_get(context_priv->vctx->vscreen, drawable, &width, &height);
+   if (!displaytarget)
       return BadDrawable;
 
    assert(flags == XVMC_TOP_FIELD || flags == XVMC_BOTTOM_FIELD || flags == XVMC_FRAME_PICTURE);
@@ -404,9 +406,6 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable,
    assert(desty + desth - 1 < height);
     */
 
-   surface_priv = surface->privData;
-   context = surface_priv->context;
-   context_priv = context->privData;
    subpicture_priv = surface_priv->subpicture ? surface_priv->subpicture->privData : NULL;
    vpipe = context_priv->vctx->vpipe;
 
@@ -435,16 +434,12 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable,
 
    XVMC_MSG(XVMC_TRACE, "[XvMC] Submitted surface %p for display. Pushing to front buffer.\n", surface);
 
-   vl_video_bind_drawable(context_priv->vctx, drawable);
-
-#if 0
    vpipe->screen->flush_frontbuffer
    (
       vpipe->screen,
       context_priv->backbuffer,
-      vpipe->priv
+      displaytarget
    );
-#endif
 
    XVMC_MSG(XVMC_TRACE, "[XvMC] Pushed surface %p to front buffer.\n", surface);
 
diff --git a/src/gallium/targets/Makefile.xvmc b/src/gallium/targets/Makefile.xvmc
new file mode 100644 (file)
index 0000000..5304434
--- /dev/null
@@ -0,0 +1,61 @@
+# This makefile template is used to build libXvMCg3dvl.so
+
+LIBBASENAME = XvMCg3dvl
+LIBNAME = lib$(LIBBASENAME).so
+XVMC_MAJOR = 1
+XVMC_MINOR = 0
+INCLUDES = -I$(TOP)/src/gallium/include \
+          -I$(TOP)/src/gallium/drivers \
+          -I$(TOP)/src/gallium/auxiliary \
+          -I$(TOP)/src/gallium/winsys/g3dvl \
+          $(DRIVER_INCLUDES)
+DEFINES = -DGALLIUM_TRACE $(DRIVER_DEFINES)
+LIBS = $(EXTRA_LIB_PATH) $(DRIVER_LIBS) -lXvMC -lXv -lX11 -lm
+STATE_TRACKER_LIB = $(TOP)/src/gallium/state_trackers/xorg/xvmc/libxvmctracker.a
+
+# XXX: Hack, XvMC public funcs aren't exported if we link to libxvmctracker.a :(
+OBJECTS = $(C_SOURCES:.c=.o) \
+         $(ASM_SOURCES:.S=.o) \
+         $(TOP)/src/gallium/state_trackers/xorg/xvmc/*.o
+
+##### RULES #####
+
+.c.o:
+       $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
+
+.S.o:
+       $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
+
+##### TARGETS #####
+
+default: depend symlinks $(TOP)/$(LIB_DIR)/gallium/$(LIBNAME)
+
+$(TOP)/$(LIB_DIR)/gallium/$(LIBNAME): $(OBJECTS) $(PIPE_DRIVERS) $(STATE_TRACKER-LIB) $(TOP)/$(LIB_DIR)/gallium Makefile
+       $(MKLIB) -o $(LIBBASENAME) -linker '$(CC)' -ldflags '$(LDFLAGS)' \
+               -major $(XVMC_MAJOR) -minor $(XVMC_MINOR) $(MKLIB_OPTIONS) \
+               -install $(TOP)/$(LIB_DIR)/gallium \
+               $(OBJECTS) $(STATE_TRACKER_LIB) $(PIPE_DRIVERS) $(LIBS)
+
+$(TOP)/$(LIB_DIR)/gallium:
+       mkdir -p $@
+
+depend: $(C_SOURCES) $(ASM_SOURCES) $(SYMLINKS)
+       rm -f depend
+       touch depend
+       $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDES) $(C_SOURCES) \
+               $(ASM_SOURCES) 2> /dev/null
+
+# Emacs tags
+tags:
+       etags `find . -name \*.[ch]` `find ../include`
+
+# Remove .o and backup files
+clean:
+       -rm -f *.o *~ *.so $(SYMLINKS)
+       -rm -f depend depend.bak
+
+#install: $(LIBNAME)
+#      $(INSTALL) -d $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR)
+#      $(MINSTALL) -m 755 $(LIBNAME) $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR)
+
+include depend
diff --git a/src/gallium/targets/xvmc-softpipe/Makefile b/src/gallium/targets/xvmc-softpipe/Makefile
new file mode 100644 (file)
index 0000000..1e3ff8a
--- /dev/null
@@ -0,0 +1,19 @@
+TOP = ../../../..
+include $(TOP)/configs/current
+
+DRIVER_DEFINES = -DGALLIUM_SOFTPIPE
+DRIVER_INCLUDES =
+
+PIPE_DRIVERS = \
+       $(TOP)/src/gallium/winsys/sw/xlib/libws_xlib.a \
+       $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
+       $(TOP)/src/gallium/auxiliary/libgallium.a
+
+C_SOURCES = \
+       $(TOP)/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c
+
+DRIVER_LIBS =
+
+include ../Makefile.xvmc
+
+symlinks:
index d95e9c58335df6c4c38e405e5315b9122b587598..c75ff9f32f5e3c4d43fc2510764cf9565e8d7b3f 100644 (file)
@@ -37,6 +37,7 @@ struct pipe_video_context;
 
 struct vl_screen
 {
+   Display *display;
    enum pipe_format format;
    struct pipe_screen *pscreen;
 };
@@ -60,7 +61,8 @@ vl_video_create(struct vl_screen *vscreen,
 
 void vl_video_destroy(struct vl_context *vctx);
 
-Drawable
-vl_video_bind_drawable(struct vl_context *vctx, Drawable drawable);
+void*
+vl_displaytarget_get(struct vl_screen *vscreen, Drawable drawable,
+                     unsigned *width, unsigned *height);
 
 #endif
index 1df78e986d631772c246f6dc101f8cc00bde94ab..e5d4664d4e84a64c738a3b5926590e76d6754ad7 100644 (file)
 
 #include <vl_winsys.h>
 #include <state_tracker/xlib_sw_winsys.h>
-//#include <X11/Xutil.h>
-//#include <util/u_simple_screen.h>
-//#include <pipe/p_state.h>
-//#include <util/u_inlines.h>
-//#include <util/u_format.h>
 #include <util/u_memory.h>
-//#include <util/u_math.h>
 #include <softpipe/sp_public.h>
 #include <softpipe/sp_video_context.h>
-//#include <softpipe/sp_texture.h>
 
 /* TODO: Find a good way to calculate this */
 static enum pipe_format VisualToPipe(Visual *visual)
@@ -45,21 +38,31 @@ static enum pipe_format VisualToPipe(Visual *visual)
    return PIPE_FORMAT_B8G8R8X8_UNORM;
 }
 
-Drawable
-vl_video_bind_drawable(struct vl_context *vctx, Drawable drawable)
+/* XXX: Not thread-safe */
+static struct xlib_drawable xdraw;
+
+void*
+vl_displaytarget_get(struct vl_screen *vscreen, Drawable drawable,
+                     unsigned *width_out, unsigned *height_out)
 {
-#if 0
-   struct xsp_context *xsp_context = (struct xsp_context*)vctx;
-   Drawable old_drawable;
+   Window root;
+   int x, y;
+   unsigned int width, height;
+   unsigned int border_width;
+   unsigned int depth;
 
-   assert(vctx);
+   assert(vscreen);
+
+   if (XGetGeometry(vscreen->display, drawable, &root, &x, &y, &width, &height, &border_width, &depth) == BadDrawable)
+      return NULL;
 
-   old_drawable = xsp_context->drawable;
-   xsp_context->drawable = drawable;
+   if (width_out) *width_out = width;
+   if (height_out) *height_out = height;
 
-   return old_drawable;
-#endif
-   return None;
+   xdraw.depth = depth;
+   xdraw.drawable = drawable;
+
+   return &xdraw;
 }
 
 struct vl_screen*
@@ -81,14 +84,15 @@ vl_screen_create(Display *display, int screen)
    }
 
    vscreen->pscreen = softpipe_create_screen(winsys);
-
    if (!vscreen->pscreen) {
       winsys->destroy(winsys);
       FREE(vscreen);
       return NULL;
    }
 
-   vscreen->format = VisualToPipe(XDefaultVisual(display, screen));
+   vscreen->display = display;
+   xdraw.visual = XDefaultVisual(display, screen);
+   vscreen->format = VisualToPipe(xdraw.visual);
 
    return vscreen;
 }
@@ -134,7 +138,7 @@ void vl_video_destroy(struct vl_context *vctx)
 {
    assert(vctx);
 
-#if 0
+#if 1
    vctx->vpipe->destroy(vctx->vpipe);
 #endif
    FREE(vctx);