From: Younes Manton Date: Sun, 23 May 2010 23:56:12 +0000 (-0400) Subject: vl: Get softpipe working again. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=0e59cd33e6a38567801c7da541e4caffbd6cccd3;p=mesa.git vl: Get softpipe working again. Still segfaults on softpipe->destroy() in the draw module when freeing a vertex buffer. --- diff --git a/src/gallium/auxiliary/vl/vl_compositor.c b/src/gallium/auxiliary/vl/vl_compositor.c index 8f21eb68d64..b128af19ba3 100644 --- a/src/gallium/auxiliary/vl/vl_compositor.c +++ b/src/gallium/auxiliary/vl/vl_compositor.c @@ -30,6 +30,8 @@ #include #include #include +#include +#include #include #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); + } } } diff --git a/src/gallium/auxiliary/vl/vl_compositor.h b/src/gallium/auxiliary/vl/vl_compositor.h index 4b0cdd6be5f..026ae559ed7 100644 --- a/src/gallium/auxiliary/vl/vl_compositor.h +++ b/src/gallium/auxiliary/vl/vl_compositor.h @@ -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); diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c index a4a9320d667..1e9a02c270d 100644 --- a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c +++ b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -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); diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h index 2e37efbc3cd..85191cf6b02 100644 --- a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h +++ b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h @@ -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, diff --git a/src/gallium/state_trackers/xorg/xvmc/surface.c b/src/gallium/state_trackers/xorg/xvmc/surface.c index 9340744fa36..985cc1a97a6 100644 --- a/src/gallium/state_trackers/xorg/xvmc/surface.c +++ b/src/gallium/state_trackers/xorg/xvmc/surface.c @@ -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 index 00000000000..53044342317 --- /dev/null +++ b/src/gallium/targets/Makefile.xvmc @@ -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 index 00000000000..1e3ff8ac89c --- /dev/null +++ b/src/gallium/targets/xvmc-softpipe/Makefile @@ -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: diff --git a/src/gallium/winsys/g3dvl/vl_winsys.h b/src/gallium/winsys/g3dvl/vl_winsys.h index d95e9c58335..c75ff9f32f5 100644 --- a/src/gallium/winsys/g3dvl/vl_winsys.h +++ b/src/gallium/winsys/g3dvl/vl_winsys.h @@ -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 diff --git a/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c b/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c index 1df78e986d6..e5d4664d4e8 100644 --- a/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c +++ b/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c @@ -27,16 +27,9 @@ #include #include -//#include -//#include -//#include -//#include -//#include #include -//#include #include #include -//#include /* 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);