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"
16 static int vlTransformBlock(short *src
, short *dst
, short bias
)
18 static const float basis
[8][8] =
20 {0.3536, 0.4904, 0.4619, 0.4157, 0.3536, 0.2778, 0.1913, 0.0975},
21 {0.3536, 0.4157, 0.1913, -0.0975, -0.3536, -0.4904, -0.4619, -0.2778},
22 {0.3536, 0.2778, -0.1913, -0.4904, -0.3536, 0.0975, 0.4619, 0.4157},
23 {0.3536, 0.0975, -0.4619, -0.2778, 0.3536, 0.4157, -0.1913, -0.4904},
24 {0.3536, -0.0975, -0.4619, 0.2778, 0.3536, -0.4157, -0.1913, 0.4904},
25 {0.3536, -0.2778, -0.1913, 0.4904, -0.3536, -0.0975, 0.4619, -0.4157},
26 {0.3536, -0.4157, 0.1913, 0.0975, -0.3536, 0.4904, -0.4619, 0.2778},
27 {0.3536, -0.4904, 0.4619, -0.4157, 0.3536, -0.2778, 0.1913, -0.0975}
33 for (y
= 0; y
< VL_BLOCK_HEIGHT
; ++y
)
34 for (x
= 0; x
< VL_BLOCK_WIDTH
; ++x
)
35 tmp
[y
* VL_BLOCK_WIDTH
+ x
] = (short)
37 src
[y
* VL_BLOCK_WIDTH
+ 0] * basis
[x
][0] +
38 src
[y
* VL_BLOCK_WIDTH
+ 1] * basis
[x
][1] +
39 src
[y
* VL_BLOCK_WIDTH
+ 2] * basis
[x
][2] +
40 src
[y
* VL_BLOCK_WIDTH
+ 3] * basis
[x
][3] +
41 src
[y
* VL_BLOCK_WIDTH
+ 4] * basis
[x
][4] +
42 src
[y
* VL_BLOCK_WIDTH
+ 5] * basis
[x
][5] +
43 src
[y
* VL_BLOCK_WIDTH
+ 6] * basis
[x
][6] +
44 src
[y
* VL_BLOCK_WIDTH
+ 7] * basis
[x
][7]
47 for (x
= 0; x
< VL_BLOCK_WIDTH
; ++x
)
48 for (y
= 0; y
< VL_BLOCK_HEIGHT
; ++y
)
50 dst
[y
* VL_BLOCK_WIDTH
+ x
] = bias
+ (short)
52 tmp
[0 * VL_BLOCK_WIDTH
+ x
] * basis
[y
][0] +
53 tmp
[1 * VL_BLOCK_WIDTH
+ x
] * basis
[y
][1] +
54 tmp
[2 * VL_BLOCK_WIDTH
+ x
] * basis
[y
][2] +
55 tmp
[3 * VL_BLOCK_WIDTH
+ x
] * basis
[y
][3] +
56 tmp
[4 * VL_BLOCK_WIDTH
+ x
] * basis
[y
][4] +
57 tmp
[5 * VL_BLOCK_WIDTH
+ x
] * basis
[y
][5] +
58 tmp
[6 * VL_BLOCK_WIDTH
+ x
] * basis
[y
][6] +
59 tmp
[7 * VL_BLOCK_WIDTH
+ x
] * basis
[y
][7]
61 if (dst
[y
* VL_BLOCK_WIDTH
+ x
] > 255)
62 dst
[y
* VL_BLOCK_WIDTH
+ x
] = 255;
63 else if (bias
> 0 && dst
[y
* VL_BLOCK_WIDTH
+ x
] < 0)
64 dst
[y
* VL_BLOCK_WIDTH
+ x
] = 0;
70 static int vlGrabFrameCodedBlock(short *src
, short *dst
, unsigned int dst_pitch
)
74 for (y
= 0; y
< VL_BLOCK_HEIGHT
; ++y
)
78 src
+ y
* VL_BLOCK_WIDTH
,
85 static int vlGrabFieldCodedBlock(short *src
, short *dst
, unsigned int dst_pitch
)
89 for (y
= 0; y
< VL_BLOCK_HEIGHT
/ 2; ++y
)
92 dst
+ y
* dst_pitch
* 2,
93 src
+ y
* VL_BLOCK_WIDTH
,
97 dst
+= VL_BLOCK_HEIGHT
* dst_pitch
;
99 for (; y
< VL_BLOCK_HEIGHT
; ++y
)
102 dst
+ y
* dst_pitch
* 2,
103 src
+ y
* VL_BLOCK_WIDTH
,
110 static int vlGrabNoBlock(short *dst
, unsigned int dst_pitch
)
114 for (y
= 0; y
< VL_BLOCK_HEIGHT
; ++y
)
125 static int vlGrabBlocks
127 struct VL_CONTEXT
*context
,
128 unsigned int coded_block_pattern
,
129 enum VL_DCT_TYPE dct_type
,
130 enum VL_SAMPLE_TYPE sample_type
,
134 struct pipe_surface
*tex_surface
;
136 unsigned int tex_pitch
;
137 unsigned int tb
, sb
= 0;
142 tex_surface
= context
->pipe
->screen
->get_tex_surface
144 context
->pipe
->screen
,
145 context
->states
.mc
.textures
[0],
146 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE
149 texels
= pipe_surface_map(tex_surface
, PIPE_BUFFER_USAGE_CPU_WRITE
);
150 tex_pitch
= tex_surface
->stride
/ tex_surface
->block
.size
;
152 for (tb
= 0; tb
< 4; ++tb
)
154 if ((coded_block_pattern
>> (5 - tb
)) & 1)
156 short *cur_block
= blocks
+ sb
* VL_BLOCK_WIDTH
* VL_BLOCK_HEIGHT
;
159 vlTransformBlock(cur_block
, cur_block
, sample_type
== VL_FULL_SAMPLE
? 128 : 0);
162 if (dct_type
== VL_DCT_FRAME_CODED
)
163 vlGrabFrameCodedBlock
166 texels
+ tb
* tex_pitch
* VL_BLOCK_HEIGHT
,
170 vlGrabFieldCodedBlock
173 texels
+ (tb
% 2) * tex_pitch
* VL_BLOCK_HEIGHT
+ (tb
/ 2) * tex_pitch
,
180 vlGrabNoBlock(texels
+ tb
* tex_pitch
* VL_BLOCK_HEIGHT
, tex_pitch
);
183 pipe_surface_unmap(tex_surface
);
185 /* TODO: Implement 422, 444 */
186 for (tb
= 0; tb
< 2; ++tb
)
188 tex_surface
= context
->pipe
->screen
->get_tex_surface
190 context
->pipe
->screen
,
191 context
->states
.mc
.textures
[tb
+ 1],
192 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE
195 texels
= pipe_surface_map(tex_surface
, PIPE_BUFFER_USAGE_CPU_WRITE
);
196 tex_pitch
= tex_surface
->stride
/ tex_surface
->block
.size
;
198 if ((coded_block_pattern
>> (1 - tb
)) & 1)
200 short *cur_block
= blocks
+ sb
* VL_BLOCK_WIDTH
* VL_BLOCK_HEIGHT
;
203 vlTransformBlock(cur_block
, cur_block
, sample_type
== VL_FULL_SAMPLE
? 128 : 0);
206 vlGrabFrameCodedBlock
216 vlGrabNoBlock(texels
, tex_pitch
);
218 pipe_surface_unmap(tex_surface
);
224 int vlCreateSurface(struct VL_CONTEXT
*context
, struct VL_SURFACE
**surface
)
226 struct pipe_context
*pipe
;
227 struct pipe_texture
template;
228 struct VL_SURFACE
*sfc
;
233 pipe
= context
->pipe
;
235 sfc
= calloc(1, sizeof(struct VL_SURFACE
));
237 sfc
->context
= context
;
238 sfc
->width
= vlRoundUpPOT(context
->video_width
);
239 sfc
->height
= vlRoundUpPOT(context
->video_height
);
240 sfc
->format
= context
->video_format
;
242 memset(&template, 0, sizeof(struct pipe_texture
));
243 template.target
= PIPE_TEXTURE_2D
;
244 template.format
= PIPE_FORMAT_A8R8G8B8_UNORM
;
245 template.last_level
= 0;
246 template.width
[0] = sfc
->width
;
247 template.height
[0] = sfc
->height
;
248 template.depth
[0] = 1;
249 template.compressed
= 0;
250 pf_get_block(template.format
, &template.block
);
252 template.tex_usage
= PIPE_TEXTURE_USAGE_SAMPLER
| PIPE_TEXTURE_USAGE_RENDER_TARGET
;
254 sfc
->texture
= pipe
->screen
->texture_create(pipe
->screen
, &template);
261 int vlDestroySurface(struct VL_SURFACE
*surface
)
264 pipe_texture_release(&surface
->texture
);
270 int vlRenderIMacroBlock
272 enum VL_PICTURE picture_type
,
273 enum VL_FIELD_ORDER field_order
,
276 unsigned int coded_block_pattern
,
277 enum VL_DCT_TYPE dct_type
,
279 struct VL_SURFACE
*surface
282 struct pipe_context
*pipe
;
283 struct VL_MC_VS_CONSTS
*vs_consts
;
288 /* TODO: Implement interlaced rendering */
289 if (picture_type
!= VL_FRAME_PICTURE
)
292 vlGrabBlocks(surface
->context
, coded_block_pattern
, dct_type
, VL_FULL_SAMPLE
, blocks
);
294 pipe
= surface
->context
->pipe
;
296 vs_consts
= pipe
->winsys
->buffer_map
299 surface
->context
->states
.mc
.vs_const_buf
.buffer
,
300 PIPE_BUFFER_USAGE_CPU_WRITE
303 vs_consts
->scale
.x
= VL_MACROBLOCK_WIDTH
/ (float)surface
->width
;
304 vs_consts
->scale
.y
= VL_MACROBLOCK_HEIGHT
/ (float)surface
->height
;
305 vs_consts
->scale
.z
= 1.0f
;
306 vs_consts
->scale
.w
= 1.0f
;
307 vs_consts
->mb_pos_trans
.x
= (mbx
* VL_MACROBLOCK_WIDTH
) / (float)surface
->width
;
308 vs_consts
->mb_pos_trans
.y
= (mby
* VL_MACROBLOCK_HEIGHT
) / (float)surface
->height
;
309 vs_consts
->mb_pos_trans
.z
= 0.0f
;
310 vs_consts
->mb_pos_trans
.w
= 0.0f
;
312 pipe
->winsys
->buffer_unmap(pipe
->winsys
, surface
->context
->states
.mc
.vs_const_buf
.buffer
);
314 surface
->context
->states
.mc
.render_target
.cbufs
[0] = pipe
->screen
->get_tex_surface
318 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ
| PIPE_BUFFER_USAGE_GPU_WRITE
320 pipe
->set_framebuffer_state(pipe
, &surface
->context
->states
.mc
.render_target
);
321 pipe
->set_sampler_textures(pipe
, 3, surface
->context
->states
.mc
.textures
);
322 pipe
->bind_sampler_states(pipe
, 3, (void**)surface
->context
->states
.mc
.samplers
);
323 pipe
->bind_vs_state(pipe
, surface
->context
->states
.mc
.i_vs
);
324 pipe
->bind_fs_state(pipe
, surface
->context
->states
.mc
.i_fs
);
326 pipe
->draw_arrays(pipe
, PIPE_PRIM_TRIANGLES
, 0, 24);
331 int vlRenderPMacroBlock
333 enum VL_PICTURE picture_type
,
334 enum VL_FIELD_ORDER field_order
,
337 enum VL_MC_TYPE mc_type
,
338 struct VL_MOTION_VECTOR
*motion_vector
,
339 unsigned int coded_block_pattern
,
340 enum VL_DCT_TYPE dct_type
,
342 struct VL_SURFACE
*ref_surface
,
343 struct VL_SURFACE
*surface
346 struct pipe_context
*pipe
;
347 struct VL_MC_VS_CONSTS
*vs_consts
;
349 assert(motion_vectors
);
354 /* TODO: Implement interlaced rendering */
355 if (picture_type
!= VL_FRAME_PICTURE
)
357 /* TODO: Implement other MC types */
358 if (mc_type
!= VL_FRAME_MC
&& mc_type
!= VL_FIELD_MC
)
361 vlGrabBlocks(surface
->context
, coded_block_pattern
, dct_type
, VL_DIFFERENCE_SAMPLE
, blocks
);
363 pipe
= surface
->context
->pipe
;
365 vs_consts
= pipe
->winsys
->buffer_map
368 surface
->context
->states
.mc
.vs_const_buf
.buffer
,
369 PIPE_BUFFER_USAGE_CPU_WRITE
372 vs_consts
->scale
.x
= VL_MACROBLOCK_WIDTH
/ (float)surface
->width
;
373 vs_consts
->scale
.y
= VL_MACROBLOCK_HEIGHT
/ (float)surface
->height
;
374 vs_consts
->scale
.z
= 1.0f
;
375 vs_consts
->scale
.w
= 1.0f
;
376 vs_consts
->mb_pos_trans
.x
= (mbx
* VL_MACROBLOCK_WIDTH
) / (float)surface
->width
;
377 vs_consts
->mb_pos_trans
.y
= (mby
* VL_MACROBLOCK_HEIGHT
) / (float)surface
->height
;
378 vs_consts
->mb_pos_trans
.z
= 0.0f
;
379 vs_consts
->mb_pos_trans
.w
= 0.0f
;
380 vs_consts
->mb_tc_trans
[0].top_field
.x
= (mbx
* VL_MACROBLOCK_WIDTH
+ motion_vector
->top_field
.x
* 0.5f
) / (float)surface
->width
;
381 vs_consts
->mb_tc_trans
[0].top_field
.y
= (mby
* VL_MACROBLOCK_HEIGHT
+ motion_vector
->top_field
.y
* 0.5f
) / (float)surface
->height
;
382 vs_consts
->mb_tc_trans
[0].top_field
.z
= 0.0f
;
383 vs_consts
->mb_tc_trans
[0].top_field
.w
= 0.0f
;
385 if (mc_type
== VL_FIELD_MC
)
387 vs_consts
->denorm
.x
= (float)surface
->width
;
388 vs_consts
->denorm
.y
= (float)surface
->height
;
390 vs_consts
->mb_tc_trans
[0].bottom_field
.x
= (mbx
* VL_MACROBLOCK_WIDTH
+ motion_vector
->bottom_field
.x
* 0.5f
) / (float)surface
->width
;
391 vs_consts
->mb_tc_trans
[0].bottom_field
.y
= (mby
* VL_MACROBLOCK_HEIGHT
+ motion_vector
->bottom_field
.y
* 0.5f
) / (float)surface
->height
;
392 vs_consts
->mb_tc_trans
[0].bottom_field
.z
= 0.0f
;
393 vs_consts
->mb_tc_trans
[0].bottom_field
.w
= 0.0f
;
395 pipe
->bind_vs_state(pipe
, surface
->context
->states
.mc
.p_vs
[1]);
396 pipe
->bind_fs_state(pipe
, surface
->context
->states
.mc
.p_fs
[1]);
400 pipe
->bind_vs_state(pipe
, surface
->context
->states
.mc
.p_vs
[0]);
401 pipe
->bind_fs_state(pipe
, surface
->context
->states
.mc
.p_fs
[0]);
404 pipe
->winsys
->buffer_unmap(pipe
->winsys
, surface
->context
->states
.mc
.vs_const_buf
.buffer
);
406 surface
->context
->states
.mc
.render_target
.cbufs
[0] = pipe
->screen
->get_tex_surface
410 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ
| PIPE_BUFFER_USAGE_GPU_WRITE
412 pipe
->set_framebuffer_state(pipe
, &surface
->context
->states
.mc
.render_target
);
414 surface
->context
->states
.mc
.textures
[3] = ref_surface
->texture
;
415 pipe
->set_sampler_textures(pipe
, 4, surface
->context
->states
.mc
.textures
);
416 pipe
->bind_sampler_states(pipe
, 4, (void**)surface
->context
->states
.mc
.samplers
);
418 pipe
->draw_arrays(pipe
, PIPE_PRIM_TRIANGLES
, 0, 24);
423 int vlRenderBMacroBlock
425 enum VL_PICTURE picture_type
,
426 enum VL_FIELD_ORDER field_order
,
429 enum VL_MC_TYPE mc_type
,
430 struct VL_MOTION_VECTOR
*motion_vector
,
431 unsigned int coded_block_pattern
,
432 enum VL_DCT_TYPE dct_type
,
434 struct VL_SURFACE
*past_surface
,
435 struct VL_SURFACE
*future_surface
,
436 struct VL_SURFACE
*surface
439 struct pipe_context
*pipe
;
440 struct VL_MC_VS_CONSTS
*vs_consts
;
442 assert(motion_vectors
);
447 /* TODO: Implement interlaced rendering */
448 if (picture_type
!= VL_FRAME_PICTURE
)
450 /* TODO: Implement other MC types */
451 if (mc_type
!= VL_FRAME_MC
&& mc_type
!= VL_FIELD_MC
)
454 vlGrabBlocks(surface
->context
, coded_block_pattern
, dct_type
, VL_DIFFERENCE_SAMPLE
, blocks
);
456 pipe
= surface
->context
->pipe
;
458 vs_consts
= pipe
->winsys
->buffer_map
461 surface
->context
->states
.mc
.vs_const_buf
.buffer
,
462 PIPE_BUFFER_USAGE_CPU_WRITE
465 vs_consts
->scale
.x
= VL_MACROBLOCK_WIDTH
/ (float)surface
->width
;
466 vs_consts
->scale
.y
= VL_MACROBLOCK_HEIGHT
/ (float)surface
->height
;
467 vs_consts
->scale
.z
= 1.0f
;
468 vs_consts
->scale
.w
= 1.0f
;
469 vs_consts
->mb_pos_trans
.x
= (mbx
* VL_MACROBLOCK_WIDTH
) / (float)surface
->width
;
470 vs_consts
->mb_pos_trans
.y
= (mby
* VL_MACROBLOCK_HEIGHT
) / (float)surface
->height
;
471 vs_consts
->mb_pos_trans
.z
= 0.0f
;
472 vs_consts
->mb_pos_trans
.w
= 0.0f
;
473 vs_consts
->mb_tc_trans
[0].top_field
.x
= (mbx
* VL_MACROBLOCK_WIDTH
+ motion_vector
[0].top_field
.x
* 0.5f
) / (float)surface
->width
;
474 vs_consts
->mb_tc_trans
[0].top_field
.y
= (mby
* VL_MACROBLOCK_HEIGHT
+ motion_vector
[0].top_field
.y
* 0.5f
) / (float)surface
->height
;
475 vs_consts
->mb_tc_trans
[0].top_field
.z
= 0.0f
;
476 vs_consts
->mb_tc_trans
[0].top_field
.w
= 0.0f
;
477 vs_consts
->mb_tc_trans
[1].top_field
.x
= (mbx
* VL_MACROBLOCK_WIDTH
+ motion_vector
[1].top_field
.x
* 0.5f
) / (float)surface
->width
;
478 vs_consts
->mb_tc_trans
[1].top_field
.y
= (mby
* VL_MACROBLOCK_HEIGHT
+ motion_vector
[1].top_field
.y
* 0.5f
) / (float)surface
->height
;
479 vs_consts
->mb_tc_trans
[1].top_field
.z
= 0.0f
;
480 vs_consts
->mb_tc_trans
[1].top_field
.w
= 0.0f
;
482 if (mc_type
== VL_FIELD_MC
)
484 vs_consts
->denorm
.x
= (float)surface
->width
;
485 vs_consts
->denorm
.y
= (float)surface
->height
;
487 vs_consts
->mb_tc_trans
[0].bottom_field
.x
= (mbx
* VL_MACROBLOCK_WIDTH
+ motion_vector
[0].bottom_field
.x
* 0.5f
) / (float)surface
->width
;
488 vs_consts
->mb_tc_trans
[0].bottom_field
.y
= (mby
* VL_MACROBLOCK_HEIGHT
+ motion_vector
[0].bottom_field
.y
* 0.5f
) / (float)surface
->height
;
489 vs_consts
->mb_tc_trans
[0].bottom_field
.z
= 0.0f
;
490 vs_consts
->mb_tc_trans
[0].bottom_field
.w
= 0.0f
;
491 vs_consts
->mb_tc_trans
[1].bottom_field
.x
= (mbx
* VL_MACROBLOCK_WIDTH
+ motion_vector
[1].bottom_field
.x
* 0.5f
) / (float)surface
->width
;
492 vs_consts
->mb_tc_trans
[1].bottom_field
.y
= (mby
* VL_MACROBLOCK_HEIGHT
+ motion_vector
[1].bottom_field
.y
* 0.5f
) / (float)surface
->height
;
493 vs_consts
->mb_tc_trans
[1].bottom_field
.z
= 0.0f
;
494 vs_consts
->mb_tc_trans
[1].bottom_field
.w
= 0.0f
;
496 pipe
->bind_vs_state(pipe
, surface
->context
->states
.mc
.b_vs
[1]);
497 pipe
->bind_fs_state(pipe
, surface
->context
->states
.mc
.b_fs
[1]);
501 pipe
->bind_vs_state(pipe
, surface
->context
->states
.mc
.b_vs
[0]);
502 pipe
->bind_fs_state(pipe
, surface
->context
->states
.mc
.b_fs
[0]);
505 pipe
->winsys
->buffer_unmap(pipe
->winsys
, surface
->context
->states
.mc
.vs_const_buf
.buffer
);
507 surface
->context
->states
.mc
.render_target
.cbufs
[0] = pipe
->screen
->get_tex_surface
511 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ
| PIPE_BUFFER_USAGE_GPU_WRITE
513 pipe
->set_framebuffer_state(pipe
, &surface
->context
->states
.mc
.render_target
);
515 surface
->context
->states
.mc
.textures
[3] = past_surface
->texture
;
516 surface
->context
->states
.mc
.textures
[4] = future_surface
->texture
;
517 pipe
->set_sampler_textures(pipe
, 5, surface
->context
->states
.mc
.textures
);
518 pipe
->bind_sampler_states(pipe
, 5, (void**)surface
->context
->states
.mc
.samplers
);
520 pipe
->draw_arrays(pipe
, PIPE_PRIM_TRIANGLES
, 0, 24);
527 struct VL_SURFACE
*surface
,
537 enum VL_PICTURE picture_type
540 unsigned int create_fb
= 0;
541 struct pipe_context
*pipe
;
542 struct VL_CSC_VS_CONSTS
*vs_consts
;
546 pipe
= surface
->context
->pipe
;
548 if (!surface
->context
->states
.csc
.framebuffer
.cbufs
[0])
552 surface
->context
->states
.csc
.framebuffer
.width
!= destw
||
553 surface
->context
->states
.csc
.framebuffer
.height
!= desth
556 pipe
->winsys
->surface_release
559 &surface
->context
->states
.csc
.framebuffer
.cbufs
[0]
567 surface
->context
->states
.csc
.viewport
.scale
[0] = destw
;
568 surface
->context
->states
.csc
.viewport
.scale
[1] = desth
;
569 surface
->context
->states
.csc
.viewport
.scale
[2] = 1;
570 surface
->context
->states
.csc
.viewport
.scale
[3] = 1;
571 surface
->context
->states
.csc
.viewport
.translate
[0] = 0;
572 surface
->context
->states
.csc
.viewport
.translate
[1] = 0;
573 surface
->context
->states
.csc
.viewport
.translate
[2] = 0;
574 surface
->context
->states
.csc
.viewport
.translate
[3] = 0;
576 surface
->context
->states
.csc
.framebuffer
.width
= destw
;
577 surface
->context
->states
.csc
.framebuffer
.height
= desth
;
578 surface
->context
->states
.csc
.framebuffer
.cbufs
[0] = pipe
->winsys
->surface_alloc(pipe
->winsys
);
579 pipe
->winsys
->surface_alloc_storage
582 surface
->context
->states
.csc
.framebuffer
.cbufs
[0],
585 PIPE_FORMAT_A8R8G8B8_UNORM
,
586 /* XXX: SoftPipe doesn't change GPU usage to CPU like it does for textures */
587 PIPE_BUFFER_USAGE_CPU_READ
| PIPE_BUFFER_USAGE_CPU_WRITE
,
592 vlEndRender(surface
->context
);
594 vs_consts
= pipe
->winsys
->buffer_map
597 surface
->context
->states
.csc
.vs_const_buf
.buffer
,
598 PIPE_BUFFER_USAGE_CPU_WRITE
601 vs_consts
->src_scale
.x
= srcw
/ (float)surface
->width
;
602 vs_consts
->src_scale
.y
= srch
/ (float)surface
->height
;
603 vs_consts
->src_scale
.z
= 1;
604 vs_consts
->src_scale
.w
= 1;
605 vs_consts
->src_trans
.x
= srcx
/ (float)surface
->width
;
606 vs_consts
->src_trans
.y
= srcy
/ (float)surface
->height
;
607 vs_consts
->src_trans
.z
= 0;
608 vs_consts
->src_trans
.w
= 0;
610 pipe
->winsys
->buffer_unmap(pipe
->winsys
, surface
->context
->states
.csc
.vs_const_buf
.buffer
);
612 pipe
->set_sampler_textures(pipe
, 1, &surface
->texture
);
613 pipe
->draw_arrays(pipe
, PIPE_PRIM_TRIANGLE_STRIP
, 0, 4);
614 pipe
->flush(pipe
, PIPE_FLUSH_RENDER_CACHE
, NULL
);
615 bind_pipe_drawable(pipe
, drawable
);
616 /* TODO: Need to take destx, desty into consideration */
617 pipe
->winsys
->flush_frontbuffer
620 surface
->context
->states
.csc
.framebuffer
.cbufs
[0],
624 vlBeginRender(surface
->context
);