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 <pipe/p_shader_tokens.h>
33 #include <util/u_inlines.h>
34 #include <util/u_memory.h>
35 #include <util/u_keymap.h>
36 #include <util/u_rect.h>
37 #include <util/u_video.h>
38 #include <util/u_surface.h>
39 #include "sp_public.h"
40 #include "sp_texture.h"
42 #define MACROBLOCK_WIDTH 16
43 #define MACROBLOCK_HEIGHT 16
45 #define BLOCK_HEIGHT 8
50 flush_buffer(struct sp_mpeg12_context
*ctx
)
52 unsigned ne_start
, ne_num
, e_start
, e_num
;
55 if(ctx
->cur_buffer
!= NULL
) {
57 vl_vb_unmap(&ctx
->cur_buffer
->vertex_stream
, ctx
->pipe
);
58 vl_idct_unmap_buffers(&ctx
->idct_y
, &ctx
->cur_buffer
->idct_y
);
59 vl_idct_unmap_buffers(&ctx
->idct_cr
, &ctx
->cur_buffer
->idct_cr
);
60 vl_idct_unmap_buffers(&ctx
->idct_cb
, &ctx
->cur_buffer
->idct_cb
);
61 vl_vb_restart(&ctx
->cur_buffer
->vertex_stream
,
62 &ne_start
, &ne_num
, &e_start
, &e_num
);
64 ctx
->pipe
->set_vertex_buffers(ctx
->pipe
, 2, ctx
->cur_buffer
->vertex_bufs
.all
);
65 ctx
->pipe
->bind_vertex_elements_state(ctx
->pipe
, ctx
->vertex_elems_state
);
66 vl_idct_flush(&ctx
->idct_y
, &ctx
->cur_buffer
->idct_y
, ne_num
);
67 vl_idct_flush(&ctx
->idct_cr
, &ctx
->cur_buffer
->idct_cr
, ne_num
);
68 vl_idct_flush(&ctx
->idct_cb
, &ctx
->cur_buffer
->idct_cb
, ne_num
);
69 vl_mpeg12_mc_renderer_flush(&ctx
->mc_renderer
, &ctx
->cur_buffer
->mc
,
70 ne_start
, ne_num
, e_start
, e_num
);
72 ctx
->cur_buffer
= NULL
;
77 rotate_buffer(struct sp_mpeg12_context
*ctx
)
79 struct pipe_resource
*y
, *cr
, *cb
;
80 static unsigned key
= 0;
81 struct sp_mpeg12_buffer
*buffer
;
87 buffer
= (struct sp_mpeg12_buffer
*)util_keymap_lookup(ctx
->buffer_map
, &key
);
91 buffer
= CALLOC_STRUCT(sp_mpeg12_buffer
);
95 buffer
->vertex_bufs
.individual
.quad
.stride
= ctx
->quads
.stride
;
96 buffer
->vertex_bufs
.individual
.quad
.buffer_offset
= ctx
->quads
.buffer_offset
;
97 pipe_resource_reference(&buffer
->vertex_bufs
.individual
.quad
.buffer
, ctx
->quads
.buffer
);
99 buffer
->vertex_bufs
.individual
.stream
= vl_vb_init(&buffer
->vertex_stream
, ctx
->pipe
,
100 ctx
->vertex_buffer_size
);
101 if (!(y
= vl_idct_init_buffer(&ctx
->idct_y
, &buffer
->idct_y
))) {
106 if (!(cr
= vl_idct_init_buffer(&ctx
->idct_cr
, &buffer
->idct_cr
))) {
111 if (!(cb
= vl_idct_init_buffer(&ctx
->idct_cb
, &buffer
->idct_cb
))) {
116 if(!vl_mpeg12_mc_init_buffer(&ctx
->mc_renderer
, &buffer
->mc
, y
, cr
, cb
)) {
121 added_to_map
= util_keymap_insert(ctx
->buffer_map
, &key
, buffer
, ctx
);
122 assert(added_to_map
);
126 ctx
->cur_buffer
= buffer
;
128 vl_vb_map(&ctx
->cur_buffer
->vertex_stream
, ctx
->pipe
);
129 vl_idct_map_buffers(&ctx
->idct_y
, &ctx
->cur_buffer
->idct_y
);
130 vl_idct_map_buffers(&ctx
->idct_cr
, &ctx
->cur_buffer
->idct_cr
);
131 vl_idct_map_buffers(&ctx
->idct_cb
, &ctx
->cur_buffer
->idct_cb
);
135 delete_buffer(const struct keymap
*map
,
136 const void *key
, void *data
,
139 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)user
;
140 struct sp_mpeg12_buffer
*buf
= (struct sp_mpeg12_buffer
*)data
;
147 vl_vb_cleanup(&buf
->vertex_stream
);
148 vl_idct_cleanup_buffer(&ctx
->idct_y
, &buf
->idct_y
);
149 vl_idct_cleanup_buffer(&ctx
->idct_cb
, &buf
->idct_cb
);
150 vl_idct_cleanup_buffer(&ctx
->idct_cr
, &buf
->idct_cr
);
151 vl_mpeg12_mc_cleanup_buffer(&ctx
->mc_renderer
, &buf
->mc
);
155 upload_buffer(struct sp_mpeg12_context
*ctx
,
156 struct sp_mpeg12_buffer
*buffer
,
157 struct pipe_mpeg12_macroblock
*mb
)
168 for (y
= 0; y
< 2; ++y
) {
169 for (x
= 0; x
< 2; ++x
, ++tb
) {
170 if (mb
->cbp
& (*ctx
->mc_renderer
.empty_block_mask
)[0][y
][x
]) {
171 vl_idct_add_block(&buffer
->idct_y
, mb
->mbx
* 2 + x
, mb
->mby
* 2 + y
, blocks
);
172 blocks
+= BLOCK_WIDTH
* BLOCK_HEIGHT
;
177 /* TODO: Implement 422, 444 */
178 assert(ctx
->base
.chroma_format
== PIPE_VIDEO_CHROMA_FORMAT_420
);
180 for (tb
= 1; tb
< 3; ++tb
) {
181 if (mb
->cbp
& (*ctx
->mc_renderer
.empty_block_mask
)[tb
][0][0]) {
183 vl_idct_add_block(&buffer
->idct_cb
, mb
->mbx
, mb
->mby
, blocks
);
185 vl_idct_add_block(&buffer
->idct_cr
, mb
->mbx
, mb
->mby
, blocks
);
186 blocks
+= BLOCK_WIDTH
* BLOCK_HEIGHT
;
192 sp_mpeg12_destroy(struct pipe_video_context
*vpipe
)
194 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
200 /* Asserted in softpipe_delete_fs_state() for some reason */
201 ctx
->pipe
->bind_vs_state(ctx
->pipe
, NULL
);
202 ctx
->pipe
->bind_fs_state(ctx
->pipe
, NULL
);
204 ctx
->pipe
->delete_blend_state(ctx
->pipe
, ctx
->blend
);
205 ctx
->pipe
->delete_rasterizer_state(ctx
->pipe
, ctx
->rast
);
206 ctx
->pipe
->delete_depth_stencil_alpha_state(ctx
->pipe
, ctx
->dsa
);
208 pipe_surface_reference(&ctx
->decode_target
, NULL
);
209 vl_compositor_cleanup(&ctx
->compositor
);
210 util_delete_keymap(ctx
->buffer_map
, ctx
);
211 vl_mpeg12_mc_renderer_cleanup(&ctx
->mc_renderer
);
212 vl_idct_cleanup(&ctx
->idct_y
);
213 vl_idct_cleanup(&ctx
->idct_cr
);
214 vl_idct_cleanup(&ctx
->idct_cb
);
215 ctx
->pipe
->delete_vertex_elements_state(ctx
->pipe
, ctx
->vertex_elems_state
);
216 pipe_resource_reference(&ctx
->quads
.buffer
, NULL
);
217 ctx
->pipe
->destroy(ctx
->pipe
);
223 sp_mpeg12_get_param(struct pipe_video_context
*vpipe
, int param
)
225 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
230 case PIPE_CAP_NPOT_TEXTURES
:
231 /* XXX: Temporary; not all paths are NPOT-tested */
233 return ctx
->pipe
->screen
->get_param(ctx
->pipe
->screen
, param
);
236 case PIPE_CAP_DECODE_TARGET_PREFERRED_FORMAT
:
237 return ctx
->decode_format
;
240 debug_printf("Softpipe: Unknown PIPE_CAP %d\n", param
);
246 static struct pipe_surface
*
247 sp_mpeg12_create_surface(struct pipe_video_context
*vpipe
,
248 struct pipe_resource
*resource
,
249 const struct pipe_surface
*templat
)
251 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
255 return ctx
->pipe
->create_surface(ctx
->pipe
, resource
, templat
);
259 sp_mpeg12_is_format_supported(struct pipe_video_context
*vpipe
,
260 enum pipe_format format
,
264 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
268 /* XXX: Temporary; not all paths are NPOT-tested */
269 if (geom
& PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO
)
273 return ctx
->pipe
->screen
->is_format_supported(ctx
->pipe
->screen
, format
, PIPE_TEXTURE_2D
,
278 sp_mpeg12_decode_macroblocks(struct pipe_video_context
*vpipe
,
279 struct pipe_surface
*past
,
280 struct pipe_surface
*future
,
281 unsigned num_macroblocks
,
282 struct pipe_macroblock
*macroblocks
,
283 struct pipe_fence_handle
**fence
)
285 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
286 struct pipe_mpeg12_macroblock
*mpeg12_macroblocks
= (struct pipe_mpeg12_macroblock
*)macroblocks
;
290 assert(num_macroblocks
);
292 assert(macroblocks
->codec
== PIPE_VIDEO_CODEC_MPEG12
);
293 assert(ctx
->decode_target
);
294 assert(ctx
->cur_buffer
);
296 for ( i
= 0; i
< num_macroblocks
; ++i
) {
297 vl_vb_add_block(&ctx
->cur_buffer
->vertex_stream
, &mpeg12_macroblocks
[i
],
298 ctx
->mc_renderer
.empty_block_mask
);
299 upload_buffer(ctx
, ctx
->cur_buffer
, &mpeg12_macroblocks
[i
]);
302 vl_mpeg12_mc_set_surfaces(&ctx
->mc_renderer
, &ctx
->cur_buffer
->mc
,
303 ctx
->decode_target
, past
, future
, fence
);
307 sp_mpeg12_clear_render_target(struct pipe_video_context
*vpipe
,
308 struct pipe_surface
*dst
,
309 unsigned dstx
, unsigned dsty
,
310 unsigned width
, unsigned height
)
312 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
313 float rgba
[4] = { 0, 0, 0, 0 };
318 if (ctx
->pipe
->clear_render_target
)
319 ctx
->pipe
->clear_render_target(ctx
->pipe
, dst
, rgba
, dstx
, dsty
, width
, height
);
321 util_clear_render_target(ctx
->pipe
, dst
, rgba
, dstx
, dsty
, width
, height
);
325 sp_mpeg12_resource_copy_region(struct pipe_video_context
*vpipe
,
326 struct pipe_surface
*dst
,
327 unsigned dstx
, unsigned dsty
,
328 struct pipe_surface
*src
,
329 unsigned srcx
, unsigned srcy
,
330 unsigned width
, unsigned height
)
332 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
344 if (ctx
->pipe
->resource_copy_region
)
345 ctx
->pipe
->resource_copy_region(ctx
->pipe
, dst
->texture
, dst
->u
.tex
.level
,
346 dstx
, dsty
, dst
->u
.tex
.first_layer
,
347 src
->texture
, src
->u
.tex
.level
, &box
);
349 util_resource_copy_region(ctx
->pipe
, dst
->texture
, dst
->u
.tex
.level
,
350 dstx
, dsty
, dst
->u
.tex
.first_layer
,
351 src
->texture
, src
->u
.tex
.level
, &box
);
354 static struct pipe_transfer
*
355 sp_mpeg12_get_transfer(struct pipe_video_context
*vpipe
,
356 struct pipe_resource
*resource
,
358 unsigned usage
, /* a combination of PIPE_TRANSFER_x */
359 const struct pipe_box
*box
)
361 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
367 return ctx
->pipe
->get_transfer(ctx
->pipe
, resource
, level
, usage
, box
);
371 sp_mpeg12_transfer_destroy(struct pipe_video_context
*vpipe
,
372 struct pipe_transfer
*transfer
)
374 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
379 ctx
->pipe
->transfer_destroy(ctx
->pipe
, transfer
);
383 sp_mpeg12_transfer_map(struct pipe_video_context
*vpipe
,
384 struct pipe_transfer
*transfer
)
386 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
391 return ctx
->pipe
->transfer_map(ctx
->pipe
, transfer
);
395 sp_mpeg12_transfer_flush_region(struct pipe_video_context
*vpipe
,
396 struct pipe_transfer
*transfer
,
397 const struct pipe_box
*box
)
399 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
405 ctx
->pipe
->transfer_flush_region(ctx
->pipe
, transfer
, box
);
409 sp_mpeg12_transfer_unmap(struct pipe_video_context
*vpipe
,
410 struct pipe_transfer
*transfer
)
412 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
417 ctx
->pipe
->transfer_unmap(ctx
->pipe
, transfer
);
421 sp_mpeg12_transfer_inline_write(struct pipe_video_context
*vpipe
,
422 struct pipe_resource
*resource
,
424 unsigned usage
, /* a combination of PIPE_TRANSFER_x */
425 const struct pipe_box
*box
,
428 unsigned slice_stride
)
430 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
436 assert(ctx
->pipe
->transfer_inline_write
);
438 ctx
->pipe
->transfer_inline_write(ctx
->pipe
, resource
, level
, usage
,
439 box
, data
, stride
, slice_stride
);
443 sp_mpeg12_render_picture(struct pipe_video_context
*vpipe
,
444 struct pipe_surface
*src_surface
,
445 enum pipe_mpeg12_picture_type picture_type
,
446 /*unsigned num_past_surfaces,
447 struct pipe_surface *past_surfaces,
448 unsigned num_future_surfaces,
449 struct pipe_surface *future_surfaces,*/
450 struct pipe_video_rect
*src_area
,
451 struct pipe_surface
*dst_surface
,
452 struct pipe_video_rect
*dst_area
,
453 struct pipe_fence_handle
**fence
)
455 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
465 vl_compositor_render(&ctx
->compositor
, src_surface
,
466 picture_type
, src_area
, dst_surface
, dst_area
, fence
);
470 sp_mpeg12_set_picture_background(struct pipe_video_context
*vpipe
,
471 struct pipe_surface
*bg
,
472 struct pipe_video_rect
*bg_src_rect
)
474 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
480 vl_compositor_set_background(&ctx
->compositor
, bg
, bg_src_rect
);
484 sp_mpeg12_set_picture_layers(struct pipe_video_context
*vpipe
,
485 struct pipe_surface
*layers
[],
486 struct pipe_video_rect
*src_rects
[],
487 struct pipe_video_rect
*dst_rects
[],
490 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
493 assert((layers
&& src_rects
&& dst_rects
) ||
494 (!layers
&& !src_rects
&& !dst_rects
));
496 vl_compositor_set_layers(&ctx
->compositor
, layers
, src_rects
, dst_rects
, num_layers
);
500 sp_mpeg12_set_decode_target(struct pipe_video_context
*vpipe
,
501 struct pipe_surface
*dt
)
503 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
508 if (ctx
->decode_target
!= dt
|| ctx
->cur_buffer
== NULL
) {
511 pipe_surface_reference(&ctx
->decode_target
, dt
);
516 sp_mpeg12_set_csc_matrix(struct pipe_video_context
*vpipe
, const float *mat
)
518 struct sp_mpeg12_context
*ctx
= (struct sp_mpeg12_context
*)vpipe
;
522 vl_compositor_set_csc_matrix(&ctx
->compositor
, mat
);
526 init_pipe_state(struct sp_mpeg12_context
*ctx
)
528 struct pipe_rasterizer_state rast
;
529 struct pipe_blend_state blend
;
530 struct pipe_depth_stencil_alpha_state dsa
;
535 memset(&rast
, 0, sizeof rast
);
537 rast
.flatshade_first
= 0;
538 rast
.light_twoside
= 0;
540 rast
.cull_face
= PIPE_FACE_NONE
;
541 rast
.fill_back
= PIPE_POLYGON_MODE_FILL
;
542 rast
.fill_front
= PIPE_POLYGON_MODE_FILL
;
543 rast
.offset_point
= 0;
544 rast
.offset_line
= 0;
546 rast
.poly_smooth
= 0;
547 rast
.poly_stipple_enable
= 0;
548 rast
.sprite_coord_enable
= 0;
549 rast
.point_size_per_vertex
= 0;
550 rast
.multisample
= 0;
551 rast
.line_smooth
= 0;
552 rast
.line_stipple_enable
= 0;
553 rast
.line_stipple_factor
= 0;
554 rast
.line_stipple_pattern
= 0;
555 rast
.line_last_pixel
= 0;
557 rast
.point_smooth
= 0;
558 rast
.point_quad_rasterization
= 0;
559 rast
.point_size_per_vertex
= 1;
560 rast
.offset_units
= 1;
561 rast
.offset_scale
= 1;
562 rast
.gl_rasterization_rules
= 1;
564 ctx
->rast
= ctx
->pipe
->create_rasterizer_state(ctx
->pipe
, &rast
);
565 ctx
->pipe
->bind_rasterizer_state(ctx
->pipe
, ctx
->rast
);
567 memset(&blend
, 0, sizeof blend
);
569 blend
.independent_blend_enable
= 0;
570 blend
.rt
[0].blend_enable
= 0;
571 blend
.rt
[0].rgb_func
= PIPE_BLEND_ADD
;
572 blend
.rt
[0].rgb_src_factor
= PIPE_BLENDFACTOR_ONE
;
573 blend
.rt
[0].rgb_dst_factor
= PIPE_BLENDFACTOR_ONE
;
574 blend
.rt
[0].alpha_func
= PIPE_BLEND_ADD
;
575 blend
.rt
[0].alpha_src_factor
= PIPE_BLENDFACTOR_ONE
;
576 blend
.rt
[0].alpha_dst_factor
= PIPE_BLENDFACTOR_ONE
;
577 blend
.logicop_enable
= 0;
578 blend
.logicop_func
= PIPE_LOGICOP_CLEAR
;
579 /* Needed to allow color writes to FB, even if blending disabled */
580 blend
.rt
[0].colormask
= PIPE_MASK_RGBA
;
582 ctx
->blend
= ctx
->pipe
->create_blend_state(ctx
->pipe
, &blend
);
583 ctx
->pipe
->bind_blend_state(ctx
->pipe
, ctx
->blend
);
585 memset(&dsa
, 0, sizeof dsa
);
586 dsa
.depth
.enabled
= 0;
587 dsa
.depth
.writemask
= 0;
588 dsa
.depth
.func
= PIPE_FUNC_ALWAYS
;
589 for (i
= 0; i
< 2; ++i
) {
590 dsa
.stencil
[i
].enabled
= 0;
591 dsa
.stencil
[i
].func
= PIPE_FUNC_ALWAYS
;
592 dsa
.stencil
[i
].fail_op
= PIPE_STENCIL_OP_KEEP
;
593 dsa
.stencil
[i
].zpass_op
= PIPE_STENCIL_OP_KEEP
;
594 dsa
.stencil
[i
].zfail_op
= PIPE_STENCIL_OP_KEEP
;
595 dsa
.stencil
[i
].valuemask
= 0;
596 dsa
.stencil
[i
].writemask
= 0;
598 dsa
.alpha
.enabled
= 0;
599 dsa
.alpha
.func
= PIPE_FUNC_ALWAYS
;
600 dsa
.alpha
.ref_value
= 0;
601 ctx
->dsa
= ctx
->pipe
->create_depth_stencil_alpha_state(ctx
->pipe
, &dsa
);
602 ctx
->pipe
->bind_depth_stencil_alpha_state(ctx
->pipe
, ctx
->dsa
);
607 static struct pipe_video_context
*
608 sp_mpeg12_create(struct pipe_context
*pipe
, enum pipe_video_profile profile
,
609 enum pipe_video_chroma_format chroma_format
,
610 unsigned width
, unsigned height
,
612 enum pipe_format decode_format
)
614 struct pipe_resource
*idct_matrix
;
615 unsigned buffer_width
, buffer_height
;
616 unsigned chroma_width
, chroma_height
, chroma_blocks_x
, chroma_blocks_y
;
617 struct sp_mpeg12_context
*ctx
;
619 assert(u_reduce_video_profile(profile
) == PIPE_VIDEO_CODEC_MPEG12
);
621 ctx
= CALLOC_STRUCT(sp_mpeg12_context
);
626 /* TODO: Non-pot buffers untested, probably doesn't work without changes to texcoord generation, vert shader, etc */
629 buffer_width
= pot_buffers
? util_next_power_of_two(width
) : width
;
630 buffer_height
= pot_buffers
? util_next_power_of_two(height
) : height
;
632 ctx
->base
.profile
= profile
;
633 ctx
->base
.chroma_format
= chroma_format
;
634 ctx
->base
.width
= width
;
635 ctx
->base
.height
= height
;
637 ctx
->base
.screen
= pipe
->screen
;
639 ctx
->base
.destroy
= sp_mpeg12_destroy
;
640 ctx
->base
.get_param
= sp_mpeg12_get_param
;
641 ctx
->base
.is_format_supported
= sp_mpeg12_is_format_supported
;
642 ctx
->base
.create_surface
= sp_mpeg12_create_surface
;
643 ctx
->base
.decode_macroblocks
= sp_mpeg12_decode_macroblocks
;
644 ctx
->base
.render_picture
= sp_mpeg12_render_picture
;
645 ctx
->base
.clear_render_target
= sp_mpeg12_clear_render_target
;
646 ctx
->base
.resource_copy_region
= sp_mpeg12_resource_copy_region
;
647 ctx
->base
.get_transfer
= sp_mpeg12_get_transfer
;
648 ctx
->base
.transfer_destroy
= sp_mpeg12_transfer_destroy
;
649 ctx
->base
.transfer_map
= sp_mpeg12_transfer_map
;
650 ctx
->base
.transfer_flush_region
= sp_mpeg12_transfer_flush_region
;
651 ctx
->base
.transfer_unmap
= sp_mpeg12_transfer_unmap
;
652 if (pipe
->transfer_inline_write
)
653 ctx
->base
.transfer_inline_write
= sp_mpeg12_transfer_inline_write
;
654 ctx
->base
.set_picture_background
= sp_mpeg12_set_picture_background
;
655 ctx
->base
.set_picture_layers
= sp_mpeg12_set_picture_layers
;
656 ctx
->base
.set_decode_target
= sp_mpeg12_set_decode_target
;
657 ctx
->base
.set_csc_matrix
= sp_mpeg12_set_csc_matrix
;
660 ctx
->decode_format
= decode_format
;
662 ctx
->quads
= vl_vb_upload_quads(ctx
->pipe
, 2, 2);
663 ctx
->vertex_buffer_size
= width
/ MACROBLOCK_WIDTH
* height
/ MACROBLOCK_HEIGHT
;
664 ctx
->vertex_elems_state
= vl_vb_get_elems_state(ctx
->pipe
, true);
666 if (ctx
->vertex_elems_state
== NULL
) {
667 ctx
->pipe
->destroy(ctx
->pipe
);
672 if (!(idct_matrix
= vl_idct_upload_matrix(ctx
->pipe
)))
675 if (!vl_idct_init(&ctx
->idct_y
, ctx
->pipe
, buffer_width
, buffer_height
,
676 2, 2, TGSI_SWIZZLE_X
, idct_matrix
))
679 if (chroma_format
== PIPE_VIDEO_CHROMA_FORMAT_420
) {
680 chroma_width
= buffer_width
/ 2;
681 chroma_height
= buffer_height
/ 2;
684 } else if (chroma_format
== PIPE_VIDEO_CHROMA_FORMAT_422
) {
685 chroma_width
= buffer_width
;
686 chroma_height
= buffer_height
/ 2;
690 chroma_width
= buffer_width
;
691 chroma_height
= buffer_height
;
696 if(!vl_idct_init(&ctx
->idct_cr
, ctx
->pipe
, chroma_width
, chroma_height
,
697 chroma_blocks_x
, chroma_blocks_y
, TGSI_SWIZZLE_Y
, idct_matrix
))
700 if(!vl_idct_init(&ctx
->idct_cb
, ctx
->pipe
, chroma_width
, chroma_height
,
701 chroma_blocks_x
, chroma_blocks_y
, TGSI_SWIZZLE_Z
, idct_matrix
))
704 if (!vl_mpeg12_mc_renderer_init(&ctx
->mc_renderer
, ctx
->pipe
,
705 buffer_width
, buffer_height
, chroma_format
)) {
706 ctx
->pipe
->destroy(ctx
->pipe
);
711 ctx
->buffer_map
= util_new_keymap(sizeof(unsigned), -1, delete_buffer
);
712 if (!ctx
->buffer_map
) {
713 vl_mpeg12_mc_renderer_cleanup(&ctx
->mc_renderer
);
714 ctx
->pipe
->destroy(ctx
->pipe
);
719 if (!vl_compositor_init(&ctx
->compositor
, ctx
->pipe
)) {
720 util_delete_keymap(ctx
->buffer_map
, ctx
);
721 vl_mpeg12_mc_renderer_cleanup(&ctx
->mc_renderer
);
722 ctx
->pipe
->destroy(ctx
->pipe
);
727 if (!init_pipe_state(ctx
)) {
728 vl_compositor_cleanup(&ctx
->compositor
);
729 util_delete_keymap(ctx
->buffer_map
, ctx
);
730 vl_mpeg12_mc_renderer_cleanup(&ctx
->mc_renderer
);
731 ctx
->pipe
->destroy(ctx
->pipe
);
739 struct pipe_video_context
*
740 sp_video_create(struct pipe_screen
*screen
, enum pipe_video_profile profile
,
741 enum pipe_video_chroma_format chroma_format
,
742 unsigned width
, unsigned height
, void *priv
)
744 struct pipe_context
*pipe
;
747 assert(width
&& height
);
749 pipe
= screen
->context_create(screen
, NULL
);
753 /* TODO: Use slice buffering for softpipe when implemented, no advantage to buffering an entire picture with softpipe */
754 return sp_video_create_ex(pipe
, profile
,
761 struct pipe_video_context
*
762 sp_video_create_ex(struct pipe_context
*pipe
, enum pipe_video_profile profile
,
763 enum pipe_video_chroma_format chroma_format
,
764 unsigned width
, unsigned height
,
766 enum pipe_format decode_format
)
769 assert(width
&& height
);
771 switch (u_reduce_video_profile(profile
)) {
772 case PIPE_VIDEO_CODEC_MPEG12
:
773 return sp_mpeg12_create(pipe
, profile
,