vl: Get softpipe working again.

Still segfaults on softpipe->destroy() in the draw module when
freeing a vertex buffer.
This commit is contained in:
Younes Manton 2010-05-23 19:56:12 -04:00
parent 2c29a93e87
commit 0e59cd33e6
9 changed files with 240 additions and 45 deletions

View 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);
}
}
}

View 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);

View 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);

View 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,

View 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);

View File

@ -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

View File

@ -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:

View 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

View File

@ -27,16 +27,9 @@
#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);
old_drawable = xsp_context->drawable;
xsp_context->drawable = drawable;
if (XGetGeometry(vscreen->display, drawable, &root, &x, &y, &width, &height, &border_width, &depth) == BadDrawable)
return NULL;
return old_drawable;
#endif
return None;
if (width_out) *width_out = width;
if (height_out) *height_out = height;
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);