#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"
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;
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;
{
assert(compositor);
+ util_delete_keymap(compositor->texview_map, compositor->pipe);
cleanup_buffers(compositor);
cleanup_shaders(compositor);
cleanup_pipe_state(compositor);
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);
+ }
}
}
#include "vl_types.h"
struct pipe_context;
+struct keymap;
#define VL_COMPOSITOR_MAX_LAYERS 16
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);
#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>
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)
{
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]);
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]);
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]);
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]);
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]);
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]);
++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,
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;
xfer_buffers_unmap(renderer);
+ util_delete_keymap(renderer->texview_map, renderer->pipe);
cleanup_pipe_state(renderer);
cleanup_shaders(renderer);
cleanup_buffers(renderer);
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
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,
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);
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)
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;
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);
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);
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;
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);
--- /dev/null
+# 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
--- /dev/null
+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:
struct vl_screen
{
+ Display *display;
enum pipe_format format;
struct pipe_screen *pscreen;
};
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
#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)
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*
}
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;
}
{
assert(vctx);
-#if 0
+#if 1
vctx->vpipe->destroy(vctx->vpipe);
#endif
FREE(vctx);