2 #include "vl_r16snorm_mc_buf.h"
5 #include <pipe/p_context.h>
6 #include <pipe/p_winsys.h>
7 #include <pipe/p_screen.h>
8 #include <pipe/p_state.h>
9 #include <pipe/p_inlines.h>
10 #include <tgsi/tgsi_parse.h>
11 #include <tgsi/tgsi_build.h>
12 #include <util/u_math.h>
13 #include "vl_render.h"
14 #include "vl_shader_build.h"
15 #include "vl_surface.h"
21 * TODO: Dynamically determine number of buf sets to use, based on
22 * video size and available mem, since we can easily run out of memory
23 * for high res videos.
24 * Note: Destroying previous frame's buffers and creating new ones
25 * doesn't work, since the buffer are not actually destroyed until their
26 * fence is signalled, and if we render fast enough we will create faster
29 #define NUM_BUF_SETS 4 /* Number of rotating buffer sets to use */
31 enum vlMacroBlockTypeEx
33 vlMacroBlockExTypeIntra
,
34 vlMacroBlockExTypeFwdPredictedFrame
,
35 vlMacroBlockExTypeFwdPredictedField
,
36 vlMacroBlockExTypeBkwdPredictedFrame
,
37 vlMacroBlockExTypeBkwdPredictedField
,
38 vlMacroBlockExTypeBiPredictedFrame
,
39 vlMacroBlockExTypeBiPredictedField
,
41 vlNumMacroBlockExTypes
44 struct vlVertexShaderConsts
46 struct vlVertex4f denorm
;
49 struct vlFragmentShaderConsts
51 struct vlVertex4f multiplier
;
52 struct vlVertex4f div
;
55 struct vlR16SnormBufferedMC
59 unsigned int picture_width
, picture_height
;
60 enum vlFormat picture_format
;
63 struct vlSurface
*buffered_surface
;
64 struct vlSurface
*past_surface
, *future_surface
;
65 struct vlVertex2f surface_tex_inv_size
;
66 struct vlVertex2f zero_block
[3];
67 unsigned int num_macroblocks
;
68 struct vlMpeg2MacroBlock
*macroblocks
;
70 struct pipe_context
*pipe
;
71 struct pipe_viewport_state viewport
;
72 struct pipe_framebuffer_state render_target
;
73 struct pipe_sampler_state
*samplers
[5];
74 struct pipe_texture
*textures
[NUM_BUF_SETS
][5];
75 struct pipe_surface
*tex_surface
[3];
77 void *i_vs
, *p_vs
[2], *b_vs
[2];
78 void *i_fs
, *p_fs
[2], *b_fs
[2];
79 struct pipe_vertex_buffer vertex_bufs
[NUM_BUF_SETS
][3];
80 struct pipe_vertex_element vertex_elems
[8];
81 struct pipe_constant_buffer vs_const_buf
, fs_const_buf
;
86 struct vlRender
*render
94 static inline int vlGrabFrameCodedBlock(short *src
, short *dst
, unsigned int dst_pitch
)
98 for (y
= 0; y
< VL_BLOCK_HEIGHT
; ++y
)
102 src
+ y
* VL_BLOCK_WIDTH
,
109 static inline int vlGrabFieldCodedBlock(short *src
, short *dst
, unsigned int dst_pitch
)
113 for (y
= 0; y
< VL_BLOCK_HEIGHT
; ++y
)
116 dst
+ y
* dst_pitch
* 2,
117 src
+ y
* VL_BLOCK_WIDTH
,
124 static inline int vlGrabNoBlock(short *dst
, unsigned int dst_pitch
)
128 for (y
= 0; y
< VL_BLOCK_HEIGHT
; ++y
)
139 static inline int vlGrabBlocks
141 struct vlR16SnormBufferedMC
*mc
,
144 enum vlDCTType dct_type
,
145 unsigned int coded_block_pattern
,
150 unsigned int tex_pitch
;
151 unsigned int x
, y
, tb
= 0, sb
= 0;
152 unsigned int mbpx
= mbx
* VL_MACROBLOCK_WIDTH
, mbpy
= mby
* VL_MACROBLOCK_HEIGHT
;
157 tex_pitch
= mc
->tex_surface
[0]->stride
/ mc
->tex_surface
[0]->block
.size
;
158 texels
= mc
->texels
[0] + mbpy
* tex_pitch
+ mbpx
;
160 for (y
= 0; y
< 2; ++y
)
162 for (x
= 0; x
< 2; ++x
, ++tb
)
164 if ((coded_block_pattern
>> (5 - tb
)) & 1)
166 short *cur_block
= blocks
+ sb
* VL_BLOCK_WIDTH
* VL_BLOCK_HEIGHT
;
168 if (dct_type
== vlDCTTypeFrameCoded
)
170 vlGrabFrameCodedBlock
173 texels
+ y
* tex_pitch
* VL_BLOCK_HEIGHT
+ x
* VL_BLOCK_WIDTH
,
179 vlGrabFieldCodedBlock
182 texels
+ y
* tex_pitch
+ x
* VL_BLOCK_WIDTH
,
189 else if (mc
->zero_block
[0].x
< 0.0f
)
191 vlGrabNoBlock(texels
+ y
* tex_pitch
* VL_BLOCK_HEIGHT
+ x
* VL_BLOCK_WIDTH
, tex_pitch
);
193 mc
->zero_block
[0].x
= (mbpx
+ x
* 8) * mc
->surface_tex_inv_size
.x
;
194 mc
->zero_block
[0].y
= (mbpy
+ y
* 8) * mc
->surface_tex_inv_size
.y
;
199 /* TODO: Implement 422, 444 */
203 for (tb
= 0; tb
< 2; ++tb
)
205 tex_pitch
= mc
->tex_surface
[tb
+ 1]->stride
/ mc
->tex_surface
[tb
+ 1]->block
.size
;
206 texels
= mc
->texels
[tb
+ 1] + mbpy
* tex_pitch
+ mbpx
;
208 if ((coded_block_pattern
>> (1 - tb
)) & 1)
210 short *cur_block
= blocks
+ sb
* VL_BLOCK_WIDTH
* VL_BLOCK_HEIGHT
;
212 vlGrabFrameCodedBlock
221 else if (mc
->zero_block
[tb
+ 1].x
< 0.0f
)
223 vlGrabNoBlock(texels
, tex_pitch
);
225 mc
->zero_block
[tb
+ 1].x
= (mbpx
<< 1) * mc
->surface_tex_inv_size
.x
;
226 mc
->zero_block
[tb
+ 1].y
= (mbpy
<< 1) * mc
->surface_tex_inv_size
.y
;
233 static inline enum vlMacroBlockTypeEx
vlGetMacroBlockTypeEx(struct vlMpeg2MacroBlock
*mb
)
239 case vlMacroBlockTypeIntra
:
240 return vlMacroBlockExTypeIntra
;
241 case vlMacroBlockTypeFwdPredicted
:
242 return mb
->mo_type
== vlMotionTypeFrame
?
243 vlMacroBlockExTypeFwdPredictedFrame
: vlMacroBlockExTypeFwdPredictedField
;
244 case vlMacroBlockTypeBkwdPredicted
:
245 return mb
->mo_type
== vlMotionTypeFrame
?
246 vlMacroBlockExTypeBkwdPredictedFrame
: vlMacroBlockExTypeBkwdPredictedField
;
247 case vlMacroBlockTypeBiPredicted
:
248 return mb
->mo_type
== vlMotionTypeFrame
?
249 vlMacroBlockExTypeBiPredictedFrame
: vlMacroBlockExTypeBiPredictedField
;
258 static inline int vlGrabMacroBlock
260 struct vlR16SnormBufferedMC
*mc
,
261 struct vlMpeg2MacroBlock
*macroblock
267 mc
->macroblocks
[mc
->num_macroblocks
].mbx
= macroblock
->mbx
;
268 mc
->macroblocks
[mc
->num_macroblocks
].mby
= macroblock
->mby
;
269 mc
->macroblocks
[mc
->num_macroblocks
].mb_type
= macroblock
->mb_type
;
270 mc
->macroblocks
[mc
->num_macroblocks
].mo_type
= macroblock
->mo_type
;
271 mc
->macroblocks
[mc
->num_macroblocks
].dct_type
= macroblock
->dct_type
;
272 mc
->macroblocks
[mc
->num_macroblocks
].PMV
[0][0][0] = macroblock
->PMV
[0][0][0];
273 mc
->macroblocks
[mc
->num_macroblocks
].PMV
[0][0][1] = macroblock
->PMV
[0][0][1];
274 mc
->macroblocks
[mc
->num_macroblocks
].PMV
[0][1][0] = macroblock
->PMV
[0][1][0];
275 mc
->macroblocks
[mc
->num_macroblocks
].PMV
[0][1][1] = macroblock
->PMV
[0][1][1];
276 mc
->macroblocks
[mc
->num_macroblocks
].PMV
[1][0][0] = macroblock
->PMV
[1][0][0];
277 mc
->macroblocks
[mc
->num_macroblocks
].PMV
[1][0][1] = macroblock
->PMV
[1][0][1];
278 mc
->macroblocks
[mc
->num_macroblocks
].PMV
[1][1][0] = macroblock
->PMV
[1][1][0];
279 mc
->macroblocks
[mc
->num_macroblocks
].PMV
[1][1][1] = macroblock
->PMV
[1][1][1];
280 mc
->macroblocks
[mc
->num_macroblocks
].cbp
= macroblock
->cbp
;
281 mc
->macroblocks
[mc
->num_macroblocks
].blocks
= macroblock
->blocks
;
288 macroblock
->dct_type
,
293 mc
->num_macroblocks
++;
298 #define SET_BLOCK(vb, cbp, mbx, mby, unitx, unity, ofsx, ofsy, hx, hy, lm, cbm, crm, zb) \
299 (vb)[0].pos.x = (mbx) * (unitx) + (ofsx); (vb)[0].pos.y = (mby) * (unity) + (ofsy); \
300 (vb)[1].pos.x = (mbx) * (unitx) + (ofsx); (vb)[1].pos.y = (mby) * (unity) + (ofsy) + (hy); \
301 (vb)[2].pos.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[2].pos.y = (mby) * (unity) + (ofsy); \
302 (vb)[3].pos.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[3].pos.y = (mby) * (unity) + (ofsy); \
303 (vb)[4].pos.x = (mbx) * (unitx) + (ofsx); (vb)[4].pos.y = (mby) * (unity) + (ofsy) + (hy); \
304 (vb)[5].pos.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[5].pos.y = (mby) * (unity) + (ofsy) + (hy); \
308 (vb)[0].luma_tc.x = (mbx) * (unitx) + (ofsx); (vb)[0].luma_tc.y = (mby) * (unity) + (ofsy); \
309 (vb)[1].luma_tc.x = (mbx) * (unitx) + (ofsx); (vb)[1].luma_tc.y = (mby) * (unity) + (ofsy) + (hy); \
310 (vb)[2].luma_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[2].luma_tc.y = (mby) * (unity) + (ofsy); \
311 (vb)[3].luma_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[3].luma_tc.y = (mby) * (unity) + (ofsy); \
312 (vb)[4].luma_tc.x = (mbx) * (unitx) + (ofsx); (vb)[4].luma_tc.y = (mby) * (unity) + (ofsy) + (hy); \
313 (vb)[5].luma_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[5].luma_tc.y = (mby) * (unity) + (ofsy) + (hy); \
317 (vb)[0].luma_tc.x = (zb)[0].x; (vb)[0].luma_tc.y = (zb)[0].y; \
318 (vb)[1].luma_tc.x = (zb)[0].x; (vb)[1].luma_tc.y = (zb)[0].y + (hy); \
319 (vb)[2].luma_tc.x = (zb)[0].x + (hx); (vb)[2].luma_tc.y = (zb)[0].y; \
320 (vb)[3].luma_tc.x = (zb)[0].x + (hx); (vb)[3].luma_tc.y = (zb)[0].y; \
321 (vb)[4].luma_tc.x = (zb)[0].x; (vb)[4].luma_tc.y = (zb)[0].y + (hy); \
322 (vb)[5].luma_tc.x = (zb)[0].x + (hx); (vb)[5].luma_tc.y = (zb)[0].y + (hy); \
327 (vb)[0].cb_tc.x = (mbx) * (unitx) + (ofsx); (vb)[0].cb_tc.y = (mby) * (unity) + (ofsy); \
328 (vb)[1].cb_tc.x = (mbx) * (unitx) + (ofsx); (vb)[1].cb_tc.y = (mby) * (unity) + (ofsy) + (hy); \
329 (vb)[2].cb_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[2].cb_tc.y = (mby) * (unity) + (ofsy); \
330 (vb)[3].cb_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[3].cb_tc.y = (mby) * (unity) + (ofsy); \
331 (vb)[4].cb_tc.x = (mbx) * (unitx) + (ofsx); (vb)[4].cb_tc.y = (mby) * (unity) + (ofsy) + (hy); \
332 (vb)[5].cb_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[5].cb_tc.y = (mby) * (unity) + (ofsy) + (hy); \
336 (vb)[0].cb_tc.x = (zb)[1].x; (vb)[0].cb_tc.y = (zb)[1].y; \
337 (vb)[1].cb_tc.x = (zb)[1].x; (vb)[1].cb_tc.y = (zb)[1].y + (hy); \
338 (vb)[2].cb_tc.x = (zb)[1].x + (hx); (vb)[2].cb_tc.y = (zb)[1].y; \
339 (vb)[3].cb_tc.x = (zb)[1].x + (hx); (vb)[3].cb_tc.y = (zb)[1].y; \
340 (vb)[4].cb_tc.x = (zb)[1].x; (vb)[4].cb_tc.y = (zb)[1].y + (hy); \
341 (vb)[5].cb_tc.x = (zb)[1].x + (hx); (vb)[5].cb_tc.y = (zb)[1].y + (hy); \
346 (vb)[0].cr_tc.x = (mbx) * (unitx) + (ofsx); (vb)[0].cr_tc.y = (mby) * (unity) + (ofsy); \
347 (vb)[1].cr_tc.x = (mbx) * (unitx) + (ofsx); (vb)[1].cr_tc.y = (mby) * (unity) + (ofsy) + (hy); \
348 (vb)[2].cr_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[2].cr_tc.y = (mby) * (unity) + (ofsy); \
349 (vb)[3].cr_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[3].cr_tc.y = (mby) * (unity) + (ofsy); \
350 (vb)[4].cr_tc.x = (mbx) * (unitx) + (ofsx); (vb)[4].cr_tc.y = (mby) * (unity) + (ofsy) + (hy); \
351 (vb)[5].cr_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[5].cr_tc.y = (mby) * (unity) + (ofsy) + (hy); \
355 (vb)[0].cr_tc.x = (zb)[2].x; (vb)[0].cr_tc.y = (zb)[2].y; \
356 (vb)[1].cr_tc.x = (zb)[2].x; (vb)[1].cr_tc.y = (zb)[2].y + (hy); \
357 (vb)[2].cr_tc.x = (zb)[2].x + (hx); (vb)[2].cr_tc.y = (zb)[2].y; \
358 (vb)[3].cr_tc.x = (zb)[2].x + (hx); (vb)[3].cr_tc.y = (zb)[2].y; \
359 (vb)[4].cr_tc.x = (zb)[2].x; (vb)[4].cr_tc.y = (zb)[2].y + (hy); \
360 (vb)[5].cr_tc.x = (zb)[2].x + (hx); (vb)[5].cr_tc.y = (zb)[2].y + (hy); \
363 static inline int vlGrabMacroBlockVB
365 struct vlR16SnormBufferedMC
*mc
,
366 struct vlMpeg2MacroBlock
*macroblock
,
370 struct vlVertex2f mo_vec
[2];
376 switch (macroblock
->mb_type
)
378 case vlMacroBlockTypeBiPredicted
:
380 struct vlVertex2f
*vb
;
382 vb
= (struct vlVertex2f
*)mc
->pipe
->winsys
->buffer_map
385 mc
->vertex_bufs
[mc
->cur_buf
% NUM_BUF_SETS
][2].buffer
,
386 PIPE_BUFFER_USAGE_CPU_WRITE
389 mo_vec
[0].x
= macroblock
->PMV
[0][1][0] * 0.5f
* mc
->surface_tex_inv_size
.x
;
390 mo_vec
[0].y
= macroblock
->PMV
[0][1][1] * 0.5f
* mc
->surface_tex_inv_size
.y
;
392 if (macroblock
->mo_type
== vlMotionTypeFrame
)
394 for (i
= 0; i
< 24 * 2; i
+= 2)
396 vb
[i
].x
= mo_vec
[0].x
;
397 vb
[i
].y
= mo_vec
[0].y
;
402 mo_vec
[1].x
= macroblock
->PMV
[1][1][0] * 0.5f
* mc
->surface_tex_inv_size
.x
;
403 mo_vec
[1].y
= macroblock
->PMV
[1][1][1] * 0.5f
* mc
->surface_tex_inv_size
.y
;
405 for (i
= 0; i
< 24 * 2; i
+= 2)
407 vb
[i
].x
= mo_vec
[0].x
;
408 vb
[i
].y
= mo_vec
[0].y
;
409 vb
[i
+ 1].x
= mo_vec
[1].x
;
410 vb
[i
+ 1].y
= mo_vec
[1].y
;
414 mc
->pipe
->winsys
->buffer_unmap(mc
->pipe
->winsys
, mc
->vertex_bufs
[mc
->cur_buf
% NUM_BUF_SETS
][2].buffer
);
418 case vlMacroBlockTypeFwdPredicted
:
419 case vlMacroBlockTypeBkwdPredicted
:
421 struct vlVertex2f
*vb
;
423 vb
= (struct vlVertex2f
*)mc
->pipe
->winsys
->buffer_map
426 mc
->vertex_bufs
[mc
->cur_buf
% NUM_BUF_SETS
][1].buffer
,
427 PIPE_BUFFER_USAGE_CPU_WRITE
430 if (macroblock
->mb_type
== vlMacroBlockTypeBkwdPredicted
)
432 mo_vec
[0].x
= macroblock
->PMV
[0][1][0] * 0.5f
* mc
->surface_tex_inv_size
.x
;
433 mo_vec
[0].y
= macroblock
->PMV
[0][1][1] * 0.5f
* mc
->surface_tex_inv_size
.y
;
435 if (macroblock
->mo_type
== vlMotionTypeField
)
437 mo_vec
[1].x
= macroblock
->PMV
[1][1][0] * 0.5f
* mc
->surface_tex_inv_size
.x
;
438 mo_vec
[1].y
= macroblock
->PMV
[1][1][1] * 0.5f
* mc
->surface_tex_inv_size
.y
;
443 mo_vec
[0].x
= macroblock
->PMV
[0][0][0] * 0.5f
* mc
->surface_tex_inv_size
.x
;
444 mo_vec
[0].y
= macroblock
->PMV
[0][0][1] * 0.5f
* mc
->surface_tex_inv_size
.y
;
446 if (macroblock
->mo_type
== vlMotionTypeField
)
448 mo_vec
[1].x
= macroblock
->PMV
[1][0][0] * 0.5f
* mc
->surface_tex_inv_size
.x
;
449 mo_vec
[1].y
= macroblock
->PMV
[1][0][1] * 0.5f
* mc
->surface_tex_inv_size
.y
;
453 if (macroblock
->mo_type
== vlMotionTypeFrame
)
455 for (i
= 0; i
< 24 * 2; i
+= 2)
457 vb
[i
].x
= mo_vec
[0].x
;
458 vb
[i
].y
= mo_vec
[0].y
;
463 for (i
= 0; i
< 24 * 2; i
+= 2)
465 vb
[i
].x
= mo_vec
[0].x
;
466 vb
[i
].y
= mo_vec
[0].y
;
467 vb
[i
+ 1].x
= mo_vec
[1].x
;
468 vb
[i
+ 1].y
= mo_vec
[1].y
;
472 mc
->pipe
->winsys
->buffer_unmap(mc
->pipe
->winsys
, mc
->vertex_bufs
[mc
->cur_buf
% NUM_BUF_SETS
][1].buffer
);
476 case vlMacroBlockTypeIntra
:
478 const struct vlVertex2f unit
=
480 mc
->surface_tex_inv_size
.x
* VL_MACROBLOCK_WIDTH
,
481 mc
->surface_tex_inv_size
.y
* VL_MACROBLOCK_HEIGHT
483 const struct vlVertex2f half
=
485 mc
->surface_tex_inv_size
.x
* (VL_MACROBLOCK_WIDTH
/ 2),
486 mc
->surface_tex_inv_size
.y
* (VL_MACROBLOCK_HEIGHT
/ 2)
489 struct vlMacroBlockVertexStream0
491 struct vlVertex2f pos
;
492 struct vlVertex2f luma_tc
;
493 struct vlVertex2f cb_tc
;
494 struct vlVertex2f cr_tc
;
497 vb
= (struct vlMacroBlockVertexStream0
*)mc
->pipe
->winsys
->buffer_map
500 mc
->vertex_bufs
[mc
->cur_buf
% NUM_BUF_SETS
][0].buffer
,
501 PIPE_BUFFER_USAGE_CPU_WRITE
507 macroblock
->cbp
, macroblock
->mbx
, macroblock
->mby
,
508 unit
.x
, unit
.y
, 0, 0, half
.x
, half
.y
,
509 32, 2, 1, mc
->zero_block
515 macroblock
->cbp
, macroblock
->mbx
, macroblock
->mby
,
516 unit
.x
, unit
.y
, half
.x
, 0, half
.x
, half
.y
,
517 16, 2, 1, mc
->zero_block
523 macroblock
->cbp
, macroblock
->mbx
, macroblock
->mby
,
524 unit
.x
, unit
.y
, 0, half
.y
, half
.x
, half
.y
,
525 8, 2, 1, mc
->zero_block
531 macroblock
->cbp
, macroblock
->mbx
, macroblock
->mby
,
532 unit
.x
, unit
.y
, half
.x
, half
.y
, half
.x
, half
.y
,
533 4, 2, 1, mc
->zero_block
536 mc
->pipe
->winsys
->buffer_unmap(mc
->pipe
->winsys
, mc
->vertex_bufs
[mc
->cur_buf
% NUM_BUF_SETS
][0].buffer
);
549 struct vlRender
*render
552 struct vlR16SnormBufferedMC
*mc
;
553 struct pipe_context
*pipe
;
554 struct vlVertexShaderConsts
*vs_consts
;
555 unsigned int num_macroblocks
[vlNumMacroBlockExTypes
] = {0};
556 unsigned int offset
[vlNumMacroBlockExTypes
];
557 unsigned int vb_start
= 0;
560 unsigned int num_mb_per_frame
;
565 mc
= (struct vlR16SnormBufferedMC
*)render
;
567 if (!mc
->buffered_surface
)
570 mbw
= align(mc
->picture_width
, VL_MACROBLOCK_WIDTH
) / VL_MACROBLOCK_WIDTH
;
571 mbh
= align(mc
->picture_height
, VL_MACROBLOCK_HEIGHT
) / VL_MACROBLOCK_HEIGHT
;
572 num_mb_per_frame
= mbw
* mbh
;
574 if (mc
->num_macroblocks
< num_mb_per_frame
)
579 for (i
= 0; i
< mc
->num_macroblocks
; ++i
)
581 enum vlMacroBlockTypeEx mb_type_ex
= vlGetMacroBlockTypeEx(&mc
->macroblocks
[i
]);
583 num_macroblocks
[mb_type_ex
]++;
588 for (i
= 1; i
< vlNumMacroBlockExTypes
; ++i
)
589 offset
[i
] = offset
[i
- 1] + num_macroblocks
[i
- 1];
591 for (i
= 0; i
< mc
->num_macroblocks
; ++i
)
593 enum vlMacroBlockTypeEx mb_type_ex
= vlGetMacroBlockTypeEx(&mc
->macroblocks
[i
]);
595 vlGrabMacroBlockVB(mc
, &mc
->macroblocks
[i
], offset
[mb_type_ex
]);
597 offset
[mb_type_ex
]++;
600 for (i
= 0; i
< 3; ++i
)
602 pipe_surface_unmap(mc
->tex_surface
[i
]);
603 mc
->pipe
->screen
->tex_surface_release(mc
->pipe
->screen
, &mc
->tex_surface
[i
]);
606 mc
->render_target
.cbufs
[0] = pipe
->screen
->get_tex_surface
609 mc
->buffered_surface
->texture
,
610 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ
| PIPE_BUFFER_USAGE_GPU_WRITE
613 pipe
->set_framebuffer_state(pipe
, &mc
->render_target
);
614 pipe
->set_viewport_state(pipe
, &mc
->viewport
);
615 vs_consts
= pipe
->winsys
->buffer_map
618 mc
->vs_const_buf
.buffer
,
619 PIPE_BUFFER_USAGE_CPU_WRITE
622 vs_consts
->denorm
.x
= mc
->buffered_surface
->texture
->width
[0];
623 vs_consts
->denorm
.y
= mc
->buffered_surface
->texture
->height
[0];
625 pipe
->winsys
->buffer_unmap(pipe
->winsys
, mc
->vs_const_buf
.buffer
);
626 pipe
->set_constant_buffer(pipe
, PIPE_SHADER_VERTEX
, 0, &mc
->vs_const_buf
);
627 pipe
->set_constant_buffer(pipe
, PIPE_SHADER_FRAGMENT
, 0, &mc
->fs_const_buf
);
629 if (num_macroblocks
[vlMacroBlockExTypeIntra
] > 0)
631 pipe
->set_vertex_buffers(pipe
, 1, mc
->vertex_bufs
[mc
->cur_buf
% NUM_BUF_SETS
]);
632 pipe
->set_vertex_elements(pipe
, 4, mc
->vertex_elems
);
633 pipe
->set_sampler_textures(pipe
, 3, mc
->textures
[mc
->cur_buf
% NUM_BUF_SETS
]);
634 pipe
->bind_sampler_states(pipe
, 3, (void**)mc
->samplers
);
635 pipe
->bind_vs_state(pipe
, mc
->i_vs
);
636 pipe
->bind_fs_state(pipe
, mc
->i_fs
);
638 pipe
->draw_arrays(pipe
, PIPE_PRIM_TRIANGLES
, vb_start
, num_macroblocks
[vlMacroBlockExTypeIntra
] * 24);
639 vb_start
+= num_macroblocks
[vlMacroBlockExTypeIntra
] * 24;
642 if (num_macroblocks
[vlMacroBlockExTypeFwdPredictedFrame
] > 0)
644 pipe
->set_vertex_buffers(pipe
, 2, mc
->vertex_bufs
[mc
->cur_buf
% NUM_BUF_SETS
]);
645 pipe
->set_vertex_elements(pipe
, 6, mc
->vertex_elems
);
646 mc
->textures
[mc
->cur_buf
% NUM_BUF_SETS
][3] = mc
->past_surface
->texture
;
647 pipe
->set_sampler_textures(pipe
, 4, mc
->textures
[mc
->cur_buf
% NUM_BUF_SETS
]);
648 pipe
->bind_sampler_states(pipe
, 4, (void**)mc
->samplers
);
649 pipe
->bind_vs_state(pipe
, mc
->p_vs
[0]);
650 pipe
->bind_fs_state(pipe
, mc
->p_fs
[0]);
652 pipe
->draw_arrays(pipe
, PIPE_PRIM_TRIANGLES
, vb_start
, num_macroblocks
[vlMacroBlockExTypeFwdPredictedFrame
] * 24);
653 vb_start
+= num_macroblocks
[vlMacroBlockExTypeFwdPredictedFrame
] * 24;
656 if (num_macroblocks
[vlMacroBlockExTypeFwdPredictedField
] > 0)
658 pipe
->set_vertex_buffers(pipe
, 2, mc
->vertex_bufs
[mc
->cur_buf
% NUM_BUF_SETS
]);
659 pipe
->set_vertex_elements(pipe
, 6, mc
->vertex_elems
);
660 mc
->textures
[mc
->cur_buf
% NUM_BUF_SETS
][3] = mc
->past_surface
->texture
;
661 pipe
->set_sampler_textures(pipe
, 4, mc
->textures
[mc
->cur_buf
% NUM_BUF_SETS
]);
662 pipe
->bind_sampler_states(pipe
, 4, (void**)mc
->samplers
);
663 pipe
->bind_vs_state(pipe
, mc
->p_vs
[1]);
664 pipe
->bind_fs_state(pipe
, mc
->p_fs
[1]);
666 pipe
->draw_arrays(pipe
, PIPE_PRIM_TRIANGLES
, vb_start
, num_macroblocks
[vlMacroBlockExTypeFwdPredictedField
] * 24);
667 vb_start
+= num_macroblocks
[vlMacroBlockExTypeFwdPredictedField
] * 24;
670 if (num_macroblocks
[vlMacroBlockExTypeBkwdPredictedFrame
] > 0)
672 pipe
->set_vertex_buffers(pipe
, 2, mc
->vertex_bufs
[mc
->cur_buf
% NUM_BUF_SETS
]);
673 pipe
->set_vertex_elements(pipe
, 6, mc
->vertex_elems
);
674 mc
->textures
[mc
->cur_buf
% NUM_BUF_SETS
][3] = mc
->future_surface
->texture
;
675 pipe
->set_sampler_textures(pipe
, 4, mc
->textures
[mc
->cur_buf
% NUM_BUF_SETS
]);
676 pipe
->bind_sampler_states(pipe
, 4, (void**)mc
->samplers
);
677 pipe
->bind_vs_state(pipe
, mc
->p_vs
[0]);
678 pipe
->bind_fs_state(pipe
, mc
->p_fs
[0]);
680 pipe
->draw_arrays(pipe
, PIPE_PRIM_TRIANGLES
, vb_start
, num_macroblocks
[vlMacroBlockExTypeBkwdPredictedFrame
] * 24);
681 vb_start
+= num_macroblocks
[vlMacroBlockExTypeBkwdPredictedFrame
] * 24;
684 if (num_macroblocks
[vlMacroBlockExTypeBkwdPredictedField
] > 0)
686 pipe
->set_vertex_buffers(pipe
, 2, mc
->vertex_bufs
[mc
->cur_buf
% NUM_BUF_SETS
]);
687 pipe
->set_vertex_elements(pipe
, 6, mc
->vertex_elems
);
688 mc
->textures
[mc
->cur_buf
% NUM_BUF_SETS
][3] = mc
->future_surface
->texture
;
689 pipe
->set_sampler_textures(pipe
, 4, mc
->textures
[mc
->cur_buf
% NUM_BUF_SETS
]);
690 pipe
->bind_sampler_states(pipe
, 4, (void**)mc
->samplers
);
691 pipe
->bind_vs_state(pipe
, mc
->p_vs
[1]);
692 pipe
->bind_fs_state(pipe
, mc
->p_fs
[1]);
694 pipe
->draw_arrays(pipe
, PIPE_PRIM_TRIANGLES
, vb_start
, num_macroblocks
[vlMacroBlockExTypeBkwdPredictedField
] * 24);
695 vb_start
+= num_macroblocks
[vlMacroBlockExTypeBkwdPredictedField
] * 24;
698 if (num_macroblocks
[vlMacroBlockExTypeBiPredictedFrame
] > 0)
700 pipe
->set_vertex_buffers(pipe
, 3, mc
->vertex_bufs
[mc
->cur_buf
% NUM_BUF_SETS
]);
701 pipe
->set_vertex_elements(pipe
, 8, mc
->vertex_elems
);
702 mc
->textures
[mc
->cur_buf
% NUM_BUF_SETS
][3] = mc
->past_surface
->texture
;
703 mc
->textures
[mc
->cur_buf
% NUM_BUF_SETS
][4] = mc
->future_surface
->texture
;
704 pipe
->set_sampler_textures(pipe
, 5, mc
->textures
[mc
->cur_buf
% NUM_BUF_SETS
]);
705 pipe
->bind_sampler_states(pipe
, 5, (void**)mc
->samplers
);
706 pipe
->bind_vs_state(pipe
, mc
->b_vs
[0]);
707 pipe
->bind_fs_state(pipe
, mc
->b_fs
[0]);
709 pipe
->draw_arrays(pipe
, PIPE_PRIM_TRIANGLES
, vb_start
, num_macroblocks
[vlMacroBlockExTypeBiPredictedFrame
] * 24);
710 vb_start
+= num_macroblocks
[vlMacroBlockExTypeBiPredictedFrame
] * 24;
713 if (num_macroblocks
[vlMacroBlockExTypeBiPredictedField
] > 0)
715 pipe
->set_vertex_buffers(pipe
, 3, mc
->vertex_bufs
[mc
->cur_buf
% NUM_BUF_SETS
]);
716 pipe
->set_vertex_elements(pipe
, 8, mc
->vertex_elems
);
717 mc
->textures
[mc
->cur_buf
% NUM_BUF_SETS
][3] = mc
->past_surface
->texture
;
718 mc
->textures
[mc
->cur_buf
% NUM_BUF_SETS
][4] = mc
->future_surface
->texture
;
719 pipe
->set_sampler_textures(pipe
, 5, mc
->textures
[mc
->cur_buf
% NUM_BUF_SETS
]);
720 pipe
->bind_sampler_states(pipe
, 5, (void**)mc
->samplers
);
721 pipe
->bind_vs_state(pipe
, mc
->b_vs
[1]);
722 pipe
->bind_fs_state(pipe
, mc
->b_fs
[1]);
724 pipe
->draw_arrays(pipe
, PIPE_PRIM_TRIANGLES
, vb_start
, num_macroblocks
[vlMacroBlockExTypeBiPredictedField
] * 24);
725 vb_start
+= num_macroblocks
[vlMacroBlockExTypeBiPredictedField
] * 24;
728 pipe
->flush(pipe
, PIPE_FLUSH_RENDER_CACHE
, &mc
->buffered_surface
->render_fence
);
730 for (i
= 0; i
< 3; ++i
)
731 mc
->zero_block
[i
].x
= -1.0f
;
733 mc
->buffered_surface
= NULL
;
734 mc
->num_macroblocks
= 0;
740 static int vlRenderMacroBlocksMpeg2R16SnormBuffered
742 struct vlRender
*render
,
743 struct vlMpeg2MacroBlockBatch
*batch
,
744 struct vlSurface
*surface
747 struct vlR16SnormBufferedMC
*mc
;
752 mc
= (struct vlR16SnormBufferedMC
*)render
;
754 if (mc
->buffered_surface
)
756 if (mc
->buffered_surface
!= surface
)
759 mc
->buffered_surface
= surface
;
760 mc
->past_surface
= batch
->past_surface
;
761 mc
->future_surface
= batch
->future_surface
;
762 mc
->surface_tex_inv_size
.x
= 1.0f
/ surface
->texture
->width
[0];
763 mc
->surface_tex_inv_size
.y
= 1.0f
/ surface
->texture
->height
[0];
765 for (i
= 0; i
< 3; ++i
)
767 mc
->tex_surface
[i
] = mc
->pipe
->screen
->get_tex_surface
770 mc
->textures
[mc
->cur_buf
% NUM_BUF_SETS
][i
],
771 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE
774 mc
->texels
[i
] = pipe_surface_map(mc
->tex_surface
[i
], PIPE_BUFFER_USAGE_CPU_WRITE
);
780 mc
->buffered_surface
= surface
;
781 mc
->past_surface
= batch
->past_surface
;
782 mc
->future_surface
= batch
->future_surface
;
783 mc
->surface_tex_inv_size
.x
= 1.0f
/ surface
->texture
->width
[0];
784 mc
->surface_tex_inv_size
.y
= 1.0f
/ surface
->texture
->height
[0];
786 for (i
= 0; i
< 3; ++i
)
788 mc
->tex_surface
[i
] = mc
->pipe
->screen
->get_tex_surface
791 mc
->textures
[mc
->cur_buf
% NUM_BUF_SETS
][i
],
792 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE
795 mc
->texels
[i
] = pipe_surface_map(mc
->tex_surface
[i
], PIPE_BUFFER_USAGE_CPU_WRITE
);
799 for (i
= 0; i
< batch
->num_macroblocks
; ++i
)
800 vlGrabMacroBlock(mc
, &batch
->macroblocks
[i
]);
807 struct vlRender
*render
817 struct vlRender
*render
820 struct vlR16SnormBufferedMC
*mc
;
821 struct pipe_context
*pipe
;
826 mc
= (struct vlR16SnormBufferedMC
*)render
;
829 for (i
= 0; i
< 5; ++i
)
830 pipe
->delete_sampler_state(pipe
, mc
->samplers
[i
]);
832 for (h
= 0; h
< NUM_BUF_SETS
; ++h
)
833 for (i
= 0; i
< 3; ++i
)
834 pipe
->winsys
->buffer_destroy(pipe
->winsys
, mc
->vertex_bufs
[h
][i
].buffer
);
836 /* Textures 3 & 4 are not created directly, no need to release them here */
837 for (i
= 0; i
< NUM_BUF_SETS
; ++i
)
839 pipe_texture_release(&mc
->textures
[i
][0]);
840 pipe_texture_release(&mc
->textures
[i
][1]);
841 pipe_texture_release(&mc
->textures
[i
][2]);
844 pipe
->delete_vs_state(pipe
, mc
->i_vs
);
845 pipe
->delete_fs_state(pipe
, mc
->i_fs
);
847 for (i
= 0; i
< 2; ++i
)
849 pipe
->delete_vs_state(pipe
, mc
->p_vs
[i
]);
850 pipe
->delete_fs_state(pipe
, mc
->p_fs
[i
]);
851 pipe
->delete_vs_state(pipe
, mc
->b_vs
[i
]);
852 pipe
->delete_fs_state(pipe
, mc
->b_fs
[i
]);
855 pipe
->winsys
->buffer_destroy(pipe
->winsys
, mc
->vs_const_buf
.buffer
);
856 pipe
->winsys
->buffer_destroy(pipe
->winsys
, mc
->fs_const_buf
.buffer
);
858 free(mc
->macroblocks
);
865 * Muliplier renormalizes block samples from 16 bits to 12 bits.
866 * Divider is used when calculating Y % 2 for choosing top or bottom
867 * field for P or B macroblocks.
868 * TODO: Use immediates.
870 static const struct vlFragmentShaderConsts fs_consts
=
872 {32767.0f
/ 255.0f
, 32767.0f
/ 255.0f
, 32767.0f
/ 255.0f
, 0.0f
},
873 {0.5f
, 2.0f
, 0.0f
, 0.0f
}
876 #include "vl_r16snorm_mc_buf_shaders.inc"
878 static int vlCreateDataBufs
880 struct vlR16SnormBufferedMC
*mc
883 const unsigned int mbw
= align(mc
->picture_width
, VL_MACROBLOCK_WIDTH
) / VL_MACROBLOCK_WIDTH
;
884 const unsigned int mbh
= align(mc
->picture_height
, VL_MACROBLOCK_HEIGHT
) / VL_MACROBLOCK_HEIGHT
;
885 const unsigned int num_mb_per_frame
= mbw
* mbh
;
887 struct pipe_context
*pipe
;
894 /* Create our vertex buffers */
895 for (h
= 0; h
< NUM_BUF_SETS
; ++h
)
897 mc
->vertex_bufs
[h
][0].pitch
= sizeof(struct vlVertex2f
) * 4;
898 mc
->vertex_bufs
[h
][0].max_index
= 24 * num_mb_per_frame
- 1;
899 mc
->vertex_bufs
[h
][0].buffer_offset
= 0;
900 mc
->vertex_bufs
[h
][0].buffer
= pipe
->winsys
->buffer_create
904 PIPE_BUFFER_USAGE_VERTEX
,
905 sizeof(struct vlVertex2f
) * 4 * 24 * num_mb_per_frame
908 for (i
= 1; i
< 3; ++i
)
910 mc
->vertex_bufs
[h
][i
].pitch
= sizeof(struct vlVertex2f
) * 2;
911 mc
->vertex_bufs
[h
][i
].max_index
= 24 * num_mb_per_frame
- 1;
912 mc
->vertex_bufs
[h
][i
].buffer_offset
= 0;
913 mc
->vertex_bufs
[h
][i
].buffer
= pipe
->winsys
->buffer_create
917 PIPE_BUFFER_USAGE_VERTEX
,
918 sizeof(struct vlVertex2f
) * 2 * 24 * num_mb_per_frame
923 /* Position element */
924 mc
->vertex_elems
[0].src_offset
= 0;
925 mc
->vertex_elems
[0].vertex_buffer_index
= 0;
926 mc
->vertex_elems
[0].nr_components
= 2;
927 mc
->vertex_elems
[0].src_format
= PIPE_FORMAT_R32G32_FLOAT
;
929 /* Luma, texcoord element */
930 mc
->vertex_elems
[1].src_offset
= sizeof(struct vlVertex2f
);
931 mc
->vertex_elems
[1].vertex_buffer_index
= 0;
932 mc
->vertex_elems
[1].nr_components
= 2;
933 mc
->vertex_elems
[1].src_format
= PIPE_FORMAT_R32G32_FLOAT
;
935 /* Chroma Cr texcoord element */
936 mc
->vertex_elems
[2].src_offset
= sizeof(struct vlVertex2f
) * 2;
937 mc
->vertex_elems
[2].vertex_buffer_index
= 0;
938 mc
->vertex_elems
[2].nr_components
= 2;
939 mc
->vertex_elems
[2].src_format
= PIPE_FORMAT_R32G32_FLOAT
;
941 /* Chroma Cb texcoord element */
942 mc
->vertex_elems
[3].src_offset
= sizeof(struct vlVertex2f
) * 3;
943 mc
->vertex_elems
[3].vertex_buffer_index
= 0;
944 mc
->vertex_elems
[3].nr_components
= 2;
945 mc
->vertex_elems
[3].src_format
= PIPE_FORMAT_R32G32_FLOAT
;
947 /* First ref surface top field texcoord element */
948 mc
->vertex_elems
[4].src_offset
= 0;
949 mc
->vertex_elems
[4].vertex_buffer_index
= 1;
950 mc
->vertex_elems
[4].nr_components
= 2;
951 mc
->vertex_elems
[4].src_format
= PIPE_FORMAT_R32G32_FLOAT
;
953 /* First ref surface bottom field texcoord element */
954 mc
->vertex_elems
[5].src_offset
= sizeof(struct vlVertex2f
);
955 mc
->vertex_elems
[5].vertex_buffer_index
= 1;
956 mc
->vertex_elems
[5].nr_components
= 2;
957 mc
->vertex_elems
[5].src_format
= PIPE_FORMAT_R32G32_FLOAT
;
959 /* Second ref surface top field texcoord element */
960 mc
->vertex_elems
[6].src_offset
= 0;
961 mc
->vertex_elems
[6].vertex_buffer_index
= 2;
962 mc
->vertex_elems
[6].nr_components
= 2;
963 mc
->vertex_elems
[6].src_format
= PIPE_FORMAT_R32G32_FLOAT
;
965 /* Second ref surface bottom field texcoord element */
966 mc
->vertex_elems
[7].src_offset
= sizeof(struct vlVertex2f
);
967 mc
->vertex_elems
[7].vertex_buffer_index
= 2;
968 mc
->vertex_elems
[7].nr_components
= 2;
969 mc
->vertex_elems
[7].src_format
= PIPE_FORMAT_R32G32_FLOAT
;
971 /* Create our constant buffer */
972 mc
->vs_const_buf
.size
= sizeof(struct vlVertexShaderConsts
);
973 mc
->vs_const_buf
.buffer
= pipe
->winsys
->buffer_create
977 PIPE_BUFFER_USAGE_CONSTANT
,
978 mc
->vs_const_buf
.size
981 mc
->fs_const_buf
.size
= sizeof(struct vlFragmentShaderConsts
);
982 mc
->fs_const_buf
.buffer
= pipe
->winsys
->buffer_create
986 PIPE_BUFFER_USAGE_CONSTANT
,
987 mc
->fs_const_buf
.size
992 pipe
->winsys
->buffer_map(pipe
->winsys
, mc
->fs_const_buf
.buffer
, PIPE_BUFFER_USAGE_CPU_WRITE
),
994 sizeof(struct vlFragmentShaderConsts
)
997 pipe
->winsys
->buffer_unmap(pipe
->winsys
, mc
->fs_const_buf
.buffer
);
999 mc
->macroblocks
= malloc(sizeof(struct vlMpeg2MacroBlock
) * num_mb_per_frame
);
1006 struct vlR16SnormBufferedMC
*mc
1009 struct pipe_context
*pipe
;
1010 struct pipe_sampler_state sampler
;
1011 struct pipe_texture
template;
1012 unsigned int filters
[5];
1019 /* For MC we render to textures, which are rounded up to nearest POT */
1020 mc
->viewport
.scale
[0] = vlRoundUpPOT(mc
->picture_width
);
1021 mc
->viewport
.scale
[1] = vlRoundUpPOT(mc
->picture_height
);
1022 mc
->viewport
.scale
[2] = 1;
1023 mc
->viewport
.scale
[3] = 1;
1024 mc
->viewport
.translate
[0] = 0;
1025 mc
->viewport
.translate
[1] = 0;
1026 mc
->viewport
.translate
[2] = 0;
1027 mc
->viewport
.translate
[3] = 0;
1029 mc
->render_target
.width
= vlRoundUpPOT(mc
->picture_width
);
1030 mc
->render_target
.height
= vlRoundUpPOT(mc
->picture_height
);
1031 mc
->render_target
.num_cbufs
= 1;
1032 /* FB for MC stage is a vlSurface created by the user, set at render time */
1033 mc
->render_target
.zsbuf
= NULL
;
1035 filters
[0] = PIPE_TEX_FILTER_NEAREST
;
1036 /* FIXME: Linear causes discoloration around block edges */
1037 filters
[1] = /*mc->picture_format == vlFormatYCbCr444 ?*/ PIPE_TEX_FILTER_NEAREST
/*: PIPE_TEX_FILTER_LINEAR*/;
1038 filters
[2] = /*mc->picture_format == vlFormatYCbCr444 ?*/ PIPE_TEX_FILTER_NEAREST
/*: PIPE_TEX_FILTER_LINEAR*/;
1039 filters
[3] = PIPE_TEX_FILTER_LINEAR
;
1040 filters
[4] = PIPE_TEX_FILTER_LINEAR
;
1042 for (i
= 0; i
< 5; ++i
)
1044 sampler
.wrap_s
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
1045 sampler
.wrap_t
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
1046 sampler
.wrap_r
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
1047 sampler
.min_img_filter
= filters
[i
];
1048 sampler
.min_mip_filter
= PIPE_TEX_MIPFILTER_NONE
;
1049 sampler
.mag_img_filter
= filters
[i
];
1050 sampler
.compare_mode
= PIPE_TEX_COMPARE_NONE
;
1051 sampler
.compare_func
= PIPE_FUNC_ALWAYS
;
1052 sampler
.normalized_coords
= 1;
1053 /*sampler.prefilter = ;*/
1054 /*sampler.shadow_ambient = ;*/
1055 /*sampler.lod_bias = ;*/
1056 sampler
.min_lod
= 0;
1057 /*sampler.max_lod = ;*/
1058 /*sampler.border_color[i] = ;*/
1059 /*sampler.max_anisotropy = ;*/
1060 mc
->samplers
[i
] = pipe
->create_sampler_state(pipe
, &sampler
);
1063 memset(&template, 0, sizeof(struct pipe_texture
));
1064 template.target
= PIPE_TEXTURE_2D
;
1065 template.format
= PIPE_FORMAT_R16_SNORM
;
1066 template.last_level
= 0;
1067 template.width
[0] = vlRoundUpPOT(mc
->picture_width
);
1068 template.height
[0] = vlRoundUpPOT(mc
->picture_height
);
1069 template.depth
[0] = 1;
1070 template.compressed
= 0;
1071 pf_get_block(template.format
, &template.block
);
1072 template.tex_usage
= PIPE_TEXTURE_USAGE_SAMPLER
;
1074 for (i
= 0; i
< NUM_BUF_SETS
; ++i
)
1075 mc
->textures
[i
][0] = pipe
->screen
->texture_create(pipe
->screen
, &template);
1077 if (mc
->picture_format
== vlFormatYCbCr420
)
1079 template.width
[0] = vlRoundUpPOT(mc
->picture_width
/ 2);
1080 template.height
[0] = vlRoundUpPOT(mc
->picture_height
/ 2);
1082 else if (mc
->picture_format
== vlFormatYCbCr422
)
1083 template.height
[0] = vlRoundUpPOT(mc
->picture_height
/ 2);
1085 for (i
= 0; i
< NUM_BUF_SETS
; ++i
)
1087 mc
->textures
[i
][1] = pipe
->screen
->texture_create(pipe
->screen
, &template);
1088 mc
->textures
[i
][2] = pipe
->screen
->texture_create(pipe
->screen
, &template);
1091 /* textures[3] & textures[4] are assigned from vlSurfaces for P and B macroblocks at render time */
1093 vlCreateVertexShaderIMB(mc
);
1094 vlCreateFragmentShaderIMB(mc
);
1095 vlCreateVertexShaderFramePMB(mc
);
1096 vlCreateVertexShaderFieldPMB(mc
);
1097 vlCreateFragmentShaderFramePMB(mc
);
1098 vlCreateFragmentShaderFieldPMB(mc
);
1099 vlCreateVertexShaderFrameBMB(mc
);
1100 vlCreateVertexShaderFieldBMB(mc
);
1101 vlCreateFragmentShaderFrameBMB(mc
);
1102 vlCreateFragmentShaderFieldBMB(mc
);
1103 vlCreateDataBufs(mc
);
1108 int vlCreateR16SNormBufferedMC
1110 struct pipe_context
*pipe
,
1111 unsigned int picture_width
,
1112 unsigned int picture_height
,
1113 enum vlFormat picture_format
,
1114 struct vlRender
**render
1117 struct vlR16SnormBufferedMC
*mc
;
1123 mc
= calloc(1, sizeof(struct vlR16SnormBufferedMC
));
1125 mc
->base
.vlBegin
= &vlBegin
;
1126 mc
->base
.vlRenderMacroBlocksMpeg2
= &vlRenderMacroBlocksMpeg2R16SnormBuffered
;
1127 mc
->base
.vlEnd
= &vlEnd
;
1128 mc
->base
.vlFlush
= &vlFlush
;
1129 mc
->base
.vlDestroy
= &vlDestroy
;
1131 mc
->picture_width
= picture_width
;
1132 mc
->picture_height
= picture_height
;
1135 mc
->buffered_surface
= NULL
;
1136 mc
->past_surface
= NULL
;
1137 mc
->future_surface
= NULL
;
1138 for (i
= 0; i
< 3; ++i
)
1139 mc
->zero_block
[i
].x
= -1.0f
;
1140 mc
->num_macroblocks
= 0;
1144 *render
= &mc
->base
;