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"
20 const unsigned int DEFAULT_BUF_ALIGNMENT
= 256;
22 enum vlMacroBlockTypeEx
24 vlMacroBlockExTypeIntra
,
25 vlMacroBlockExTypeFwdPredictedFrame
,
26 vlMacroBlockExTypeFwdPredictedField
,
27 vlMacroBlockExTypeBkwdPredictedFrame
,
28 vlMacroBlockExTypeBkwdPredictedField
,
29 vlMacroBlockExTypeBiPredictedFrame
,
30 vlMacroBlockExTypeBiPredictedField
,
32 vlNumMacroBlockExTypes
35 struct vlVertexShaderConsts
37 struct vlVertex4f denorm
;
40 struct vlFragmentShaderConsts
42 struct vlVertex4f multiplier
;
43 struct vlVertex4f div
;
46 struct vlR16SnormBufferedMC
50 unsigned int picture_width
;
51 unsigned int picture_height
;
52 enum vlFormat picture_format
;
53 unsigned int macroblocks_per_picture
;
55 struct vlSurface
*buffered_surface
;
56 struct vlSurface
*past_surface
;
57 struct vlSurface
*future_surface
;
58 struct vlVertex2f surface_tex_inv_size
;
59 struct vlVertex2f zero_block
[3];
60 unsigned int num_macroblocks
;
61 struct vlMpeg2MacroBlock
*macroblocks
;
62 struct pipe_surface
*tex_surface
[3];
65 struct pipe_context
*pipe
;
66 struct pipe_viewport_state viewport
;
67 struct pipe_framebuffer_state render_target
;
83 struct pipe_texture
*all
[5];
86 struct pipe_texture
*y
;
87 struct pipe_texture
*cb
;
88 struct pipe_texture
*cr
;
89 struct pipe_texture
*ref
[2];
95 struct pipe_vertex_buffer all
[3];
98 struct pipe_vertex_buffer ycbcr
;
99 struct pipe_vertex_buffer ref
[2];
103 void *i_vs
, *p_vs
[2], *b_vs
[2];
104 void *i_fs
, *p_fs
[2], *b_fs
[2];
105 struct pipe_vertex_element vertex_elems
[8];
106 struct pipe_constant_buffer vs_const_buf
;
107 struct pipe_constant_buffer fs_const_buf
;
110 static inline int vlBegin
112 struct vlRender
*render
120 static inline int vlGrabFrameCodedBlock(short *src
, short *dst
, unsigned int dst_pitch
)
124 for (y
= 0; y
< VL_BLOCK_HEIGHT
; ++y
)
128 src
+ y
* VL_BLOCK_WIDTH
,
135 static inline int vlGrabFieldCodedBlock(short *src
, short *dst
, unsigned int dst_pitch
)
139 for (y
= 0; y
< VL_BLOCK_HEIGHT
; ++y
)
142 dst
+ y
* dst_pitch
* 2,
143 src
+ y
* VL_BLOCK_WIDTH
,
150 static inline int vlGrabNoBlock(short *dst
, unsigned int dst_pitch
)
154 for (y
= 0; y
< VL_BLOCK_HEIGHT
; ++y
)
165 static inline int vlGrabBlocks
167 struct vlR16SnormBufferedMC
*mc
,
170 enum vlDCTType dct_type
,
171 unsigned int coded_block_pattern
,
176 unsigned int tex_pitch
;
177 unsigned int x
, y
, tb
= 0, sb
= 0;
178 unsigned int mbpx
= mbx
* VL_MACROBLOCK_WIDTH
, mbpy
= mby
* VL_MACROBLOCK_HEIGHT
;
183 tex_pitch
= mc
->tex_surface
[0]->stride
/ mc
->tex_surface
[0]->block
.size
;
184 texels
= mc
->texels
[0] + mbpy
* tex_pitch
+ mbpx
;
186 for (y
= 0; y
< 2; ++y
)
188 for (x
= 0; x
< 2; ++x
, ++tb
)
190 if ((coded_block_pattern
>> (5 - tb
)) & 1)
192 short *cur_block
= blocks
+ sb
* VL_BLOCK_WIDTH
* VL_BLOCK_HEIGHT
;
194 if (dct_type
== vlDCTTypeFrameCoded
)
196 vlGrabFrameCodedBlock
199 texels
+ y
* tex_pitch
* VL_BLOCK_HEIGHT
+ x
* VL_BLOCK_WIDTH
,
205 vlGrabFieldCodedBlock
208 texels
+ y
* tex_pitch
+ x
* VL_BLOCK_WIDTH
,
215 else if (mc
->zero_block
[0].x
< 0.0f
)
217 vlGrabNoBlock(texels
+ y
* tex_pitch
* VL_BLOCK_HEIGHT
+ x
* VL_BLOCK_WIDTH
, tex_pitch
);
219 mc
->zero_block
[0].x
= (mbpx
+ x
* 8) * mc
->surface_tex_inv_size
.x
;
220 mc
->zero_block
[0].y
= (mbpy
+ y
* 8) * mc
->surface_tex_inv_size
.y
;
225 /* TODO: Implement 422, 444 */
229 for (tb
= 0; tb
< 2; ++tb
)
231 tex_pitch
= mc
->tex_surface
[tb
+ 1]->stride
/ mc
->tex_surface
[tb
+ 1]->block
.size
;
232 texels
= mc
->texels
[tb
+ 1] + mbpy
* tex_pitch
+ mbpx
;
234 if ((coded_block_pattern
>> (1 - tb
)) & 1)
236 short *cur_block
= blocks
+ sb
* VL_BLOCK_WIDTH
* VL_BLOCK_HEIGHT
;
238 vlGrabFrameCodedBlock
247 else if (mc
->zero_block
[tb
+ 1].x
< 0.0f
)
249 vlGrabNoBlock(texels
, tex_pitch
);
251 mc
->zero_block
[tb
+ 1].x
= (mbpx
<< 1) * mc
->surface_tex_inv_size
.x
;
252 mc
->zero_block
[tb
+ 1].y
= (mbpy
<< 1) * mc
->surface_tex_inv_size
.y
;
259 static inline enum vlMacroBlockTypeEx
vlGetMacroBlockTypeEx(struct vlMpeg2MacroBlock
*mb
)
265 case vlMacroBlockTypeIntra
:
266 return vlMacroBlockExTypeIntra
;
267 case vlMacroBlockTypeFwdPredicted
:
268 return mb
->mo_type
== vlMotionTypeFrame
?
269 vlMacroBlockExTypeFwdPredictedFrame
: vlMacroBlockExTypeFwdPredictedField
;
270 case vlMacroBlockTypeBkwdPredicted
:
271 return mb
->mo_type
== vlMotionTypeFrame
?
272 vlMacroBlockExTypeBkwdPredictedFrame
: vlMacroBlockExTypeBkwdPredictedField
;
273 case vlMacroBlockTypeBiPredicted
:
274 return mb
->mo_type
== vlMotionTypeFrame
?
275 vlMacroBlockExTypeBiPredictedFrame
: vlMacroBlockExTypeBiPredictedField
;
284 static inline int vlGrabMacroBlock
286 struct vlR16SnormBufferedMC
*mc
,
287 struct vlMpeg2MacroBlock
*macroblock
293 mc
->macroblocks
[mc
->num_macroblocks
].mbx
= macroblock
->mbx
;
294 mc
->macroblocks
[mc
->num_macroblocks
].mby
= macroblock
->mby
;
295 mc
->macroblocks
[mc
->num_macroblocks
].mb_type
= macroblock
->mb_type
;
296 mc
->macroblocks
[mc
->num_macroblocks
].mo_type
= macroblock
->mo_type
;
297 mc
->macroblocks
[mc
->num_macroblocks
].dct_type
= macroblock
->dct_type
;
298 mc
->macroblocks
[mc
->num_macroblocks
].PMV
[0][0][0] = macroblock
->PMV
[0][0][0];
299 mc
->macroblocks
[mc
->num_macroblocks
].PMV
[0][0][1] = macroblock
->PMV
[0][0][1];
300 mc
->macroblocks
[mc
->num_macroblocks
].PMV
[0][1][0] = macroblock
->PMV
[0][1][0];
301 mc
->macroblocks
[mc
->num_macroblocks
].PMV
[0][1][1] = macroblock
->PMV
[0][1][1];
302 mc
->macroblocks
[mc
->num_macroblocks
].PMV
[1][0][0] = macroblock
->PMV
[1][0][0];
303 mc
->macroblocks
[mc
->num_macroblocks
].PMV
[1][0][1] = macroblock
->PMV
[1][0][1];
304 mc
->macroblocks
[mc
->num_macroblocks
].PMV
[1][1][0] = macroblock
->PMV
[1][1][0];
305 mc
->macroblocks
[mc
->num_macroblocks
].PMV
[1][1][1] = macroblock
->PMV
[1][1][1];
306 mc
->macroblocks
[mc
->num_macroblocks
].cbp
= macroblock
->cbp
;
307 mc
->macroblocks
[mc
->num_macroblocks
].blocks
= macroblock
->blocks
;
314 macroblock
->dct_type
,
319 mc
->num_macroblocks
++;
324 #define SET_BLOCK(vb, cbp, mbx, mby, unitx, unity, ofsx, ofsy, hx, hy, lm, cbm, crm, zb) \
325 (vb)[0].pos.x = (mbx) * (unitx) + (ofsx); (vb)[0].pos.y = (mby) * (unity) + (ofsy); \
326 (vb)[1].pos.x = (mbx) * (unitx) + (ofsx); (vb)[1].pos.y = (mby) * (unity) + (ofsy) + (hy); \
327 (vb)[2].pos.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[2].pos.y = (mby) * (unity) + (ofsy); \
328 (vb)[3].pos.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[3].pos.y = (mby) * (unity) + (ofsy); \
329 (vb)[4].pos.x = (mbx) * (unitx) + (ofsx); (vb)[4].pos.y = (mby) * (unity) + (ofsy) + (hy); \
330 (vb)[5].pos.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[5].pos.y = (mby) * (unity) + (ofsy) + (hy); \
334 (vb)[0].luma_tc.x = (mbx) * (unitx) + (ofsx); (vb)[0].luma_tc.y = (mby) * (unity) + (ofsy); \
335 (vb)[1].luma_tc.x = (mbx) * (unitx) + (ofsx); (vb)[1].luma_tc.y = (mby) * (unity) + (ofsy) + (hy); \
336 (vb)[2].luma_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[2].luma_tc.y = (mby) * (unity) + (ofsy); \
337 (vb)[3].luma_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[3].luma_tc.y = (mby) * (unity) + (ofsy); \
338 (vb)[4].luma_tc.x = (mbx) * (unitx) + (ofsx); (vb)[4].luma_tc.y = (mby) * (unity) + (ofsy) + (hy); \
339 (vb)[5].luma_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[5].luma_tc.y = (mby) * (unity) + (ofsy) + (hy); \
343 (vb)[0].luma_tc.x = (zb)[0].x; (vb)[0].luma_tc.y = (zb)[0].y; \
344 (vb)[1].luma_tc.x = (zb)[0].x; (vb)[1].luma_tc.y = (zb)[0].y + (hy); \
345 (vb)[2].luma_tc.x = (zb)[0].x + (hx); (vb)[2].luma_tc.y = (zb)[0].y; \
346 (vb)[3].luma_tc.x = (zb)[0].x + (hx); (vb)[3].luma_tc.y = (zb)[0].y; \
347 (vb)[4].luma_tc.x = (zb)[0].x; (vb)[4].luma_tc.y = (zb)[0].y + (hy); \
348 (vb)[5].luma_tc.x = (zb)[0].x + (hx); (vb)[5].luma_tc.y = (zb)[0].y + (hy); \
353 (vb)[0].cb_tc.x = (mbx) * (unitx) + (ofsx); (vb)[0].cb_tc.y = (mby) * (unity) + (ofsy); \
354 (vb)[1].cb_tc.x = (mbx) * (unitx) + (ofsx); (vb)[1].cb_tc.y = (mby) * (unity) + (ofsy) + (hy); \
355 (vb)[2].cb_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[2].cb_tc.y = (mby) * (unity) + (ofsy); \
356 (vb)[3].cb_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[3].cb_tc.y = (mby) * (unity) + (ofsy); \
357 (vb)[4].cb_tc.x = (mbx) * (unitx) + (ofsx); (vb)[4].cb_tc.y = (mby) * (unity) + (ofsy) + (hy); \
358 (vb)[5].cb_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[5].cb_tc.y = (mby) * (unity) + (ofsy) + (hy); \
362 (vb)[0].cb_tc.x = (zb)[1].x; (vb)[0].cb_tc.y = (zb)[1].y; \
363 (vb)[1].cb_tc.x = (zb)[1].x; (vb)[1].cb_tc.y = (zb)[1].y + (hy); \
364 (vb)[2].cb_tc.x = (zb)[1].x + (hx); (vb)[2].cb_tc.y = (zb)[1].y; \
365 (vb)[3].cb_tc.x = (zb)[1].x + (hx); (vb)[3].cb_tc.y = (zb)[1].y; \
366 (vb)[4].cb_tc.x = (zb)[1].x; (vb)[4].cb_tc.y = (zb)[1].y + (hy); \
367 (vb)[5].cb_tc.x = (zb)[1].x + (hx); (vb)[5].cb_tc.y = (zb)[1].y + (hy); \
372 (vb)[0].cr_tc.x = (mbx) * (unitx) + (ofsx); (vb)[0].cr_tc.y = (mby) * (unity) + (ofsy); \
373 (vb)[1].cr_tc.x = (mbx) * (unitx) + (ofsx); (vb)[1].cr_tc.y = (mby) * (unity) + (ofsy) + (hy); \
374 (vb)[2].cr_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[2].cr_tc.y = (mby) * (unity) + (ofsy); \
375 (vb)[3].cr_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[3].cr_tc.y = (mby) * (unity) + (ofsy); \
376 (vb)[4].cr_tc.x = (mbx) * (unitx) + (ofsx); (vb)[4].cr_tc.y = (mby) * (unity) + (ofsy) + (hy); \
377 (vb)[5].cr_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[5].cr_tc.y = (mby) * (unity) + (ofsy) + (hy); \
381 (vb)[0].cr_tc.x = (zb)[2].x; (vb)[0].cr_tc.y = (zb)[2].y; \
382 (vb)[1].cr_tc.x = (zb)[2].x; (vb)[1].cr_tc.y = (zb)[2].y + (hy); \
383 (vb)[2].cr_tc.x = (zb)[2].x + (hx); (vb)[2].cr_tc.y = (zb)[2].y; \
384 (vb)[3].cr_tc.x = (zb)[2].x + (hx); (vb)[3].cr_tc.y = (zb)[2].y; \
385 (vb)[4].cr_tc.x = (zb)[2].x; (vb)[4].cr_tc.y = (zb)[2].y + (hy); \
386 (vb)[5].cr_tc.x = (zb)[2].x + (hx); (vb)[5].cr_tc.y = (zb)[2].y + (hy); \
389 static inline int vlGrabMacroBlockVB
391 struct vlR16SnormBufferedMC
*mc
,
392 struct vlMpeg2MacroBlock
*macroblock
,
396 struct vlVertex2f mo_vec
[2];
402 switch (macroblock
->mb_type
)
404 case vlMacroBlockTypeBiPredicted
:
406 struct vlVertex2f
*vb
;
408 vb
= (struct vlVertex2f
*)mc
->pipe
->winsys
->buffer_map
411 mc
->vertex_bufs
.ref
[1].buffer
,
412 PIPE_BUFFER_USAGE_CPU_WRITE
415 mo_vec
[0].x
= macroblock
->PMV
[0][1][0] * 0.5f
* mc
->surface_tex_inv_size
.x
;
416 mo_vec
[0].y
= macroblock
->PMV
[0][1][1] * 0.5f
* mc
->surface_tex_inv_size
.y
;
418 if (macroblock
->mo_type
== vlMotionTypeFrame
)
420 for (i
= 0; i
< 24 * 2; i
+= 2)
422 vb
[i
].x
= mo_vec
[0].x
;
423 vb
[i
].y
= mo_vec
[0].y
;
428 mo_vec
[1].x
= macroblock
->PMV
[1][1][0] * 0.5f
* mc
->surface_tex_inv_size
.x
;
429 mo_vec
[1].y
= macroblock
->PMV
[1][1][1] * 0.5f
* mc
->surface_tex_inv_size
.y
;
431 for (i
= 0; i
< 24 * 2; i
+= 2)
433 vb
[i
].x
= mo_vec
[0].x
;
434 vb
[i
].y
= mo_vec
[0].y
;
435 vb
[i
+ 1].x
= mo_vec
[1].x
;
436 vb
[i
+ 1].y
= mo_vec
[1].y
;
440 mc
->pipe
->winsys
->buffer_unmap(mc
->pipe
->winsys
, mc
->vertex_bufs
.ref
[1].buffer
);
444 case vlMacroBlockTypeFwdPredicted
:
445 case vlMacroBlockTypeBkwdPredicted
:
447 struct vlVertex2f
*vb
;
449 vb
= (struct vlVertex2f
*)mc
->pipe
->winsys
->buffer_map
452 mc
->vertex_bufs
.ref
[0].buffer
,
453 PIPE_BUFFER_USAGE_CPU_WRITE
456 if (macroblock
->mb_type
== vlMacroBlockTypeBkwdPredicted
)
458 mo_vec
[0].x
= macroblock
->PMV
[0][1][0] * 0.5f
* mc
->surface_tex_inv_size
.x
;
459 mo_vec
[0].y
= macroblock
->PMV
[0][1][1] * 0.5f
* mc
->surface_tex_inv_size
.y
;
461 if (macroblock
->mo_type
== vlMotionTypeField
)
463 mo_vec
[1].x
= macroblock
->PMV
[1][1][0] * 0.5f
* mc
->surface_tex_inv_size
.x
;
464 mo_vec
[1].y
= macroblock
->PMV
[1][1][1] * 0.5f
* mc
->surface_tex_inv_size
.y
;
469 mo_vec
[0].x
= macroblock
->PMV
[0][0][0] * 0.5f
* mc
->surface_tex_inv_size
.x
;
470 mo_vec
[0].y
= macroblock
->PMV
[0][0][1] * 0.5f
* mc
->surface_tex_inv_size
.y
;
472 if (macroblock
->mo_type
== vlMotionTypeField
)
474 mo_vec
[1].x
= macroblock
->PMV
[1][0][0] * 0.5f
* mc
->surface_tex_inv_size
.x
;
475 mo_vec
[1].y
= macroblock
->PMV
[1][0][1] * 0.5f
* mc
->surface_tex_inv_size
.y
;
479 if (macroblock
->mo_type
== vlMotionTypeFrame
)
481 for (i
= 0; i
< 24 * 2; i
+= 2)
483 vb
[i
].x
= mo_vec
[0].x
;
484 vb
[i
].y
= mo_vec
[0].y
;
489 for (i
= 0; i
< 24 * 2; i
+= 2)
491 vb
[i
].x
= mo_vec
[0].x
;
492 vb
[i
].y
= mo_vec
[0].y
;
493 vb
[i
+ 1].x
= mo_vec
[1].x
;
494 vb
[i
+ 1].y
= mo_vec
[1].y
;
498 mc
->pipe
->winsys
->buffer_unmap(mc
->pipe
->winsys
, mc
->vertex_bufs
.ref
[0].buffer
);
502 case vlMacroBlockTypeIntra
:
504 const struct vlVertex2f unit
=
506 mc
->surface_tex_inv_size
.x
* VL_MACROBLOCK_WIDTH
,
507 mc
->surface_tex_inv_size
.y
* VL_MACROBLOCK_HEIGHT
509 const struct vlVertex2f half
=
511 mc
->surface_tex_inv_size
.x
* (VL_MACROBLOCK_WIDTH
/ 2),
512 mc
->surface_tex_inv_size
.y
* (VL_MACROBLOCK_HEIGHT
/ 2)
515 struct vlMacroBlockVertexStream0
517 struct vlVertex2f pos
;
518 struct vlVertex2f luma_tc
;
519 struct vlVertex2f cb_tc
;
520 struct vlVertex2f cr_tc
;
523 vb
= (struct vlMacroBlockVertexStream0
*)mc
->pipe
->winsys
->buffer_map
526 mc
->vertex_bufs
.ycbcr
.buffer
,
527 PIPE_BUFFER_USAGE_CPU_WRITE
533 macroblock
->cbp
, macroblock
->mbx
, macroblock
->mby
,
534 unit
.x
, unit
.y
, 0, 0, half
.x
, half
.y
,
535 32, 2, 1, mc
->zero_block
541 macroblock
->cbp
, macroblock
->mbx
, macroblock
->mby
,
542 unit
.x
, unit
.y
, half
.x
, 0, half
.x
, half
.y
,
543 16, 2, 1, mc
->zero_block
549 macroblock
->cbp
, macroblock
->mbx
, macroblock
->mby
,
550 unit
.x
, unit
.y
, 0, half
.y
, half
.x
, half
.y
,
551 8, 2, 1, mc
->zero_block
557 macroblock
->cbp
, macroblock
->mbx
, macroblock
->mby
,
558 unit
.x
, unit
.y
, half
.x
, half
.y
, half
.x
, half
.y
,
559 4, 2, 1, mc
->zero_block
562 mc
->pipe
->winsys
->buffer_unmap(mc
->pipe
->winsys
, mc
->vertex_bufs
.ycbcr
.buffer
);
575 struct vlRender
*render
578 struct vlR16SnormBufferedMC
*mc
;
579 struct pipe_context
*pipe
;
580 struct vlVertexShaderConsts
*vs_consts
;
581 unsigned int num_macroblocks
[vlNumMacroBlockExTypes
] = {0};
582 unsigned int offset
[vlNumMacroBlockExTypes
];
583 unsigned int vb_start
= 0;
588 mc
= (struct vlR16SnormBufferedMC
*)render
;
590 if (!mc
->buffered_surface
)
593 if (mc
->num_macroblocks
< mc
->macroblocks_per_picture
)
598 for (i
= 0; i
< mc
->num_macroblocks
; ++i
)
600 enum vlMacroBlockTypeEx mb_type_ex
= vlGetMacroBlockTypeEx(&mc
->macroblocks
[i
]);
602 num_macroblocks
[mb_type_ex
]++;
607 for (i
= 1; i
< vlNumMacroBlockExTypes
; ++i
)
608 offset
[i
] = offset
[i
- 1] + num_macroblocks
[i
- 1];
610 for (i
= 0; i
< mc
->num_macroblocks
; ++i
)
612 enum vlMacroBlockTypeEx mb_type_ex
= vlGetMacroBlockTypeEx(&mc
->macroblocks
[i
]);
614 vlGrabMacroBlockVB(mc
, &mc
->macroblocks
[i
], offset
[mb_type_ex
]);
616 offset
[mb_type_ex
]++;
619 for (i
= 0; i
< 3; ++i
)
621 pipe_surface_unmap(mc
->tex_surface
[i
]);
622 mc
->pipe
->screen
->tex_surface_release(mc
->pipe
->screen
, &mc
->tex_surface
[i
]);
625 mc
->render_target
.cbufs
[0] = pipe
->screen
->get_tex_surface
628 mc
->buffered_surface
->texture
,
629 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ
| PIPE_BUFFER_USAGE_GPU_WRITE
632 pipe
->set_framebuffer_state(pipe
, &mc
->render_target
);
633 pipe
->set_viewport_state(pipe
, &mc
->viewport
);
634 vs_consts
= pipe
->winsys
->buffer_map
637 mc
->vs_const_buf
.buffer
,
638 PIPE_BUFFER_USAGE_CPU_WRITE
641 vs_consts
->denorm
.x
= mc
->buffered_surface
->texture
->width
[0];
642 vs_consts
->denorm
.y
= mc
->buffered_surface
->texture
->height
[0];
644 pipe
->winsys
->buffer_unmap(pipe
->winsys
, mc
->vs_const_buf
.buffer
);
645 pipe
->set_constant_buffer(pipe
, PIPE_SHADER_VERTEX
, 0, &mc
->vs_const_buf
);
646 pipe
->set_constant_buffer(pipe
, PIPE_SHADER_FRAGMENT
, 0, &mc
->fs_const_buf
);
648 if (num_macroblocks
[vlMacroBlockExTypeIntra
] > 0)
650 pipe
->set_vertex_buffers(pipe
, 1, mc
->vertex_bufs
.all
);
651 pipe
->set_vertex_elements(pipe
, 4, mc
->vertex_elems
);
652 pipe
->set_sampler_textures(pipe
, 3, mc
->textures
.all
);
653 pipe
->bind_sampler_states(pipe
, 3, mc
->samplers
.all
);
654 pipe
->bind_vs_state(pipe
, mc
->i_vs
);
655 pipe
->bind_fs_state(pipe
, mc
->i_fs
);
657 pipe
->draw_arrays(pipe
, PIPE_PRIM_TRIANGLES
, vb_start
, num_macroblocks
[vlMacroBlockExTypeIntra
] * 24);
658 vb_start
+= num_macroblocks
[vlMacroBlockExTypeIntra
] * 24;
661 if (num_macroblocks
[vlMacroBlockExTypeFwdPredictedFrame
] > 0)
663 pipe
->set_vertex_buffers(pipe
, 2, mc
->vertex_bufs
.all
);
664 pipe
->set_vertex_elements(pipe
, 6, mc
->vertex_elems
);
665 mc
->textures
.ref
[0] = mc
->past_surface
->texture
;
666 pipe
->set_sampler_textures(pipe
, 4, mc
->textures
.all
);
667 pipe
->bind_sampler_states(pipe
, 4, mc
->samplers
.all
);
668 pipe
->bind_vs_state(pipe
, mc
->p_vs
[0]);
669 pipe
->bind_fs_state(pipe
, mc
->p_fs
[0]);
671 pipe
->draw_arrays(pipe
, PIPE_PRIM_TRIANGLES
, vb_start
, num_macroblocks
[vlMacroBlockExTypeFwdPredictedFrame
] * 24);
672 vb_start
+= num_macroblocks
[vlMacroBlockExTypeFwdPredictedFrame
] * 24;
675 if (num_macroblocks
[vlMacroBlockExTypeFwdPredictedField
] > 0)
677 pipe
->set_vertex_buffers(pipe
, 2, mc
->vertex_bufs
.all
);
678 pipe
->set_vertex_elements(pipe
, 6, mc
->vertex_elems
);
679 mc
->textures
.ref
[0] = mc
->past_surface
->texture
;
680 pipe
->set_sampler_textures(pipe
, 4, mc
->textures
.all
);
681 pipe
->bind_sampler_states(pipe
, 4, mc
->samplers
.all
);
682 pipe
->bind_vs_state(pipe
, mc
->p_vs
[1]);
683 pipe
->bind_fs_state(pipe
, mc
->p_fs
[1]);
685 pipe
->draw_arrays(pipe
, PIPE_PRIM_TRIANGLES
, vb_start
, num_macroblocks
[vlMacroBlockExTypeFwdPredictedField
] * 24);
686 vb_start
+= num_macroblocks
[vlMacroBlockExTypeFwdPredictedField
] * 24;
689 if (num_macroblocks
[vlMacroBlockExTypeBkwdPredictedFrame
] > 0)
691 pipe
->set_vertex_buffers(pipe
, 2, mc
->vertex_bufs
.all
);
692 pipe
->set_vertex_elements(pipe
, 6, mc
->vertex_elems
);
693 mc
->textures
.ref
[0] = mc
->future_surface
->texture
;
694 pipe
->set_sampler_textures(pipe
, 4, mc
->textures
.all
);
695 pipe
->bind_sampler_states(pipe
, 4, mc
->samplers
.all
);
696 pipe
->bind_vs_state(pipe
, mc
->p_vs
[0]);
697 pipe
->bind_fs_state(pipe
, mc
->p_fs
[0]);
699 pipe
->draw_arrays(pipe
, PIPE_PRIM_TRIANGLES
, vb_start
, num_macroblocks
[vlMacroBlockExTypeBkwdPredictedFrame
] * 24);
700 vb_start
+= num_macroblocks
[vlMacroBlockExTypeBkwdPredictedFrame
] * 24;
703 if (num_macroblocks
[vlMacroBlockExTypeBkwdPredictedField
] > 0)
705 pipe
->set_vertex_buffers(pipe
, 2, mc
->vertex_bufs
.all
);
706 pipe
->set_vertex_elements(pipe
, 6, mc
->vertex_elems
);
707 mc
->textures
.ref
[0] = mc
->future_surface
->texture
;
708 pipe
->set_sampler_textures(pipe
, 4, mc
->textures
.all
);
709 pipe
->bind_sampler_states(pipe
, 4, mc
->samplers
.all
);
710 pipe
->bind_vs_state(pipe
, mc
->p_vs
[1]);
711 pipe
->bind_fs_state(pipe
, mc
->p_fs
[1]);
713 pipe
->draw_arrays(pipe
, PIPE_PRIM_TRIANGLES
, vb_start
, num_macroblocks
[vlMacroBlockExTypeBkwdPredictedField
] * 24);
714 vb_start
+= num_macroblocks
[vlMacroBlockExTypeBkwdPredictedField
] * 24;
717 if (num_macroblocks
[vlMacroBlockExTypeBiPredictedFrame
] > 0)
719 pipe
->set_vertex_buffers(pipe
, 3, mc
->vertex_bufs
.all
);
720 pipe
->set_vertex_elements(pipe
, 8, mc
->vertex_elems
);
721 mc
->textures
.ref
[0] = mc
->past_surface
->texture
;
722 mc
->textures
.ref
[1] = mc
->future_surface
->texture
;
723 pipe
->set_sampler_textures(pipe
, 5, mc
->textures
.all
);
724 pipe
->bind_sampler_states(pipe
, 5, mc
->samplers
.all
);
725 pipe
->bind_vs_state(pipe
, mc
->b_vs
[0]);
726 pipe
->bind_fs_state(pipe
, mc
->b_fs
[0]);
728 pipe
->draw_arrays(pipe
, PIPE_PRIM_TRIANGLES
, vb_start
, num_macroblocks
[vlMacroBlockExTypeBiPredictedFrame
] * 24);
729 vb_start
+= num_macroblocks
[vlMacroBlockExTypeBiPredictedFrame
] * 24;
732 if (num_macroblocks
[vlMacroBlockExTypeBiPredictedField
] > 0)
734 pipe
->set_vertex_buffers(pipe
, 3, mc
->vertex_bufs
.all
);
735 pipe
->set_vertex_elements(pipe
, 8, mc
->vertex_elems
);
736 mc
->textures
.ref
[0] = mc
->past_surface
->texture
;
737 mc
->textures
.ref
[1] = mc
->future_surface
->texture
;
738 pipe
->set_sampler_textures(pipe
, 5, mc
->textures
.all
);
739 pipe
->bind_sampler_states(pipe
, 5, mc
->samplers
.all
);
740 pipe
->bind_vs_state(pipe
, mc
->b_vs
[1]);
741 pipe
->bind_fs_state(pipe
, mc
->b_fs
[1]);
743 pipe
->draw_arrays(pipe
, PIPE_PRIM_TRIANGLES
, vb_start
, num_macroblocks
[vlMacroBlockExTypeBiPredictedField
] * 24);
744 vb_start
+= num_macroblocks
[vlMacroBlockExTypeBiPredictedField
] * 24;
747 pipe
->flush(pipe
, PIPE_FLUSH_RENDER_CACHE
, &mc
->buffered_surface
->render_fence
);
748 pipe
->screen
->tex_surface_release(pipe
->screen
, mc
->render_target
.cbufs
[0]);
750 for (i
= 0; i
< 3; ++i
)
751 mc
->zero_block
[i
].x
= -1.0f
;
753 mc
->buffered_surface
= NULL
;
754 mc
->num_macroblocks
= 0;
759 static int vlRenderMacroBlocksMpeg2R16SnormBuffered
761 struct vlRender
*render
,
762 struct vlMpeg2MacroBlockBatch
*batch
,
763 struct vlSurface
*surface
766 struct vlR16SnormBufferedMC
*mc
;
767 bool new_surface
= false;
772 mc
= (struct vlR16SnormBufferedMC
*)render
;
774 if (mc
->buffered_surface
)
776 if (mc
->buffered_surface
!= surface
)
787 mc
->buffered_surface
= surface
;
788 mc
->past_surface
= batch
->past_surface
;
789 mc
->future_surface
= batch
->future_surface
;
790 mc
->surface_tex_inv_size
.x
= 1.0f
/ surface
->texture
->width
[0];
791 mc
->surface_tex_inv_size
.y
= 1.0f
/ surface
->texture
->height
[0];
793 for (i
= 0; i
< 3; ++i
)
795 mc
->tex_surface
[i
] = mc
->pipe
->screen
->get_tex_surface
799 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE
802 mc
->texels
[i
] = pipe_surface_map(mc
->tex_surface
[i
], PIPE_BUFFER_USAGE_CPU_WRITE
);
806 for (i
= 0; i
< batch
->num_macroblocks
; ++i
)
807 vlGrabMacroBlock(mc
, &batch
->macroblocks
[i
]);
812 static inline int vlEnd
814 struct vlRender
*render
824 struct vlRender
*render
827 struct vlR16SnormBufferedMC
*mc
;
828 struct pipe_context
*pipe
;
833 mc
= (struct vlR16SnormBufferedMC
*)render
;
836 for (i
= 0; i
< 5; ++i
)
837 pipe
->delete_sampler_state(pipe
, mc
->samplers
.all
[i
]);
839 for (i
= 0; i
< 3; ++i
)
840 pipe
->winsys
->buffer_destroy(pipe
->winsys
, mc
->vertex_bufs
.all
[i
].buffer
);
842 /* Textures 3 & 4 are not created directly, no need to release them here */
843 for (i
= 0; i
< 3; ++i
)
844 pipe_texture_release(&mc
->textures
.all
[i
]);
846 pipe
->delete_vs_state(pipe
, mc
->i_vs
);
847 pipe
->delete_fs_state(pipe
, mc
->i_fs
);
849 for (i
= 0; i
< 2; ++i
)
851 pipe
->delete_vs_state(pipe
, mc
->p_vs
[i
]);
852 pipe
->delete_fs_state(pipe
, mc
->p_fs
[i
]);
853 pipe
->delete_vs_state(pipe
, mc
->b_vs
[i
]);
854 pipe
->delete_fs_state(pipe
, mc
->b_fs
[i
]);
857 pipe
->winsys
->buffer_destroy(pipe
->winsys
, mc
->vs_const_buf
.buffer
);
858 pipe
->winsys
->buffer_destroy(pipe
->winsys
, mc
->fs_const_buf
.buffer
);
860 free(mc
->macroblocks
);
867 * Muliplier renormalizes block samples from 16 bits to 12 bits.
868 * Divider is used when calculating Y % 2 for choosing top or bottom
869 * field for P or B macroblocks.
870 * TODO: Use immediates.
872 static const struct vlFragmentShaderConsts fs_consts
=
874 {32767.0f
/ 255.0f
, 32767.0f
/ 255.0f
, 32767.0f
/ 255.0f
, 0.0f
},
875 {0.5f
, 2.0f
, 0.0f
, 0.0f
}
878 #include "vl_r16snorm_mc_buf_shaders.inc"
880 static int vlCreateDataBufs
882 struct vlR16SnormBufferedMC
*mc
885 const unsigned int mbw
= align(mc
->picture_width
, VL_MACROBLOCK_WIDTH
) / VL_MACROBLOCK_WIDTH
;
886 const unsigned int mbh
= align(mc
->picture_height
, VL_MACROBLOCK_HEIGHT
) / VL_MACROBLOCK_HEIGHT
;
888 struct pipe_context
*pipe
;
894 mc
->macroblocks_per_picture
= mbw
* mbh
;
896 /* Create our vertex buffers */
897 mc
->vertex_bufs
.ycbcr
.pitch
= sizeof(struct vlVertex2f
) * 4;
898 mc
->vertex_bufs
.ycbcr
.max_index
= 24 * mc
->macroblocks_per_picture
- 1;
899 mc
->vertex_bufs
.ycbcr
.buffer_offset
= 0;
900 mc
->vertex_bufs
.ycbcr
.buffer
= pipe
->winsys
->buffer_create
903 DEFAULT_BUF_ALIGNMENT
,
904 PIPE_BUFFER_USAGE_VERTEX
,
905 sizeof(struct vlVertex2f
) * 4 * 24 * mc
->macroblocks_per_picture
908 for (i
= 1; i
< 3; ++i
)
910 mc
->vertex_bufs
.all
[i
].pitch
= sizeof(struct vlVertex2f
) * 2;
911 mc
->vertex_bufs
.all
[i
].max_index
= 24 * mc
->macroblocks_per_picture
- 1;
912 mc
->vertex_bufs
.all
[i
].buffer_offset
= 0;
913 mc
->vertex_bufs
.all
[i
].buffer
= pipe
->winsys
->buffer_create
916 DEFAULT_BUF_ALIGNMENT
,
917 PIPE_BUFFER_USAGE_VERTEX
,
918 sizeof(struct vlVertex2f
) * 2 * 24 * mc
->macroblocks_per_picture
922 /* Position element */
923 mc
->vertex_elems
[0].src_offset
= 0;
924 mc
->vertex_elems
[0].vertex_buffer_index
= 0;
925 mc
->vertex_elems
[0].nr_components
= 2;
926 mc
->vertex_elems
[0].src_format
= PIPE_FORMAT_R32G32_FLOAT
;
928 /* Luma, texcoord element */
929 mc
->vertex_elems
[1].src_offset
= sizeof(struct vlVertex2f
);
930 mc
->vertex_elems
[1].vertex_buffer_index
= 0;
931 mc
->vertex_elems
[1].nr_components
= 2;
932 mc
->vertex_elems
[1].src_format
= PIPE_FORMAT_R32G32_FLOAT
;
934 /* Chroma Cr texcoord element */
935 mc
->vertex_elems
[2].src_offset
= sizeof(struct vlVertex2f
) * 2;
936 mc
->vertex_elems
[2].vertex_buffer_index
= 0;
937 mc
->vertex_elems
[2].nr_components
= 2;
938 mc
->vertex_elems
[2].src_format
= PIPE_FORMAT_R32G32_FLOAT
;
940 /* Chroma Cb texcoord element */
941 mc
->vertex_elems
[3].src_offset
= sizeof(struct vlVertex2f
) * 3;
942 mc
->vertex_elems
[3].vertex_buffer_index
= 0;
943 mc
->vertex_elems
[3].nr_components
= 2;
944 mc
->vertex_elems
[3].src_format
= PIPE_FORMAT_R32G32_FLOAT
;
946 /* First ref surface top field texcoord element */
947 mc
->vertex_elems
[4].src_offset
= 0;
948 mc
->vertex_elems
[4].vertex_buffer_index
= 1;
949 mc
->vertex_elems
[4].nr_components
= 2;
950 mc
->vertex_elems
[4].src_format
= PIPE_FORMAT_R32G32_FLOAT
;
952 /* First ref surface bottom field texcoord element */
953 mc
->vertex_elems
[5].src_offset
= sizeof(struct vlVertex2f
);
954 mc
->vertex_elems
[5].vertex_buffer_index
= 1;
955 mc
->vertex_elems
[5].nr_components
= 2;
956 mc
->vertex_elems
[5].src_format
= PIPE_FORMAT_R32G32_FLOAT
;
958 /* Second ref surface top field texcoord element */
959 mc
->vertex_elems
[6].src_offset
= 0;
960 mc
->vertex_elems
[6].vertex_buffer_index
= 2;
961 mc
->vertex_elems
[6].nr_components
= 2;
962 mc
->vertex_elems
[6].src_format
= PIPE_FORMAT_R32G32_FLOAT
;
964 /* Second ref surface bottom field texcoord element */
965 mc
->vertex_elems
[7].src_offset
= sizeof(struct vlVertex2f
);
966 mc
->vertex_elems
[7].vertex_buffer_index
= 2;
967 mc
->vertex_elems
[7].nr_components
= 2;
968 mc
->vertex_elems
[7].src_format
= PIPE_FORMAT_R32G32_FLOAT
;
970 /* Create our constant buffer */
971 mc
->vs_const_buf
.size
= sizeof(struct vlVertexShaderConsts
);
972 mc
->vs_const_buf
.buffer
= pipe
->winsys
->buffer_create
975 DEFAULT_BUF_ALIGNMENT
,
976 PIPE_BUFFER_USAGE_CONSTANT
,
977 mc
->vs_const_buf
.size
980 mc
->fs_const_buf
.size
= sizeof(struct vlFragmentShaderConsts
);
981 mc
->fs_const_buf
.buffer
= pipe
->winsys
->buffer_create
984 DEFAULT_BUF_ALIGNMENT
,
985 PIPE_BUFFER_USAGE_CONSTANT
,
986 mc
->fs_const_buf
.size
991 pipe
->winsys
->buffer_map(pipe
->winsys
, mc
->fs_const_buf
.buffer
, PIPE_BUFFER_USAGE_CPU_WRITE
),
993 sizeof(struct vlFragmentShaderConsts
)
996 pipe
->winsys
->buffer_unmap(pipe
->winsys
, mc
->fs_const_buf
.buffer
);
998 mc
->macroblocks
= malloc(sizeof(struct vlMpeg2MacroBlock
) * mc
->macroblocks_per_picture
);
1005 struct vlR16SnormBufferedMC
*mc
1008 struct pipe_context
*pipe
;
1009 struct pipe_sampler_state sampler
;
1010 struct pipe_texture
template;
1011 unsigned int filters
[5];
1018 mc
->buffered_surface
= NULL
;
1019 mc
->past_surface
= NULL
;
1020 mc
->future_surface
= NULL
;
1021 for (i
= 0; i
< 3; ++i
)
1022 mc
->zero_block
[i
].x
= -1.0f
;
1023 mc
->num_macroblocks
= 0;
1025 /* For MC we render to textures, which are rounded up to nearest POT */
1026 mc
->viewport
.scale
[0] = vlRoundUpPOT(mc
->picture_width
);
1027 mc
->viewport
.scale
[1] = vlRoundUpPOT(mc
->picture_height
);
1028 mc
->viewport
.scale
[2] = 1;
1029 mc
->viewport
.scale
[3] = 1;
1030 mc
->viewport
.translate
[0] = 0;
1031 mc
->viewport
.translate
[1] = 0;
1032 mc
->viewport
.translate
[2] = 0;
1033 mc
->viewport
.translate
[3] = 0;
1035 mc
->render_target
.width
= vlRoundUpPOT(mc
->picture_width
);
1036 mc
->render_target
.height
= vlRoundUpPOT(mc
->picture_height
);
1037 mc
->render_target
.num_cbufs
= 1;
1038 /* FB for MC stage is a vlSurface created by the user, set at render time */
1039 mc
->render_target
.zsbuf
= NULL
;
1041 filters
[0] = PIPE_TEX_FILTER_NEAREST
;
1042 /* FIXME: Linear causes discoloration around block edges */
1043 filters
[1] = /*mc->picture_format == vlFormatYCbCr444 ?*/ PIPE_TEX_FILTER_NEAREST
/*: PIPE_TEX_FILTER_LINEAR*/;
1044 filters
[2] = /*mc->picture_format == vlFormatYCbCr444 ?*/ PIPE_TEX_FILTER_NEAREST
/*: PIPE_TEX_FILTER_LINEAR*/;
1045 filters
[3] = PIPE_TEX_FILTER_LINEAR
;
1046 filters
[4] = PIPE_TEX_FILTER_LINEAR
;
1048 for (i
= 0; i
< 5; ++i
)
1050 sampler
.wrap_s
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
1051 sampler
.wrap_t
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
1052 sampler
.wrap_r
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
1053 sampler
.min_img_filter
= filters
[i
];
1054 sampler
.min_mip_filter
= PIPE_TEX_MIPFILTER_NONE
;
1055 sampler
.mag_img_filter
= filters
[i
];
1056 sampler
.compare_mode
= PIPE_TEX_COMPARE_NONE
;
1057 sampler
.compare_func
= PIPE_FUNC_ALWAYS
;
1058 sampler
.normalized_coords
= 1;
1059 /*sampler.prefilter = ;*/
1060 /*sampler.shadow_ambient = ;*/
1061 /*sampler.lod_bias = ;*/
1062 sampler
.min_lod
= 0;
1063 /*sampler.max_lod = ;*/
1064 /*sampler.border_color[i] = ;*/
1065 /*sampler.max_anisotropy = ;*/
1066 mc
->samplers
.all
[i
] = pipe
->create_sampler_state(pipe
, &sampler
);
1069 memset(&template, 0, sizeof(struct pipe_texture
));
1070 template.target
= PIPE_TEXTURE_2D
;
1071 template.format
= PIPE_FORMAT_R16_SNORM
;
1072 template.last_level
= 0;
1073 template.width
[0] = vlRoundUpPOT(mc
->picture_width
);
1074 template.height
[0] = vlRoundUpPOT(mc
->picture_height
);
1075 template.depth
[0] = 1;
1076 template.compressed
= 0;
1077 pf_get_block(template.format
, &template.block
);
1078 template.tex_usage
= PIPE_TEXTURE_USAGE_SAMPLER
| PIPE_TEXTURE_USAGE_DYNAMIC
;
1080 mc
->textures
.y
= pipe
->screen
->texture_create(pipe
->screen
, &template);
1082 if (mc
->picture_format
== vlFormatYCbCr420
)
1084 template.width
[0] = vlRoundUpPOT(mc
->picture_width
/ 2);
1085 template.height
[0] = vlRoundUpPOT(mc
->picture_height
/ 2);
1087 else if (mc
->picture_format
== vlFormatYCbCr422
)
1088 template.height
[0] = vlRoundUpPOT(mc
->picture_height
/ 2);
1090 mc
->textures
.cb
= pipe
->screen
->texture_create(pipe
->screen
, &template);
1091 mc
->textures
.cr
= pipe
->screen
->texture_create(pipe
->screen
, &template);
1093 /* textures.all[3] & textures.all[4] are assigned from vlSurfaces for P and B macroblocks at render time */
1095 vlCreateVertexShaderIMB(mc
);
1096 vlCreateFragmentShaderIMB(mc
);
1097 vlCreateVertexShaderFramePMB(mc
);
1098 vlCreateVertexShaderFieldPMB(mc
);
1099 vlCreateFragmentShaderFramePMB(mc
);
1100 vlCreateFragmentShaderFieldPMB(mc
);
1101 vlCreateVertexShaderFrameBMB(mc
);
1102 vlCreateVertexShaderFieldBMB(mc
);
1103 vlCreateFragmentShaderFrameBMB(mc
);
1104 vlCreateFragmentShaderFieldBMB(mc
);
1105 vlCreateDataBufs(mc
);
1110 int vlCreateR16SNormBufferedMC
1112 struct pipe_context
*pipe
,
1113 unsigned int picture_width
,
1114 unsigned int picture_height
,
1115 enum vlFormat picture_format
,
1116 struct vlRender
**render
1119 struct vlR16SnormBufferedMC
*mc
;
1124 mc
= calloc(1, sizeof(struct vlR16SnormBufferedMC
));
1126 mc
->base
.vlBegin
= &vlBegin
;
1127 mc
->base
.vlRenderMacroBlocksMpeg2
= &vlRenderMacroBlocksMpeg2R16SnormBuffered
;
1128 mc
->base
.vlEnd
= &vlEnd
;
1129 mc
->base
.vlFlush
= &vlFlush
;
1130 mc
->base
.vlDestroy
= &vlDestroy
;
1132 mc
->picture_width
= picture_width
;
1133 mc
->picture_height
= picture_height
;
1137 *render
= &mc
->base
;