1 #include "vl_surface.h"
4 #include <pipe/p_context.h>
5 #include <pipe/p_state.h>
6 #include <pipe/p_format.h>
7 #include <pipe/p_inlines.h>
8 #include "vl_context.h"
12 static int vlTransformBlock(short *src
, short *dst
, short bias
)
14 static const float basis
[8][8] =
16 {0.3536, 0.4904, 0.4619, 0.4157, 0.3536, 0.2778, 0.1913, 0.0975},
17 {0.3536, 0.4157, 0.1913, -0.0975, -0.3536, -0.4904, -0.4619, -0.2778},
18 {0.3536, 0.2778, -0.1913, -0.4904, -0.3536, 0.0975, 0.4619, 0.4157},
19 {0.3536, 0.0975, -0.4619, -0.2778, 0.3536, 0.4157, -0.1913, -0.4904},
20 {0.3536, -0.0975, -0.4619, 0.2778, 0.3536, -0.4157, -0.1913, 0.4904},
21 {0.3536, -0.2778, -0.1913, 0.4904, -0.3536, -0.0975, 0.4619, -0.4157},
22 {0.3536, -0.4157, 0.1913, 0.0975, -0.3536, 0.4904, -0.4619, 0.2778},
23 {0.3536, -0.4904, 0.4619, -0.4157, 0.3536, -0.2778, 0.1913, -0.0975}
29 for (y
= 0; y
< VL_BLOCK_HEIGHT
; ++y
)
30 for (x
= 0; x
< VL_BLOCK_WIDTH
; ++x
)
31 tmp
[y
* VL_BLOCK_WIDTH
+ x
] = (short)
33 src
[y
* VL_BLOCK_WIDTH
+ 0] * basis
[x
][0] +
34 src
[y
* VL_BLOCK_WIDTH
+ 1] * basis
[x
][1] +
35 src
[y
* VL_BLOCK_WIDTH
+ 2] * basis
[x
][2] +
36 src
[y
* VL_BLOCK_WIDTH
+ 3] * basis
[x
][3] +
37 src
[y
* VL_BLOCK_WIDTH
+ 4] * basis
[x
][4] +
38 src
[y
* VL_BLOCK_WIDTH
+ 5] * basis
[x
][5] +
39 src
[y
* VL_BLOCK_WIDTH
+ 6] * basis
[x
][6] +
40 src
[y
* VL_BLOCK_WIDTH
+ 7] * basis
[x
][7]
43 for (x
= 0; x
< VL_BLOCK_WIDTH
; ++x
)
44 for (y
= 0; y
< VL_BLOCK_HEIGHT
; ++y
)
46 dst
[y
* VL_BLOCK_WIDTH
+ x
] = bias
+ (short)
48 tmp
[0 * VL_BLOCK_WIDTH
+ x
] * basis
[y
][0] +
49 tmp
[1 * VL_BLOCK_WIDTH
+ x
] * basis
[y
][1] +
50 tmp
[2 * VL_BLOCK_WIDTH
+ x
] * basis
[y
][2] +
51 tmp
[3 * VL_BLOCK_WIDTH
+ x
] * basis
[y
][3] +
52 tmp
[4 * VL_BLOCK_WIDTH
+ x
] * basis
[y
][4] +
53 tmp
[5 * VL_BLOCK_WIDTH
+ x
] * basis
[y
][5] +
54 tmp
[6 * VL_BLOCK_WIDTH
+ x
] * basis
[y
][6] +
55 tmp
[7 * VL_BLOCK_WIDTH
+ x
] * basis
[y
][7]
57 if (dst
[y
* VL_BLOCK_WIDTH
+ x
] > 255)
58 dst
[y
* VL_BLOCK_WIDTH
+ x
] = 255;
59 else if (bias
> 0 && dst
[y
* VL_BLOCK_WIDTH
+ x
] < 0)
60 dst
[y
* VL_BLOCK_WIDTH
+ x
] = 0;
65 static int vlGrabFrameCodedFullBlock(short *src
, short *dst
, unsigned int dst_pitch
)
69 for (y
= 0; y
< VL_BLOCK_HEIGHT
; ++y
)
73 src
+ y
* VL_BLOCK_WIDTH
,
80 static int vlGrabFrameCodedDiffBlock(short *src
, short *dst
, unsigned int dst_pitch
)
84 for (y
= 0; y
< VL_BLOCK_HEIGHT
; ++y
)
85 for (x
= 0; x
< VL_BLOCK_WIDTH
; ++x
)
86 dst
[y
* dst_pitch
+ x
] = src
[y
* VL_BLOCK_WIDTH
+ x
] + 0x100;
91 static int vlGrabFieldCodedFullBlock(short *src
, short *dst
, unsigned int dst_pitch
)
95 for (y
= 0; y
< VL_BLOCK_HEIGHT
/ 2; ++y
)
98 dst
+ y
* dst_pitch
* 2,
99 src
+ y
* VL_BLOCK_WIDTH
,
103 dst
+= VL_BLOCK_HEIGHT
* dst_pitch
;
105 for (; y
< VL_BLOCK_HEIGHT
; ++y
)
108 dst
+ y
* dst_pitch
* 2,
109 src
+ y
* VL_BLOCK_WIDTH
,
116 static int vlGrabFieldCodedDiffBlock(short *src
, short *dst
, unsigned int dst_pitch
)
120 for (y
= 0; y
< VL_BLOCK_HEIGHT
/ 2; ++y
)
121 for (x
= 0; x
< VL_BLOCK_WIDTH
; ++x
)
122 dst
[y
* dst_pitch
* 2 + x
] = src
[y
* VL_BLOCK_WIDTH
+ x
] + 0x100;
124 dst
+= VL_BLOCK_HEIGHT
* dst_pitch
;
126 for (; y
< VL_BLOCK_HEIGHT
; ++y
)
127 for (x
= 0; x
< VL_BLOCK_WIDTH
; ++x
)
128 dst
[y
* dst_pitch
* 2 + x
] = src
[y
* VL_BLOCK_WIDTH
+ x
] + 0x100;
133 static int vlGrabNoBlock(short *dst
, unsigned int dst_pitch
)
137 for (y
= 0; y
< VL_BLOCK_HEIGHT
; ++y
)
138 for (x
= 0; x
< VL_BLOCK_WIDTH
; ++x
)
139 dst
[y
* dst_pitch
+ x
] = 0x100;
144 static int vlGrabBlocks
146 struct VL_CONTEXT
*context
,
147 unsigned int coded_block_pattern
,
148 enum VL_DCT_TYPE dct_type
,
149 enum VL_SAMPLE_TYPE sample_type
,
153 struct pipe_surface
*tex_surface
;
155 unsigned int tex_pitch
;
156 unsigned int tb
, sb
= 0;
158 const int do_idct
= 1;
159 short temp_block
[64];
164 tex_surface
= context
->pipe
->screen
->get_tex_surface
166 context
->pipe
->screen
,
167 context
->states
.mc
.textures
[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 for (tb
= 0; tb
< 4; ++tb
)
176 if ((coded_block_pattern
>> (5 - tb
)) & 1)
178 if (dct_type
== VL_DCT_FRAME_CODED
)
179 if (sample_type
== VL_FULL_SAMPLE
)
182 vlTransformBlock(blocks
+ sb
* VL_BLOCK_WIDTH
* VL_BLOCK_HEIGHT
, temp_block
, 128);
183 vlGrabFrameCodedFullBlock
186 texels
+ tb
* tex_pitch
* VL_BLOCK_HEIGHT
,
191 vlGrabFrameCodedFullBlock
193 blocks
+ sb
* VL_BLOCK_WIDTH
* VL_BLOCK_HEIGHT
,
194 texels
+ tb
* tex_pitch
* VL_BLOCK_HEIGHT
,
200 vlTransformBlock(blocks
+ sb
* VL_BLOCK_WIDTH
* VL_BLOCK_HEIGHT
, temp_block
, 0);
201 vlGrabFrameCodedDiffBlock
204 texels
+ tb
* tex_pitch
* VL_BLOCK_HEIGHT
,
209 vlGrabFrameCodedDiffBlock
211 blocks
+ sb
* VL_BLOCK_WIDTH
* VL_BLOCK_HEIGHT
,
212 texels
+ tb
* tex_pitch
* VL_BLOCK_HEIGHT
,
216 if (sample_type
== VL_FULL_SAMPLE
)
219 vlTransformBlock(blocks
+ sb
* VL_BLOCK_WIDTH
* VL_BLOCK_HEIGHT
, temp_block
, 128);
220 vlGrabFieldCodedFullBlock
223 texels
+ (tb
% 2) * tex_pitch
* VL_BLOCK_HEIGHT
+ (tb
/ 2) * tex_pitch
,
228 vlGrabFieldCodedFullBlock
230 blocks
+ sb
* VL_BLOCK_WIDTH
* VL_BLOCK_HEIGHT
,
231 texels
+ (tb
% 2) * tex_pitch
* VL_BLOCK_HEIGHT
+ (tb
/ 2) * tex_pitch
,
237 vlTransformBlock(blocks
+ sb
* VL_BLOCK_WIDTH
* VL_BLOCK_HEIGHT
, temp_block
, 0);
238 vlGrabFieldCodedDiffBlock
241 texels
+ (tb
% 2) * tex_pitch
* VL_BLOCK_HEIGHT
+ (tb
/ 2) * tex_pitch
,
246 vlGrabFieldCodedDiffBlock
248 blocks
+ sb
* VL_BLOCK_WIDTH
* VL_BLOCK_HEIGHT
,
249 texels
+ (tb
% 2) * tex_pitch
* VL_BLOCK_HEIGHT
+ (tb
/ 2) * tex_pitch
,
255 vlGrabNoBlock(texels
+ tb
* tex_pitch
* VL_BLOCK_HEIGHT
, tex_pitch
);
258 pipe_surface_unmap(tex_surface
);
260 /* TODO: Implement 422, 444 */
261 for (tb
= 0; tb
< 2; ++tb
)
263 tex_surface
= context
->pipe
->screen
->get_tex_surface
265 context
->pipe
->screen
,
266 context
->states
.mc
.textures
[tb
+ 1],
267 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE
270 texels
= pipe_surface_map(tex_surface
, PIPE_BUFFER_USAGE_CPU_WRITE
);
271 tex_pitch
= tex_surface
->stride
/ tex_surface
->block
.size
;
273 if ((coded_block_pattern
>> (1 - tb
)) & 1)
275 if (sample_type
== VL_FULL_SAMPLE
)
278 vlTransformBlock(blocks
+ sb
* VL_BLOCK_WIDTH
* VL_BLOCK_HEIGHT
, temp_block
, 128);
279 vlGrabFrameCodedFullBlock
287 vlGrabFrameCodedFullBlock
289 blocks
+ sb
* VL_BLOCK_WIDTH
* VL_BLOCK_HEIGHT
,
296 vlTransformBlock(blocks
+ sb
* VL_BLOCK_WIDTH
* VL_BLOCK_HEIGHT
, temp_block
, 0);
297 vlGrabFrameCodedDiffBlock
305 vlGrabFrameCodedDiffBlock
307 blocks
+ sb
* VL_BLOCK_WIDTH
* VL_BLOCK_HEIGHT
,
315 vlGrabNoBlock(texels
, tex_pitch
);
317 pipe_surface_unmap(tex_surface
);
323 int vlCreateSurface(struct VL_CONTEXT
*context
, struct VL_SURFACE
**surface
)
325 struct pipe_context
*pipe
;
326 struct pipe_texture
template;
327 struct VL_SURFACE
*sfc
;
332 pipe
= context
->pipe
;
334 sfc
= calloc(1, sizeof(struct VL_SURFACE
));
336 sfc
->context
= context
;
337 sfc
->width
= vlRoundUpPOT(context
->video_width
);
338 sfc
->height
= vlRoundUpPOT(context
->video_height
);
339 sfc
->format
= context
->video_format
;
341 memset(&template, 0, sizeof(struct pipe_texture
));
342 template.target
= PIPE_TEXTURE_2D
;
343 template.format
= PIPE_FORMAT_A8R8G8B8_UNORM
;
344 template.last_level
= 0;
345 template.width
[0] = sfc
->width
;
346 template.height
[0] = sfc
->height
;
347 template.depth
[0] = 1;
348 template.compressed
= 0;
349 pf_get_block(template.format
, &template.block
);
351 template.tex_usage
= PIPE_TEXTURE_USAGE_SAMPLER
| PIPE_TEXTURE_USAGE_RENDER_TARGET
;
353 sfc
->texture
= pipe
->screen
->texture_create(pipe
->screen
, &template);
360 int vlDestroySurface(struct VL_SURFACE
*surface
)
363 pipe_texture_release(&surface
->texture
);
369 int vlRenderIMacroBlock
371 enum VL_PICTURE picture_type
,
372 enum VL_FIELD_ORDER field_order
,
375 unsigned int coded_block_pattern
,
376 enum VL_DCT_TYPE dct_type
,
378 struct VL_SURFACE
*surface
381 struct pipe_context
*pipe
;
382 struct VL_MC_VS_CONSTS
*vs_consts
;
387 /* TODO: Implement interlaced rendering */
388 if (picture_type
!= VL_FRAME_PICTURE
)
391 vlGrabBlocks(surface
->context
, coded_block_pattern
, dct_type
, VL_FULL_SAMPLE
, blocks
);
393 pipe
= surface
->context
->pipe
;
395 vs_consts
= pipe
->winsys
->buffer_map
398 surface
->context
->states
.mc
.vs_const_buf
.buffer
,
399 PIPE_BUFFER_USAGE_CPU_WRITE
402 vs_consts
->scale
.x
= VL_MACROBLOCK_WIDTH
/ (float)surface
->width
;
403 vs_consts
->scale
.y
= VL_MACROBLOCK_HEIGHT
/ (float)surface
->height
;
404 vs_consts
->scale
.z
= 1.0f
;
405 vs_consts
->scale
.w
= 1.0f
;
406 vs_consts
->mb_pos_trans
.x
= (mbx
* VL_MACROBLOCK_WIDTH
) / (float)surface
->width
;
407 vs_consts
->mb_pos_trans
.y
= (mby
* VL_MACROBLOCK_HEIGHT
) / (float)surface
->height
;
408 vs_consts
->mb_pos_trans
.z
= 0.0f
;
409 vs_consts
->mb_pos_trans
.w
= 0.0f
;
411 pipe
->winsys
->buffer_unmap(pipe
->winsys
, surface
->context
->states
.mc
.vs_const_buf
.buffer
);
413 surface
->context
->states
.mc
.render_target
.cbufs
[0] = pipe
->screen
->get_tex_surface
417 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ
| PIPE_BUFFER_USAGE_GPU_WRITE
419 pipe
->set_framebuffer_state(pipe
, &surface
->context
->states
.mc
.render_target
);
420 pipe
->set_sampler_textures(pipe
, 3, surface
->context
->states
.mc
.textures
);
421 pipe
->bind_sampler_states(pipe
, 3, (void**)surface
->context
->states
.mc
.samplers
);
422 pipe
->bind_vs_state(pipe
, surface
->context
->states
.mc
.i_vs
);
423 pipe
->bind_fs_state(pipe
, surface
->context
->states
.mc
.i_fs
);
425 pipe
->draw_arrays(pipe
, PIPE_PRIM_TRIANGLES
, 0, 24);
430 int vlRenderPMacroBlock
432 enum VL_PICTURE picture_type
,
433 enum VL_FIELD_ORDER field_order
,
436 enum VL_MC_TYPE mc_type
,
437 struct VL_MOTION_VECTOR
*motion_vector
,
438 unsigned int coded_block_pattern
,
439 enum VL_DCT_TYPE dct_type
,
441 struct VL_SURFACE
*ref_surface
,
442 struct VL_SURFACE
*surface
445 struct pipe_context
*pipe
;
446 struct VL_MC_VS_CONSTS
*vs_consts
;
448 assert(motion_vectors
);
453 /* TODO: Implement interlaced rendering */
454 if (picture_type
!= VL_FRAME_PICTURE
)
456 /* TODO: Implement other MC types */
457 if (mc_type
!= VL_FRAME_MC
&& mc_type
!= VL_FIELD_MC
)
460 vlGrabBlocks(surface
->context
, coded_block_pattern
, dct_type
, VL_DIFFERENCE_SAMPLE
, blocks
);
462 pipe
= surface
->context
->pipe
;
464 vs_consts
= pipe
->winsys
->buffer_map
467 surface
->context
->states
.mc
.vs_const_buf
.buffer
,
468 PIPE_BUFFER_USAGE_CPU_WRITE
471 vs_consts
->scale
.x
= VL_MACROBLOCK_WIDTH
/ (float)surface
->width
;
472 vs_consts
->scale
.y
= VL_MACROBLOCK_HEIGHT
/ (float)surface
->height
;
473 vs_consts
->scale
.z
= 1.0f
;
474 vs_consts
->scale
.w
= 1.0f
;
475 vs_consts
->mb_pos_trans
.x
= (mbx
* VL_MACROBLOCK_WIDTH
) / (float)surface
->width
;
476 vs_consts
->mb_pos_trans
.y
= (mby
* VL_MACROBLOCK_HEIGHT
) / (float)surface
->height
;
477 vs_consts
->mb_pos_trans
.z
= 0.0f
;
478 vs_consts
->mb_pos_trans
.w
= 0.0f
;
479 vs_consts
->mb_tc_trans
[0].top_field
.x
= (mbx
* VL_MACROBLOCK_WIDTH
+ motion_vector
->top_field
.x
* 0.5f
) / (float)surface
->width
;
480 vs_consts
->mb_tc_trans
[0].top_field
.y
= (mby
* VL_MACROBLOCK_HEIGHT
+ motion_vector
->top_field
.y
* 0.5f
) / (float)surface
->height
;
481 vs_consts
->mb_tc_trans
[0].top_field
.z
= 0.0f
;
482 vs_consts
->mb_tc_trans
[0].top_field
.w
= 0.0f
;
484 if (mc_type
== VL_FIELD_MC
)
486 vs_consts
->denorm
.x
= (float)surface
->width
;
487 vs_consts
->denorm
.y
= (float)surface
->height
;
489 vs_consts
->mb_tc_trans
[0].bottom_field
.x
= (mbx
* VL_MACROBLOCK_WIDTH
+ motion_vector
->bottom_field
.x
* 0.5f
) / (float)surface
->width
;
490 vs_consts
->mb_tc_trans
[0].bottom_field
.y
= (mby
* VL_MACROBLOCK_HEIGHT
+ motion_vector
->bottom_field
.y
* 0.5f
) / (float)surface
->height
;
491 vs_consts
->mb_tc_trans
[0].bottom_field
.z
= 0.0f
;
492 vs_consts
->mb_tc_trans
[0].bottom_field
.w
= 0.0f
;
494 pipe
->bind_vs_state(pipe
, surface
->context
->states
.mc
.p_vs
[1]);
495 pipe
->bind_fs_state(pipe
, surface
->context
->states
.mc
.p_fs
[1]);
499 pipe
->bind_vs_state(pipe
, surface
->context
->states
.mc
.p_vs
[0]);
500 pipe
->bind_fs_state(pipe
, surface
->context
->states
.mc
.p_fs
[0]);
503 pipe
->winsys
->buffer_unmap(pipe
->winsys
, surface
->context
->states
.mc
.vs_const_buf
.buffer
);
505 surface
->context
->states
.mc
.render_target
.cbufs
[0] = pipe
->screen
->get_tex_surface
509 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ
| PIPE_BUFFER_USAGE_GPU_WRITE
511 pipe
->set_framebuffer_state(pipe
, &surface
->context
->states
.mc
.render_target
);
513 surface
->context
->states
.mc
.textures
[3] = ref_surface
->texture
;
514 pipe
->set_sampler_textures(pipe
, 4, surface
->context
->states
.mc
.textures
);
515 pipe
->bind_sampler_states(pipe
, 4, (void**)surface
->context
->states
.mc
.samplers
);
517 pipe
->draw_arrays(pipe
, PIPE_PRIM_TRIANGLES
, 0, 24);
522 int vlRenderBMacroBlock
524 enum VL_PICTURE picture_type
,
525 enum VL_FIELD_ORDER field_order
,
528 enum VL_MC_TYPE mc_type
,
529 struct VL_MOTION_VECTOR
*motion_vector
,
530 unsigned int coded_block_pattern
,
531 enum VL_DCT_TYPE dct_type
,
533 struct VL_SURFACE
*past_surface
,
534 struct VL_SURFACE
*future_surface
,
535 struct VL_SURFACE
*surface
538 struct pipe_context
*pipe
;
539 struct VL_MC_VS_CONSTS
*vs_consts
;
541 assert(motion_vectors
);
546 /* TODO: Implement interlaced rendering */
547 if (picture_type
!= VL_FRAME_PICTURE
)
549 /* TODO: Implement other MC types */
550 if (mc_type
!= VL_FRAME_MC
&& mc_type
!= VL_FIELD_MC
)
553 vlGrabBlocks(surface
->context
, coded_block_pattern
, dct_type
, VL_DIFFERENCE_SAMPLE
, blocks
);
555 pipe
= surface
->context
->pipe
;
557 vs_consts
= pipe
->winsys
->buffer_map
560 surface
->context
->states
.mc
.vs_const_buf
.buffer
,
561 PIPE_BUFFER_USAGE_CPU_WRITE
564 vs_consts
->scale
.x
= VL_MACROBLOCK_WIDTH
/ (float)surface
->width
;
565 vs_consts
->scale
.y
= VL_MACROBLOCK_HEIGHT
/ (float)surface
->height
;
566 vs_consts
->scale
.z
= 1.0f
;
567 vs_consts
->scale
.w
= 1.0f
;
568 vs_consts
->mb_pos_trans
.x
= (mbx
* VL_MACROBLOCK_WIDTH
) / (float)surface
->width
;
569 vs_consts
->mb_pos_trans
.y
= (mby
* VL_MACROBLOCK_HEIGHT
) / (float)surface
->height
;
570 vs_consts
->mb_pos_trans
.z
= 0.0f
;
571 vs_consts
->mb_pos_trans
.w
= 0.0f
;
572 vs_consts
->mb_tc_trans
[0].top_field
.x
= (mbx
* VL_MACROBLOCK_WIDTH
+ motion_vector
[0].top_field
.x
* 0.5f
) / (float)surface
->width
;
573 vs_consts
->mb_tc_trans
[0].top_field
.y
= (mby
* VL_MACROBLOCK_HEIGHT
+ motion_vector
[0].top_field
.y
* 0.5f
) / (float)surface
->height
;
574 vs_consts
->mb_tc_trans
[0].top_field
.z
= 0.0f
;
575 vs_consts
->mb_tc_trans
[0].top_field
.w
= 0.0f
;
576 vs_consts
->mb_tc_trans
[1].top_field
.x
= (mbx
* VL_MACROBLOCK_WIDTH
+ motion_vector
[1].top_field
.x
* 0.5f
) / (float)surface
->width
;
577 vs_consts
->mb_tc_trans
[1].top_field
.y
= (mby
* VL_MACROBLOCK_HEIGHT
+ motion_vector
[1].top_field
.y
* 0.5f
) / (float)surface
->height
;
578 vs_consts
->mb_tc_trans
[1].top_field
.z
= 0.0f
;
579 vs_consts
->mb_tc_trans
[1].top_field
.w
= 0.0f
;
581 if (mc_type
== VL_FIELD_MC
)
583 vs_consts
->denorm
.x
= (float)surface
->width
;
584 vs_consts
->denorm
.y
= (float)surface
->height
;
586 vs_consts
->mb_tc_trans
[0].bottom_field
.x
= (mbx
* VL_MACROBLOCK_WIDTH
+ motion_vector
[0].bottom_field
.x
* 0.5f
) / (float)surface
->width
;
587 vs_consts
->mb_tc_trans
[0].bottom_field
.y
= (mby
* VL_MACROBLOCK_HEIGHT
+ motion_vector
[0].bottom_field
.y
* 0.5f
) / (float)surface
->height
;
588 vs_consts
->mb_tc_trans
[0].bottom_field
.z
= 0.0f
;
589 vs_consts
->mb_tc_trans
[0].bottom_field
.w
= 0.0f
;
590 vs_consts
->mb_tc_trans
[1].bottom_field
.x
= (mbx
* VL_MACROBLOCK_WIDTH
+ motion_vector
[1].bottom_field
.x
* 0.5f
) / (float)surface
->width
;
591 vs_consts
->mb_tc_trans
[1].bottom_field
.y
= (mby
* VL_MACROBLOCK_HEIGHT
+ motion_vector
[1].bottom_field
.y
* 0.5f
) / (float)surface
->height
;
592 vs_consts
->mb_tc_trans
[1].bottom_field
.z
= 0.0f
;
593 vs_consts
->mb_tc_trans
[1].bottom_field
.w
= 0.0f
;
595 pipe
->bind_vs_state(pipe
, surface
->context
->states
.mc
.b_vs
[1]);
596 pipe
->bind_fs_state(pipe
, surface
->context
->states
.mc
.b_fs
[1]);
600 pipe
->bind_vs_state(pipe
, surface
->context
->states
.mc
.b_vs
[0]);
601 pipe
->bind_fs_state(pipe
, surface
->context
->states
.mc
.b_fs
[0]);
604 pipe
->winsys
->buffer_unmap(pipe
->winsys
, surface
->context
->states
.mc
.vs_const_buf
.buffer
);
606 surface
->context
->states
.mc
.render_target
.cbufs
[0] = pipe
->screen
->get_tex_surface
610 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ
| PIPE_BUFFER_USAGE_GPU_WRITE
612 pipe
->set_framebuffer_state(pipe
, &surface
->context
->states
.mc
.render_target
);
614 surface
->context
->states
.mc
.textures
[3] = past_surface
->texture
;
615 surface
->context
->states
.mc
.textures
[4] = future_surface
->texture
;
616 pipe
->set_sampler_textures(pipe
, 5, surface
->context
->states
.mc
.textures
);
617 pipe
->bind_sampler_states(pipe
, 5, (void**)surface
->context
->states
.mc
.samplers
);
619 pipe
->draw_arrays(pipe
, PIPE_PRIM_TRIANGLES
, 0, 24);
626 struct VL_SURFACE
*surface
,
636 enum VL_PICTURE picture_type
639 unsigned int create_fb
= 0;
640 struct pipe_context
*pipe
;
641 struct VL_CSC_VS_CONSTS
*vs_consts
;
645 pipe
= surface
->context
->pipe
;
647 if (!surface
->context
->states
.csc
.framebuffer
.cbufs
[0])
651 surface
->context
->states
.csc
.framebuffer
.width
!= destw
||
652 surface
->context
->states
.csc
.framebuffer
.height
!= desth
655 pipe
->winsys
->surface_release
658 &surface
->context
->states
.csc
.framebuffer
.cbufs
[0]
666 surface
->context
->states
.csc
.viewport
.scale
[0] = destw
;
667 surface
->context
->states
.csc
.viewport
.scale
[1] = desth
;
668 surface
->context
->states
.csc
.viewport
.scale
[2] = 1;
669 surface
->context
->states
.csc
.viewport
.scale
[3] = 1;
670 surface
->context
->states
.csc
.viewport
.translate
[0] = 0;
671 surface
->context
->states
.csc
.viewport
.translate
[1] = 0;
672 surface
->context
->states
.csc
.viewport
.translate
[2] = 0;
673 surface
->context
->states
.csc
.viewport
.translate
[3] = 0;
675 surface
->context
->states
.csc
.framebuffer
.width
= destw
;
676 surface
->context
->states
.csc
.framebuffer
.height
= desth
;
677 surface
->context
->states
.csc
.framebuffer
.cbufs
[0] = pipe
->winsys
->surface_alloc(pipe
->winsys
);
678 pipe
->winsys
->surface_alloc_storage
681 surface
->context
->states
.csc
.framebuffer
.cbufs
[0],
684 PIPE_FORMAT_A8R8G8B8_UNORM
,
685 /* XXX: SoftPipe doesn't change GPU usage to CPU like it does for textures */
686 PIPE_BUFFER_USAGE_CPU_READ
| PIPE_BUFFER_USAGE_CPU_WRITE
,
691 vlEndRender(surface
->context
);
693 vs_consts
= pipe
->winsys
->buffer_map
696 surface
->context
->states
.csc
.vs_const_buf
.buffer
,
697 PIPE_BUFFER_USAGE_CPU_WRITE
700 vs_consts
->src_scale
.x
= srcw
/ (float)surface
->width
;
701 vs_consts
->src_scale
.y
= srch
/ (float)surface
->height
;
702 vs_consts
->src_scale
.z
= 1;
703 vs_consts
->src_scale
.w
= 1;
704 vs_consts
->src_trans
.x
= srcx
/ (float)surface
->width
;
705 vs_consts
->src_trans
.y
= srcy
/ (float)surface
->height
;
706 vs_consts
->src_trans
.z
= 0;
707 vs_consts
->src_trans
.w
= 0;
709 pipe
->winsys
->buffer_unmap(pipe
->winsys
, surface
->context
->states
.csc
.vs_const_buf
.buffer
);
711 pipe
->set_sampler_textures(pipe
, 1, &surface
->texture
);
712 pipe
->draw_arrays(pipe
, PIPE_PRIM_TRIANGLE_STRIP
, 0, 4);
713 pipe
->flush(pipe
, PIPE_FLUSH_RENDER_CACHE
, NULL
);
714 /* TODO: Need to take destx, desty into consideration */
715 pipe
->winsys
->flush_frontbuffer
718 surface
->context
->states
.csc
.framebuffer
.cbufs
[0],
722 vlBeginRender(surface
->context
);