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>
9 #include "vl_context.h"
13 static int vlTransformBlock(short *src
, short *dst
, short bias
)
15 static const float basis
[8][8] =
17 {0.3536, 0.4904, 0.4619, 0.4157, 0.3536, 0.2778, 0.1913, 0.0975},
18 {0.3536, 0.4157, 0.1913, -0.0975, -0.3536, -0.4904, -0.4619, -0.2778},
19 {0.3536, 0.2778, -0.1913, -0.4904, -0.3536, 0.0975, 0.4619, 0.4157},
20 {0.3536, 0.0975, -0.4619, -0.2778, 0.3536, 0.4157, -0.1913, -0.4904},
21 {0.3536, -0.0975, -0.4619, 0.2778, 0.3536, -0.4157, -0.1913, 0.4904},
22 {0.3536, -0.2778, -0.1913, 0.4904, -0.3536, -0.0975, 0.4619, -0.4157},
23 {0.3536, -0.4157, 0.1913, 0.0975, -0.3536, 0.4904, -0.4619, 0.2778},
24 {0.3536, -0.4904, 0.4619, -0.4157, 0.3536, -0.2778, 0.1913, -0.0975}
30 for (y
= 0; y
< VL_BLOCK_HEIGHT
; ++y
)
31 for (x
= 0; x
< VL_BLOCK_WIDTH
; ++x
)
32 tmp
[y
* VL_BLOCK_WIDTH
+ x
] = (short)
34 src
[y
* VL_BLOCK_WIDTH
+ 0] * basis
[x
][0] +
35 src
[y
* VL_BLOCK_WIDTH
+ 1] * basis
[x
][1] +
36 src
[y
* VL_BLOCK_WIDTH
+ 2] * basis
[x
][2] +
37 src
[y
* VL_BLOCK_WIDTH
+ 3] * basis
[x
][3] +
38 src
[y
* VL_BLOCK_WIDTH
+ 4] * basis
[x
][4] +
39 src
[y
* VL_BLOCK_WIDTH
+ 5] * basis
[x
][5] +
40 src
[y
* VL_BLOCK_WIDTH
+ 6] * basis
[x
][6] +
41 src
[y
* VL_BLOCK_WIDTH
+ 7] * basis
[x
][7]
44 for (x
= 0; x
< VL_BLOCK_WIDTH
; ++x
)
45 for (y
= 0; y
< VL_BLOCK_HEIGHT
; ++y
)
47 dst
[y
* VL_BLOCK_WIDTH
+ x
] = bias
+ (short)
49 tmp
[0 * VL_BLOCK_WIDTH
+ x
] * basis
[y
][0] +
50 tmp
[1 * VL_BLOCK_WIDTH
+ x
] * basis
[y
][1] +
51 tmp
[2 * VL_BLOCK_WIDTH
+ x
] * basis
[y
][2] +
52 tmp
[3 * VL_BLOCK_WIDTH
+ x
] * basis
[y
][3] +
53 tmp
[4 * VL_BLOCK_WIDTH
+ x
] * basis
[y
][4] +
54 tmp
[5 * VL_BLOCK_WIDTH
+ x
] * basis
[y
][5] +
55 tmp
[6 * VL_BLOCK_WIDTH
+ x
] * basis
[y
][6] +
56 tmp
[7 * VL_BLOCK_WIDTH
+ x
] * basis
[y
][7]
58 if (dst
[y
* VL_BLOCK_WIDTH
+ x
] > 255)
59 dst
[y
* VL_BLOCK_WIDTH
+ x
] = 255;
60 else if (bias
> 0 && dst
[y
* VL_BLOCK_WIDTH
+ x
] < 0)
61 dst
[y
* VL_BLOCK_WIDTH
+ x
] = 0;
66 static int vlGrabFrameCodedFullBlock(short *src
, short *dst
, unsigned int dst_pitch
)
70 for (y
= 0; y
< VL_BLOCK_HEIGHT
; ++y
)
74 src
+ y
* VL_BLOCK_WIDTH
,
81 static int vlGrabFrameCodedDiffBlock(short *src
, short *dst
, unsigned int dst_pitch
)
85 for (y
= 0; y
< VL_BLOCK_HEIGHT
; ++y
)
86 for (x
= 0; x
< VL_BLOCK_WIDTH
; ++x
)
87 dst
[y
* dst_pitch
+ x
] = src
[y
* VL_BLOCK_WIDTH
+ x
] + 0x100;
92 static int vlGrabFieldCodedFullBlock(short *src
, short *dst
, unsigned int dst_pitch
)
96 for (y
= 0; y
< VL_BLOCK_HEIGHT
/ 2; ++y
)
99 dst
+ y
* dst_pitch
* 2,
100 src
+ y
* VL_BLOCK_WIDTH
,
104 dst
+= VL_BLOCK_HEIGHT
* dst_pitch
;
106 for (; y
< VL_BLOCK_HEIGHT
; ++y
)
109 dst
+ y
* dst_pitch
* 2,
110 src
+ y
* VL_BLOCK_WIDTH
,
117 static int vlGrabFieldCodedDiffBlock(short *src
, short *dst
, unsigned int dst_pitch
)
121 for (y
= 0; y
< VL_BLOCK_HEIGHT
/ 2; ++y
)
122 for (x
= 0; x
< VL_BLOCK_WIDTH
; ++x
)
123 dst
[y
* dst_pitch
* 2 + x
] = src
[y
* VL_BLOCK_WIDTH
+ x
] + 0x100;
125 dst
+= VL_BLOCK_HEIGHT
* dst_pitch
;
127 for (; y
< VL_BLOCK_HEIGHT
; ++y
)
128 for (x
= 0; x
< VL_BLOCK_WIDTH
; ++x
)
129 dst
[y
* dst_pitch
* 2 + x
] = src
[y
* VL_BLOCK_WIDTH
+ x
] + 0x100;
134 static int vlGrabNoBlock(short *dst
, unsigned int dst_pitch
)
138 for (y
= 0; y
< VL_BLOCK_HEIGHT
; ++y
)
139 for (x
= 0; x
< VL_BLOCK_WIDTH
; ++x
)
140 dst
[y
* dst_pitch
+ x
] = 0x100;
145 static int vlGrabBlocks
147 struct VL_CONTEXT
*context
,
148 unsigned int coded_block_pattern
,
149 enum VL_DCT_TYPE dct_type
,
150 enum VL_SAMPLE_TYPE sample_type
,
154 struct pipe_surface
*tex_surface
;
156 unsigned int tex_pitch
;
157 unsigned int tb
, sb
= 0;
159 const int do_idct
= 1;
160 short temp_block
[64];
165 tex_surface
= context
->pipe
->screen
->get_tex_surface
167 context
->pipe
->screen
,
168 context
->states
.mc
.textures
[0],
169 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE
172 texels
= pipe_surface_map(tex_surface
, PIPE_BUFFER_USAGE_CPU_WRITE
);
173 tex_pitch
= tex_surface
->stride
/ tex_surface
->block
.size
;
175 for (tb
= 0; tb
< 4; ++tb
)
177 if ((coded_block_pattern
>> (5 - tb
)) & 1)
179 if (dct_type
== VL_DCT_FRAME_CODED
)
180 if (sample_type
== VL_FULL_SAMPLE
)
183 vlTransformBlock(blocks
+ sb
* VL_BLOCK_WIDTH
* VL_BLOCK_HEIGHT
, temp_block
, 128);
184 vlGrabFrameCodedFullBlock
187 texels
+ tb
* tex_pitch
* VL_BLOCK_HEIGHT
,
192 vlGrabFrameCodedFullBlock
194 blocks
+ sb
* VL_BLOCK_WIDTH
* VL_BLOCK_HEIGHT
,
195 texels
+ tb
* tex_pitch
* VL_BLOCK_HEIGHT
,
201 vlTransformBlock(blocks
+ sb
* VL_BLOCK_WIDTH
* VL_BLOCK_HEIGHT
, temp_block
, 0);
202 vlGrabFrameCodedDiffBlock
205 texels
+ tb
* tex_pitch
* VL_BLOCK_HEIGHT
,
210 vlGrabFrameCodedDiffBlock
212 blocks
+ sb
* VL_BLOCK_WIDTH
* VL_BLOCK_HEIGHT
,
213 texels
+ tb
* tex_pitch
* VL_BLOCK_HEIGHT
,
217 if (sample_type
== VL_FULL_SAMPLE
)
220 vlTransformBlock(blocks
+ sb
* VL_BLOCK_WIDTH
* VL_BLOCK_HEIGHT
, temp_block
, 128);
221 vlGrabFieldCodedFullBlock
224 texels
+ (tb
% 2) * tex_pitch
* VL_BLOCK_HEIGHT
+ (tb
/ 2) * tex_pitch
,
229 vlGrabFieldCodedFullBlock
231 blocks
+ sb
* VL_BLOCK_WIDTH
* VL_BLOCK_HEIGHT
,
232 texels
+ (tb
% 2) * tex_pitch
* VL_BLOCK_HEIGHT
+ (tb
/ 2) * tex_pitch
,
238 vlTransformBlock(blocks
+ sb
* VL_BLOCK_WIDTH
* VL_BLOCK_HEIGHT
, temp_block
, 0);
239 vlGrabFieldCodedDiffBlock
242 texels
+ (tb
% 2) * tex_pitch
* VL_BLOCK_HEIGHT
+ (tb
/ 2) * tex_pitch
,
247 vlGrabFieldCodedDiffBlock
249 blocks
+ sb
* VL_BLOCK_WIDTH
* VL_BLOCK_HEIGHT
,
250 texels
+ (tb
% 2) * tex_pitch
* VL_BLOCK_HEIGHT
+ (tb
/ 2) * tex_pitch
,
256 vlGrabNoBlock(texels
+ tb
* tex_pitch
* VL_BLOCK_HEIGHT
, tex_pitch
);
259 pipe_surface_unmap(tex_surface
);
261 /* TODO: Implement 422, 444 */
262 for (tb
= 0; tb
< 2; ++tb
)
264 tex_surface
= context
->pipe
->screen
->get_tex_surface
266 context
->pipe
->screen
,
267 context
->states
.mc
.textures
[tb
+ 1],
268 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE
271 texels
= pipe_surface_map(tex_surface
, PIPE_BUFFER_USAGE_CPU_WRITE
);
272 tex_pitch
= tex_surface
->stride
/ tex_surface
->block
.size
;
274 if ((coded_block_pattern
>> (1 - tb
)) & 1)
276 if (sample_type
== VL_FULL_SAMPLE
)
279 vlTransformBlock(blocks
+ sb
* VL_BLOCK_WIDTH
* VL_BLOCK_HEIGHT
, temp_block
, 128);
280 vlGrabFrameCodedFullBlock
288 vlGrabFrameCodedFullBlock
290 blocks
+ sb
* VL_BLOCK_WIDTH
* VL_BLOCK_HEIGHT
,
297 vlTransformBlock(blocks
+ sb
* VL_BLOCK_WIDTH
* VL_BLOCK_HEIGHT
, temp_block
, 0);
298 vlGrabFrameCodedDiffBlock
306 vlGrabFrameCodedDiffBlock
308 blocks
+ sb
* VL_BLOCK_WIDTH
* VL_BLOCK_HEIGHT
,
316 vlGrabNoBlock(texels
, tex_pitch
);
318 pipe_surface_unmap(tex_surface
);
324 int vlCreateSurface(struct VL_CONTEXT
*context
, struct VL_SURFACE
**surface
)
326 struct pipe_context
*pipe
;
327 struct pipe_texture
template;
328 struct VL_SURFACE
*sfc
;
333 pipe
= context
->pipe
;
335 sfc
= calloc(1, sizeof(struct VL_SURFACE
));
337 sfc
->context
= context
;
338 sfc
->width
= vlRoundUpPOT(context
->video_width
);
339 sfc
->height
= vlRoundUpPOT(context
->video_height
);
340 sfc
->format
= context
->video_format
;
342 memset(&template, 0, sizeof(struct pipe_texture
));
343 template.target
= PIPE_TEXTURE_2D
;
344 template.format
= PIPE_FORMAT_A8R8G8B8_UNORM
;
345 template.last_level
= 0;
346 template.width
[0] = sfc
->width
;
347 template.height
[0] = sfc
->height
;
348 template.depth
[0] = 1;
349 template.compressed
= 0;
350 pf_get_block(template.format
, &template.block
);
352 template.tex_usage
= PIPE_TEXTURE_USAGE_SAMPLER
| PIPE_TEXTURE_USAGE_RENDER_TARGET
;
354 sfc
->texture
= pipe
->screen
->texture_create(pipe
->screen
, &template);
361 int vlDestroySurface(struct VL_SURFACE
*surface
)
364 pipe_texture_release(&surface
->texture
);
370 int vlRenderIMacroBlock
372 enum VL_PICTURE picture_type
,
373 enum VL_FIELD_ORDER field_order
,
376 unsigned int coded_block_pattern
,
377 enum VL_DCT_TYPE dct_type
,
379 struct VL_SURFACE
*surface
382 struct pipe_context
*pipe
;
383 struct VL_MC_VS_CONSTS
*vs_consts
;
388 /* TODO: Implement interlaced rendering */
389 if (picture_type
!= VL_FRAME_PICTURE
)
392 vlGrabBlocks(surface
->context
, coded_block_pattern
, dct_type
, VL_FULL_SAMPLE
, blocks
);
394 pipe
= surface
->context
->pipe
;
396 vs_consts
= pipe
->winsys
->buffer_map
399 surface
->context
->states
.mc
.vs_const_buf
.buffer
,
400 PIPE_BUFFER_USAGE_CPU_WRITE
403 vs_consts
->scale
.x
= VL_MACROBLOCK_WIDTH
/ (float)surface
->width
;
404 vs_consts
->scale
.y
= VL_MACROBLOCK_HEIGHT
/ (float)surface
->height
;
405 vs_consts
->scale
.z
= 1.0f
;
406 vs_consts
->scale
.w
= 1.0f
;
407 vs_consts
->mb_pos_trans
.x
= (mbx
* VL_MACROBLOCK_WIDTH
) / (float)surface
->width
;
408 vs_consts
->mb_pos_trans
.y
= (mby
* VL_MACROBLOCK_HEIGHT
) / (float)surface
->height
;
409 vs_consts
->mb_pos_trans
.z
= 0.0f
;
410 vs_consts
->mb_pos_trans
.w
= 0.0f
;
412 pipe
->winsys
->buffer_unmap(pipe
->winsys
, surface
->context
->states
.mc
.vs_const_buf
.buffer
);
414 surface
->context
->states
.mc
.render_target
.cbufs
[0] = pipe
->screen
->get_tex_surface
418 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ
| PIPE_BUFFER_USAGE_GPU_WRITE
420 pipe
->set_framebuffer_state(pipe
, &surface
->context
->states
.mc
.render_target
);
421 pipe
->set_sampler_textures(pipe
, 3, surface
->context
->states
.mc
.textures
);
422 pipe
->bind_sampler_states(pipe
, 3, (void**)surface
->context
->states
.mc
.samplers
);
423 pipe
->bind_vs_state(pipe
, surface
->context
->states
.mc
.i_vs
);
424 pipe
->bind_fs_state(pipe
, surface
->context
->states
.mc
.i_fs
);
426 pipe
->draw_arrays(pipe
, PIPE_PRIM_TRIANGLES
, 0, 24);
431 int vlRenderPMacroBlock
433 enum VL_PICTURE picture_type
,
434 enum VL_FIELD_ORDER field_order
,
437 enum VL_MC_TYPE mc_type
,
438 struct VL_MOTION_VECTOR
*motion_vector
,
439 unsigned int coded_block_pattern
,
440 enum VL_DCT_TYPE dct_type
,
442 struct VL_SURFACE
*ref_surface
,
443 struct VL_SURFACE
*surface
446 struct pipe_context
*pipe
;
447 struct VL_MC_VS_CONSTS
*vs_consts
;
449 assert(motion_vectors
);
454 /* TODO: Implement interlaced rendering */
455 if (picture_type
!= VL_FRAME_PICTURE
)
457 /* TODO: Implement other MC types */
458 if (mc_type
!= VL_FRAME_MC
&& mc_type
!= VL_FIELD_MC
)
461 vlGrabBlocks(surface
->context
, coded_block_pattern
, dct_type
, VL_DIFFERENCE_SAMPLE
, blocks
);
463 pipe
= surface
->context
->pipe
;
465 vs_consts
= pipe
->winsys
->buffer_map
468 surface
->context
->states
.mc
.vs_const_buf
.buffer
,
469 PIPE_BUFFER_USAGE_CPU_WRITE
472 vs_consts
->scale
.x
= VL_MACROBLOCK_WIDTH
/ (float)surface
->width
;
473 vs_consts
->scale
.y
= VL_MACROBLOCK_HEIGHT
/ (float)surface
->height
;
474 vs_consts
->scale
.z
= 1.0f
;
475 vs_consts
->scale
.w
= 1.0f
;
476 vs_consts
->mb_pos_trans
.x
= (mbx
* VL_MACROBLOCK_WIDTH
) / (float)surface
->width
;
477 vs_consts
->mb_pos_trans
.y
= (mby
* VL_MACROBLOCK_HEIGHT
) / (float)surface
->height
;
478 vs_consts
->mb_pos_trans
.z
= 0.0f
;
479 vs_consts
->mb_pos_trans
.w
= 0.0f
;
480 vs_consts
->mb_tc_trans
[0].top_field
.x
= (mbx
* VL_MACROBLOCK_WIDTH
+ motion_vector
->top_field
.x
* 0.5f
) / (float)surface
->width
;
481 vs_consts
->mb_tc_trans
[0].top_field
.y
= (mby
* VL_MACROBLOCK_HEIGHT
+ motion_vector
->top_field
.y
* 0.5f
) / (float)surface
->height
;
482 vs_consts
->mb_tc_trans
[0].top_field
.z
= 0.0f
;
483 vs_consts
->mb_tc_trans
[0].top_field
.w
= 0.0f
;
485 if (mc_type
== VL_FIELD_MC
)
487 vs_consts
->denorm
.x
= (float)surface
->width
;
488 vs_consts
->denorm
.y
= (float)surface
->height
;
490 vs_consts
->mb_tc_trans
[0].bottom_field
.x
= (mbx
* VL_MACROBLOCK_WIDTH
+ motion_vector
->bottom_field
.x
* 0.5f
) / (float)surface
->width
;
491 vs_consts
->mb_tc_trans
[0].bottom_field
.y
= (mby
* VL_MACROBLOCK_HEIGHT
+ motion_vector
->bottom_field
.y
* 0.5f
) / (float)surface
->height
;
492 vs_consts
->mb_tc_trans
[0].bottom_field
.z
= 0.0f
;
493 vs_consts
->mb_tc_trans
[0].bottom_field
.w
= 0.0f
;
495 pipe
->bind_vs_state(pipe
, surface
->context
->states
.mc
.p_vs
[1]);
496 pipe
->bind_fs_state(pipe
, surface
->context
->states
.mc
.p_fs
[1]);
500 pipe
->bind_vs_state(pipe
, surface
->context
->states
.mc
.p_vs
[0]);
501 pipe
->bind_fs_state(pipe
, surface
->context
->states
.mc
.p_fs
[0]);
504 pipe
->winsys
->buffer_unmap(pipe
->winsys
, surface
->context
->states
.mc
.vs_const_buf
.buffer
);
506 surface
->context
->states
.mc
.render_target
.cbufs
[0] = pipe
->screen
->get_tex_surface
510 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ
| PIPE_BUFFER_USAGE_GPU_WRITE
512 pipe
->set_framebuffer_state(pipe
, &surface
->context
->states
.mc
.render_target
);
514 surface
->context
->states
.mc
.textures
[3] = ref_surface
->texture
;
515 pipe
->set_sampler_textures(pipe
, 4, surface
->context
->states
.mc
.textures
);
516 pipe
->bind_sampler_states(pipe
, 4, (void**)surface
->context
->states
.mc
.samplers
);
518 pipe
->draw_arrays(pipe
, PIPE_PRIM_TRIANGLES
, 0, 24);
523 int vlRenderBMacroBlock
525 enum VL_PICTURE picture_type
,
526 enum VL_FIELD_ORDER field_order
,
529 enum VL_MC_TYPE mc_type
,
530 struct VL_MOTION_VECTOR
*motion_vector
,
531 unsigned int coded_block_pattern
,
532 enum VL_DCT_TYPE dct_type
,
534 struct VL_SURFACE
*past_surface
,
535 struct VL_SURFACE
*future_surface
,
536 struct VL_SURFACE
*surface
539 struct pipe_context
*pipe
;
540 struct VL_MC_VS_CONSTS
*vs_consts
;
542 assert(motion_vectors
);
547 /* TODO: Implement interlaced rendering */
548 if (picture_type
!= VL_FRAME_PICTURE
)
550 /* TODO: Implement other MC types */
551 if (mc_type
!= VL_FRAME_MC
&& mc_type
!= VL_FIELD_MC
)
554 vlGrabBlocks(surface
->context
, coded_block_pattern
, dct_type
, VL_DIFFERENCE_SAMPLE
, blocks
);
556 pipe
= surface
->context
->pipe
;
558 vs_consts
= pipe
->winsys
->buffer_map
561 surface
->context
->states
.mc
.vs_const_buf
.buffer
,
562 PIPE_BUFFER_USAGE_CPU_WRITE
565 vs_consts
->scale
.x
= VL_MACROBLOCK_WIDTH
/ (float)surface
->width
;
566 vs_consts
->scale
.y
= VL_MACROBLOCK_HEIGHT
/ (float)surface
->height
;
567 vs_consts
->scale
.z
= 1.0f
;
568 vs_consts
->scale
.w
= 1.0f
;
569 vs_consts
->mb_pos_trans
.x
= (mbx
* VL_MACROBLOCK_WIDTH
) / (float)surface
->width
;
570 vs_consts
->mb_pos_trans
.y
= (mby
* VL_MACROBLOCK_HEIGHT
) / (float)surface
->height
;
571 vs_consts
->mb_pos_trans
.z
= 0.0f
;
572 vs_consts
->mb_pos_trans
.w
= 0.0f
;
573 vs_consts
->mb_tc_trans
[0].top_field
.x
= (mbx
* VL_MACROBLOCK_WIDTH
+ motion_vector
[0].top_field
.x
* 0.5f
) / (float)surface
->width
;
574 vs_consts
->mb_tc_trans
[0].top_field
.y
= (mby
* VL_MACROBLOCK_HEIGHT
+ motion_vector
[0].top_field
.y
* 0.5f
) / (float)surface
->height
;
575 vs_consts
->mb_tc_trans
[0].top_field
.z
= 0.0f
;
576 vs_consts
->mb_tc_trans
[0].top_field
.w
= 0.0f
;
577 vs_consts
->mb_tc_trans
[1].top_field
.x
= (mbx
* VL_MACROBLOCK_WIDTH
+ motion_vector
[1].top_field
.x
* 0.5f
) / (float)surface
->width
;
578 vs_consts
->mb_tc_trans
[1].top_field
.y
= (mby
* VL_MACROBLOCK_HEIGHT
+ motion_vector
[1].top_field
.y
* 0.5f
) / (float)surface
->height
;
579 vs_consts
->mb_tc_trans
[1].top_field
.z
= 0.0f
;
580 vs_consts
->mb_tc_trans
[1].top_field
.w
= 0.0f
;
582 if (mc_type
== VL_FIELD_MC
)
584 vs_consts
->denorm
.x
= (float)surface
->width
;
585 vs_consts
->denorm
.y
= (float)surface
->height
;
587 vs_consts
->mb_tc_trans
[0].bottom_field
.x
= (mbx
* VL_MACROBLOCK_WIDTH
+ motion_vector
[0].bottom_field
.x
* 0.5f
) / (float)surface
->width
;
588 vs_consts
->mb_tc_trans
[0].bottom_field
.y
= (mby
* VL_MACROBLOCK_HEIGHT
+ motion_vector
[0].bottom_field
.y
* 0.5f
) / (float)surface
->height
;
589 vs_consts
->mb_tc_trans
[0].bottom_field
.z
= 0.0f
;
590 vs_consts
->mb_tc_trans
[0].bottom_field
.w
= 0.0f
;
591 vs_consts
->mb_tc_trans
[1].bottom_field
.x
= (mbx
* VL_MACROBLOCK_WIDTH
+ motion_vector
[1].bottom_field
.x
* 0.5f
) / (float)surface
->width
;
592 vs_consts
->mb_tc_trans
[1].bottom_field
.y
= (mby
* VL_MACROBLOCK_HEIGHT
+ motion_vector
[1].bottom_field
.y
* 0.5f
) / (float)surface
->height
;
593 vs_consts
->mb_tc_trans
[1].bottom_field
.z
= 0.0f
;
594 vs_consts
->mb_tc_trans
[1].bottom_field
.w
= 0.0f
;
596 pipe
->bind_vs_state(pipe
, surface
->context
->states
.mc
.b_vs
[1]);
597 pipe
->bind_fs_state(pipe
, surface
->context
->states
.mc
.b_fs
[1]);
601 pipe
->bind_vs_state(pipe
, surface
->context
->states
.mc
.b_vs
[0]);
602 pipe
->bind_fs_state(pipe
, surface
->context
->states
.mc
.b_fs
[0]);
605 pipe
->winsys
->buffer_unmap(pipe
->winsys
, surface
->context
->states
.mc
.vs_const_buf
.buffer
);
607 surface
->context
->states
.mc
.render_target
.cbufs
[0] = pipe
->screen
->get_tex_surface
611 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ
| PIPE_BUFFER_USAGE_GPU_WRITE
613 pipe
->set_framebuffer_state(pipe
, &surface
->context
->states
.mc
.render_target
);
615 surface
->context
->states
.mc
.textures
[3] = past_surface
->texture
;
616 surface
->context
->states
.mc
.textures
[4] = future_surface
->texture
;
617 pipe
->set_sampler_textures(pipe
, 5, surface
->context
->states
.mc
.textures
);
618 pipe
->bind_sampler_states(pipe
, 5, (void**)surface
->context
->states
.mc
.samplers
);
620 pipe
->draw_arrays(pipe
, PIPE_PRIM_TRIANGLES
, 0, 24);
627 struct VL_SURFACE
*surface
,
637 enum VL_PICTURE picture_type
640 unsigned int create_fb
= 0;
641 struct pipe_context
*pipe
;
642 struct VL_CSC_VS_CONSTS
*vs_consts
;
646 pipe
= surface
->context
->pipe
;
648 if (!surface
->context
->states
.csc
.framebuffer
.cbufs
[0])
652 surface
->context
->states
.csc
.framebuffer
.width
!= destw
||
653 surface
->context
->states
.csc
.framebuffer
.height
!= desth
656 pipe
->winsys
->surface_release
659 &surface
->context
->states
.csc
.framebuffer
.cbufs
[0]
667 surface
->context
->states
.csc
.viewport
.scale
[0] = destw
;
668 surface
->context
->states
.csc
.viewport
.scale
[1] = desth
;
669 surface
->context
->states
.csc
.viewport
.scale
[2] = 1;
670 surface
->context
->states
.csc
.viewport
.scale
[3] = 1;
671 surface
->context
->states
.csc
.viewport
.translate
[0] = 0;
672 surface
->context
->states
.csc
.viewport
.translate
[1] = 0;
673 surface
->context
->states
.csc
.viewport
.translate
[2] = 0;
674 surface
->context
->states
.csc
.viewport
.translate
[3] = 0;
676 surface
->context
->states
.csc
.framebuffer
.width
= destw
;
677 surface
->context
->states
.csc
.framebuffer
.height
= desth
;
678 surface
->context
->states
.csc
.framebuffer
.cbufs
[0] = pipe
->winsys
->surface_alloc(pipe
->winsys
);
679 pipe
->winsys
->surface_alloc_storage
682 surface
->context
->states
.csc
.framebuffer
.cbufs
[0],
685 PIPE_FORMAT_A8R8G8B8_UNORM
,
686 /* XXX: SoftPipe doesn't change GPU usage to CPU like it does for textures */
687 PIPE_BUFFER_USAGE_CPU_READ
| PIPE_BUFFER_USAGE_CPU_WRITE
,
692 vlEndRender(surface
->context
);
694 vs_consts
= pipe
->winsys
->buffer_map
697 surface
->context
->states
.csc
.vs_const_buf
.buffer
,
698 PIPE_BUFFER_USAGE_CPU_WRITE
701 vs_consts
->src_scale
.x
= srcw
/ (float)surface
->width
;
702 vs_consts
->src_scale
.y
= srch
/ (float)surface
->height
;
703 vs_consts
->src_scale
.z
= 1;
704 vs_consts
->src_scale
.w
= 1;
705 vs_consts
->src_trans
.x
= srcx
/ (float)surface
->width
;
706 vs_consts
->src_trans
.y
= srcy
/ (float)surface
->height
;
707 vs_consts
->src_trans
.z
= 0;
708 vs_consts
->src_trans
.w
= 0;
710 pipe
->winsys
->buffer_unmap(pipe
->winsys
, surface
->context
->states
.csc
.vs_const_buf
.buffer
);
712 pipe
->set_sampler_textures(pipe
, 1, &surface
->texture
);
713 pipe
->draw_arrays(pipe
, PIPE_PRIM_TRIANGLE_STRIP
, 0, 4);
714 pipe
->flush(pipe
, PIPE_FLUSH_RENDER_CACHE
, NULL
);
715 bind_pipe_drawable(pipe
, drawable
);
716 /* TODO: Need to take destx, desty into consideration */
717 pipe
->winsys
->flush_frontbuffer
720 surface
->context
->states
.csc
.framebuffer
.cbufs
[0],
724 vlBeginRender(surface
->context
);