1 /**************************************************************************
3 * Copyright 2009 Younes Manton.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
28 #include "util/u_inlines.h"
29 #include "util/u_memory.h"
31 #include "sp_video_context.h"
32 #include <util/u_inlines.h>
33 #include <util/u_memory.h>
34 #include <util/u_rect.h>
35 #include <util/u_video.h>
36 #include "sp_public.h"
37 #include "sp_texture.h"
40 sp_mpeg12_destroy(struct pipe_video_context
*vpipe
)
42 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
46 /* Asserted in softpipe_delete_fs_state() for some reason */
47 ctx
->pipe
->bind_vs_state(ctx
->pipe
, NULL
);
48 ctx
->pipe
->bind_fs_state(ctx
->pipe
, NULL
);
50 ctx
->pipe
->delete_blend_state(ctx
->pipe
, ctx
->blend
);
51 ctx
->pipe
->delete_rasterizer_state(ctx
->pipe
, ctx
->rast
);
52 ctx
->pipe
->delete_depth_stencil_alpha_state(ctx
->pipe
, ctx
->dsa
);
54 pipe_surface_reference(&ctx
->decode_target
, NULL
);
55 vl_compositor_cleanup(&ctx
->compositor
);
56 vl_mpeg12_mc_renderer_cleanup(&ctx
->mc_renderer
);
57 ctx
->pipe
->destroy(ctx
->pipe
);
63 sp_mpeg12_get_param(struct pipe_video_context
*vpipe
, int param
)
65 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
70 case PIPE_CAP_NPOT_TEXTURES
:
71 /* XXX: Temporary; not all paths are NPOT-tested */
73 return ctx
->pipe
->screen
->get_param(ctx
->pipe
->screen
, param
);
76 case PIPE_CAP_DECODE_TARGET_PREFERRED_FORMAT
:
77 return ctx
->decode_format
;
80 debug_printf("Softpipe: Unknown PIPE_CAP %d\n", param
);
87 sp_mpeg12_is_format_supported(struct pipe_video_context
*vpipe
,
88 enum pipe_format format
,
92 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
96 /* XXX: Temporary; not all paths are NPOT-tested */
97 if (geom
& PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO
)
100 return ctx
->pipe
->screen
->is_format_supported(ctx
->pipe
->screen
, PIPE_TEXTURE_2D
,
101 format
, usage
, geom
);
105 sp_mpeg12_decode_macroblocks(struct pipe_video_context
*vpipe
,
106 struct pipe_surface
*past
,
107 struct pipe_surface
*future
,
108 unsigned num_macroblocks
,
109 struct pipe_macroblock
*macroblocks
,
110 struct pipe_fence_handle
**fence
)
112 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
113 struct pipe_mpeg12_macroblock
*mpeg12_macroblocks
= (struct pipe_mpeg12_macroblock
*)macroblocks
;
116 assert(num_macroblocks
);
118 assert(macroblocks
->codec
== PIPE_VIDEO_CODEC_MPEG12
);
119 assert(ctx
->decode_target
);
121 vl_mpeg12_mc_renderer_render_macroblocks(&ctx
->mc_renderer
,
123 past
, future
, num_macroblocks
,
124 mpeg12_macroblocks
, fence
);
128 sp_mpeg12_surface_fill(struct pipe_video_context
*vpipe
,
129 struct pipe_surface
*dst
,
130 unsigned dstx
, unsigned dsty
,
131 unsigned width
, unsigned height
,
134 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
139 if (ctx
->pipe
->surface_fill
)
140 ctx
->pipe
->surface_fill(ctx
->pipe
, dst
, dstx
, dsty
, width
, height
, value
);
142 util_surface_fill(ctx
->pipe
, dst
, dstx
, dsty
, width
, height
, value
);
146 sp_mpeg12_surface_copy(struct pipe_video_context
*vpipe
,
147 struct pipe_surface
*dst
,
148 unsigned dstx
, unsigned dsty
,
149 struct pipe_surface
*src
,
150 unsigned srcx
, unsigned srcy
,
151 unsigned width
, unsigned height
)
153 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
158 if (ctx
->pipe
->surface_copy
)
159 ctx
->pipe
->surface_copy(ctx
->pipe
, dst
, dstx
, dsty
, src
, srcx
, srcy
, width
, height
);
161 util_surface_copy(ctx
->pipe
, FALSE
, dst
, dstx
, dsty
, src
, srcx
, srcy
, width
, height
);
165 sp_mpeg12_render_picture(struct pipe_video_context
*vpipe
,
166 struct pipe_surface
*src_surface
,
167 enum pipe_mpeg12_picture_type picture_type
,
168 /*unsigned num_past_surfaces,
169 struct pipe_surface *past_surfaces,
170 unsigned num_future_surfaces,
171 struct pipe_surface *future_surfaces,*/
172 struct pipe_video_rect
*src_area
,
173 struct pipe_surface
*dst_surface
,
174 struct pipe_video_rect
*dst_area
,
175 struct pipe_fence_handle
**fence
)
177 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
185 vl_compositor_render(&ctx
->compositor
, src_surface
,
186 picture_type
, src_area
, dst_surface
, dst_area
, fence
);
190 sp_mpeg12_set_picture_background(struct pipe_video_context
*vpipe
,
191 struct pipe_surface
*bg
,
192 struct pipe_video_rect
*bg_src_rect
)
194 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
200 vl_compositor_set_background(&ctx
->compositor
, bg
, bg_src_rect
);
204 sp_mpeg12_set_picture_layers(struct pipe_video_context
*vpipe
,
205 struct pipe_surface
*layers
[],
206 struct pipe_video_rect
*src_rects
[],
207 struct pipe_video_rect
*dst_rects
[],
210 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
213 assert((layers
&& src_rects
&& dst_rects
) ||
214 (!layers
&& !src_rects
&& !dst_rects
));
216 vl_compositor_set_layers(&ctx
->compositor
, layers
, src_rects
, dst_rects
, num_layers
);
220 sp_mpeg12_set_decode_target(struct pipe_video_context
*vpipe
,
221 struct pipe_surface
*dt
)
223 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
228 pipe_surface_reference(&ctx
->decode_target
, dt
);
232 sp_mpeg12_set_csc_matrix(struct pipe_video_context
*vpipe
, const float *mat
)
234 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
238 vl_compositor_set_csc_matrix(&ctx
->compositor
, mat
);
242 init_pipe_state(struct sp_mpeg12_context
*ctx
)
244 struct pipe_rasterizer_state rast
;
245 struct pipe_blend_state blend
;
246 struct pipe_depth_stencil_alpha_state dsa
;
252 rast
.flatshade_first
= 0;
253 rast
.light_twoside
= 0;
254 rast
.front_winding
= PIPE_WINDING_CCW
;
255 rast
.cull_mode
= PIPE_WINDING_CW
;
256 rast
.fill_cw
= PIPE_POLYGON_MODE_FILL
;
257 rast
.fill_ccw
= PIPE_POLYGON_MODE_FILL
;
261 rast
.poly_smooth
= 0;
262 rast
.poly_stipple_enable
= 0;
263 rast
.sprite_coord_enable
= 0;
264 rast
.point_size_per_vertex
= 0;
265 rast
.multisample
= 0;
266 rast
.line_smooth
= 0;
267 rast
.line_stipple_enable
= 0;
268 rast
.line_stipple_factor
= 0;
269 rast
.line_stipple_pattern
= 0;
270 rast
.line_last_pixel
= 0;
272 rast
.point_smooth
= 0;
273 rast
.point_quad_rasterization
= 0;
275 rast
.offset_units
= 1;
276 rast
.offset_scale
= 1;
277 rast
.gl_rasterization_rules
= 1;
278 ctx
->rast
= ctx
->pipe
->create_rasterizer_state(ctx
->pipe
, &rast
);
279 ctx
->pipe
->bind_rasterizer_state(ctx
->pipe
, ctx
->rast
);
281 blend
.independent_blend_enable
= 0;
282 blend
.rt
[0].blend_enable
= 0;
283 blend
.rt
[0].rgb_func
= PIPE_BLEND_ADD
;
284 blend
.rt
[0].rgb_src_factor
= PIPE_BLENDFACTOR_ONE
;
285 blend
.rt
[0].rgb_dst_factor
= PIPE_BLENDFACTOR_ONE
;
286 blend
.rt
[0].alpha_func
= PIPE_BLEND_ADD
;
287 blend
.rt
[0].alpha_src_factor
= PIPE_BLENDFACTOR_ONE
;
288 blend
.rt
[0].alpha_dst_factor
= PIPE_BLENDFACTOR_ONE
;
289 blend
.logicop_enable
= 0;
290 blend
.logicop_func
= PIPE_LOGICOP_CLEAR
;
291 /* Needed to allow color writes to FB, even if blending disabled */
292 blend
.rt
[0].colormask
= PIPE_MASK_RGBA
;
294 ctx
->blend
= ctx
->pipe
->create_blend_state(ctx
->pipe
, &blend
);
295 ctx
->pipe
->bind_blend_state(ctx
->pipe
, ctx
->blend
);
297 dsa
.depth
.enabled
= 0;
298 dsa
.depth
.writemask
= 0;
299 dsa
.depth
.func
= PIPE_FUNC_ALWAYS
;
300 for (i
= 0; i
< 2; ++i
) {
301 dsa
.stencil
[i
].enabled
= 0;
302 dsa
.stencil
[i
].func
= PIPE_FUNC_ALWAYS
;
303 dsa
.stencil
[i
].fail_op
= PIPE_STENCIL_OP_KEEP
;
304 dsa
.stencil
[i
].zpass_op
= PIPE_STENCIL_OP_KEEP
;
305 dsa
.stencil
[i
].zfail_op
= PIPE_STENCIL_OP_KEEP
;
306 dsa
.stencil
[i
].valuemask
= 0;
307 dsa
.stencil
[i
].writemask
= 0;
309 dsa
.alpha
.enabled
= 0;
310 dsa
.alpha
.func
= PIPE_FUNC_ALWAYS
;
311 dsa
.alpha
.ref_value
= 0;
312 ctx
->dsa
= ctx
->pipe
->create_depth_stencil_alpha_state(ctx
->pipe
, &dsa
);
313 ctx
->pipe
->bind_depth_stencil_alpha_state(ctx
->pipe
, ctx
->dsa
);
318 static struct pipe_video_context
*
319 sp_mpeg12_create(struct pipe_context
*pipe
, enum pipe_video_profile profile
,
320 enum pipe_video_chroma_format chroma_format
,
321 unsigned width
, unsigned height
,
322 enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode
,
323 enum VL_MPEG12_MC_RENDERER_EMPTY_BLOCK eb_handling
,
325 enum pipe_format decode_format
)
327 struct sp_mpeg12_context
*ctx
;
329 assert(u_reduce_video_profile(profile
) == PIPE_VIDEO_CODEC_MPEG12
);
331 ctx
= CALLOC_STRUCT(sp_mpeg12_context
);
336 ctx
->base
.profile
= profile
;
337 ctx
->base
.chroma_format
= chroma_format
;
338 ctx
->base
.width
= width
;
339 ctx
->base
.height
= height
;
341 ctx
->base
.screen
= pipe
->screen
;
342 ctx
->base
.destroy
= sp_mpeg12_destroy
;
343 ctx
->base
.get_param
= sp_mpeg12_get_param
;
344 ctx
->base
.is_format_supported
= sp_mpeg12_is_format_supported
;
345 ctx
->base
.decode_macroblocks
= sp_mpeg12_decode_macroblocks
;
346 ctx
->base
.render_picture
= sp_mpeg12_render_picture
;
347 ctx
->base
.surface_fill
= sp_mpeg12_surface_fill
;
348 ctx
->base
.surface_copy
= sp_mpeg12_surface_copy
;
349 ctx
->base
.set_picture_background
= sp_mpeg12_set_picture_background
;
350 ctx
->base
.set_picture_layers
= sp_mpeg12_set_picture_layers
;
351 ctx
->base
.set_decode_target
= sp_mpeg12_set_decode_target
;
352 ctx
->base
.set_csc_matrix
= sp_mpeg12_set_csc_matrix
;
355 ctx
->decode_format
= decode_format
;
357 if (!vl_mpeg12_mc_renderer_init(&ctx
->mc_renderer
, ctx
->pipe
,
358 width
, height
, chroma_format
,
359 bufmode
, eb_handling
, pot_buffers
)) {
360 ctx
->pipe
->destroy(ctx
->pipe
);
365 if (!vl_compositor_init(&ctx
->compositor
, ctx
->pipe
)) {
366 vl_mpeg12_mc_renderer_cleanup(&ctx
->mc_renderer
);
367 ctx
->pipe
->destroy(ctx
->pipe
);
372 if (!init_pipe_state(ctx
)) {
373 vl_compositor_cleanup(&ctx
->compositor
);
374 vl_mpeg12_mc_renderer_cleanup(&ctx
->mc_renderer
);
375 ctx
->pipe
->destroy(ctx
->pipe
);
383 struct pipe_video_context
*
384 sp_video_create(struct pipe_screen
*screen
, enum pipe_video_profile profile
,
385 enum pipe_video_chroma_format chroma_format
,
386 unsigned width
, unsigned height
, void *priv
)
388 struct pipe_context
*pipe
;
391 assert(width
&& height
);
393 pipe
= screen
->context_create(screen
, NULL
);
397 /* TODO: Use slice buffering for softpipe when implemented, no advantage to buffering an entire picture with softpipe */
398 /* TODO: Use XFER_NONE when implemented */
399 return sp_video_create_ex(pipe
, profile
,
402 VL_MPEG12_MC_RENDERER_BUFFER_PICTURE
,
403 VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE
,
408 struct pipe_video_context
*
409 sp_video_create_ex(struct pipe_context
*pipe
, enum pipe_video_profile profile
,
410 enum pipe_video_chroma_format chroma_format
,
411 unsigned width
, unsigned height
,
412 enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode
,
413 enum VL_MPEG12_MC_RENDERER_EMPTY_BLOCK eb_handling
,
415 enum pipe_format decode_format
)
418 assert(width
&& height
);
420 switch (u_reduce_video_profile(profile
)) {
421 case PIPE_VIDEO_CODEC_MPEG12
:
422 return sp_mpeg12_create(pipe
, profile
,
425 bufmode
, eb_handling
,