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 <util/u_surface.h>
37 #include "sp_public.h"
38 #include "sp_texture.h"
41 sp_mpeg12_destroy(struct pipe_video_context
*vpipe
)
43 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
47 /* Asserted in softpipe_delete_fs_state() for some reason */
48 ctx
->pipe
->bind_vs_state(ctx
->pipe
, NULL
);
49 ctx
->pipe
->bind_fs_state(ctx
->pipe
, NULL
);
51 ctx
->pipe
->delete_blend_state(ctx
->pipe
, ctx
->blend
);
52 ctx
->pipe
->delete_rasterizer_state(ctx
->pipe
, ctx
->rast
);
53 ctx
->pipe
->delete_depth_stencil_alpha_state(ctx
->pipe
, ctx
->dsa
);
55 pipe_surface_reference(&ctx
->decode_target
, NULL
);
56 vl_compositor_cleanup(&ctx
->compositor
);
57 vl_mpeg12_mc_renderer_cleanup(&ctx
->mc_renderer
);
58 ctx
->pipe
->destroy(ctx
->pipe
);
64 sp_mpeg12_get_param(struct pipe_video_context
*vpipe
, int param
)
66 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
71 case PIPE_CAP_NPOT_TEXTURES
:
72 /* XXX: Temporary; not all paths are NPOT-tested */
74 return ctx
->pipe
->screen
->get_param(ctx
->pipe
->screen
, param
);
77 case PIPE_CAP_DECODE_TARGET_PREFERRED_FORMAT
:
78 return ctx
->decode_format
;
81 debug_printf("Softpipe: Unknown PIPE_CAP %d\n", param
);
88 sp_mpeg12_is_format_supported(struct pipe_video_context
*vpipe
,
89 enum pipe_format format
,
93 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
97 /* XXX: Temporary; not all paths are NPOT-tested */
98 if (geom
& PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO
)
102 return ctx
->pipe
->screen
->is_format_supported(ctx
->pipe
->screen
, format
, PIPE_TEXTURE_2D
, 1,
105 return ctx
->pipe
->screen
->is_format_supported(ctx
->pipe
->screen
, format
, PIPE_TEXTURE_2D
,
107 >>>>>>> 97a7cf230a70c64fff300931ae7c00aa00449c97
111 sp_mpeg12_decode_macroblocks(struct pipe_video_context
*vpipe
,
112 struct pipe_surface
*past
,
113 struct pipe_surface
*future
,
114 unsigned num_macroblocks
,
115 struct pipe_macroblock
*macroblocks
,
116 struct pipe_fence_handle
**fence
)
118 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
119 struct pipe_mpeg12_macroblock
*mpeg12_macroblocks
= (struct pipe_mpeg12_macroblock
*)macroblocks
;
122 assert(num_macroblocks
);
124 assert(macroblocks
->codec
== PIPE_VIDEO_CODEC_MPEG12
);
125 assert(ctx
->decode_target
);
127 vl_mpeg12_mc_renderer_render_macroblocks(&ctx
->mc_renderer
,
129 past
, future
, num_macroblocks
,
130 mpeg12_macroblocks
, fence
);
134 sp_mpeg12_clear_render_target(struct pipe_video_context
*vpipe
,
135 struct pipe_surface
*dst
,
136 unsigned dstx
, unsigned dsty
,
138 unsigned width
, unsigned height
)
140 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
141 float rgba
[4] = { 0, 0, 0, 0 };
146 if (ctx
->pipe
->clear_render_target
)
147 ctx
->pipe
->clear_render_target(ctx
->pipe
, dst
, rgba
, dstx
, dsty
, width
, height
);
149 util_clear_render_target(ctx
->pipe
, dst
, rgba
, dstx
, dsty
, width
, height
);
153 sp_mpeg12_resource_copy_region(struct pipe_video_context
*vpipe
,
154 struct pipe_resource
*dst
,
155 struct pipe_subresource subdst
,
156 unsigned dstx
, unsigned dsty
, unsigned dstz
,
157 struct pipe_resource
*src
,
158 struct pipe_subresource subsrc
,
159 unsigned srcx
, unsigned srcy
, unsigned srcz
,
160 unsigned width
, unsigned height
)
162 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
168 if (ctx
->pipe
->resource_copy_region
)
169 ctx
->pipe
->resource_copy_region(ctx
->pipe
, dst
, subdst
, dstx
, dsty
, dstz
, src
, subsrc
, srcx
, srcy
, srcz
, width
, height
);
171 util_resource_copy_region(ctx
->pipe
, dst
, subdst
, dstx
, dsty
, dstz
, src
, subsrc
, srcx
, srcy
, srcz
, width
, height
);
173 struct pipe_subresource subdst
, subsrc
;
174 subdst
.face
= dst
->face
;
175 subdst
.level
= dst
->level
;
176 subsrc
.face
= src
->face
;
177 subsrc
.level
= src
->level
;
179 if (ctx
->pipe
->resource_copy_region
)
180 ctx
->pipe
->resource_copy_region(ctx
->pipe
, dst
->texture
, subdst
, dstx
, dsty
, dst
->zslice
,
181 src
->texture
, subsrc
, srcx
, srcy
, src
->zslice
,
184 util_resource_copy_region(ctx
->pipe
, dst
->texture
, subdst
, dstx
, dsty
, dst
->zslice
,
185 src
->texture
, subsrc
, srcx
, srcy
, src
->zslice
,
187 >>>>>>> 97a7cf230a70c64fff300931ae7c00aa00449c97
190 static struct pipe_transfer
*
191 sp_mpeg12_get_transfer(struct pipe_video_context
*vpipe
,
192 struct pipe_resource
*resource
,
193 struct pipe_subresource subresource
,
194 unsigned usage
, /* a combination of PIPE_TRANSFER_x */
195 const struct pipe_box
*box
)
197 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
203 return ctx
->pipe
->get_transfer(ctx
->pipe
, resource
, subresource
, usage
, box
);
207 sp_mpeg12_transfer_destroy(struct pipe_video_context
*vpipe
,
208 struct pipe_transfer
*transfer
)
210 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
215 ctx
->pipe
->transfer_destroy(ctx
->pipe
, transfer
);
219 sp_mpeg12_transfer_map(struct pipe_video_context
*vpipe
,
220 struct pipe_transfer
*transfer
)
222 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
227 return ctx
->pipe
->transfer_map(ctx
->pipe
, transfer
);
231 sp_mpeg12_transfer_flush_region(struct pipe_video_context
*vpipe
,
232 struct pipe_transfer
*transfer
,
233 const struct pipe_box
*box
)
235 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
241 ctx
->pipe
->transfer_flush_region(ctx
->pipe
, transfer
, box
);
245 sp_mpeg12_transfer_unmap(struct pipe_video_context
*vpipe
,
246 struct pipe_transfer
*transfer
)
248 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
253 ctx
->pipe
->transfer_unmap(ctx
->pipe
, transfer
);
257 sp_mpeg12_transfer_inline_write(struct pipe_video_context
*vpipe
,
258 struct pipe_resource
*resource
,
259 struct pipe_subresource subresource
,
260 unsigned usage
, /* a combination of PIPE_TRANSFER_x */
261 const struct pipe_box
*box
,
264 unsigned slice_stride
)
266 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
272 assert(ctx
->pipe
->transfer_inline_write
);
274 ctx
->pipe
->transfer_inline_write(ctx
->pipe
, resource
, subresource
, usage
,
275 box
, data
, stride
, slice_stride
);
279 sp_mpeg12_render_picture(struct pipe_video_context
*vpipe
,
280 struct pipe_surface
*src_surface
,
281 enum pipe_mpeg12_picture_type picture_type
,
282 /*unsigned num_past_surfaces,
283 struct pipe_surface *past_surfaces,
284 unsigned num_future_surfaces,
285 struct pipe_surface *future_surfaces,*/
286 struct pipe_video_rect
*src_area
,
287 struct pipe_surface
*dst_surface
,
288 struct pipe_video_rect
*dst_area
,
289 struct pipe_fence_handle
**fence
)
291 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
299 vl_compositor_render(&ctx
->compositor
, src_surface
,
300 picture_type
, src_area
, dst_surface
, dst_area
, fence
);
304 sp_mpeg12_set_picture_background(struct pipe_video_context
*vpipe
,
305 struct pipe_surface
*bg
,
306 struct pipe_video_rect
*bg_src_rect
)
308 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
314 vl_compositor_set_background(&ctx
->compositor
, bg
, bg_src_rect
);
318 sp_mpeg12_set_picture_layers(struct pipe_video_context
*vpipe
,
319 struct pipe_surface
*layers
[],
320 struct pipe_video_rect
*src_rects
[],
321 struct pipe_video_rect
*dst_rects
[],
324 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
327 assert((layers
&& src_rects
&& dst_rects
) ||
328 (!layers
&& !src_rects
&& !dst_rects
));
330 vl_compositor_set_layers(&ctx
->compositor
, layers
, src_rects
, dst_rects
, num_layers
);
334 sp_mpeg12_set_decode_target(struct pipe_video_context
*vpipe
,
335 struct pipe_surface
*dt
)
337 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
342 pipe_surface_reference(&ctx
->decode_target
, dt
);
346 sp_mpeg12_set_csc_matrix(struct pipe_video_context
*vpipe
, const float *mat
)
348 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
352 vl_compositor_set_csc_matrix(&ctx
->compositor
, mat
);
356 init_pipe_state(struct sp_mpeg12_context
*ctx
)
358 struct pipe_rasterizer_state rast
;
359 struct pipe_blend_state blend
;
360 struct pipe_depth_stencil_alpha_state dsa
;
365 memset(&rast
, 0, sizeof rast
);
367 rast
.flatshade_first
= 0;
368 rast
.light_twoside
= 0;
370 rast
.cull_face
= PIPE_FACE_FRONT
;
371 rast
.fill_front
= PIPE_POLYGON_MODE_FILL
;
372 rast
.fill_back
= PIPE_POLYGON_MODE_FILL
;
375 rast
.cull_face
= PIPE_FACE_NONE
;
376 rast
.fill_back
= PIPE_POLYGON_MODE_FILL
;
377 rast
.fill_front
= PIPE_POLYGON_MODE_FILL
;
378 rast
.offset_point
= 0;
379 rast
.offset_line
= 0;
380 >>>>>>> 97a7cf230a70c64fff300931ae7c00aa00449c97
382 rast
.poly_smooth
= 0;
383 rast
.poly_stipple_enable
= 0;
384 rast
.sprite_coord_enable
= 0;
385 rast
.point_size_per_vertex
= 0;
386 rast
.multisample
= 0;
387 rast
.line_smooth
= 0;
388 rast
.line_stipple_enable
= 0;
389 rast
.line_stipple_factor
= 0;
390 rast
.line_stipple_pattern
= 0;
391 rast
.line_last_pixel
= 0;
393 rast
.point_smooth
= 0;
394 rast
.point_quad_rasterization
= 0;
395 rast
.point_size_per_vertex
= 1;
396 rast
.offset_units
= 1;
397 rast
.offset_scale
= 1;
398 rast
.gl_rasterization_rules
= 1;
400 ctx
->rast
= ctx
->pipe
->create_rasterizer_state(ctx
->pipe
, &rast
);
401 ctx
->pipe
->bind_rasterizer_state(ctx
->pipe
, ctx
->rast
);
406 memset(&blend
, 0, sizeof blend
);
407 >>>>>>> 97a7cf230a70c64fff300931ae7c00aa00449c97
408 blend
.independent_blend_enable
= 0;
409 blend
.rt
[0].blend_enable
= 0;
410 blend
.rt
[0].rgb_func
= PIPE_BLEND_ADD
;
411 blend
.rt
[0].rgb_src_factor
= PIPE_BLENDFACTOR_ONE
;
412 blend
.rt
[0].rgb_dst_factor
= PIPE_BLENDFACTOR_ONE
;
413 blend
.rt
[0].alpha_func
= PIPE_BLEND_ADD
;
414 blend
.rt
[0].alpha_src_factor
= PIPE_BLENDFACTOR_ONE
;
415 blend
.rt
[0].alpha_dst_factor
= PIPE_BLENDFACTOR_ONE
;
416 blend
.logicop_enable
= 0;
417 blend
.logicop_func
= PIPE_LOGICOP_CLEAR
;
418 /* Needed to allow color writes to FB, even if blending disabled */
419 blend
.rt
[0].colormask
= PIPE_MASK_RGBA
;
421 ctx
->blend
= ctx
->pipe
->create_blend_state(ctx
->pipe
, &blend
);
422 ctx
->pipe
->bind_blend_state(ctx
->pipe
, ctx
->blend
);
424 memset(&dsa
, 0, sizeof dsa
);
425 dsa
.depth
.enabled
= 0;
426 dsa
.depth
.writemask
= 0;
427 dsa
.depth
.func
= PIPE_FUNC_ALWAYS
;
428 for (i
= 0; i
< 2; ++i
) {
429 dsa
.stencil
[i
].enabled
= 0;
430 dsa
.stencil
[i
].func
= PIPE_FUNC_ALWAYS
;
431 dsa
.stencil
[i
].fail_op
= PIPE_STENCIL_OP_KEEP
;
432 dsa
.stencil
[i
].zpass_op
= PIPE_STENCIL_OP_KEEP
;
433 dsa
.stencil
[i
].zfail_op
= PIPE_STENCIL_OP_KEEP
;
434 dsa
.stencil
[i
].valuemask
= 0;
435 dsa
.stencil
[i
].writemask
= 0;
437 dsa
.alpha
.enabled
= 0;
438 dsa
.alpha
.func
= PIPE_FUNC_ALWAYS
;
439 dsa
.alpha
.ref_value
= 0;
440 ctx
->dsa
= ctx
->pipe
->create_depth_stencil_alpha_state(ctx
->pipe
, &dsa
);
441 ctx
->pipe
->bind_depth_stencil_alpha_state(ctx
->pipe
, ctx
->dsa
);
446 static struct pipe_video_context
*
447 sp_mpeg12_create(struct pipe_context
*pipe
, enum pipe_video_profile profile
,
448 enum pipe_video_chroma_format chroma_format
,
449 unsigned width
, unsigned height
,
450 enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode
,
451 enum VL_MPEG12_MC_RENDERER_EMPTY_BLOCK eb_handling
,
453 enum pipe_format decode_format
)
455 struct sp_mpeg12_context
*ctx
;
457 assert(u_reduce_video_profile(profile
) == PIPE_VIDEO_CODEC_MPEG12
);
459 ctx
= CALLOC_STRUCT(sp_mpeg12_context
);
464 ctx
->base
.profile
= profile
;
465 ctx
->base
.chroma_format
= chroma_format
;
466 ctx
->base
.width
= width
;
467 ctx
->base
.height
= height
;
469 ctx
->base
.screen
= pipe
->screen
;
471 ctx
->base
.destroy
= sp_mpeg12_destroy
;
472 ctx
->base
.get_param
= sp_mpeg12_get_param
;
473 ctx
->base
.is_format_supported
= sp_mpeg12_is_format_supported
;
474 ctx
->base
.decode_macroblocks
= sp_mpeg12_decode_macroblocks
;
475 ctx
->base
.render_picture
= sp_mpeg12_render_picture
;
476 ctx
->base
.clear_render_target
= sp_mpeg12_clear_render_target
;
477 ctx
->base
.resource_copy_region
= sp_mpeg12_resource_copy_region
;
478 ctx
->base
.get_transfer
= sp_mpeg12_get_transfer
;
479 ctx
->base
.transfer_destroy
= sp_mpeg12_transfer_destroy
;
480 ctx
->base
.transfer_map
= sp_mpeg12_transfer_map
;
481 ctx
->base
.transfer_flush_region
= sp_mpeg12_transfer_flush_region
;
482 ctx
->base
.transfer_unmap
= sp_mpeg12_transfer_unmap
;
483 if (pipe
->transfer_inline_write
)
484 ctx
->base
.transfer_inline_write
= sp_mpeg12_transfer_inline_write
;
485 ctx
->base
.set_picture_background
= sp_mpeg12_set_picture_background
;
486 ctx
->base
.set_picture_layers
= sp_mpeg12_set_picture_layers
;
487 ctx
->base
.set_decode_target
= sp_mpeg12_set_decode_target
;
488 ctx
->base
.set_csc_matrix
= sp_mpeg12_set_csc_matrix
;
491 ctx
->decode_format
= decode_format
;
493 if (!vl_mpeg12_mc_renderer_init(&ctx
->mc_renderer
, ctx
->pipe
,
494 width
, height
, chroma_format
,
495 bufmode
, eb_handling
, pot_buffers
)) {
496 ctx
->pipe
->destroy(ctx
->pipe
);
501 if (!vl_compositor_init(&ctx
->compositor
, ctx
->pipe
)) {
502 vl_mpeg12_mc_renderer_cleanup(&ctx
->mc_renderer
);
503 ctx
->pipe
->destroy(ctx
->pipe
);
508 if (!init_pipe_state(ctx
)) {
509 vl_compositor_cleanup(&ctx
->compositor
);
510 vl_mpeg12_mc_renderer_cleanup(&ctx
->mc_renderer
);
511 ctx
->pipe
->destroy(ctx
->pipe
);
519 struct pipe_video_context
*
520 sp_video_create(struct pipe_screen
*screen
, enum pipe_video_profile profile
,
521 enum pipe_video_chroma_format chroma_format
,
522 unsigned width
, unsigned height
, void *priv
)
524 struct pipe_context
*pipe
;
527 assert(width
&& height
);
529 pipe
= screen
->context_create(screen
, NULL
);
533 /* TODO: Use slice buffering for softpipe when implemented, no advantage to buffering an entire picture with softpipe */
534 /* TODO: Use XFER_NONE when implemented */
535 return sp_video_create_ex(pipe
, profile
,
538 VL_MPEG12_MC_RENDERER_BUFFER_PICTURE
,
539 VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE
,
544 struct pipe_video_context
*
545 sp_video_create_ex(struct pipe_context
*pipe
, enum pipe_video_profile profile
,
546 enum pipe_video_chroma_format chroma_format
,
547 unsigned width
, unsigned height
,
548 enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode
,
549 enum VL_MPEG12_MC_RENDERER_EMPTY_BLOCK eb_handling
,
551 enum pipe_format decode_format
)
554 assert(width
&& height
);
556 switch (u_reduce_video_profile(profile
)) {
557 case PIPE_VIDEO_CODEC_MPEG12
:
558 return sp_mpeg12_create(pipe
, profile
,
561 bufmode
, eb_handling
,