From 7f426615ab308de508f672567094b8b21d836a9b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Christian=20K=C3=B6nig?= Date: Sat, 26 Mar 2011 12:36:01 +0100 Subject: [PATCH] [g3dvl] fully implement paletted subpictures --- src/gallium/auxiliary/vl/vl_compositor.c | 77 ++++++++++++++++--- src/gallium/auxiliary/vl/vl_compositor.h | 3 + src/gallium/auxiliary/vl/vl_mpeg12_context.c | 3 +- src/gallium/include/pipe/p_video_context.h | 1 + .../state_trackers/xorg/xvmc/subpicture.c | 8 +- .../state_trackers/xorg/xvmc/surface.c | 4 +- 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 @@ -140,6 +140,43 @@ create_frag_shader_ycbcr_2_rgb(struct vl_compositor *c) return true; } +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) { @@ -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), -- 2.30.2