diff options
author | Cooper Yuan <cooperyuan@gmail.com> | 2009-10-10 14:45:15 +0800 |
---|---|---|
committer | Cooper Yuan <cooperyuan@gmail.com> | 2009-10-10 14:45:15 +0800 |
commit | f12cba15932d319c4c006bdbb1aed41136ab11fd (patch) | |
tree | 32e84b0987778bb851da1feb04cfe7dd0386c770 | |
parent | a152dd69aeb7a41145a091acf9de93c7e904ee49 (diff) |
xvmc: add several mpeg12 related functions
-rw-r--r-- | src/gallium/winsys/g3dvl/radeon/Makefile | 3 | ||||
-rw-r--r-- | src/gallium/winsys/g3dvl/radeon/radeon_vl.c | 235 | ||||
-rw-r--r-- | src/gallium/winsys/g3dvl/radeon/radeon_vl.h | 18 |
3 files changed, 223 insertions, 33 deletions
diff --git a/src/gallium/winsys/g3dvl/radeon/Makefile b/src/gallium/winsys/g3dvl/radeon/Makefile index a27693547..88d34e825 100644 --- a/src/gallium/winsys/g3dvl/radeon/Makefile +++ b/src/gallium/winsys/g3dvl/radeon/Makefile @@ -15,7 +15,8 @@ INCLUDE_DIRS = \ -I$(TOP)/src/gallium/drivers/r300 \ -I$(TOP)/src/gallium/auxiliary \ -I$(TOP)/src/gallium/winsys/drm/radeon/core \ - -I${DRMDIR}/include/drm + -I${DRMDIR}/include/drm \ + -I$(TOP)/src/gallium/auxiliary/vl WINSYS_SOURCES = \ radeon_vl.c diff --git a/src/gallium/winsys/g3dvl/radeon/radeon_vl.c b/src/gallium/winsys/g3dvl/radeon/radeon_vl.c index e6dbdd815..57b4c168c 100644 --- a/src/gallium/winsys/g3dvl/radeon/radeon_vl.c +++ b/src/gallium/winsys/g3dvl/radeon/radeon_vl.c @@ -28,6 +28,7 @@ #include <pipe/p_defines.h> #include <pipe/p_context.h> #include <pipe/p_screen.h> +#include <pipe/p_inlines.h> #include <util/u_memory.h> #include <X11/Xlib.h> @@ -36,15 +37,199 @@ #include "radeon_buffer.h" #include "radeon_r300.h" -#include "radeon_winsys_softpipe.h" #include "r300_screen.h" #include "p_video_context.h" #include "radeon_vl.h" +#include "softpipe/sp_winsys.h" +#include "softpipe/sp_texture.h" -struct pipe_video_context * +static void +radeon_mpeg12_destroy(struct pipe_video_context *vpipe) +{ + struct radeon_mpeg12_context *ctx = (struct radeon_mpeg12_context*)vpipe; + + assert(vpipe); + + ctx->pipe->bind_vs_state(ctx->pipe, NULL); + ctx->pipe->bind_fs_state(ctx->pipe, NULL); + + ctx->pipe->delete_blend_state(ctx->pipe, ctx->blend); + ctx->pipe->delete_rasterizer_state(ctx->pipe, ctx->rast); + ctx->pipe->delete_depth_stencil_alpha_state(ctx->pipe, ctx->dsa); + + pipe_video_surface_reference(&ctx->decode_target, NULL); + vl_compositor_cleanup(&ctx->compositor); + vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer); + ctx->pipe->destroy(ctx->pipe); + + FREE(ctx); +} + +static void +radeon_mpeg12_decode_macroblocks(struct pipe_video_context *vpipe, + struct pipe_video_surface *past, + struct pipe_video_surface *future, + unsigned num_macroblocks, + struct pipe_macroblock *macroblocks, + struct pipe_fence_handle **fence) +{ + struct radeon_mpeg12_context *ctx = (struct radeon_mpeg12_context*)vpipe; + struct pipe_mpeg12_macroblock *mpeg12_macroblocks = + (struct pipe_mpeg12_macroblock*)macroblocks; + + assert(vpipe); + assert(num_macroblocks); + assert(macroblocks); + assert(macroblocks->codec == PIPE_VIDEO_CODEC_MPEG12); + assert(ctx->decode_target); + + vl_mpeg12_mc_renderer_render_macroblocks( + &ctx->mc_renderer, + r300_video_surface(ctx->decode_target)->tex, + past ? r300_video_surface(past)->tex : NULL, + future ? r300_video_surface(future)->tex : NULL, + num_macroblocks, mpeg12_macroblocks, fence); +} + +static void radeon_mpeg12_clear_surface(struct pipe_video_context *vpipe, + unsigned x, unsigned y, + unsigned width, unsigned height, + unsigned value, + struct pipe_surface *surface) +{ + struct radeon_mpeg12_context *ctx = (struct radeon_mpeg12_context*)vpipe; + + assert(vpipe); + assert(surface); + + ctx->pipe->surface_fill(ctx->pipe, surface, x, y, width, height, value); +} + +static void +radeon_mpeg12_render_picture(struct pipe_video_context *vpipe, + struct pipe_video_surface *src_surface, + enum pipe_mpeg12_picture_type picture_type, + struct pipe_video_rect *src_area, + struct pipe_surface *dst_surface, + struct pipe_video_rect *dst_area, + struct pipe_fence_handle **fence) +{ + struct radeon_mpeg12_context *ctx = (struct radeon_mpeg12_context*)vpipe; + + assert(vpipe); + assert(src_surface); + assert(src_area); + assert(dst_surface); + assert(dst_area); + + vl_compositor_render(&ctx->compositor, + r300_video_surface(src_surface)->tex, + picture_type, src_area, dst_surface->texture, + dst_area, fence); +} + +static void radeon_mpeg12_set_decode_target(struct pipe_video_context *vpipe, + struct pipe_video_surface *dt) +{ + struct radeon_mpeg12_context *ctx = (struct radeon_mpeg12_context*)vpipe; + + assert(vpipe); + assert(dt); + + pipe_video_surface_reference(&ctx->decode_target, dt); +} + +static void radeon_mpeg12_set_csc_matrix(struct pipe_video_context *vpipe, + const float *mat) +{ + struct radeon_mpeg12_context *ctx = (struct radeon_mpeg12_context*)vpipe; + + assert(vpipe); + + vl_compositor_set_csc_matrix(&ctx->compositor, mat); +} + +static bool radeon_mpeg12_init_pipe_state(struct radeon_mpeg12_context *ctx) +{ + struct pipe_rasterizer_state rast; + struct pipe_blend_state blend; + struct pipe_depth_stencil_alpha_state dsa; + unsigned i; + + assert(ctx); + + rast.flatshade = 1; + rast.flatshade_first = 0; + rast.light_twoside = 0; + rast.front_winding = PIPE_WINDING_CCW; + rast.cull_mode = PIPE_WINDING_CW; + rast.fill_cw = PIPE_POLYGON_MODE_FILL; + rast.fill_ccw = PIPE_POLYGON_MODE_FILL; + rast.offset_cw = 0; + rast.offset_ccw = 0; + rast.scissor = 0; + rast.poly_smooth = 0; + rast.poly_stipple_enable = 0; + rast.point_sprite = 0; + rast.point_size_per_vertex = 0; + rast.multisample = 0; + rast.line_smooth = 0; + rast.line_stipple_enable = 0; + rast.line_stipple_factor = 0; + rast.line_stipple_pattern = 0; + rast.line_last_pixel = 0; + rast.bypass_vs_clip_and_viewport = 0; + rast.line_width = 1; + rast.point_smooth = 0; + rast.point_size = 1; + rast.offset_units = 1; + rast.offset_scale = 1; + /*rast.sprite_coord_mode[i] = ;*/ + ctx->rast = ctx->pipe->create_rasterizer_state(ctx->pipe, &rast); + ctx->pipe->bind_rasterizer_state(ctx->pipe, ctx->rast); + + blend.blend_enable = 0; + blend.rgb_func = PIPE_BLEND_ADD; + blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rgb_dst_factor = PIPE_BLENDFACTOR_ONE; + blend.alpha_func = PIPE_BLEND_ADD; + blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend.alpha_dst_factor = PIPE_BLENDFACTOR_ONE; + blend.logicop_enable = 0; + blend.logicop_func = PIPE_LOGICOP_CLEAR; + /* Needed to allow color writes to FB, even if blending disabled */ + blend.colormask = PIPE_MASK_RGBA; + blend.dither = 0; + ctx->blend = ctx->pipe->create_blend_state(ctx->pipe, &blend); + ctx->pipe->bind_blend_state(ctx->pipe, ctx->blend); + + dsa.depth.enabled = 0; + dsa.depth.writemask = 0; + dsa.depth.func = PIPE_FUNC_ALWAYS; + for (i = 0; i < 2; ++i) + { + dsa.stencil[i].enabled = 0; + dsa.stencil[i].func = PIPE_FUNC_ALWAYS; + dsa.stencil[i].fail_op = PIPE_STENCIL_OP_KEEP; + dsa.stencil[i].zpass_op = PIPE_STENCIL_OP_KEEP; + dsa.stencil[i].zfail_op = PIPE_STENCIL_OP_KEEP; + dsa.stencil[i].ref_value = 0; + dsa.stencil[i].valuemask = 0; + dsa.stencil[i].writemask = 0; + } + dsa.alpha.enabled = 0; + dsa.alpha.func = PIPE_FUNC_ALWAYS; + dsa.alpha.ref_value = 0; + ctx->dsa = ctx->pipe->create_depth_stencil_alpha_state(ctx->pipe, &dsa); + ctx->pipe->bind_depth_stencil_alpha_state(ctx->pipe, ctx->dsa); + + return true; +} + +static struct pipe_video_context * radeon_mpeg12_context_create(struct pipe_screen *screen, enum pipe_video_profile profile, - enum pipe_video_chroma_format chr_f, + enum pipe_video_chroma_format chroma_format, unsigned int width, unsigned int height) { @@ -54,17 +239,17 @@ radeon_mpeg12_context_create(struct pipe_screen *screen, return NULL; ctx->base.profile = profile; - ctx->base.chroma_format = chr_f; + ctx->base.chroma_format = chroma_format; ctx->base.width = width; ctx->base.height = height; ctx->base.screen = screen; - ctx->base.destroy = NULL; - ctx->base.decode_macroblocks = NULL; - ctx->base.clear_surface = NULL; - ctx->base.render_picture = NULL; - ctx->base.set_decode_target = NULL; - ctx->base.set_csc_matrix = NULL; + ctx->base.destroy = radeon_mpeg12_destroy; + ctx->base.decode_macroblocks = radeon_mpeg12_decode_macroblocks; + ctx->base.clear_surface = radeon_mpeg12_clear_surface; + ctx->base.render_picture = radeon_mpeg12_render_picture; + ctx->base.set_decode_target = radeon_mpeg12_set_decode_target; + ctx->base.set_csc_matrix = radeon_mpeg12_set_csc_matrix; ctx->pipe = r300_create_context(screen,(struct r300_winsys*)screen->winsys); if (!ctx->pipe) @@ -74,7 +259,7 @@ radeon_mpeg12_context_create(struct pipe_screen *screen, } if (!vl_mpeg12_mc_renderer_init(&ctx->mc_renderer, ctx->pipe, - width, height, chr_f, + width, height, chroma_format, VL_MPEG12_MC_RENDERER_BUFFER_PICTURE, VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE, true)) @@ -92,7 +277,7 @@ radeon_mpeg12_context_create(struct pipe_screen *screen, return NULL; } - if (!init_pipe_state(ctx)) + if (!radeon_mpeg12_init_pipe_state(ctx)) { vl_compositor_cleanup(&ctx->compositor); vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer); @@ -107,15 +292,15 @@ radeon_mpeg12_context_create(struct pipe_screen *screen, /* * The following 3 functions are exported to xvmc. */ -Drawable vl_video_bind_drawable(struct pipe_video_context *p_context, +Drawable vl_video_bind_drawable(struct pipe_video_context *vpipe, Drawable drawable) { struct radeon_vl_context *rvl_ctx; Drawable old_drawable; - assert(p_context); + assert(vpipe); - rvl_ctx = p_context->priv; + rvl_ctx = vpipe->priv; old_drawable = rvl_ctx->drawable; rvl_ctx->drawable = drawable; @@ -124,7 +309,7 @@ Drawable vl_video_bind_drawable(struct pipe_video_context *p_context, struct pipe_screen *vl_screen_create(Display *display, int screen) { - struct pipe_screen *p_screen; + struct pipe_screen *screen_pipe; struct r300_winsys *r300; struct radeon_winsys *p_winsys; int drmFD; @@ -134,9 +319,9 @@ struct pipe_screen *vl_screen_create(Display *display, int screen) /* create radeon pipe_screen */ p_winsys = radeon_pipe_winsys(drmFD); r300 = radeon_create_r300_winsys(drmFD, p_winsys); - p_screen = r300_create_screen(r300); + screen_pipe = r300_create_screen(r300); - return p_screen; + return screen_pipe; } struct pipe_video_context *vl_video_create(struct pipe_screen *screen, @@ -145,7 +330,7 @@ struct pipe_video_context *vl_video_create(struct pipe_screen *screen, unsigned int width, unsigned int height) { - struct pipe_video_context *p_context; + struct pipe_video_context *vpipe; struct radeon_vl_context *rvl_ctx; assert(screen); @@ -155,18 +340,20 @@ struct pipe_video_context *vl_video_create(struct pipe_screen *screen, switch(u_reduce_video_profile(profile)) { case PIPE_VIDEO_CODEC_MPEG12: - p_context = radeon_mpeg12_context_create(screen, profile, chr_f, - width, height); + vpipe = radeon_mpeg12_context_create(screen, profile, chr_f, + width, height); + break; default: return NULL; } - /* create radeon_vl_context*/ + /* create radeon_vl_context, but it seems not necessary..... + */ rvl_ctx = calloc(1, sizeof(struct radeon_vl_context)); rvl_ctx->screen = screen; - p_context->priv = rvl_ctx; + vpipe->priv = rvl_ctx; - return p_context; + return vpipe; } diff --git a/src/gallium/winsys/g3dvl/radeon/radeon_vl.h b/src/gallium/winsys/g3dvl/radeon/radeon_vl.h index fe846f991..7fc285f11 100644 --- a/src/gallium/winsys/g3dvl/radeon/radeon_vl.h +++ b/src/gallium/winsys/g3dvl/radeon/radeon_vl.h @@ -26,6 +26,8 @@ #ifndef __RADEON_VL_H__ #define __RADEON_VL_H__ +#include "vl_mpeg12_mc_renderer.h" +#include "vl_compositor.h" struct radeon_vl_context { @@ -41,14 +43,14 @@ struct radeon_vl_screen struct radeon_mpeg12_context { - struct pipe_video_context base; - struct pipe_context *pipe; - struct pipe_video_surface *decode_surface; - struct vl_mpeg12_mc_renderer mc_render; - struct vl_compositor compositor; - void *rast; - void *dsa; - void *blend; + struct pipe_video_context base; + struct pipe_context *pipe; + struct pipe_video_surface *decode_target; + struct vl_mpeg12_mc_renderer mc_renderer; + struct vl_compositor compositor; + void *rast; + void *dsa; + void *blend; }; #endif //__RADEON_VL_H__
\ No newline at end of file |