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 "sp_video_context.h"
29 #include <pipe/p_inlines.h>
30 #include <util/u_memory.h>
31 #include <util/u_rect.h>
32 #include <util/u_video.h>
33 #include "sp_winsys.h"
34 #include "sp_texture.h"
37 sp_mpeg12_destroy(struct pipe_video_context
*vpipe
)
39 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
43 /* Asserted in softpipe_delete_fs_state() for some reason */
44 ctx
->pipe
->bind_vs_state(ctx
->pipe
, NULL
);
45 ctx
->pipe
->bind_fs_state(ctx
->pipe
, NULL
);
47 ctx
->pipe
->delete_blend_state(ctx
->pipe
, ctx
->blend
);
48 ctx
->pipe
->delete_rasterizer_state(ctx
->pipe
, ctx
->rast
);
49 ctx
->pipe
->delete_depth_stencil_alpha_state(ctx
->pipe
, ctx
->dsa
);
51 pipe_video_surface_reference(&ctx
->decode_target
, NULL
);
52 vl_compositor_cleanup(&ctx
->compositor
);
53 vl_mpeg12_mc_renderer_cleanup(&ctx
->mc_renderer
);
54 ctx
->pipe
->destroy(ctx
->pipe
);
60 sp_mpeg12_decode_macroblocks(struct pipe_video_context
*vpipe
,
61 struct pipe_video_surface
*past
,
62 struct pipe_video_surface
*future
,
63 unsigned num_macroblocks
,
64 struct pipe_macroblock
*macroblocks
,
65 struct pipe_fence_handle
**fence
)
67 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
68 struct pipe_mpeg12_macroblock
*mpeg12_macroblocks
= (struct pipe_mpeg12_macroblock
*)macroblocks
;
71 assert(num_macroblocks
);
73 assert(macroblocks
->codec
== PIPE_VIDEO_CODEC_MPEG12
);
74 assert(ctx
->decode_target
);
76 vl_mpeg12_mc_renderer_render_macroblocks(&ctx
->mc_renderer
,
77 softpipe_video_surface(ctx
->decode_target
)->tex
,
78 past
? softpipe_video_surface(past
)->tex
: NULL
,
79 future
? softpipe_video_surface(future
)->tex
: NULL
,
80 num_macroblocks
, mpeg12_macroblocks
, fence
);
84 sp_mpeg12_surface_fill(struct pipe_video_context
*vpipe
,
85 struct pipe_surface
*dst
,
86 unsigned dstx
, unsigned dsty
,
87 unsigned width
, unsigned height
,
90 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
95 if (ctx
->pipe
->surface_fill
)
96 ctx
->pipe
->surface_fill(ctx
->pipe
, dst
, dstx
, dsty
, width
, height
, value
);
98 util_surface_fill(ctx
->pipe
, dst
, dstx
, dsty
, width
, height
, value
);
102 sp_mpeg12_surface_copy(struct pipe_video_context
*vpipe
,
103 struct pipe_surface
*dst
,
104 unsigned dstx
, unsigned dsty
,
105 struct pipe_surface
*src
,
106 unsigned srcx
, unsigned srcy
,
107 unsigned width
, unsigned height
)
109 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
114 if (ctx
->pipe
->surface_copy
)
115 ctx
->pipe
->surface_copy(ctx
->pipe
, dst
, dstx
, dsty
, src
, srcx
, srcy
, width
, height
);
117 util_surface_copy(ctx
->pipe
, FALSE
, dst
, dstx
, dsty
, src
, srcx
, srcy
, width
, height
);
121 sp_mpeg12_render_picture(struct pipe_video_context
*vpipe
,
122 /*struct pipe_surface *backround,
123 struct pipe_video_rect *backround_area,*/
124 struct pipe_video_surface
*src_surface
,
125 enum pipe_mpeg12_picture_type picture_type
,
126 /*unsigned num_past_surfaces,
127 struct pipe_video_surface *past_surfaces,
128 unsigned num_future_surfaces,
129 struct pipe_video_surface *future_surfaces,*/
130 struct pipe_video_rect
*src_area
,
131 struct pipe_surface
*dst_surface
,
132 struct pipe_video_rect
*dst_area
,
133 /*unsigned num_layers,
134 struct pipe_surface *layers,
135 struct pipe_video_rect *layer_src_areas,
136 struct pipe_video_rect *layer_dst_areas*/
137 struct pipe_fence_handle
**fence
)
139 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
147 vl_compositor_render(&ctx
->compositor
, softpipe_video_surface(src_surface
)->tex
,
148 picture_type
, src_area
, dst_surface
->texture
, dst_area
, fence
);
152 sp_mpeg12_set_decode_target(struct pipe_video_context
*vpipe
,
153 struct pipe_video_surface
*dt
)
155 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
160 pipe_video_surface_reference(&ctx
->decode_target
, dt
);
164 sp_mpeg12_set_csc_matrix(struct pipe_video_context
*vpipe
, const float *mat
)
166 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
170 vl_compositor_set_csc_matrix(&ctx
->compositor
, mat
);
174 init_pipe_state(struct sp_mpeg12_context
*ctx
)
176 struct pipe_rasterizer_state rast
;
177 struct pipe_blend_state blend
;
178 struct pipe_depth_stencil_alpha_state dsa
;
184 rast
.flatshade_first
= 0;
185 rast
.light_twoside
= 0;
186 rast
.front_winding
= PIPE_WINDING_CCW
;
187 rast
.cull_mode
= PIPE_WINDING_CW
;
188 rast
.fill_cw
= PIPE_POLYGON_MODE_FILL
;
189 rast
.fill_ccw
= PIPE_POLYGON_MODE_FILL
;
193 rast
.poly_smooth
= 0;
194 rast
.poly_stipple_enable
= 0;
195 rast
.point_sprite
= 0;
196 rast
.point_size_per_vertex
= 0;
197 rast
.multisample
= 0;
198 rast
.line_smooth
= 0;
199 rast
.line_stipple_enable
= 0;
200 rast
.line_stipple_factor
= 0;
201 rast
.line_stipple_pattern
= 0;
202 rast
.line_last_pixel
= 0;
203 rast
.bypass_vs_clip_and_viewport
= 0;
205 rast
.point_smooth
= 0;
207 rast
.offset_units
= 1;
208 rast
.offset_scale
= 1;
209 rast
.gl_rasterization_rules
= 1;
210 /*rast.sprite_coord_mode[i] = ;*/
211 ctx
->rast
= ctx
->pipe
->create_rasterizer_state(ctx
->pipe
, &rast
);
212 ctx
->pipe
->bind_rasterizer_state(ctx
->pipe
, ctx
->rast
);
214 blend
.blend_enable
= 0;
215 blend
.rgb_func
= PIPE_BLEND_ADD
;
216 blend
.rgb_src_factor
= PIPE_BLENDFACTOR_ONE
;
217 blend
.rgb_dst_factor
= PIPE_BLENDFACTOR_ONE
;
218 blend
.alpha_func
= PIPE_BLEND_ADD
;
219 blend
.alpha_src_factor
= PIPE_BLENDFACTOR_ONE
;
220 blend
.alpha_dst_factor
= PIPE_BLENDFACTOR_ONE
;
221 blend
.logicop_enable
= 0;
222 blend
.logicop_func
= PIPE_LOGICOP_CLEAR
;
223 /* Needed to allow color writes to FB, even if blending disabled */
224 blend
.colormask
= PIPE_MASK_RGBA
;
226 ctx
->blend
= ctx
->pipe
->create_blend_state(ctx
->pipe
, &blend
);
227 ctx
->pipe
->bind_blend_state(ctx
->pipe
, ctx
->blend
);
229 dsa
.depth
.enabled
= 0;
230 dsa
.depth
.writemask
= 0;
231 dsa
.depth
.func
= PIPE_FUNC_ALWAYS
;
232 for (i
= 0; i
< 2; ++i
) {
233 dsa
.stencil
[i
].enabled
= 0;
234 dsa
.stencil
[i
].func
= PIPE_FUNC_ALWAYS
;
235 dsa
.stencil
[i
].fail_op
= PIPE_STENCIL_OP_KEEP
;
236 dsa
.stencil
[i
].zpass_op
= PIPE_STENCIL_OP_KEEP
;
237 dsa
.stencil
[i
].zfail_op
= PIPE_STENCIL_OP_KEEP
;
238 dsa
.stencil
[i
].ref_value
= 0;
239 dsa
.stencil
[i
].valuemask
= 0;
240 dsa
.stencil
[i
].writemask
= 0;
242 dsa
.alpha
.enabled
= 0;
243 dsa
.alpha
.func
= PIPE_FUNC_ALWAYS
;
244 dsa
.alpha
.ref_value
= 0;
245 ctx
->dsa
= ctx
->pipe
->create_depth_stencil_alpha_state(ctx
->pipe
, &dsa
);
246 ctx
->pipe
->bind_depth_stencil_alpha_state(ctx
->pipe
, ctx
->dsa
);
251 static struct pipe_video_context
*
252 sp_mpeg12_create(struct pipe_context
*pipe
, enum pipe_video_profile profile
,
253 enum pipe_video_chroma_format chroma_format
,
254 unsigned width
, unsigned height
,
255 enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode
,
256 enum VL_MPEG12_MC_RENDERER_EMPTY_BLOCK eb_handling
,
259 struct sp_mpeg12_context
*ctx
;
261 assert(u_reduce_video_profile(profile
) == PIPE_VIDEO_CODEC_MPEG12
);
263 ctx
= CALLOC_STRUCT(sp_mpeg12_context
);
268 ctx
->base
.profile
= profile
;
269 ctx
->base
.chroma_format
= chroma_format
;
270 ctx
->base
.width
= width
;
271 ctx
->base
.height
= height
;
273 ctx
->base
.screen
= pipe
->screen
;
274 ctx
->base
.destroy
= sp_mpeg12_destroy
;
275 ctx
->base
.decode_macroblocks
= sp_mpeg12_decode_macroblocks
;
276 ctx
->base
.render_picture
= sp_mpeg12_render_picture
;
277 ctx
->base
.surface_fill
= sp_mpeg12_surface_fill
;
278 ctx
->base
.surface_copy
= sp_mpeg12_surface_copy
;
279 ctx
->base
.set_decode_target
= sp_mpeg12_set_decode_target
;
280 ctx
->base
.set_csc_matrix
= sp_mpeg12_set_csc_matrix
;
284 if (!vl_mpeg12_mc_renderer_init(&ctx
->mc_renderer
, ctx
->pipe
,
285 width
, height
, chroma_format
,
286 bufmode
, eb_handling
, pot_buffers
)) {
287 ctx
->pipe
->destroy(ctx
->pipe
);
292 if (!vl_compositor_init(&ctx
->compositor
, ctx
->pipe
)) {
293 vl_mpeg12_mc_renderer_cleanup(&ctx
->mc_renderer
);
294 ctx
->pipe
->destroy(ctx
->pipe
);
299 if (!init_pipe_state(ctx
)) {
300 vl_compositor_cleanup(&ctx
->compositor
);
301 vl_mpeg12_mc_renderer_cleanup(&ctx
->mc_renderer
);
302 ctx
->pipe
->destroy(ctx
->pipe
);
310 struct pipe_video_context
*
311 sp_video_create(struct pipe_screen
*screen
, enum pipe_video_profile profile
,
312 enum pipe_video_chroma_format chroma_format
,
313 unsigned width
, unsigned height
)
315 struct pipe_context
*pipe
;
318 assert(width
&& height
);
320 pipe
= softpipe_create(screen
);
324 /* TODO: Use slice buffering for softpipe when implemented, no advantage to buffering an entire picture with softpipe */
325 /* TODO: Use XFER_NONE when implemented */
326 return sp_video_create_ex(pipe
, profile
,
329 VL_MPEG12_MC_RENDERER_BUFFER_PICTURE
,
330 VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE
,
334 struct pipe_video_context
*
335 sp_video_create_ex(struct pipe_context
*pipe
, enum pipe_video_profile profile
,
336 enum pipe_video_chroma_format chroma_format
,
337 unsigned width
, unsigned height
,
338 enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode
,
339 enum VL_MPEG12_MC_RENDERER_EMPTY_BLOCK eb_handling
,
343 assert(width
&& height
);
345 switch (u_reduce_video_profile(profile
)) {
346 case PIPE_VIDEO_CODEC_MPEG12
:
347 return sp_mpeg12_create(pipe
, profile
,
350 bufmode
, eb_handling
,