summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian König <deathsimple@vodafone.de>2011-03-26 12:36:01 +0100
committerChristian König <deathsimple@vodafone.de>2011-03-26 12:36:01 +0100
commit7f426615ab308de508f672567094b8b21d836a9b (patch)
treeb44610a77761deaa82e9c09d16e24492aa41477d
parent9a59f22d114e11a84c99609013ffe00f709c998b (diff)
[g3dvl] fully implement paletted subpictures
-rw-r--r--src/gallium/auxiliary/vl/vl_compositor.c77
-rw-r--r--src/gallium/auxiliary/vl/vl_compositor.h3
-rw-r--r--src/gallium/auxiliary/vl/vl_mpeg12_context.c3
-rw-r--r--src/gallium/include/pipe/p_video_context.h1
-rw-r--r--src/gallium/state_trackers/xorg/xvmc/subpicture.c8
-rw-r--r--src/gallium/state_trackers/xorg/xvmc/surface.c4
6 files changed, 79 insertions, 17 deletions
diff --git a/src/gallium/auxiliary/vl/vl_compositor.c b/src/gallium/auxiliary/vl/vl_compositor.c
index b1adef99700..b0e0b3bfa72 100644
--- a/src/gallium/auxiliary/vl/vl_compositor.c
+++ b/src/gallium/auxiliary/vl/vl_compositor.c
@@ -141,6 +141,43 @@ create_frag_shader_ycbcr_2_rgb(struct vl_compositor *c)
}
static bool
+create_frag_shader_palette_2_rgb(struct vl_compositor *c)
+{
+ struct ureg_program *shader;
+ struct ureg_src tc;
+ struct ureg_src sampler;
+ struct ureg_src palette;
+ struct ureg_dst texel;
+ struct ureg_dst fragment;
+
+ shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
+ if (!shader)
+ return false;
+
+ tc = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, 1, TGSI_INTERPOLATE_LINEAR);
+ sampler = ureg_DECL_sampler(shader, 0);
+ palette = ureg_DECL_sampler(shader, 1);
+ fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);
+ texel = ureg_DECL_temporary(shader);
+
+ /*
+ * fragment = tex(tc, sampler)
+ */
+ ureg_TEX(shader, texel, TGSI_TEXTURE_2D, tc, sampler);
+ ureg_TEX(shader, fragment, TGSI_TEXTURE_1D, ureg_src(texel), palette);
+ ureg_MOV(shader, ureg_writemask(fragment, TGSI_WRITEMASK_W), ureg_src(texel));
+
+ ureg_release_temporary(shader, texel);
+ ureg_END(shader);
+
+ c->fragment_shader.palette_2_rgb = ureg_create_shader_and_destroy(shader, c->pipe);
+ if (!c->fragment_shader.palette_2_rgb)
+ return false;
+
+ return true;
+}
+
+static bool
create_frag_shader_rgb_2_rgb(struct vl_compositor *c)
{
struct ureg_program *shader;
@@ -236,6 +273,10 @@ init_shaders(struct vl_compositor *c)
debug_printf("Unable to create YCbCr-to-RGB fragment shader.\n");
return false;
}
+ if (!create_frag_shader_palette_2_rgb(c)) {
+ debug_printf("Unable to create Palette-to-RGB fragment shader.\n");
+ return false;
+ }
if (!create_frag_shader_rgb_2_rgb(c)) {
debug_printf("Unable to create RGB-to-RGB fragment shader.\n");
return false;
@@ -250,6 +291,7 @@ static void cleanup_shaders(struct vl_compositor *c)
c->pipe->delete_vs_state(c->pipe, c->vertex_shader);
c->pipe->delete_fs_state(c->pipe, c->fragment_shader.ycbcr_2_rgb);
+ c->pipe->delete_fs_state(c->pipe, c->fragment_shader.palette_2_rgb);
c->pipe->delete_fs_state(c->pipe, c->fragment_shader.rgb_2_rgb);
}
@@ -358,6 +400,7 @@ void vl_compositor_cleanup(struct vl_compositor *compositor)
void vl_compositor_set_layers(struct vl_compositor *compositor,
struct pipe_sampler_view *layers[],
+ struct pipe_sampler_view *palettes[],
struct pipe_video_rect *src_rects[],
struct pipe_video_rect *dst_rects[],
unsigned num_layers)
@@ -373,10 +416,12 @@ void vl_compositor_set_layers(struct vl_compositor *compositor,
(!layers[i] && !src_rects[i] && !dst_rects[i]));
if (compositor->layers[i] != layers[i] ||
+ compositor->palettes[i] != palettes[i] ||
!u_video_rects_equal(&compositor->layer_src_rects[i], src_rects[i]) ||
!u_video_rects_equal(&compositor->layer_dst_rects[i], dst_rects[i]))
{
pipe_sampler_view_reference(&compositor->layers[i], layers[i]);
+ pipe_sampler_view_reference(&compositor->palettes[i], palettes[i]);
compositor->layer_src_rects[i] = *src_rects[i];
compositor->layer_dst_rects[i] = *dst_rects[i];
compositor->dirty_layers |= 1 << i;
@@ -386,8 +431,10 @@ void vl_compositor_set_layers(struct vl_compositor *compositor,
compositor->dirty_layers |= 1 << i;
}
- for (; i < VL_COMPOSITOR_MAX_LAYERS; ++i)
+ for (; i < VL_COMPOSITOR_MAX_LAYERS; ++i) {
pipe_sampler_view_reference(&compositor->layers[i], NULL);
+ pipe_sampler_view_reference(&compositor->palettes[i], NULL);
+ }
}
static void gen_rect_verts(struct pipe_video_rect *src_rect,
@@ -426,7 +473,7 @@ static unsigned gen_data(struct vl_compositor *c,
struct pipe_sampler_view *src_surface,
struct pipe_video_rect *src_rect,
struct pipe_video_rect *dst_rect,
- struct pipe_sampler_view **textures,
+ struct pipe_sampler_view *textures[VL_COMPOSITOR_MAX_LAYERS + 1][2],
void **frag_shaders)
{
struct vertex4f *vb;
@@ -450,7 +497,8 @@ static unsigned gen_data(struct vl_compositor *c,
{
struct vertex2f src_inv_size = { 1.0f / src_surface->texture->width0, 1.0f / src_surface->texture->height0};
gen_rect_verts(src_rect, &src_inv_size, dst_rect, &c->fb_inv_size, vb);
- textures[num_rects] = src_surface;
+ textures[num_rects][0] = src_surface;
+ textures[num_rects][1] = NULL;
/* XXX: Hack, sort of */
frag_shaders[num_rects] = c->fragment_shader.ycbcr_2_rgb;
++num_rects;
@@ -463,9 +511,14 @@ static unsigned gen_data(struct vl_compositor *c,
if (c->dirty_layers & (1 << i)) {
struct vertex2f layer_inv_size = {1.0f / c->layers[i]->texture->width0, 1.0f / c->layers[i]->texture->height0};
gen_rect_verts(&c->layer_src_rects[i], &layer_inv_size, &c->layer_dst_rects[i], &layer_inv_size, vb);
- textures[num_rects] = c->layers[i];
- /* XXX: Hack */
- frag_shaders[num_rects] = c->fragment_shader.rgb_2_rgb;
+ textures[num_rects][0] = c->layers[i];
+ textures[num_rects][1] = c->palettes[i];
+
+ if (c->palettes[i])
+ frag_shaders[num_rects] = c->fragment_shader.palette_2_rgb;
+ else
+ frag_shaders[num_rects] = c->fragment_shader.rgb_2_rgb;
+
++num_rects;
vb += 4;
c->dirty_layers &= ~(1 << i);
@@ -483,7 +536,7 @@ static void draw_layers(struct vl_compositor *c,
struct pipe_video_rect *dst_rect)
{
unsigned num_rects;
- struct pipe_sampler_view *src_surfaces[VL_COMPOSITOR_MAX_LAYERS + 1];
+ struct pipe_sampler_view *surfaces[VL_COMPOSITOR_MAX_LAYERS + 1][2];
void *frag_shaders[VL_COMPOSITOR_MAX_LAYERS + 1];
unsigned i;
@@ -492,12 +545,12 @@ static void draw_layers(struct vl_compositor *c,
assert(src_rect);
assert(dst_rect);
- num_rects = gen_data(c, src_surface, src_rect, dst_rect, src_surfaces, frag_shaders);
+ num_rects = gen_data(c, src_surface, src_rect, dst_rect, surfaces, frag_shaders);
c->pipe->bind_blend_state(c->pipe, c->blend);
for (i = 0; i < num_rects; ++i) {
c->pipe->bind_fs_state(c->pipe, frag_shaders[i]);
- c->pipe->set_fragment_sampler_views(c->pipe, 1, &src_surfaces[i]);
+ c->pipe->set_fragment_sampler_views(c->pipe, surfaces[i][1] ? 2 : 1, &surfaces[i][0]);
util_draw_arrays(c->pipe, PIPE_PRIM_QUADS, i * 4, 4);
}
@@ -511,6 +564,8 @@ void vl_compositor_render(struct vl_compositor *compositor,
struct pipe_video_rect *dst_area,
struct pipe_fence_handle **fence)
{
+ void *samplers[2];
+
assert(compositor);
assert(src_surface);
assert(src_area);
@@ -538,9 +593,11 @@ void vl_compositor_render(struct vl_compositor *compositor,
compositor->viewport.translate[2] = 0;
compositor->viewport.translate[3] = 0;
+ samplers[0] = samplers[1] = compositor->sampler;
+
compositor->pipe->set_framebuffer_state(compositor->pipe, &compositor->fb_state);
compositor->pipe->set_viewport_state(compositor->pipe, &compositor->viewport);
- compositor->pipe->bind_fragment_sampler_states(compositor->pipe, 1, &compositor->sampler);
+ compositor->pipe->bind_fragment_sampler_states(compositor->pipe, 2, &samplers[0]);
compositor->pipe->bind_vs_state(compositor->pipe, compositor->vertex_shader);
compositor->pipe->set_vertex_buffers(compositor->pipe, 1, &compositor->vertex_buf);
compositor->pipe->bind_vertex_elements_state(compositor->pipe, compositor->vertex_elems_state);
diff --git a/src/gallium/auxiliary/vl/vl_compositor.h b/src/gallium/auxiliary/vl/vl_compositor.h
index aa1e480ed4c..249eb685b40 100644
--- a/src/gallium/auxiliary/vl/vl_compositor.h
+++ b/src/gallium/auxiliary/vl/vl_compositor.h
@@ -52,6 +52,7 @@ struct vl_compositor
{
void *ycbcr_2_rgb;
void *rgb_2_rgb;
+ void *palette_2_rgb;
} fragment_shader;
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buf;
@@ -59,6 +60,7 @@ struct vl_compositor
struct pipe_resource *fs_const_buf;
struct pipe_sampler_view *layers[VL_COMPOSITOR_MAX_LAYERS];
+ struct pipe_sampler_view *palettes[VL_COMPOSITOR_MAX_LAYERS];
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;
@@ -70,6 +72,7 @@ void vl_compositor_cleanup(struct vl_compositor *compositor);
void vl_compositor_set_layers(struct vl_compositor *compositor,
struct pipe_sampler_view *layers[],
+ struct pipe_sampler_view *palettes[],
struct pipe_video_rect *src_rects[],
struct pipe_video_rect *dst_rects[],
unsigned num_layers);
diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_context.c b/src/gallium/auxiliary/vl/vl_mpeg12_context.c
index 6d4a7713068..7fd3a0377c9 100644
--- a/src/gallium/auxiliary/vl/vl_mpeg12_context.c
+++ b/src/gallium/auxiliary/vl/vl_mpeg12_context.c
@@ -463,6 +463,7 @@ vl_mpeg12_render_picture(struct pipe_video_context *vpipe,
static void
vl_mpeg12_set_picture_layers(struct pipe_video_context *vpipe,
struct pipe_sampler_view *layers[],
+ struct pipe_sampler_view *palettes[],
struct pipe_video_rect *src_rects[],
struct pipe_video_rect *dst_rects[],
unsigned num_layers)
@@ -473,7 +474,7 @@ vl_mpeg12_set_picture_layers(struct pipe_video_context *vpipe,
assert((layers && src_rects && dst_rects) ||
(!layers && !src_rects && !dst_rects));
- vl_compositor_set_layers(&ctx->compositor, layers, src_rects, dst_rects, num_layers);
+ vl_compositor_set_layers(&ctx->compositor, layers, palettes, src_rects, dst_rects, num_layers);
}
static void
diff --git a/src/gallium/include/pipe/p_video_context.h b/src/gallium/include/pipe/p_video_context.h
index 49b1038eea7..09e2d2702c7 100644
--- a/src/gallium/include/pipe/p_video_context.h
+++ b/src/gallium/include/pipe/p_video_context.h
@@ -150,6 +150,7 @@ struct pipe_video_context
*/
void (*set_picture_layers)(struct pipe_video_context *vpipe,
struct pipe_sampler_view *layers[],
+ struct pipe_sampler_view *palettes[],
struct pipe_video_rect *src_rects[],
struct pipe_video_rect *dst_rects[],
unsigned num_layers);
diff --git a/src/gallium/state_trackers/xorg/xvmc/subpicture.c b/src/gallium/state_trackers/xorg/xvmc/subpicture.c
index f2bb845cb7a..da9e87f50dd 100644
--- a/src/gallium/state_trackers/xorg/xvmc/subpicture.c
+++ b/src/gallium/state_trackers/xorg/xvmc/subpicture.c
@@ -226,15 +226,15 @@ Status XvMCCreateSubpicture(Display *dpy, XvMCContext *context, XvMCSubpicture *
case FOURCC_AI44:
sampler_templ.swizzle_r = PIPE_SWIZZLE_ALPHA;
- sampler_templ.swizzle_g = PIPE_SWIZZLE_ALPHA;
- sampler_templ.swizzle_b = PIPE_SWIZZLE_ALPHA;
+ sampler_templ.swizzle_g = PIPE_SWIZZLE_ZERO;
+ sampler_templ.swizzle_b = PIPE_SWIZZLE_ZERO;
sampler_templ.swizzle_a = PIPE_SWIZZLE_RED;
break;
case FOURCC_IA44:
sampler_templ.swizzle_r = PIPE_SWIZZLE_RED;
- sampler_templ.swizzle_g = PIPE_SWIZZLE_RED;
- sampler_templ.swizzle_b = PIPE_SWIZZLE_RED;
+ sampler_templ.swizzle_g = PIPE_SWIZZLE_ZERO;
+ sampler_templ.swizzle_b = PIPE_SWIZZLE_ZERO;
sampler_templ.swizzle_a = PIPE_SWIZZLE_ALPHA;
break;
diff --git a/src/gallium/state_trackers/xorg/xvmc/surface.c b/src/gallium/state_trackers/xorg/xvmc/surface.c
index 6fb19124867..b3b594125a2 100644
--- a/src/gallium/state_trackers/xorg/xvmc/surface.c
+++ b/src/gallium/state_trackers/xorg/xvmc/surface.c
@@ -449,13 +449,13 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable,
XVMC_MSG(XVMC_TRACE, "[XvMC] Surface %p has subpicture %p.\n", surface, surface_priv->subpicture);
assert(subpicture_priv->surface == surface);
- vpipe->set_picture_layers(vpipe, &subpicture_priv->sampler, src_rects, dst_rects, 1);
+ vpipe->set_picture_layers(vpipe, &subpicture_priv->sampler, &subpicture_priv->palette, src_rects, dst_rects, 1);
surface_priv->subpicture = NULL;
subpicture_priv->surface = NULL;
}
else
- vpipe->set_picture_layers(vpipe, NULL, NULL, NULL, 0);
+ vpipe->set_picture_layers(vpipe, NULL, NULL, NULL, NULL, 0);
unmap_and_flush_surface(surface_priv);
vpipe->render_picture(vpipe, surface_priv->pipe_buffer, &src_rect, PictureToPipe(flags),