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_util.h>
10 #include <pipe/p_inlines.h>
11 #include <tgsi/tgsi_parse.h>
12 #include <tgsi/tgsi_build.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 video_width
, video_height
;
60 enum vlFormat video_format
;
63 struct vlSurface
*buffered_surface
;
64 struct vlSurface
*past_surface
, *future_surface
;
65 struct vlVertex2f surface_tex_inv_size
;
66 unsigned int num_macroblocks
[vlNumMacroBlockExTypes
];
68 struct pipe_context
*pipe
;
69 struct pipe_viewport_state viewport
;
70 struct pipe_framebuffer_state render_target
;
71 struct pipe_sampler_state
*samplers
[5];
72 struct pipe_texture
*textures
[NUM_BUF_SETS
][5];
73 void *i_vs
, *p_vs
[2], *b_vs
[2];
74 void *i_fs
, *p_fs
[2], *b_fs
[2];
75 struct pipe_vertex_buffer vertex_bufs
[NUM_BUF_SETS
][vlNumMacroBlockExTypes
][3];
76 struct pipe_vertex_element vertex_elems
[5];
77 struct pipe_constant_buffer vs_const_buf
, fs_const_buf
;
82 struct vlRender
*render
90 static inline int vlGrabFrameCodedBlock(short *src
, short *dst
, unsigned int dst_pitch
)
94 for (y
= 0; y
< VL_BLOCK_HEIGHT
; ++y
)
98 src
+ y
* VL_BLOCK_WIDTH
,
105 static inline int vlGrabFieldCodedBlock(short *src
, short *dst
, unsigned int dst_pitch
)
109 for (y
= 0; y
< VL_BLOCK_HEIGHT
/ 2; ++y
)
112 dst
+ y
* dst_pitch
* 2,
113 src
+ y
* VL_BLOCK_WIDTH
,
117 dst
+= VL_BLOCK_HEIGHT
* dst_pitch
;
119 for (; y
< VL_BLOCK_HEIGHT
; ++y
)
122 dst
+ y
* dst_pitch
* 2,
123 src
+ y
* VL_BLOCK_WIDTH
,
130 static inline int vlGrabNoBlock(short *dst
, unsigned int dst_pitch
)
134 for (y
= 0; y
< VL_BLOCK_HEIGHT
; ++y
)
145 static inline int vlGrabBlocks
147 struct vlR16SnormBufferedMC
*mc
,
150 enum vlDCTType dct_type
,
151 unsigned int coded_block_pattern
,
155 struct pipe_surface
*tex_surface
;
157 unsigned int tex_pitch
;
158 unsigned int x
, y
, tb
= 0, sb
= 0;
159 unsigned int mbpx
= mbx
* VL_MACROBLOCK_WIDTH
, mbpy
= mby
* VL_MACROBLOCK_HEIGHT
;
164 tex_surface
= mc
->pipe
->screen
->get_tex_surface
167 mc
->textures
[mc
->cur_buf
% NUM_BUF_SETS
][0],
168 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE
171 texels
= pipe_surface_map(tex_surface
, PIPE_BUFFER_USAGE_CPU_WRITE
);
172 tex_pitch
= tex_surface
->stride
/ tex_surface
->block
.size
;
174 texels
+= mbpy
* tex_pitch
+ mbpx
;
176 for (y
= 0; y
< 2; ++y
)
178 for (x
= 0; x
< 2; ++x
, ++tb
)
180 if ((coded_block_pattern
>> (5 - tb
)) & 1)
182 short *cur_block
= blocks
+ sb
* VL_BLOCK_WIDTH
* VL_BLOCK_HEIGHT
;
184 if (dct_type
== vlDCTTypeFrameCoded
)
186 vlGrabFrameCodedBlock
189 texels
+ y
* tex_pitch
* VL_BLOCK_HEIGHT
+ x
* VL_BLOCK_WIDTH
,
195 vlGrabFieldCodedBlock
198 texels
+ y
* tex_pitch
+ x
* VL_BLOCK_WIDTH
,
206 vlGrabNoBlock(texels
+ y
* tex_pitch
* VL_BLOCK_HEIGHT
+ x
* VL_BLOCK_WIDTH
, tex_pitch
);
210 pipe_surface_unmap(tex_surface
);
212 /* TODO: Implement 422, 444 */
216 for (tb
= 0; tb
< 2; ++tb
)
218 tex_surface
= mc
->pipe
->screen
->get_tex_surface
221 mc
->textures
[mc
->cur_buf
% NUM_BUF_SETS
][tb
+ 1],
222 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE
225 texels
= pipe_surface_map(tex_surface
, PIPE_BUFFER_USAGE_CPU_WRITE
);
226 tex_pitch
= tex_surface
->stride
/ tex_surface
->block
.size
;
228 texels
+= mbpy
* tex_pitch
+ mbpx
;
230 if ((coded_block_pattern
>> (1 - tb
)) & 1)
232 short *cur_block
= blocks
+ sb
* VL_BLOCK_WIDTH
* VL_BLOCK_HEIGHT
;
234 vlGrabFrameCodedBlock
244 vlGrabNoBlock(texels
, tex_pitch
);
246 pipe_surface_unmap(tex_surface
);
252 static inline int vlGrabMacroBlock
254 struct vlR16SnormBufferedMC
*mc
,
255 struct vlMpeg2MacroBlock
*macroblock
258 const struct vlVertex2f unit
=
260 mc
->surface_tex_inv_size
.x
* VL_MACROBLOCK_WIDTH
,
261 mc
->surface_tex_inv_size
.y
* VL_MACROBLOCK_HEIGHT
263 const struct vlVertex2f half
=
265 mc
->surface_tex_inv_size
.x
* (VL_MACROBLOCK_WIDTH
/ 2),
266 mc
->surface_tex_inv_size
.y
* (VL_MACROBLOCK_HEIGHT
/ 2)
269 struct vlVertex2f
*vb
;
270 enum vlMacroBlockTypeEx mb_type_ex
;
271 struct vlVertex2f mo_vec
[2];
277 switch (macroblock
->mb_type
)
279 case vlMacroBlockTypeIntra
:
281 mb_type_ex
= vlMacroBlockExTypeIntra
;
284 case vlMacroBlockTypeFwdPredicted
:
286 mb_type_ex
= macroblock
->mo_type
== vlMotionTypeFrame
?
287 vlMacroBlockExTypeFwdPredictedFrame
: vlMacroBlockExTypeFwdPredictedField
;
290 case vlMacroBlockTypeBkwdPredicted
:
292 mb_type_ex
= macroblock
->mo_type
== vlMotionTypeFrame
?
293 vlMacroBlockExTypeBkwdPredictedFrame
: vlMacroBlockExTypeBkwdPredictedField
;
296 case vlMacroBlockTypeBiPredicted
:
298 mb_type_ex
= macroblock
->mo_type
== vlMotionTypeFrame
?
299 vlMacroBlockExTypeBiPredictedFrame
: vlMacroBlockExTypeBiPredictedField
;
306 switch (macroblock
->mb_type
)
308 case vlMacroBlockTypeBiPredicted
:
310 vb
= (struct vlVertex2f
*)mc
->pipe
->winsys
->buffer_map
313 mc
->vertex_bufs
[mc
->cur_buf
% NUM_BUF_SETS
][mb_type_ex
][2].buffer
,
314 PIPE_BUFFER_USAGE_CPU_WRITE
315 ) + mc
->num_macroblocks
[mb_type_ex
] * 2 * 24;
317 mo_vec
[0].x
= macroblock
->PMV
[0][1][0] * 0.5f
* mc
->surface_tex_inv_size
.x
;
318 mo_vec
[0].y
= macroblock
->PMV
[0][1][1] * 0.5f
* mc
->surface_tex_inv_size
.y
;
320 if (macroblock
->mo_type
== vlMotionTypeFrame
)
322 for (i
= 0; i
< 24 * 2; i
+= 2)
324 vb
[i
].x
= mo_vec
[0].x
;
325 vb
[i
].y
= mo_vec
[0].y
;
330 mo_vec
[1].x
= macroblock
->PMV
[1][1][0] * 0.5f
* mc
->surface_tex_inv_size
.x
;
331 mo_vec
[1].y
= macroblock
->PMV
[1][1][1] * 0.5f
* mc
->surface_tex_inv_size
.y
;
333 for (i
= 0; i
< 24 * 2; i
+= 2)
335 vb
[i
].x
= mo_vec
[0].x
;
336 vb
[i
].y
= mo_vec
[0].y
;
337 vb
[i
+ 1].x
= mo_vec
[1].x
;
338 vb
[i
+ 1].y
= mo_vec
[1].y
;
342 mc
->pipe
->winsys
->buffer_unmap(mc
->pipe
->winsys
, mc
->vertex_bufs
[mc
->cur_buf
% NUM_BUF_SETS
][mb_type_ex
][2].buffer
);
346 case vlMacroBlockTypeFwdPredicted
:
347 case vlMacroBlockTypeBkwdPredicted
:
349 vb
= (struct vlVertex2f
*)mc
->pipe
->winsys
->buffer_map
352 mc
->vertex_bufs
[mc
->cur_buf
% NUM_BUF_SETS
][mb_type_ex
][1].buffer
,
353 PIPE_BUFFER_USAGE_CPU_WRITE
354 ) + mc
->num_macroblocks
[mb_type_ex
] * 2 * 24;
356 if (macroblock
->mb_type
== vlMacroBlockTypeBkwdPredicted
)
358 mo_vec
[0].x
= macroblock
->PMV
[0][1][0] * 0.5f
* mc
->surface_tex_inv_size
.x
;
359 mo_vec
[0].y
= macroblock
->PMV
[0][1][1] * 0.5f
* mc
->surface_tex_inv_size
.y
;
361 if (macroblock
->mo_type
== vlMotionTypeField
)
363 mo_vec
[1].x
= macroblock
->PMV
[1][1][0] * 0.5f
* mc
->surface_tex_inv_size
.x
;
364 mo_vec
[1].y
= macroblock
->PMV
[1][1][1] * 0.5f
* mc
->surface_tex_inv_size
.y
;
369 mo_vec
[0].x
= macroblock
->PMV
[0][0][0] * 0.5f
* mc
->surface_tex_inv_size
.x
;
370 mo_vec
[0].y
= macroblock
->PMV
[0][0][1] * 0.5f
* mc
->surface_tex_inv_size
.y
;
372 if (macroblock
->mo_type
== vlMotionTypeField
)
374 mo_vec
[1].x
= macroblock
->PMV
[1][0][0] * 0.5f
* mc
->surface_tex_inv_size
.x
;
375 mo_vec
[1].y
= macroblock
->PMV
[1][0][1] * 0.5f
* mc
->surface_tex_inv_size
.y
;
379 if (macroblock
->mo_type
== vlMotionTypeFrame
)
381 for (i
= 0; i
< 24 * 2; i
+= 2)
383 vb
[i
].x
= mo_vec
[0].x
;
384 vb
[i
].y
= mo_vec
[0].y
;
389 for (i
= 0; i
< 24 * 2; i
+= 2)
391 vb
[i
].x
= mo_vec
[0].x
;
392 vb
[i
].y
= mo_vec
[0].y
;
393 vb
[i
+ 1].x
= mo_vec
[1].x
;
394 vb
[i
+ 1].y
= mo_vec
[1].y
;
398 mc
->pipe
->winsys
->buffer_unmap(mc
->pipe
->winsys
, mc
->vertex_bufs
[mc
->cur_buf
% NUM_BUF_SETS
][mb_type_ex
][1].buffer
);
402 case vlMacroBlockTypeIntra
:
404 vb
= (struct vlVertex2f
*)mc
->pipe
->winsys
->buffer_map
407 mc
->vertex_bufs
[mc
->cur_buf
% NUM_BUF_SETS
][mb_type_ex
][0].buffer
,
408 PIPE_BUFFER_USAGE_CPU_WRITE
409 ) + mc
->num_macroblocks
[mb_type_ex
] * 24;
411 vb
[0].x
= macroblock
->mbx
* unit
.x
; vb
[0].y
= macroblock
->mby
* unit
.y
;
412 vb
[1].x
= macroblock
->mbx
* unit
.x
; vb
[1].y
= macroblock
->mby
* unit
.y
+ half
.y
;
413 vb
[2].x
= macroblock
->mbx
* unit
.x
+ half
.x
; vb
[2].y
= macroblock
->mby
* unit
.y
;
415 vb
[3].x
= macroblock
->mbx
* unit
.x
+ half
.x
; vb
[3].y
= macroblock
->mby
* unit
.y
;
416 vb
[4].x
= macroblock
->mbx
* unit
.x
; vb
[4].y
= macroblock
->mby
* unit
.y
+ half
.y
;
417 vb
[5].x
= macroblock
->mbx
* unit
.x
+ half
.x
; vb
[5].y
= macroblock
->mby
* unit
.y
+ half
.y
;
419 vb
[6].x
= macroblock
->mbx
* unit
.x
+ half
.x
; vb
[6].y
= macroblock
->mby
* unit
.y
;
420 vb
[7].x
= macroblock
->mbx
* unit
.x
+ half
.x
; vb
[7].y
= macroblock
->mby
* unit
.y
+ half
.y
;
421 vb
[8].x
= macroblock
->mbx
* unit
.x
+ unit
.x
; vb
[8].y
= macroblock
->mby
* unit
.y
;
423 vb
[9].x
= macroblock
->mbx
* unit
.x
+ unit
.x
; vb
[9].y
= macroblock
->mby
* unit
.y
;
424 vb
[10].x
= macroblock
->mbx
* unit
.x
+ half
.x
; vb
[10].y
= macroblock
->mby
* unit
.y
+ half
.y
;
425 vb
[11].x
= macroblock
->mbx
* unit
.x
+ unit
.x
; vb
[11].y
= macroblock
->mby
* unit
.y
+ half
.y
;
427 vb
[12].x
= macroblock
->mbx
* unit
.x
; vb
[12].y
= macroblock
->mby
* unit
.y
+ half
.y
;
428 vb
[13].x
= macroblock
->mbx
* unit
.x
; vb
[13].y
= macroblock
->mby
* unit
.y
+ unit
.y
;
429 vb
[14].x
= macroblock
->mbx
* unit
.x
+ half
.x
; vb
[14].y
= macroblock
->mby
* unit
.y
+ half
.y
;
431 vb
[15].x
= macroblock
->mbx
* unit
.x
+ half
.x
; vb
[15].y
= macroblock
->mby
* unit
.y
+ half
.y
;
432 vb
[16].x
= macroblock
->mbx
* unit
.x
; vb
[16].y
= macroblock
->mby
* unit
.y
+ unit
.y
;
433 vb
[17].x
= macroblock
->mbx
* unit
.x
+ half
.x
; vb
[17].y
= macroblock
->mby
* unit
.y
+ unit
.y
;
435 vb
[18].x
= macroblock
->mbx
* unit
.x
+ half
.x
; vb
[18].y
= macroblock
->mby
* unit
.y
+ half
.y
;
436 vb
[19].x
= macroblock
->mbx
* unit
.x
+ half
.x
; vb
[19].y
= macroblock
->mby
* unit
.y
+ unit
.y
;
437 vb
[20].x
= macroblock
->mbx
* unit
.x
+ unit
.x
; vb
[20].y
= macroblock
->mby
* unit
.y
+ half
.y
;
439 vb
[21].x
= macroblock
->mbx
* unit
.x
+ unit
.x
; vb
[21].y
= macroblock
->mby
* unit
.y
+ half
.y
;
440 vb
[22].x
= macroblock
->mbx
* unit
.x
+ half
.x
; vb
[22].y
= macroblock
->mby
* unit
.y
+ unit
.y
;
441 vb
[23].x
= macroblock
->mbx
* unit
.x
+ unit
.x
; vb
[23].y
= macroblock
->mby
* unit
.y
+ unit
.y
;
443 mc
->pipe
->winsys
->buffer_unmap(mc
->pipe
->winsys
, mc
->vertex_bufs
[mc
->cur_buf
% NUM_BUF_SETS
][mb_type_ex
][0].buffer
);
456 macroblock
->dct_type
,
461 mc
->num_macroblocks
[mb_type_ex
]++;
468 struct vlRender
*render
471 struct vlR16SnormBufferedMC
*mc
;
472 struct pipe_context
*pipe
;
473 struct vlVertexShaderConsts
*vs_consts
;
477 mc
= (struct vlR16SnormBufferedMC
*)render
;
480 mc
->render_target
.cbufs
[0] = pipe
->screen
->get_tex_surface
483 mc
->buffered_surface
->texture
,
484 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ
| PIPE_BUFFER_USAGE_GPU_WRITE
487 pipe
->set_framebuffer_state(pipe
, &mc
->render_target
);
488 pipe
->set_viewport_state(pipe
, &mc
->viewport
);
489 vs_consts
= pipe
->winsys
->buffer_map
492 mc
->vs_const_buf
.buffer
,
493 PIPE_BUFFER_USAGE_CPU_WRITE
496 vs_consts
->denorm
.x
= mc
->buffered_surface
->texture
->width
[0];
497 vs_consts
->denorm
.y
= mc
->buffered_surface
->texture
->height
[0];
499 pipe
->winsys
->buffer_unmap(pipe
->winsys
, mc
->vs_const_buf
.buffer
);
500 pipe
->set_constant_buffer(pipe
, PIPE_SHADER_FRAGMENT
, 0, &mc
->fs_const_buf
);
502 if (mc
->num_macroblocks
[vlMacroBlockExTypeIntra
] > 0)
504 pipe
->set_vertex_buffers(pipe
, 1, mc
->vertex_bufs
[mc
->cur_buf
% NUM_BUF_SETS
][vlMacroBlockExTypeIntra
]);
505 pipe
->set_vertex_elements(pipe
, 1, mc
->vertex_elems
);
506 pipe
->set_sampler_textures(pipe
, 3, mc
->textures
[mc
->cur_buf
% NUM_BUF_SETS
]);
507 pipe
->bind_sampler_states(pipe
, 3, (void**)mc
->samplers
);
508 pipe
->bind_vs_state(pipe
, mc
->i_vs
);
509 pipe
->bind_fs_state(pipe
, mc
->i_fs
);
511 pipe
->draw_arrays(pipe
, PIPE_PRIM_TRIANGLES
, 0, mc
->num_macroblocks
[vlMacroBlockExTypeIntra
] * 24);
514 if (mc
->num_macroblocks
[vlMacroBlockExTypeFwdPredictedFrame
] > 0)
516 pipe
->set_vertex_buffers(pipe
, 2, mc
->vertex_bufs
[mc
->cur_buf
% NUM_BUF_SETS
][vlMacroBlockExTypeFwdPredictedFrame
]);
517 pipe
->set_vertex_elements(pipe
, 3, mc
->vertex_elems
);
518 mc
->textures
[mc
->cur_buf
% NUM_BUF_SETS
][3] = mc
->past_surface
->texture
;
519 pipe
->set_sampler_textures(pipe
, 4, mc
->textures
[mc
->cur_buf
% NUM_BUF_SETS
]);
520 pipe
->bind_sampler_states(pipe
, 4, (void**)mc
->samplers
);
521 pipe
->bind_vs_state(pipe
, mc
->p_vs
[0]);
522 pipe
->bind_fs_state(pipe
, mc
->p_fs
[0]);
524 pipe
->draw_arrays(pipe
, PIPE_PRIM_TRIANGLES
, 0, mc
->num_macroblocks
[vlMacroBlockExTypeFwdPredictedFrame
] * 24);
527 if (mc
->num_macroblocks
[vlMacroBlockExTypeFwdPredictedField
] > 0)
529 pipe
->set_vertex_buffers(pipe
, 2, mc
->vertex_bufs
[mc
->cur_buf
% NUM_BUF_SETS
][vlMacroBlockExTypeFwdPredictedField
]);
530 pipe
->set_vertex_elements(pipe
, 3, mc
->vertex_elems
);
531 mc
->textures
[mc
->cur_buf
% NUM_BUF_SETS
][3] = mc
->past_surface
->texture
;
532 pipe
->set_sampler_textures(pipe
, 4, mc
->textures
[mc
->cur_buf
% NUM_BUF_SETS
]);
533 pipe
->bind_sampler_states(pipe
, 4, (void**)mc
->samplers
);
534 pipe
->bind_vs_state(pipe
, mc
->p_vs
[1]);
535 pipe
->bind_fs_state(pipe
, mc
->p_fs
[1]);
537 pipe
->draw_arrays(pipe
, PIPE_PRIM_TRIANGLES
, 0, mc
->num_macroblocks
[vlMacroBlockExTypeFwdPredictedField
] * 24);
540 if (mc
->num_macroblocks
[vlMacroBlockExTypeBkwdPredictedFrame
] > 0)
542 pipe
->set_vertex_buffers(pipe
, 2, mc
->vertex_bufs
[mc
->cur_buf
% NUM_BUF_SETS
][vlMacroBlockExTypeBkwdPredictedFrame
]);
543 pipe
->set_vertex_elements(pipe
, 3, mc
->vertex_elems
);
544 mc
->textures
[mc
->cur_buf
% NUM_BUF_SETS
][3] = mc
->future_surface
->texture
;
545 pipe
->set_sampler_textures(pipe
, 4, mc
->textures
[mc
->cur_buf
% NUM_BUF_SETS
]);
546 pipe
->bind_sampler_states(pipe
, 4, (void**)mc
->samplers
);
547 pipe
->bind_vs_state(pipe
, mc
->p_vs
[0]);
548 pipe
->bind_fs_state(pipe
, mc
->p_fs
[0]);
550 pipe
->draw_arrays(pipe
, PIPE_PRIM_TRIANGLES
, 0, mc
->num_macroblocks
[vlMacroBlockExTypeBkwdPredictedFrame
] * 24);
553 if (mc
->num_macroblocks
[vlMacroBlockExTypeBkwdPredictedField
] > 0)
555 pipe
->set_vertex_buffers(pipe
, 2, mc
->vertex_bufs
[mc
->cur_buf
% NUM_BUF_SETS
][vlMacroBlockExTypeBkwdPredictedField
]);
556 pipe
->set_vertex_elements(pipe
, 3, mc
->vertex_elems
);
557 mc
->textures
[mc
->cur_buf
% NUM_BUF_SETS
][3] = mc
->future_surface
->texture
;
558 pipe
->set_sampler_textures(pipe
, 4, mc
->textures
[mc
->cur_buf
% NUM_BUF_SETS
]);
559 pipe
->bind_sampler_states(pipe
, 4, (void**)mc
->samplers
);
560 pipe
->bind_vs_state(pipe
, mc
->p_vs
[1]);
561 pipe
->bind_fs_state(pipe
, mc
->p_fs
[1]);
563 pipe
->draw_arrays(pipe
, PIPE_PRIM_TRIANGLES
, 0, mc
->num_macroblocks
[vlMacroBlockExTypeBkwdPredictedField
] * 24);
566 if (mc
->num_macroblocks
[vlMacroBlockExTypeBiPredictedFrame
] > 0)
568 pipe
->set_vertex_buffers(pipe
, 3, mc
->vertex_bufs
[mc
->cur_buf
% NUM_BUF_SETS
][vlMacroBlockExTypeBiPredictedFrame
]);
569 pipe
->set_vertex_elements(pipe
, 5, mc
->vertex_elems
);
570 mc
->textures
[mc
->cur_buf
% NUM_BUF_SETS
][3] = mc
->past_surface
->texture
;
571 mc
->textures
[mc
->cur_buf
% NUM_BUF_SETS
][4] = mc
->future_surface
->texture
;
572 pipe
->set_sampler_textures(pipe
, 5, mc
->textures
[mc
->cur_buf
% NUM_BUF_SETS
]);
573 pipe
->bind_sampler_states(pipe
, 5, (void**)mc
->samplers
);
574 pipe
->bind_vs_state(pipe
, mc
->b_vs
[0]);
575 pipe
->bind_fs_state(pipe
, mc
->b_fs
[0]);
577 pipe
->draw_arrays(pipe
, PIPE_PRIM_TRIANGLES
, 0, mc
->num_macroblocks
[vlMacroBlockExTypeBiPredictedFrame
] * 24);
580 if (mc
->num_macroblocks
[vlMacroBlockExTypeBiPredictedField
] > 0)
582 pipe
->set_vertex_buffers(pipe
, 3, mc
->vertex_bufs
[mc
->cur_buf
% NUM_BUF_SETS
][vlMacroBlockExTypeBiPredictedField
]);
583 pipe
->set_vertex_elements(pipe
, 5, mc
->vertex_elems
);
584 mc
->textures
[mc
->cur_buf
% NUM_BUF_SETS
][3] = mc
->past_surface
->texture
;
585 mc
->textures
[mc
->cur_buf
% NUM_BUF_SETS
][4] = mc
->future_surface
->texture
;
586 pipe
->set_sampler_textures(pipe
, 5, mc
->textures
[mc
->cur_buf
% NUM_BUF_SETS
]);
587 pipe
->bind_sampler_states(pipe
, 5, (void**)mc
->samplers
);
588 pipe
->bind_vs_state(pipe
, mc
->b_vs
[1]);
589 pipe
->bind_fs_state(pipe
, mc
->b_fs
[1]);
591 pipe
->draw_arrays(pipe
, PIPE_PRIM_TRIANGLES
, 0, mc
->num_macroblocks
[vlMacroBlockExTypeBiPredictedField
] * 24);
594 memset(mc
->num_macroblocks
, 0, sizeof(unsigned int) * vlNumMacroBlockExTypes
);
600 static int vlRenderMacroBlocksMpeg2R16SnormBuffered
602 struct vlRender
*render
,
603 struct vlMpeg2MacroBlockBatch
*batch
,
604 struct vlSurface
*surface
607 struct vlR16SnormBufferedMC
*mc
;
612 mc
= (struct vlR16SnormBufferedMC
*)render
;
614 if (mc
->buffered_surface
)
618 mc
->buffered_surface
!= surface
/*||
619 mc->past_surface != batch->past_surface ||
620 mc->future_surface != batch->future_surface*/
624 mc
->buffered_surface
= surface
;
625 mc
->past_surface
= batch
->past_surface
;
626 mc
->future_surface
= batch
->future_surface
;
627 mc
->surface_tex_inv_size
.x
= 1.0f
/ surface
->texture
->width
[0];
628 mc
->surface_tex_inv_size
.y
= 1.0f
/ surface
->texture
->height
[0];
633 mc
->buffered_surface
= surface
;
634 mc
->past_surface
= batch
->past_surface
;
635 mc
->future_surface
= batch
->future_surface
;
636 mc
->surface_tex_inv_size
.x
= 1.0f
/ surface
->texture
->width
[0];
637 mc
->surface_tex_inv_size
.y
= 1.0f
/ surface
->texture
->height
[0];
640 for (i
= 0; i
< batch
->num_macroblocks
; ++i
)
641 vlGrabMacroBlock(mc
, &batch
->macroblocks
[i
]);
648 struct vlRender
*render
658 struct vlRender
*render
661 struct vlR16SnormBufferedMC
*mc
;
662 struct pipe_context
*pipe
;
663 unsigned int g
, h
, i
;
667 mc
= (struct vlR16SnormBufferedMC
*)render
;
670 for (i
= 0; i
< 5; ++i
)
671 pipe
->delete_sampler_state(pipe
, mc
->samplers
[i
]);
673 for (g
= 0; g
< NUM_BUF_SETS
; ++g
)
674 for (h
= 0; h
< vlNumMacroBlockExTypes
; ++h
)
675 for (i
= 0; i
< 3; ++i
)
676 pipe
->winsys
->buffer_destroy(pipe
->winsys
, mc
->vertex_bufs
[g
][h
][i
].buffer
);
678 /* Textures 3 & 4 are not created directly, no need to release them here */
679 for (i
= 0; i
< NUM_BUF_SETS
; ++i
)
681 pipe_texture_release(&mc
->textures
[i
][0]);
682 pipe_texture_release(&mc
->textures
[i
][1]);
683 pipe_texture_release(&mc
->textures
[i
][2]);
686 pipe
->delete_vs_state(pipe
, mc
->i_vs
);
687 pipe
->delete_fs_state(pipe
, mc
->i_fs
);
689 for (i
= 0; i
< 2; ++i
)
691 pipe
->delete_vs_state(pipe
, mc
->p_vs
[i
]);
692 pipe
->delete_fs_state(pipe
, mc
->p_fs
[i
]);
693 pipe
->delete_vs_state(pipe
, mc
->b_vs
[i
]);
694 pipe
->delete_fs_state(pipe
, mc
->b_fs
[i
]);
697 pipe
->winsys
->buffer_destroy(pipe
->winsys
, mc
->vs_const_buf
.buffer
);
698 pipe
->winsys
->buffer_destroy(pipe
->winsys
, mc
->fs_const_buf
.buffer
);
706 * Muliplier renormalizes block samples from 16 bits to 12 bits.
707 * Divider is used when calculating Y % 2 for choosing top or bottom
708 * field for P or B macroblocks.
709 * TODO: Use immediates.
711 static const struct vlFragmentShaderConsts fs_consts
=
713 {32767.0f
/ 255.0f
, 32767.0f
/ 255.0f
, 32767.0f
/ 255.0f
, 0.0f
},
714 {0.5f
, 2.0f
, 0.0f
, 0.0f
}
717 static int vlCreateVertexShaderIMB
719 struct vlR16SnormBufferedMC
*mc
722 const unsigned int max_tokens
= 50;
724 struct pipe_context
*pipe
;
725 struct pipe_shader_state vs
;
726 struct tgsi_token
*tokens
;
727 struct tgsi_header
*header
;
729 struct tgsi_full_declaration decl
;
730 struct tgsi_full_instruction inst
;
738 tokens
= (struct tgsi_token
*)malloc(max_tokens
* sizeof(struct tgsi_token
));
741 *(struct tgsi_version
*)&tokens
[0] = tgsi_build_version();
743 header
= (struct tgsi_header
*)&tokens
[1];
744 *header
= tgsi_build_header();
746 *(struct tgsi_processor
*)&tokens
[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX
, header
);
751 * decl i0 ; Vertex pos, luma & chroma texcoords
753 for (i
= 0; i
< 3; i
++)
755 decl
= vl_decl_input(i
== 0 ? TGSI_SEMANTIC_POSITION
: TGSI_SEMANTIC_GENERIC
, i
, i
, i
);
756 ti
+= tgsi_build_full_declaration(&decl
, &tokens
[ti
], header
, max_tokens
- ti
);
760 * decl o0 ; Vertex pos
761 * decl o1 ; Luma/chroma texcoords
763 for (i
= 0; i
< 2; i
++)
765 decl
= vl_decl_output(i
== 0 ? TGSI_SEMANTIC_POSITION
: TGSI_SEMANTIC_GENERIC
, i
, i
, i
);
766 ti
+= tgsi_build_full_declaration(&decl
, &tokens
[ti
], header
, max_tokens
- ti
);
770 * mov o0, i0 ; Move input vertex pos to output
771 * mov o1, i0 ; Move input luma/chroma texcoords to output
773 for (i
= 0; i
< 2; ++i
)
775 inst
= vl_inst2(TGSI_OPCODE_MOV
, TGSI_FILE_OUTPUT
, i
, TGSI_FILE_INPUT
, 0);
776 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
781 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
784 mc
->i_vs
= pipe
->create_vs_state(pipe
, &vs
);
790 static int vlCreateFragmentShaderIMB
792 struct vlR16SnormBufferedMC
*mc
795 const unsigned int max_tokens
= 100;
797 struct pipe_context
*pipe
;
798 struct pipe_shader_state fs
;
799 struct tgsi_token
*tokens
;
800 struct tgsi_header
*header
;
802 struct tgsi_full_declaration decl
;
803 struct tgsi_full_instruction inst
;
811 tokens
= (struct tgsi_token
*)malloc(max_tokens
* sizeof(struct tgsi_token
));
814 *(struct tgsi_version
*)&tokens
[0] = tgsi_build_version();
816 header
= (struct tgsi_header
*)&tokens
[1];
817 *header
= tgsi_build_header();
819 *(struct tgsi_processor
*)&tokens
[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT
, header
);
823 /* decl i0 ; Luma/chroma texcoords */
824 decl
= vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC
, 1, 0, 0, TGSI_INTERPOLATE_LINEAR
);
825 ti
+= tgsi_build_full_declaration(&decl
, &tokens
[ti
], header
, max_tokens
- ti
);
827 /* decl c0 ; Scaling factor, rescales 16-bit snorm to 9-bit snorm */
828 decl
= vl_decl_constants(TGSI_SEMANTIC_GENERIC
, 0, 0, 0);
829 ti
+= tgsi_build_full_declaration(&decl
, &tokens
[ti
], header
, max_tokens
- ti
);
831 /* decl o0 ; Fragment color */
832 decl
= vl_decl_output(TGSI_SEMANTIC_COLOR
, 0, 0, 0);
833 ti
+= tgsi_build_full_declaration(&decl
, &tokens
[ti
], header
, max_tokens
- ti
);
836 decl
= vl_decl_temps(0, 1);
837 ti
+= tgsi_build_full_declaration(&decl
, &tokens
[ti
], header
, max_tokens
- ti
);
840 * decl s0 ; Sampler for luma texture
841 * decl s1 ; Sampler for chroma Cb texture
842 * decl s2 ; Sampler for chroma Cr texture
844 for (i
= 0; i
< 3; ++i
)
846 decl
= vl_decl_samplers(i
, i
);
847 ti
+= tgsi_build_full_declaration(&decl
, &tokens
[ti
], header
,max_tokens
- ti
);
851 * tex2d t1, i0, s0 ; Read texel from luma texture
852 * mov t0.x, t1.x ; Move luma sample into .x component
853 * tex2d t1, i0, s1 ; Read texel from chroma Cb texture
854 * mov t0.y, t1.x ; Move Cb sample into .y component
855 * tex2d t1, i0, s2 ; Read texel from chroma Cr texture
856 * mov t0.z, t1.x ; Move Cr sample into .z component
858 for (i
= 0; i
< 3; ++i
)
860 inst
= vl_tex(TGSI_TEXTURE_2D
, TGSI_FILE_TEMPORARY
, 1, TGSI_FILE_INPUT
, 0, TGSI_FILE_SAMPLER
, i
);
861 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
863 inst
= vl_inst2(TGSI_OPCODE_MOV
, TGSI_FILE_TEMPORARY
, 0, TGSI_FILE_TEMPORARY
, 1);
864 inst
.FullSrcRegisters
[0].SrcRegister
.SwizzleX
= TGSI_SWIZZLE_X
;
865 inst
.FullSrcRegisters
[0].SrcRegister
.SwizzleY
= TGSI_SWIZZLE_X
;
866 inst
.FullSrcRegisters
[0].SrcRegister
.SwizzleZ
= TGSI_SWIZZLE_X
;
867 inst
.FullDstRegisters
[0].DstRegister
.WriteMask
= TGSI_WRITEMASK_X
<< i
;
868 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
872 /* mul o0, t0, c0 ; Rescale texel to correct range */
873 inst
= vl_inst3(TGSI_OPCODE_MUL
, TGSI_FILE_OUTPUT
, 0, TGSI_FILE_TEMPORARY
, 0, TGSI_FILE_CONSTANT
, 0);
874 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
878 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
881 mc
->i_fs
= pipe
->create_fs_state(pipe
, &fs
);
887 static int vlCreateVertexShaderFramePMB
889 struct vlR16SnormBufferedMC
*mc
892 const unsigned int max_tokens
= 100;
894 struct pipe_context
*pipe
;
895 struct pipe_shader_state vs
;
896 struct tgsi_token
*tokens
;
897 struct tgsi_header
*header
;
899 struct tgsi_full_declaration decl
;
900 struct tgsi_full_instruction inst
;
908 tokens
= (struct tgsi_token
*)malloc(max_tokens
* sizeof(struct tgsi_token
));
911 *(struct tgsi_version
*)&tokens
[0] = tgsi_build_version();
913 header
= (struct tgsi_header
*)&tokens
[1];
914 *header
= tgsi_build_header();
916 *(struct tgsi_processor
*)&tokens
[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX
, header
);
921 * decl i0 ; Vertex pos, luma/chroma texcoords
922 * decl i1 ; Ref surface top field texcoords
923 * decl i2 ; Ref surface bottom field texcoords (unused, packed in the same stream)
925 for (i
= 0; i
< 3; i
++)
927 decl
= vl_decl_input(i
== 0 ? TGSI_SEMANTIC_POSITION
: TGSI_SEMANTIC_GENERIC
, i
, i
, i
);
928 ti
+= tgsi_build_full_declaration(&decl
, &tokens
[ti
], header
, max_tokens
- ti
);
932 * decl o0 ; Vertex pos
933 * decl o1 ; Luma/chroma texcoords
934 * decl o2 ; Ref macroblock texcoords
936 for (i
= 0; i
< 3; i
++)
938 decl
= vl_decl_output(i
== 0 ? TGSI_SEMANTIC_POSITION
: TGSI_SEMANTIC_GENERIC
, i
, i
, i
);
939 ti
+= tgsi_build_full_declaration(&decl
, &tokens
[ti
], header
, max_tokens
- ti
);
943 * mov o0, i0 ; Move input vertex pos to output
944 * mov o1, i0 ; Move input luma/chroma texcoords to output
946 for (i
= 0; i
< 2; ++i
)
948 inst
= vl_inst2(TGSI_OPCODE_MOV
, TGSI_FILE_OUTPUT
, i
, TGSI_FILE_INPUT
, 0);
949 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
952 /* add o2, i0, i1 ; Translate vertex pos by motion vec to form ref macroblock texcoords */
953 inst
= vl_inst3(TGSI_OPCODE_ADD
, TGSI_FILE_OUTPUT
, 2, TGSI_FILE_INPUT
, 0, TGSI_FILE_INPUT
, 1);
954 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
958 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
961 mc
->p_vs
[0] = pipe
->create_vs_state(pipe
, &vs
);
967 static int vlCreateVertexShaderFieldPMB
969 struct vlR16SnormBufferedMC
*mc
972 const unsigned int max_tokens
= 100;
974 struct pipe_context
*pipe
;
975 struct pipe_shader_state vs
;
976 struct tgsi_token
*tokens
;
977 struct tgsi_header
*header
;
979 struct tgsi_full_declaration decl
;
980 struct tgsi_full_instruction inst
;
988 tokens
= (struct tgsi_token
*)malloc(max_tokens
* sizeof(struct tgsi_token
));
991 *(struct tgsi_version
*)&tokens
[0] = tgsi_build_version();
993 header
= (struct tgsi_header
*)&tokens
[1];
994 *header
= tgsi_build_header();
996 *(struct tgsi_processor
*)&tokens
[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX
, header
);
1001 * decl i0 ; Vertex pos, luma/chroma texcoords
1002 * decl i1 ; Ref surface top field texcoords
1003 * decl i2 ; Ref surface bottom field texcoords
1005 for (i
= 0; i
< 3; i
++)
1007 decl
= vl_decl_input(i
== 0 ? TGSI_SEMANTIC_POSITION
: TGSI_SEMANTIC_GENERIC
, i
, i
, i
);
1008 ti
+= tgsi_build_full_declaration(&decl
, &tokens
[ti
], header
, max_tokens
- ti
);
1011 /* decl c0 ; Texcoord denorm coefficients */
1012 decl
= vl_decl_constants(TGSI_SEMANTIC_GENERIC
, 0, 0, 0);
1013 ti
+= tgsi_build_full_declaration(&decl
, &tokens
[ti
], header
, max_tokens
- ti
);
1016 * decl o0 ; Vertex pos
1017 * decl o1 ; Luma/chroma texcoords
1018 * decl o2 ; Top field ref macroblock texcoords
1019 * decl o3 ; Bottom field ref macroblock texcoords
1020 * decl o4 ; Denormalized vertex pos
1022 for (i
= 0; i
< 5; i
++)
1024 decl
= vl_decl_output((i
== 0 || i
== 5) ? TGSI_SEMANTIC_POSITION
: TGSI_SEMANTIC_GENERIC
, i
, i
, i
);
1025 ti
+= tgsi_build_full_declaration(&decl
, &tokens
[ti
], header
, max_tokens
- ti
);
1029 * mov o0, i0 ; Move input vertex pos to output
1030 * mov o1, i0 ; Move input luma/chroma texcoords to output
1032 for (i
= 0; i
< 3; ++i
)
1034 inst
= vl_inst2(TGSI_OPCODE_MOV
, TGSI_FILE_OUTPUT
, i
, TGSI_FILE_INPUT
, i
== 0 ? 0 : i
- 1);
1035 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1039 * add o2, i0, i1 ; Translate vertex pos by motion vec to form top field macroblock texcoords
1040 * add o3, i0, i2 ; Translate vertex pos by motion vec to form bottom field macroblock texcoords
1042 for (i
= 0; i
< 2; ++i
)
1044 inst
= vl_inst3(TGSI_OPCODE_ADD
, TGSI_FILE_OUTPUT
, i
+ 2, TGSI_FILE_INPUT
, 0, TGSI_FILE_INPUT
, i
+ 1);
1045 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1048 /* mul o4, i0, c0 ; Denorm vertex pos */
1049 inst
= vl_inst3(TGSI_OPCODE_MUL
, TGSI_FILE_OUTPUT
, 5, TGSI_FILE_INPUT
, 0, TGSI_FILE_CONSTANT
, 0);
1050 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1054 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1057 mc
->p_vs
[1] = pipe
->create_vs_state(pipe
, &vs
);
1063 static int vlCreateFragmentShaderFramePMB
1065 struct vlR16SnormBufferedMC
*mc
1068 const unsigned int max_tokens
= 100;
1070 struct pipe_context
*pipe
;
1071 struct pipe_shader_state fs
;
1072 struct tgsi_token
*tokens
;
1073 struct tgsi_header
*header
;
1075 struct tgsi_full_declaration decl
;
1076 struct tgsi_full_instruction inst
;
1084 tokens
= (struct tgsi_token
*)malloc(max_tokens
* sizeof(struct tgsi_token
));
1087 *(struct tgsi_version
*)&tokens
[0] = tgsi_build_version();
1089 header
= (struct tgsi_header
*)&tokens
[1];
1090 *header
= tgsi_build_header();
1092 *(struct tgsi_processor
*)&tokens
[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT
, header
);
1097 * decl i0 ; Texcoords for s0, s1, s2
1098 * decl i1 ; Texcoords for s3
1100 for (i
= 0; i
< 2; ++i
)
1102 decl
= vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC
, i
+ 1, i
, i
, TGSI_INTERPOLATE_LINEAR
);
1103 ti
+= tgsi_build_full_declaration(&decl
, &tokens
[ti
], header
, max_tokens
- ti
);
1106 /* decl c0 ; Scaling factor, rescales 16-bit snorm to 9-bit snorm */
1107 decl
= vl_decl_constants(TGSI_SEMANTIC_GENERIC
, 0, 0, 0);
1108 ti
+= tgsi_build_full_declaration(&decl
, &tokens
[ti
], header
, max_tokens
- ti
);
1110 /* decl o0 ; Fragment color */
1111 decl
= vl_decl_output(TGSI_SEMANTIC_COLOR
, 0, 0, 0);
1112 ti
+= tgsi_build_full_declaration(&decl
, &tokens
[ti
], header
, max_tokens
- ti
);
1115 decl
= vl_decl_temps(0, 1);
1116 ti
+= tgsi_build_full_declaration(&decl
, &tokens
[ti
], header
, max_tokens
- ti
);
1119 * decl s0 ; Sampler for luma texture
1120 * decl s1 ; Sampler for chroma Cb texture
1121 * decl s2 ; Sampler for chroma Cr texture
1122 * decl s3 ; Sampler for ref surface texture
1124 for (i
= 0; i
< 4; ++i
)
1126 decl
= vl_decl_samplers(i
, i
);
1127 ti
+= tgsi_build_full_declaration(&decl
, &tokens
[ti
], header
, max_tokens
- ti
);
1131 * tex2d t1, i0, s0 ; Read texel from luma texture
1132 * mov t0.x, t1.x ; Move luma sample into .x component
1133 * tex2d t1, i0, s1 ; Read texel from chroma Cb texture
1134 * mov t0.y, t1.x ; Move Cb sample into .y component
1135 * tex2d t1, i0, s2 ; Read texel from chroma Cr texture
1136 * mov t0.z, t1.x ; Move Cr sample into .z component
1138 for (i
= 0; i
< 3; ++i
)
1140 inst
= vl_tex(TGSI_TEXTURE_2D
, TGSI_FILE_TEMPORARY
, 1, TGSI_FILE_INPUT
, 0, TGSI_FILE_SAMPLER
, i
);
1141 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1143 inst
= vl_inst2(TGSI_OPCODE_MOV
, TGSI_FILE_TEMPORARY
, 0, TGSI_FILE_TEMPORARY
, 1);
1144 inst
.FullSrcRegisters
[0].SrcRegister
.SwizzleX
= TGSI_SWIZZLE_X
;
1145 inst
.FullSrcRegisters
[0].SrcRegister
.SwizzleY
= TGSI_SWIZZLE_X
;
1146 inst
.FullSrcRegisters
[0].SrcRegister
.SwizzleZ
= TGSI_SWIZZLE_X
;
1147 inst
.FullDstRegisters
[0].DstRegister
.WriteMask
= TGSI_WRITEMASK_X
<< i
;
1148 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1152 /* mul t0, t0, c0 ; Rescale texel to correct range */
1153 inst
= vl_inst3(TGSI_OPCODE_MUL
, TGSI_FILE_TEMPORARY
, 0, TGSI_FILE_TEMPORARY
, 0, TGSI_FILE_CONSTANT
, 0);
1154 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1156 /* tex2d t1, i1, s3 ; Read texel from ref macroblock */
1157 inst
= vl_tex(TGSI_TEXTURE_2D
, TGSI_FILE_TEMPORARY
, 1, TGSI_FILE_INPUT
, 1, TGSI_FILE_SAMPLER
, 3);
1158 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1160 /* add o0, t0, t1 ; Add ref and differential to form final output */
1161 inst
= vl_inst3(TGSI_OPCODE_ADD
, TGSI_FILE_OUTPUT
, 0, TGSI_FILE_TEMPORARY
, 0, TGSI_FILE_TEMPORARY
, 1);
1162 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1166 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1169 mc
->p_fs
[0] = pipe
->create_fs_state(pipe
, &fs
);
1175 static int vlCreateFragmentShaderFieldPMB
1177 struct vlR16SnormBufferedMC
*mc
1180 const unsigned int max_tokens
= 200;
1182 struct pipe_context
*pipe
;
1183 struct pipe_shader_state fs
;
1184 struct tgsi_token
*tokens
;
1185 struct tgsi_header
*header
;
1187 struct tgsi_full_declaration decl
;
1188 struct tgsi_full_instruction inst
;
1196 tokens
= (struct tgsi_token
*)malloc(max_tokens
* sizeof(struct tgsi_token
));
1199 *(struct tgsi_version
*)&tokens
[0] = tgsi_build_version();
1201 header
= (struct tgsi_header
*)&tokens
[1];
1202 *header
= tgsi_build_header();
1204 *(struct tgsi_processor
*)&tokens
[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT
, header
);
1209 * decl i0 ; Texcoords for s0, s1, s2
1210 * decl i1 ; Texcoords for s3
1211 * decl i2 ; Texcoords for s3
1212 * decl i3 ; Denormalized vertex pos
1214 for (i
= 0; i
< 4; ++i
)
1216 decl
= vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC
, i
+ 1, i
, i
, TGSI_INTERPOLATE_LINEAR
);
1217 ti
+= tgsi_build_full_declaration(&decl
, &tokens
[ti
], header
, max_tokens
- ti
);
1221 * decl c0 ; Scaling factor, rescales 16-bit snorm to 9-bit snorm
1222 * decl c1 ; Constants 1/2 & 2 in .x, .y channels for Y-mod-2 top/bottom field selection
1224 decl
= vl_decl_constants(TGSI_SEMANTIC_GENERIC
, 0, 0, 1);
1225 ti
+= tgsi_build_full_declaration(&decl
, &tokens
[ti
], header
, max_tokens
- ti
);
1227 /* decl o0 ; Fragment color */
1228 decl
= vl_decl_output(TGSI_SEMANTIC_COLOR
, 0, 0, 0);
1229 ti
+= tgsi_build_full_declaration(&decl
, &tokens
[ti
], header
, max_tokens
- ti
);
1232 decl
= vl_decl_temps(0, 4);
1233 ti
+= tgsi_build_full_declaration(&decl
, &tokens
[ti
], header
, max_tokens
- ti
);
1236 * decl s0 ; Sampler for luma texture
1237 * decl s1 ; Sampler for chroma Cb texture
1238 * decl s2 ; Sampler for chroma Cr texture
1239 * decl s3 ; Sampler for ref surface texture
1241 for (i
= 0; i
< 4; ++i
)
1243 decl
= vl_decl_samplers(i
, i
);
1244 ti
+= tgsi_build_full_declaration(&decl
, &tokens
[ti
], header
, max_tokens
- ti
);
1248 * tex2d t1, i0, s0 ; Read texel from luma texture
1249 * mov t0.x, t1.x ; Move luma sample into .x component
1250 * tex2d t1, i0, s1 ; Read texel from chroma Cb texture
1251 * mov t0.y, t1.x ; Move Cb sample into .y component
1252 * tex2d t1, i0, s2 ; Read texel from chroma Cr texture
1253 * mov t0.z, t1.x ; Move Cr sample into .z component
1255 for (i
= 0; i
< 3; ++i
)
1257 inst
= vl_tex(TGSI_TEXTURE_2D
, TGSI_FILE_TEMPORARY
, 1, TGSI_FILE_INPUT
, 0, TGSI_FILE_SAMPLER
, i
);
1258 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1260 inst
= vl_inst2(TGSI_OPCODE_MOV
, TGSI_FILE_TEMPORARY
, 0, TGSI_FILE_TEMPORARY
, 1);
1261 inst
.FullSrcRegisters
[0].SrcRegister
.SwizzleX
= TGSI_SWIZZLE_X
;
1262 inst
.FullSrcRegisters
[0].SrcRegister
.SwizzleY
= TGSI_SWIZZLE_X
;
1263 inst
.FullSrcRegisters
[0].SrcRegister
.SwizzleZ
= TGSI_SWIZZLE_X
;
1264 inst
.FullDstRegisters
[0].DstRegister
.WriteMask
= TGSI_WRITEMASK_X
<< i
;
1265 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1269 /* mul t0, t0, c0 ; Rescale texel to correct range */
1270 inst
= vl_inst3(TGSI_OPCODE_MUL
, TGSI_FILE_TEMPORARY
, 0, TGSI_FILE_TEMPORARY
, 0, TGSI_FILE_CONSTANT
, 0);
1271 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1274 * tex2d t1, i1, s3 ; Read texel from ref macroblock top field
1275 * tex2d t2, i2, s3 ; Read texel from ref macroblock bottom field
1277 for (i
= 0; i
< 2; ++i
)
1279 inst
= vl_tex(TGSI_TEXTURE_2D
, TGSI_FILE_TEMPORARY
, i
+ 1, TGSI_FILE_INPUT
, i
+ 1, TGSI_FILE_SAMPLER
, 3);
1280 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1283 /* XXX: Pos values off by 0.5? */
1284 /* sub t4, i3.y, c1.x ; Sub 0.5 from denormalized pos */
1285 inst
= vl_inst3(TGSI_OPCODE_SUB
, TGSI_FILE_TEMPORARY
, 4, TGSI_FILE_INPUT
, 3, TGSI_FILE_CONSTANT
, 1);
1286 inst
.FullSrcRegisters
[0].SrcRegister
.SwizzleX
= TGSI_SWIZZLE_Y
;
1287 inst
.FullSrcRegisters
[0].SrcRegister
.SwizzleY
= TGSI_SWIZZLE_Y
;
1288 inst
.FullSrcRegisters
[0].SrcRegister
.SwizzleZ
= TGSI_SWIZZLE_Y
;
1289 inst
.FullSrcRegisters
[0].SrcRegister
.SwizzleW
= TGSI_SWIZZLE_Y
;
1290 inst
.FullSrcRegisters
[1].SrcRegister
.SwizzleX
= TGSI_SWIZZLE_X
;
1291 inst
.FullSrcRegisters
[1].SrcRegister
.SwizzleY
= TGSI_SWIZZLE_X
;
1292 inst
.FullSrcRegisters
[1].SrcRegister
.SwizzleZ
= TGSI_SWIZZLE_X
;
1293 inst
.FullSrcRegisters
[1].SrcRegister
.SwizzleW
= TGSI_SWIZZLE_X
;
1294 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1296 /* mul t3, t4, c1.x ; Multiply pos Y-coord by 1/2 */
1297 inst
= vl_inst3(TGSI_OPCODE_MUL
, TGSI_FILE_TEMPORARY
, 3, TGSI_FILE_TEMPORARY
, 4, TGSI_FILE_CONSTANT
, 1);
1298 inst
.FullSrcRegisters
[1].SrcRegister
.SwizzleX
= TGSI_SWIZZLE_X
;
1299 inst
.FullSrcRegisters
[1].SrcRegister
.SwizzleY
= TGSI_SWIZZLE_X
;
1300 inst
.FullSrcRegisters
[1].SrcRegister
.SwizzleZ
= TGSI_SWIZZLE_X
;
1301 inst
.FullSrcRegisters
[1].SrcRegister
.SwizzleW
= TGSI_SWIZZLE_X
;
1302 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1304 /* floor t3, t3 ; Get rid of fractional part */
1305 inst
= vl_inst2(TGSI_OPCODE_FLOOR
, TGSI_FILE_TEMPORARY
, 3, TGSI_FILE_TEMPORARY
, 3);
1306 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1308 /* mul t3, t3, c1.y ; Multiply by 2 */
1309 inst
= vl_inst3(TGSI_OPCODE_MUL
, TGSI_FILE_TEMPORARY
, 3, TGSI_FILE_TEMPORARY
, 3, TGSI_FILE_CONSTANT
, 1);
1310 inst
.FullSrcRegisters
[1].SrcRegister
.SwizzleX
= TGSI_SWIZZLE_Y
;
1311 inst
.FullSrcRegisters
[1].SrcRegister
.SwizzleY
= TGSI_SWIZZLE_Y
;
1312 inst
.FullSrcRegisters
[1].SrcRegister
.SwizzleZ
= TGSI_SWIZZLE_Y
;
1313 inst
.FullSrcRegisters
[1].SrcRegister
.SwizzleW
= TGSI_SWIZZLE_Y
;
1314 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1316 /* sub t3, t4, t3 ; Subtract from original Y to get Y % 2 */
1317 inst
= vl_inst3(TGSI_OPCODE_SUB
, TGSI_FILE_TEMPORARY
, 3, TGSI_FILE_TEMPORARY
, 4, TGSI_FILE_TEMPORARY
, 3);
1318 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1320 /* TODO: Move to conditional tex fetch on t3 instead of lerp */
1321 /* lerp t1, t3, t1, t2 ; Choose between top and bottom fields based on Y % 2 */
1322 inst
= vl_inst4(TGSI_OPCODE_LERP
, TGSI_FILE_TEMPORARY
, 1, TGSI_FILE_TEMPORARY
, 3, TGSI_FILE_TEMPORARY
, 1, TGSI_FILE_TEMPORARY
, 2);
1323 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1325 /* add o0, t0, t1 ; Add ref and differential to form final output */
1326 inst
= vl_inst3(TGSI_OPCODE_ADD
, TGSI_FILE_OUTPUT
, 0, TGSI_FILE_TEMPORARY
, 0, TGSI_FILE_TEMPORARY
, 1);
1327 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1331 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1334 mc
->p_fs
[1] = pipe
->create_fs_state(pipe
, &fs
);
1340 static int vlCreateVertexShaderFrameBMB
1342 struct vlR16SnormBufferedMC
*mc
1345 const unsigned int max_tokens
= 100;
1347 struct pipe_context
*pipe
;
1348 struct pipe_shader_state vs
;
1349 struct tgsi_token
*tokens
;
1350 struct tgsi_header
*header
;
1352 struct tgsi_full_declaration decl
;
1353 struct tgsi_full_instruction inst
;
1361 tokens
= (struct tgsi_token
*)malloc(max_tokens
* sizeof(struct tgsi_token
));
1364 *(struct tgsi_version
*)&tokens
[0] = tgsi_build_version();
1366 header
= (struct tgsi_header
*)&tokens
[1];
1367 *header
= tgsi_build_header();
1369 *(struct tgsi_processor
*)&tokens
[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX
, header
);
1374 * decl i0 ; Vertex pos, luma/chroma texcoords
1375 * decl i1 ; First ref surface top field texcoords
1376 * decl i2 ; First ref surface bottom field texcoords (unused, packed in the same stream)
1377 * decl i3 ; Second ref surface top field texcoords
1378 * decl i4 ; Second ref surface bottom field texcoords (unused, packed in the same stream)
1380 for (i
= 0; i
< 5; i
++)
1382 decl
= vl_decl_input(i
== 0 ? TGSI_SEMANTIC_POSITION
: TGSI_SEMANTIC_GENERIC
, i
, i
, i
);
1383 ti
+= tgsi_build_full_declaration(&decl
, &tokens
[ti
], header
, max_tokens
- ti
);
1387 * decl o0 ; Vertex pos
1388 * decl o1 ; Luma/chroma texcoords
1389 * decl o2 ; First ref macroblock texcoords
1390 * decl o3 ; Second ref macroblock texcoords
1392 for (i
= 0; i
< 4; i
++)
1394 decl
= vl_decl_output(i
== 0 ? TGSI_SEMANTIC_POSITION
: TGSI_SEMANTIC_GENERIC
, i
, i
, i
);
1395 ti
+= tgsi_build_full_declaration(&decl
, &tokens
[ti
], header
, max_tokens
- ti
);
1399 * mov o0, i0 ; Move input vertex pos to output
1400 * mov o1, i0 ; Move input luma/chroma texcoords to output
1402 for (i
= 0; i
< 2; ++i
)
1404 inst
= vl_inst2(TGSI_OPCODE_MOV
, TGSI_FILE_OUTPUT
, i
, TGSI_FILE_INPUT
, 0);
1405 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1409 * add o2, i0, i1 ; Translate vertex pos by motion vec to form first ref macroblock texcoords
1410 * add o3, i0, i3 ; Translate vertex pos by motion vec to form second ref macroblock texcoords
1412 for (i
= 0; i
< 2; ++i
)
1414 inst
= vl_inst3(TGSI_OPCODE_ADD
, TGSI_FILE_OUTPUT
, i
+ 2, TGSI_FILE_INPUT
, 0, TGSI_FILE_INPUT
, i
* 2 + 1);
1415 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1420 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1423 mc
->b_vs
[0] = pipe
->create_vs_state(pipe
, &vs
);
1429 static int vlCreateVertexShaderFieldBMB
1431 struct vlR16SnormBufferedMC
*mc
1434 const unsigned int max_tokens
= 100;
1436 struct pipe_context
*pipe
;
1437 struct pipe_shader_state vs
;
1438 struct tgsi_token
*tokens
;
1439 struct tgsi_header
*header
;
1441 struct tgsi_full_declaration decl
;
1442 struct tgsi_full_instruction inst
;
1450 tokens
= (struct tgsi_token
*)malloc(max_tokens
* sizeof(struct tgsi_token
));
1453 *(struct tgsi_version
*)&tokens
[0] = tgsi_build_version();
1455 header
= (struct tgsi_header
*)&tokens
[1];
1456 *header
= tgsi_build_header();
1458 *(struct tgsi_processor
*)&tokens
[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX
, header
);
1463 * decl i0 ; Vertex pos, Luma/chroma texcoords
1464 * decl i1 ; First ref surface top field texcoords
1465 * decl i2 ; First ref surface bottom field texcoords
1466 * decl i3 ; Second ref surface top field texcoords
1467 * decl i4 ; Second ref surface bottom field texcoords
1469 for (i
= 0; i
< 5; i
++)
1471 decl
= vl_decl_input(i
== 0 ? TGSI_SEMANTIC_POSITION
: TGSI_SEMANTIC_GENERIC
, i
, i
, i
);
1472 ti
+= tgsi_build_full_declaration(&decl
, &tokens
[ti
], header
, max_tokens
- ti
);
1475 /* decl c0 ; Denorm coefficients */
1476 decl
= vl_decl_constants(TGSI_SEMANTIC_GENERIC
, 0, 0, 6);
1477 ti
+= tgsi_build_full_declaration(&decl
, &tokens
[ti
], header
, max_tokens
- ti
);
1480 * decl o0 ; Vertex pos
1481 * decl o1 ; Luma/chroma texcoords
1482 * decl o2 ; Top field past ref macroblock texcoords
1483 * decl o3 ; Bottom field past ref macroblock texcoords
1484 * decl o4 ; Top field future ref macroblock texcoords
1485 * decl o5 ; Bottom field future ref macroblock texcoords
1486 * decl o6 ; Denormalized vertex pos
1488 for (i
= 0; i
< 7; i
++)
1490 decl
= vl_decl_output((i
== 0 || i
== 7) ? TGSI_SEMANTIC_POSITION
: TGSI_SEMANTIC_GENERIC
, i
, i
, i
);
1491 ti
+= tgsi_build_full_declaration(&decl
, &tokens
[ti
], header
, max_tokens
- ti
);
1495 decl
= vl_decl_temps(0, 1);
1496 ti
+= tgsi_build_full_declaration(&decl
, &tokens
[ti
], header
, max_tokens
- ti
);
1499 * mov o0, i0 ; Move input vertex pos to output
1500 * mov o1, i0 ; Move input luma/chroma texcoords to output
1501 * mov o2, i1 ; Move past top field texcoords to output
1502 * mov o3, i2 ; Move past bottom field texcoords to output
1503 * mov o4, i3 ; Move future top field texcoords to output
1504 * mov o5, i4 ; Move future bottom field texcoords to output
1506 for (i
= 0; i
< 6; ++i
)
1508 inst
= vl_inst2(TGSI_OPCODE_MOV
, TGSI_FILE_OUTPUT
, i
, TGSI_FILE_INPUT
, 0);
1509 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1513 * add o2, i0, i1 ; Translate vertex pos by motion vec to form first top field macroblock texcoords
1514 * add o3, i0, i2 ; Translate vertex pos by motion vec to form first bottom field macroblock texcoords
1515 * add o4, i0, i3 ; Translate vertex pos by motion vec to form second top field macroblock texcoords
1516 * add o5, i0, i4 ; Translate vertex pos by motion vec to form second bottom field macroblock texcoords
1518 for (i
= 0; i
< 4; ++i
)
1520 inst
= vl_inst3(TGSI_OPCODE_ADD
, TGSI_FILE_OUTPUT
, i
+ 2, TGSI_FILE_INPUT
, 0, TGSI_FILE_INPUT
, i
+ 1);
1521 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1524 /* mul o6, i0, c0 ; Denorm vertex pos */
1525 inst
= vl_inst3(TGSI_OPCODE_MUL
, TGSI_FILE_OUTPUT
, 6, TGSI_FILE_INPUT
, 0, TGSI_FILE_CONSTANT
, 0);
1526 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1530 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1533 mc
->b_vs
[1] = pipe
->create_vs_state(pipe
, &vs
);
1539 static int vlCreateFragmentShaderFrameBMB
1541 struct vlR16SnormBufferedMC
*mc
1544 const unsigned int max_tokens
= 100;
1546 struct pipe_context
*pipe
;
1547 struct pipe_shader_state fs
;
1548 struct tgsi_token
*tokens
;
1549 struct tgsi_header
*header
;
1551 struct tgsi_full_declaration decl
;
1552 struct tgsi_full_instruction inst
;
1560 tokens
= (struct tgsi_token
*)malloc(max_tokens
* sizeof(struct tgsi_token
));
1563 *(struct tgsi_version
*)&tokens
[0] = tgsi_build_version();
1565 header
= (struct tgsi_header
*)&tokens
[1];
1566 *header
= tgsi_build_header();
1568 *(struct tgsi_processor
*)&tokens
[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT
, header
);
1573 * decl i0 ; Texcoords for s0, s1, s2
1574 * decl i1 ; Texcoords for s3
1575 * decl i2 ; Texcoords for s4
1577 for (i
= 0; i
< 3; ++i
)
1579 decl
= vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC
, i
+ 1, i
, i
, TGSI_INTERPOLATE_LINEAR
);
1580 ti
+= tgsi_build_full_declaration(&decl
, &tokens
[ti
], header
, max_tokens
- ti
);
1584 * decl c0 ; Scaling factor, rescales 16-bit snorm to 9-bit snorm
1585 * decl c1 ; Constant 1/2 in .x channel to use as weight to blend past and future texels
1587 decl
= vl_decl_constants(TGSI_SEMANTIC_GENERIC
, 0, 0, 1);
1588 ti
+= tgsi_build_full_declaration(&decl
, &tokens
[ti
], header
, max_tokens
- ti
);
1590 /* decl o0 ; Fragment color */
1591 decl
= vl_decl_output(TGSI_SEMANTIC_COLOR
, 0, 0, 0);
1592 ti
+= tgsi_build_full_declaration(&decl
, &tokens
[ti
], header
, max_tokens
- ti
);
1595 decl
= vl_decl_temps(0, 2);
1596 ti
+= tgsi_build_full_declaration(&decl
, &tokens
[ti
], header
, max_tokens
- ti
);
1599 * decl s0 ; Sampler for luma texture
1600 * decl s1 ; Sampler for chroma Cb texture
1601 * decl s2 ; Sampler for chroma Cr texture
1602 * decl s3 ; Sampler for past ref surface texture
1603 * decl s4 ; Sampler for future ref surface texture
1605 for (i
= 0; i
< 5; ++i
)
1607 decl
= vl_decl_samplers(i
, i
);
1608 ti
+= tgsi_build_full_declaration(&decl
, &tokens
[ti
], header
, max_tokens
- ti
);
1612 * tex2d t1, i0, s0 ; Read texel from luma texture
1613 * mov t0.x, t1.x ; Move luma sample into .x component
1614 * tex2d t1, i0, s1 ; Read texel from chroma Cb texture
1615 * mov t0.y, t1.x ; Move Cb sample into .y component
1616 * tex2d t1, i0, s2 ; Read texel from chroma Cr texture
1617 * mov t0.z, t1.x ; Move Cr sample into .z component
1619 for (i
= 0; i
< 3; ++i
)
1621 inst
= vl_tex(TGSI_TEXTURE_2D
, TGSI_FILE_TEMPORARY
, 1, TGSI_FILE_INPUT
, 0, TGSI_FILE_SAMPLER
, i
);
1622 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1624 inst
= vl_inst2(TGSI_OPCODE_MOV
, TGSI_FILE_TEMPORARY
, 0, TGSI_FILE_TEMPORARY
, 1);
1625 inst
.FullSrcRegisters
[0].SrcRegister
.SwizzleX
= TGSI_SWIZZLE_X
;
1626 inst
.FullSrcRegisters
[0].SrcRegister
.SwizzleY
= TGSI_SWIZZLE_X
;
1627 inst
.FullSrcRegisters
[0].SrcRegister
.SwizzleZ
= TGSI_SWIZZLE_X
;
1628 inst
.FullDstRegisters
[0].DstRegister
.WriteMask
= TGSI_WRITEMASK_X
<< i
;
1629 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1633 /* mul t0, t0, c0 ; Rescale texel to correct range */
1634 inst
= vl_inst3(TGSI_OPCODE_MUL
, TGSI_FILE_TEMPORARY
, 0, TGSI_FILE_TEMPORARY
, 0, TGSI_FILE_CONSTANT
, 0);
1635 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1638 * tex2d t1, i1, s3 ; Read texel from past ref macroblock
1639 * tex2d t2, i2, s4 ; Read texel from future ref macroblock
1641 for (i
= 0; i
< 2; ++i
)
1643 inst
= vl_tex(TGSI_TEXTURE_2D
, TGSI_FILE_TEMPORARY
, i
+ 1, TGSI_FILE_INPUT
, i
+ 1, TGSI_FILE_SAMPLER
, i
+ 3);
1644 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1647 /* lerp t1, c1.x, t1, t2 ; Blend past and future texels */
1648 inst
= vl_inst4(TGSI_OPCODE_LERP
, TGSI_FILE_TEMPORARY
, 1, TGSI_FILE_CONSTANT
, 1, TGSI_FILE_TEMPORARY
, 1, TGSI_FILE_TEMPORARY
, 2);
1649 inst
.FullSrcRegisters
[0].SrcRegister
.SwizzleX
= TGSI_SWIZZLE_X
;
1650 inst
.FullSrcRegisters
[0].SrcRegister
.SwizzleY
= TGSI_SWIZZLE_X
;
1651 inst
.FullSrcRegisters
[0].SrcRegister
.SwizzleZ
= TGSI_SWIZZLE_X
;
1652 inst
.FullSrcRegisters
[0].SrcRegister
.SwizzleW
= TGSI_SWIZZLE_X
;
1653 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1655 /* add o0, t0, t1 ; Add past/future ref and differential to form final output */
1656 inst
= vl_inst3(TGSI_OPCODE_ADD
, TGSI_FILE_OUTPUT
, 0, TGSI_FILE_TEMPORARY
, 0, TGSI_FILE_TEMPORARY
, 1);
1657 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1661 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1664 mc
->b_fs
[0] = pipe
->create_fs_state(pipe
, &fs
);
1670 static int vlCreateFragmentShaderFieldBMB
1672 struct vlR16SnormBufferedMC
*mc
1675 const unsigned int max_tokens
= 200;
1677 struct pipe_context
*pipe
;
1678 struct pipe_shader_state fs
;
1679 struct tgsi_token
*tokens
;
1680 struct tgsi_header
*header
;
1682 struct tgsi_full_declaration decl
;
1683 struct tgsi_full_instruction inst
;
1691 tokens
= (struct tgsi_token
*)malloc(max_tokens
* sizeof(struct tgsi_token
));
1694 *(struct tgsi_version
*)&tokens
[0] = tgsi_build_version();
1696 header
= (struct tgsi_header
*)&tokens
[1];
1697 *header
= tgsi_build_header();
1699 *(struct tgsi_processor
*)&tokens
[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT
, header
);
1704 * decl i0 ; Texcoords for s0, s1, s2
1705 * decl i1 ; Texcoords for s3
1706 * decl i2 ; Texcoords for s3
1707 * decl i3 ; Texcoords for s4
1708 * decl i4 ; Texcoords for s4
1709 * decl i5 ; Denormalized vertex pos
1711 for (i
= 0; i
< 6; ++i
)
1713 decl
= vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC
, i
+ 1, i
, i
, TGSI_INTERPOLATE_LINEAR
);
1714 ti
+= tgsi_build_full_declaration(&decl
, &tokens
[ti
], header
, max_tokens
- ti
);
1718 * decl c0 ; Scaling factor, rescales 16-bit snorm to 9-bit snorm
1719 * decl c1 ; Constants 1/2 & 2 in .x, .y channels to use as weight to blend past and future texels
1720 * ; and for Y-mod-2 top/bottom field selection
1722 decl
= vl_decl_constants(TGSI_SEMANTIC_GENERIC
, 0, 0, 1);
1723 ti
+= tgsi_build_full_declaration(&decl
, &tokens
[ti
], header
, max_tokens
- ti
);
1725 /* decl o0 ; Fragment color */
1726 decl
= vl_decl_output(TGSI_SEMANTIC_COLOR
, 0, 0, 0);
1727 ti
+= tgsi_build_full_declaration(&decl
, &tokens
[ti
], header
, max_tokens
- ti
);
1730 decl
= vl_decl_temps(0, 5);
1731 ti
+= tgsi_build_full_declaration(&decl
, &tokens
[ti
], header
, max_tokens
- ti
);
1734 * decl s0 ; Sampler for luma texture
1735 * decl s1 ; Sampler for chroma Cb texture
1736 * decl s2 ; Sampler for chroma Cr texture
1737 * decl s3 ; Sampler for past ref surface texture
1738 * decl s4 ; Sampler for future ref surface texture
1740 for (i
= 0; i
< 5; ++i
)
1742 decl
= vl_decl_samplers(i
, i
);
1743 ti
+= tgsi_build_full_declaration(&decl
, &tokens
[ti
], header
, max_tokens
- ti
);
1747 * tex2d t1, i0, s0 ; Read texel from luma texture
1748 * mov t0.x, t1.x ; Move luma sample into .x component
1749 * tex2d t1, i0, s1 ; Read texel from chroma Cb texture
1750 * mov t0.y, t1.x ; Move Cb sample into .y component
1751 * tex2d t1, i0, s2 ; Read texel from chroma Cr texture
1752 * mov t0.z, t1.x ; Move Cr sample into .z component
1754 for (i
= 0; i
< 3; ++i
)
1756 inst
= vl_tex(TGSI_TEXTURE_2D
, TGSI_FILE_TEMPORARY
, 1, TGSI_FILE_INPUT
, 0, TGSI_FILE_SAMPLER
, i
);
1757 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1759 inst
= vl_inst2(TGSI_OPCODE_MOV
, TGSI_FILE_TEMPORARY
, 0, TGSI_FILE_TEMPORARY
, 1);
1760 inst
.FullSrcRegisters
[0].SrcRegister
.SwizzleX
= TGSI_SWIZZLE_X
;
1761 inst
.FullSrcRegisters
[0].SrcRegister
.SwizzleY
= TGSI_SWIZZLE_X
;
1762 inst
.FullSrcRegisters
[0].SrcRegister
.SwizzleZ
= TGSI_SWIZZLE_X
;
1763 inst
.FullDstRegisters
[0].DstRegister
.WriteMask
= TGSI_WRITEMASK_X
<< i
;
1764 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1768 /* mul t0, t0, c0 ; Rescale texel to correct range */
1769 inst
= vl_inst3(TGSI_OPCODE_MUL
, TGSI_FILE_TEMPORARY
, 0, TGSI_FILE_TEMPORARY
, 0, TGSI_FILE_CONSTANT
, 0);
1770 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1772 /* XXX: Pos values off by 0.5? */
1773 /* sub t4, i5.y, c1.x ; Sub 0.5 from denormalized pos */
1774 inst
= vl_inst3(TGSI_OPCODE_SUB
, TGSI_FILE_TEMPORARY
, 4, TGSI_FILE_INPUT
, 5, TGSI_FILE_CONSTANT
, 1);
1775 inst
.FullSrcRegisters
[0].SrcRegister
.SwizzleX
= TGSI_SWIZZLE_Y
;
1776 inst
.FullSrcRegisters
[0].SrcRegister
.SwizzleY
= TGSI_SWIZZLE_Y
;
1777 inst
.FullSrcRegisters
[0].SrcRegister
.SwizzleZ
= TGSI_SWIZZLE_Y
;
1778 inst
.FullSrcRegisters
[0].SrcRegister
.SwizzleW
= TGSI_SWIZZLE_Y
;
1779 inst
.FullSrcRegisters
[1].SrcRegister
.SwizzleX
= TGSI_SWIZZLE_X
;
1780 inst
.FullSrcRegisters
[1].SrcRegister
.SwizzleY
= TGSI_SWIZZLE_X
;
1781 inst
.FullSrcRegisters
[1].SrcRegister
.SwizzleZ
= TGSI_SWIZZLE_X
;
1782 inst
.FullSrcRegisters
[1].SrcRegister
.SwizzleW
= TGSI_SWIZZLE_X
;
1783 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1785 /* mul t3, t4, c1.x ; Multiply pos Y-coord by 1/2 */
1786 inst
= vl_inst3(TGSI_OPCODE_MUL
, TGSI_FILE_TEMPORARY
, 3, TGSI_FILE_TEMPORARY
, 4, TGSI_FILE_CONSTANT
, 1);
1787 inst
.FullSrcRegisters
[1].SrcRegister
.SwizzleX
= TGSI_SWIZZLE_X
;
1788 inst
.FullSrcRegisters
[1].SrcRegister
.SwizzleY
= TGSI_SWIZZLE_X
;
1789 inst
.FullSrcRegisters
[1].SrcRegister
.SwizzleZ
= TGSI_SWIZZLE_X
;
1790 inst
.FullSrcRegisters
[1].SrcRegister
.SwizzleW
= TGSI_SWIZZLE_X
;
1791 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1793 /* floor t3, t3 ; Get rid of fractional part */
1794 inst
= vl_inst2(TGSI_OPCODE_FLOOR
, TGSI_FILE_TEMPORARY
, 3, TGSI_FILE_TEMPORARY
, 3);
1795 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1797 /* mul t3, t3, c1.y ; Multiply by 2 */
1798 inst
= vl_inst3( TGSI_OPCODE_MUL
, TGSI_FILE_TEMPORARY
, 3, TGSI_FILE_TEMPORARY
, 3, TGSI_FILE_CONSTANT
, 1);
1799 inst
.FullSrcRegisters
[1].SrcRegister
.SwizzleX
= TGSI_SWIZZLE_Y
;
1800 inst
.FullSrcRegisters
[1].SrcRegister
.SwizzleY
= TGSI_SWIZZLE_Y
;
1801 inst
.FullSrcRegisters
[1].SrcRegister
.SwizzleZ
= TGSI_SWIZZLE_Y
;
1802 inst
.FullSrcRegisters
[1].SrcRegister
.SwizzleW
= TGSI_SWIZZLE_Y
;
1803 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1805 /* sub t3, t4, t3 ; Subtract from original Y to get Y % 2 */
1806 inst
= vl_inst3(TGSI_OPCODE_SUB
, TGSI_FILE_TEMPORARY
, 3, TGSI_FILE_TEMPORARY
, 4, TGSI_FILE_TEMPORARY
, 3);
1807 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1810 * tex2d t1, i1, s3 ; Read texel from past ref macroblock top field
1811 * tex2d t2, i2, s3 ; Read texel from past ref macroblock bottom field
1813 for (i
= 0; i
< 2; ++i
)
1815 inst
= vl_tex(TGSI_TEXTURE_2D
, TGSI_FILE_TEMPORARY
, i
+ 1, TGSI_FILE_INPUT
, i
+ 1, TGSI_FILE_SAMPLER
, 3);
1816 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1819 /* TODO: Move to conditional tex fetch on t3 instead of lerp */
1820 /* lerp t1, t3, t1, t2 ; Choose between top and bottom fields based on Y % 2 */
1821 inst
= vl_inst4(TGSI_OPCODE_LERP
, TGSI_FILE_TEMPORARY
, 1, TGSI_FILE_TEMPORARY
, 3, TGSI_FILE_TEMPORARY
, 1, TGSI_FILE_TEMPORARY
, 2);
1822 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1825 * tex2d t4, i3, s4 ; Read texel from future ref macroblock top field
1826 * tex2d t5, i4, s4 ; Read texel from future ref macroblock bottom field
1828 for (i
= 0; i
< 2; ++i
)
1830 inst
= vl_tex(TGSI_TEXTURE_2D
, TGSI_FILE_TEMPORARY
, i
+ 4, TGSI_FILE_INPUT
, i
+ 3, TGSI_FILE_SAMPLER
, 4);
1831 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1834 /* TODO: Move to conditional tex fetch on t3 instead of lerp */
1835 /* lerp t2, t3, t4, t5 ; Choose between top and bottom fields based on Y % 2 */
1836 inst
= vl_inst4(TGSI_OPCODE_LERP
, TGSI_FILE_TEMPORARY
, 2, TGSI_FILE_TEMPORARY
, 3, TGSI_FILE_TEMPORARY
, 4, TGSI_FILE_TEMPORARY
, 5);
1837 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1839 /* lerp t1, c1.x, t1, t2 ; Blend past and future texels */
1840 inst
= vl_inst4(TGSI_OPCODE_LERP
, TGSI_FILE_TEMPORARY
, 1, TGSI_FILE_CONSTANT
, 1, TGSI_FILE_TEMPORARY
, 1, TGSI_FILE_TEMPORARY
, 2);
1841 inst
.FullSrcRegisters
[0].SrcRegister
.SwizzleX
= TGSI_SWIZZLE_X
;
1842 inst
.FullSrcRegisters
[0].SrcRegister
.SwizzleY
= TGSI_SWIZZLE_X
;
1843 inst
.FullSrcRegisters
[0].SrcRegister
.SwizzleZ
= TGSI_SWIZZLE_X
;
1844 inst
.FullSrcRegisters
[0].SrcRegister
.SwizzleW
= TGSI_SWIZZLE_X
;
1845 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1847 /* add o0, t0, t1 ; Add past/future ref and differential to form final output */
1848 inst
= vl_inst3(TGSI_OPCODE_ADD
, TGSI_FILE_OUTPUT
, 0, TGSI_FILE_TEMPORARY
, 0, TGSI_FILE_TEMPORARY
, 1);
1849 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1853 ti
+= tgsi_build_full_instruction(&inst
, &tokens
[ti
], header
, max_tokens
- ti
);
1856 mc
->b_fs
[1] = pipe
->create_fs_state(pipe
, &fs
);
1862 static int vlCreateDataBufs
1864 struct vlR16SnormBufferedMC
*mc
1867 const unsigned int mbw
= align(mc
->video_width
, VL_MACROBLOCK_WIDTH
) / VL_MACROBLOCK_WIDTH
;
1868 const unsigned int mbh
= align(mc
->video_height
, VL_MACROBLOCK_HEIGHT
) / VL_MACROBLOCK_HEIGHT
;
1869 const unsigned int num_mb_per_frame
= mbw
* mbh
;
1871 struct pipe_context
*pipe
;
1872 unsigned int g
, h
, i
;
1878 for (g
= 0; g
< NUM_BUF_SETS
; ++g
)
1880 for (h
= 0; h
< vlNumMacroBlockExTypes
; ++h
)
1882 /* Create our vertex buffer and vertex buffer element */
1883 mc
->vertex_bufs
[g
][h
][0].pitch
= sizeof(struct vlVertex2f
);
1884 mc
->vertex_bufs
[g
][h
][0].max_index
= 24 * num_mb_per_frame
- 1;
1885 mc
->vertex_bufs
[g
][h
][0].buffer_offset
= 0;
1886 mc
->vertex_bufs
[g
][h
][0].buffer
= pipe
->winsys
->buffer_create
1890 PIPE_BUFFER_USAGE_VERTEX
,
1891 sizeof(struct vlVertex2f
) * 24 * num_mb_per_frame
1896 /* Position & block luma, block chroma texcoord element */
1897 mc
->vertex_elems
[0].src_offset
= 0;
1898 mc
->vertex_elems
[0].vertex_buffer_index
= 0;
1899 mc
->vertex_elems
[0].nr_components
= 2;
1900 mc
->vertex_elems
[0].src_format
= PIPE_FORMAT_R32G32_FLOAT
;
1902 for (g
= 0; g
< NUM_BUF_SETS
; ++g
)
1904 for (h
= 0; h
< vlNumMacroBlockExTypes
; ++h
)
1906 for (i
= 1; i
< 3; ++i
)
1908 mc
->vertex_bufs
[g
][h
][i
].pitch
= sizeof(struct vlVertex2f
) * 2;
1909 mc
->vertex_bufs
[g
][h
][i
].max_index
= 24 * num_mb_per_frame
- 1;
1910 mc
->vertex_bufs
[g
][h
][i
].buffer_offset
= 0;
1911 mc
->vertex_bufs
[g
][h
][i
].buffer
= pipe
->winsys
->buffer_create
1915 PIPE_BUFFER_USAGE_VERTEX
,
1916 sizeof(struct vlVertex2f
) * 2 * 24 * num_mb_per_frame
1922 /* First ref surface top field texcoord element */
1923 mc
->vertex_elems
[1].src_offset
= 0;
1924 mc
->vertex_elems
[1].vertex_buffer_index
= 1;
1925 mc
->vertex_elems
[1].nr_components
= 2;
1926 mc
->vertex_elems
[1].src_format
= PIPE_FORMAT_R32G32_FLOAT
;
1928 /* First ref surface bottom field texcoord element */
1929 mc
->vertex_elems
[2].src_offset
= sizeof(struct vlVertex2f
);
1930 mc
->vertex_elems
[2].vertex_buffer_index
= 1;
1931 mc
->vertex_elems
[2].nr_components
= 2;
1932 mc
->vertex_elems
[2].src_format
= PIPE_FORMAT_R32G32_FLOAT
;
1934 /* Second ref surface top field texcoord element */
1935 mc
->vertex_elems
[3].src_offset
= 0;
1936 mc
->vertex_elems
[3].vertex_buffer_index
= 2;
1937 mc
->vertex_elems
[3].nr_components
= 2;
1938 mc
->vertex_elems
[3].src_format
= PIPE_FORMAT_R32G32_FLOAT
;
1940 /* Second ref surface bottom field texcoord element */
1941 mc
->vertex_elems
[4].src_offset
= sizeof(struct vlVertex2f
);
1942 mc
->vertex_elems
[4].vertex_buffer_index
= 2;
1943 mc
->vertex_elems
[4].nr_components
= 2;
1944 mc
->vertex_elems
[4].src_format
= PIPE_FORMAT_R32G32_FLOAT
;
1946 /* Create our constant buffer */
1947 mc
->vs_const_buf
.size
= sizeof(struct vlVertexShaderConsts
);
1948 mc
->vs_const_buf
.buffer
= pipe
->winsys
->buffer_create
1952 PIPE_BUFFER_USAGE_CONSTANT
,
1953 mc
->vs_const_buf
.size
1956 mc
->fs_const_buf
.size
= sizeof(struct vlFragmentShaderConsts
);
1957 mc
->fs_const_buf
.buffer
= pipe
->winsys
->buffer_create
1961 PIPE_BUFFER_USAGE_CONSTANT
,
1962 mc
->fs_const_buf
.size
1967 pipe
->winsys
->buffer_map(pipe
->winsys
, mc
->fs_const_buf
.buffer
, PIPE_BUFFER_USAGE_CPU_WRITE
),
1969 sizeof(struct vlFragmentShaderConsts
)
1972 pipe
->winsys
->buffer_unmap(pipe
->winsys
, mc
->fs_const_buf
.buffer
);
1979 struct vlR16SnormBufferedMC
*mc
1982 struct pipe_context
*pipe
;
1983 struct pipe_sampler_state sampler
;
1984 struct pipe_texture
template;
1985 unsigned int filters
[5];
1992 /* For MC we render to textures, which are rounded up to nearest POT */
1993 mc
->viewport
.scale
[0] = vlRoundUpPOT(mc
->video_width
);
1994 mc
->viewport
.scale
[1] = vlRoundUpPOT(mc
->video_height
);
1995 mc
->viewport
.scale
[2] = 1;
1996 mc
->viewport
.scale
[3] = 1;
1997 mc
->viewport
.translate
[0] = 0;
1998 mc
->viewport
.translate
[1] = 0;
1999 mc
->viewport
.translate
[2] = 0;
2000 mc
->viewport
.translate
[3] = 0;
2002 mc
->render_target
.width
= vlRoundUpPOT(mc
->video_width
);
2003 mc
->render_target
.height
= vlRoundUpPOT(mc
->video_height
);
2004 mc
->render_target
.num_cbufs
= 1;
2005 /* FB for MC stage is a vlSurface created by the user, set at render time */
2006 mc
->render_target
.zsbuf
= NULL
;
2008 filters
[0] = PIPE_TEX_FILTER_NEAREST
;
2009 /* FIXME: Linear causes discoloration around block edges */
2010 filters
[1] = /*mc->video_format == vlFormatYCbCr444 ?*/ PIPE_TEX_FILTER_NEAREST
/*: PIPE_TEX_FILTER_LINEAR*/;
2011 filters
[2] = /*mc->video_format == vlFormatYCbCr444 ?*/ PIPE_TEX_FILTER_NEAREST
/*: PIPE_TEX_FILTER_LINEAR*/;
2012 filters
[3] = PIPE_TEX_FILTER_LINEAR
;
2013 filters
[4] = PIPE_TEX_FILTER_LINEAR
;
2015 for (i
= 0; i
< 5; ++i
)
2017 sampler
.wrap_s
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
2018 sampler
.wrap_t
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
2019 sampler
.wrap_r
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
2020 sampler
.min_img_filter
= filters
[i
];
2021 sampler
.min_mip_filter
= PIPE_TEX_MIPFILTER_NONE
;
2022 sampler
.mag_img_filter
= filters
[i
];
2023 sampler
.compare_mode
= PIPE_TEX_COMPARE_NONE
;
2024 sampler
.compare_func
= PIPE_FUNC_ALWAYS
;
2025 sampler
.normalized_coords
= 1;
2026 /*sampler.prefilter = ;*/
2027 /*sampler.shadow_ambient = ;*/
2028 /*sampler.lod_bias = ;*/
2029 sampler
.min_lod
= 0;
2030 /*sampler.max_lod = ;*/
2031 /*sampler.border_color[i] = ;*/
2032 /*sampler.max_anisotropy = ;*/
2033 mc
->samplers
[i
] = pipe
->create_sampler_state(pipe
, &sampler
);
2036 memset(&template, 0, sizeof(struct pipe_texture
));
2037 template.target
= PIPE_TEXTURE_2D
;
2038 template.format
= PIPE_FORMAT_R16_SNORM
;
2039 template.last_level
= 0;
2040 template.width
[0] = vlRoundUpPOT(mc
->video_width
);
2041 template.height
[0] = vlRoundUpPOT(mc
->video_height
);
2042 template.depth
[0] = 1;
2043 template.compressed
= 0;
2044 pf_get_block(template.format
, &template.block
);
2046 for (i
= 0; i
< NUM_BUF_SETS
; ++i
)
2047 mc
->textures
[i
][0] = pipe
->screen
->texture_create(pipe
->screen
, &template);
2049 if (mc
->video_format
== vlFormatYCbCr420
)
2051 template.width
[0] = vlRoundUpPOT(mc
->video_width
/ 2);
2052 template.height
[0] = vlRoundUpPOT(mc
->video_height
/ 2);
2054 else if (mc
->video_format
== vlFormatYCbCr422
)
2055 template.height
[0] = vlRoundUpPOT(mc
->video_height
/ 2);
2057 for (i
= 0; i
< NUM_BUF_SETS
; ++i
)
2059 mc
->textures
[i
][1] = pipe
->screen
->texture_create(pipe
->screen
, &template);
2060 mc
->textures
[i
][2] = pipe
->screen
->texture_create(pipe
->screen
, &template);
2063 /* textures[3] & textures[4] are assigned from vlSurfaces for P and B macroblocks at render time */
2065 vlCreateVertexShaderIMB(mc
);
2066 vlCreateFragmentShaderIMB(mc
);
2067 vlCreateVertexShaderFramePMB(mc
);
2068 vlCreateVertexShaderFieldPMB(mc
);
2069 vlCreateFragmentShaderFramePMB(mc
);
2070 vlCreateFragmentShaderFieldPMB(mc
);
2071 vlCreateVertexShaderFrameBMB(mc
);
2072 vlCreateVertexShaderFieldBMB(mc
);
2073 vlCreateFragmentShaderFrameBMB(mc
);
2074 vlCreateFragmentShaderFieldBMB(mc
);
2075 vlCreateDataBufs(mc
);
2080 int vlCreateR16SNormBufferedMC
2082 struct pipe_context
*pipe
,
2083 unsigned int video_width
,
2084 unsigned int video_height
,
2085 enum vlFormat video_format
,
2086 struct vlRender
**render
2089 struct vlR16SnormBufferedMC
*mc
;
2094 mc
= calloc(1, sizeof(struct vlR16SnormBufferedMC
));
2096 mc
->base
.vlBegin
= &vlBegin
;
2097 mc
->base
.vlRenderMacroBlocksMpeg2
= &vlRenderMacroBlocksMpeg2R16SnormBuffered
;
2098 mc
->base
.vlEnd
= &vlEnd
;
2099 mc
->base
.vlFlush
= &vlFlush
;
2100 mc
->base
.vlDestroy
= &vlDestroy
;
2102 mc
->video_width
= video_width
;
2103 mc
->video_height
= video_height
;
2106 mc
->buffered_surface
= NULL
;
2107 mc
->past_surface
= NULL
;
2108 mc
->future_surface
= NULL
;
2109 memset(mc
->num_macroblocks
, 0, sizeof(unsigned int) * vlNumMacroBlockExTypes
);
2113 *render
= &mc
->base
;