1 /**************************************************************************
3 * Copyright 2009 Younes Manton.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
30 #include <pipe/p_context.h>
32 #include <util/u_sampler.h>
33 #include <util/u_draw.h>
35 #include <tgsi/tgsi_ureg.h>
37 #include "vl_defines.h"
38 #include "vl_vertex_buffers.h"
49 static struct ureg_dst
50 calc_position(struct vl_mc
*r
, struct ureg_program
*shader
)
52 struct ureg_src block_scale
;
53 struct ureg_src vrect
, vpos
;
54 struct ureg_dst t_vpos
;
55 struct ureg_dst o_vpos
;
57 vrect
= ureg_DECL_vs_input(shader
, VS_I_RECT
);
58 vpos
= ureg_DECL_vs_input(shader
, VS_I_VPOS
);
60 t_vpos
= ureg_DECL_temporary(shader
);
62 o_vpos
= ureg_DECL_output(shader
, TGSI_SEMANTIC_POSITION
, VS_O_VPOS
);
65 * block_scale = (MACROBLOCK_WIDTH, MACROBLOCK_HEIGHT) / (dst.width, dst.height)
67 * t_vpos = (vpos + vrect) * block_scale
71 block_scale
= ureg_imm2f(shader
,
72 (float)MACROBLOCK_WIDTH
/ r
->buffer_width
,
73 (float)MACROBLOCK_HEIGHT
/ r
->buffer_height
);
75 ureg_ADD(shader
, ureg_writemask(t_vpos
, TGSI_WRITEMASK_XY
), vpos
, vrect
);
76 ureg_MUL(shader
, ureg_writemask(t_vpos
, TGSI_WRITEMASK_XY
), ureg_src(t_vpos
), block_scale
);
77 ureg_MOV(shader
, ureg_writemask(o_vpos
, TGSI_WRITEMASK_XY
), ureg_src(t_vpos
));
78 ureg_MOV(shader
, ureg_writemask(o_vpos
, TGSI_WRITEMASK_ZW
), vpos
);
84 create_ycbcr_vert_shader(struct vl_mc
*r
)
86 struct ureg_program
*shader
;
87 struct ureg_src block_scale
;
88 struct ureg_src vrect
, vpos
, eb
, flags
;
89 struct ureg_dst t_vpos
, t_vtex
;
90 struct ureg_dst o_line
, o_vtex
[2];
93 shader
= ureg_create(TGSI_PROCESSOR_VERTEX
);
97 vrect
= ureg_DECL_vs_input(shader
, VS_I_RECT
);
98 vpos
= ureg_DECL_vs_input(shader
, VS_I_VPOS
);
99 eb
= ureg_DECL_vs_input(shader
, VS_I_EB
);
100 flags
= ureg_DECL_vs_input(shader
, VS_I_FLAGS
);
102 t_vpos
= calc_position(r
, shader
);
103 t_vtex
= ureg_DECL_temporary(shader
);
105 o_line
= ureg_DECL_output(shader
, TGSI_SEMANTIC_GENERIC
, VS_O_LINE
);
106 o_vtex
[0] = ureg_DECL_output(shader
, TGSI_SEMANTIC_GENERIC
, VS_O_VTOP
);
107 o_vtex
[1] = ureg_DECL_output(shader
, TGSI_SEMANTIC_GENERIC
, VS_O_VBOTTOM
);
110 * block_scale = (MACROBLOCK_WIDTH, MACROBLOCK_HEIGHT) / (dst.width, dst.height)
112 * o_line.x = interlaced
115 * o_vtex[0].z = vrect.x ? eb.y : eb.x
116 * o_vtex[1].z = vrect.x ? eb.w : eb.z
120 * t_vtex.y = vrect.y * 0.5
123 * o_vtex[0].xy = t_vtex * block_scale
126 * o_vtex[1].xy = t_vtex * block_scale
128 * o_vtex[0..1].xy = t_vpos
130 * o_vtex[2].xy = t_vpos
133 block_scale
= ureg_imm2f(shader
,
134 (float)MACROBLOCK_WIDTH
/ r
->buffer_width
,
135 (float)MACROBLOCK_HEIGHT
/ r
->buffer_height
);
137 ureg_MUL(shader
, ureg_writemask(o_line
, TGSI_WRITEMASK_X
), flags
, ureg_imm1f(shader
, 0.5f
));
138 ureg_MOV(shader
, ureg_writemask(o_line
, TGSI_WRITEMASK_Y
), vrect
);
140 ureg_MOV(shader
, ureg_writemask(o_vtex
[0], TGSI_WRITEMASK_XY
), ureg_src(t_vpos
));
141 ureg_CMP(shader
, ureg_writemask(o_vtex
[0], TGSI_WRITEMASK_Z
),
142 ureg_negate(ureg_scalar(vrect
, TGSI_SWIZZLE_X
)),
143 ureg_scalar(eb
, TGSI_SWIZZLE_Y
),
144 ureg_scalar(eb
, TGSI_SWIZZLE_X
));
146 ureg_MOV(shader
, ureg_writemask(o_vtex
[1], TGSI_WRITEMASK_XY
), ureg_src(t_vpos
));
147 ureg_CMP(shader
, ureg_writemask(o_vtex
[1], TGSI_WRITEMASK_Z
),
148 ureg_negate(ureg_scalar(vrect
, TGSI_SWIZZLE_X
)),
149 ureg_scalar(eb
, TGSI_SWIZZLE_W
),
150 ureg_scalar(eb
, TGSI_SWIZZLE_Z
));
152 if (r
->macroblock_size
== MACROBLOCK_HEIGHT
) { //TODO
153 ureg_IF(shader
, ureg_scalar(flags
, TGSI_SWIZZLE_Y
), &label
);
155 ureg_MOV(shader
, ureg_writemask(t_vtex
, TGSI_WRITEMASK_X
), vrect
);
156 ureg_MUL(shader
, ureg_writemask(t_vtex
, TGSI_WRITEMASK_Y
), vrect
, ureg_imm1f(shader
, 0.5f
));
157 ureg_ADD(shader
, ureg_writemask(t_vtex
, TGSI_WRITEMASK_XY
), vpos
, ureg_src(t_vtex
));
158 ureg_MUL(shader
, ureg_writemask(o_vtex
[0], TGSI_WRITEMASK_XY
), ureg_src(t_vtex
), block_scale
);
159 ureg_ADD(shader
, ureg_writemask(t_vtex
, TGSI_WRITEMASK_Y
), ureg_src(t_vtex
), ureg_imm1f(shader
, 0.5f
));
160 ureg_MUL(shader
, ureg_writemask(o_vtex
[1], TGSI_WRITEMASK_XY
), ureg_src(t_vtex
), block_scale
);
162 ureg_MUL(shader
, ureg_writemask(o_line
, TGSI_WRITEMASK_Y
),
163 ureg_scalar(vrect
, TGSI_SWIZZLE_Y
),
164 ureg_imm1f(shader
, MACROBLOCK_HEIGHT
/ 2));
166 ureg_fixup_label(shader
, label
, ureg_get_instruction_number(shader
));
170 ureg_release_temporary(shader
, t_vtex
);
171 ureg_release_temporary(shader
, t_vpos
);
175 return ureg_create_shader_and_destroy(shader
, r
->pipe
);
179 create_ref_vert_shader(struct vl_mc
*r
)
181 struct ureg_program
*shader
;
182 struct ureg_src mv_scale
;
183 struct ureg_src vrect
, vmv
[2];
184 struct ureg_dst t_vpos
;
185 struct ureg_dst o_vpos
, o_line
, o_vmv
[2];
188 shader
= ureg_create(TGSI_PROCESSOR_VERTEX
);
192 vrect
= ureg_DECL_vs_input(shader
, VS_I_RECT
);
193 ureg_DECL_vs_input(shader
, VS_I_EB
);
194 ureg_DECL_vs_input(shader
, VS_I_FLAGS
);
195 vmv
[0] = ureg_DECL_vs_input(shader
, VS_I_MV_TOP
);
196 vmv
[1] = ureg_DECL_vs_input(shader
, VS_I_MV_BOTTOM
);
198 t_vpos
= calc_position(r
, shader
);
200 o_vpos
= ureg_DECL_output(shader
, TGSI_SEMANTIC_POSITION
, VS_O_VPOS
);
201 o_line
= ureg_DECL_output(shader
, TGSI_SEMANTIC_GENERIC
, VS_O_LINE
);
202 o_vmv
[0] = ureg_DECL_output(shader
, TGSI_SEMANTIC_GENERIC
, VS_O_VTOP
);
203 o_vmv
[1] = ureg_DECL_output(shader
, TGSI_SEMANTIC_GENERIC
, VS_O_VBOTTOM
);
206 * mv_scale = 0.5 / (dst.width, dst.height);
208 * // Apply motion vectors
209 * o_vmv[0..3] = t_vpos + vmv[0..3] * mv_scale
215 ureg_MUL(shader
, ureg_writemask(o_line
, TGSI_WRITEMASK_Y
),
216 vrect
, ureg_imm1f(shader
, r
->macroblock_size
/ 2));
218 mv_scale
= ureg_imm4f(shader
,
219 0.5f
/ r
->buffer_width
,
220 0.5f
/ r
->buffer_height
,
224 for (i
= 0; i
< 2; ++i
) {
225 ureg_MAD(shader
, ureg_writemask(o_vmv
[i
], TGSI_WRITEMASK_XY
), mv_scale
, vmv
[i
], ureg_src(t_vpos
));
226 ureg_MUL(shader
, ureg_writemask(o_vmv
[i
], TGSI_WRITEMASK_ZW
), mv_scale
, vmv
[i
]);
229 ureg_release_temporary(shader
, t_vpos
);
233 return ureg_create_shader_and_destroy(shader
, r
->pipe
);
236 static struct ureg_dst
237 calc_field(struct ureg_program
*shader
)
240 struct ureg_src line
;
242 tmp
= ureg_DECL_temporary(shader
);
244 line
= ureg_DECL_fs_input(shader
, TGSI_SEMANTIC_GENERIC
, VS_O_LINE
, TGSI_INTERPOLATE_LINEAR
);
247 * line.x is flag for intra frames
248 * line.y going from 0 to 1 if not interlaced
249 * line.y going from 0 to 8 in steps of 0.5 if interlaced
251 * tmp.xy = fraction(line)
252 * tmp.xy = tmp.xy >= 0.5 ? 1 : 0
254 ureg_MOV(shader
, ureg_writemask(tmp
, TGSI_WRITEMASK_X
), line
);
255 ureg_FRC(shader
, ureg_writemask(tmp
, TGSI_WRITEMASK_Y
), line
);
256 ureg_SGE(shader
, ureg_writemask(tmp
, TGSI_WRITEMASK_Y
), ureg_src(tmp
), ureg_imm1f(shader
, 0.5f
));
262 create_ycbcr_frag_shader(struct vl_mc
*r
, float scale
)
264 struct ureg_program
*shader
;
265 struct ureg_src tc
[2], sampler
;
266 struct ureg_dst texel
, t_tc
, field
;
267 struct ureg_dst fragment
;
270 shader
= ureg_create(TGSI_PROCESSOR_FRAGMENT
);
274 tc
[0] = ureg_DECL_fs_input(shader
, TGSI_SEMANTIC_GENERIC
, VS_O_VTOP
, TGSI_INTERPOLATE_LINEAR
);
275 tc
[1] = ureg_DECL_fs_input(shader
, TGSI_SEMANTIC_GENERIC
, VS_O_VBOTTOM
, TGSI_INTERPOLATE_LINEAR
);
277 sampler
= ureg_DECL_sampler(shader
, 0);
279 t_tc
= ureg_DECL_temporary(shader
);
280 texel
= ureg_DECL_temporary(shader
);
282 fragment
= ureg_DECL_output(shader
, TGSI_SEMANTIC_COLOR
, 0);
284 field
= calc_field(shader
);
287 * texel.y = tex(field.y ? tc[1] : tc[0], sampler[0])
288 * texel.cb = tex(tc[2], sampler[1])
289 * texel.cr = tex(tc[2], sampler[2])
292 ureg_CMP(shader
, ureg_writemask(t_tc
, TGSI_WRITEMASK_XYZ
),
293 ureg_negate(ureg_scalar(ureg_src(field
), TGSI_SWIZZLE_Y
)),
296 ureg_SLT(shader
, ureg_writemask(t_tc
, TGSI_WRITEMASK_Z
), ureg_src(t_tc
), ureg_imm1f(shader
, 0.5f
));
298 ureg_MOV(shader
, fragment
, ureg_imm4f(shader
, 0.0f
, 0.0f
, 0.0f
, 1.0f
));
299 ureg_IF(shader
, ureg_scalar(ureg_src(t_tc
), TGSI_SWIZZLE_Z
), &label
);
301 ureg_TEX(shader
, texel
, TGSI_TEXTURE_3D
, ureg_src(t_tc
), sampler
);
304 ureg_MAD(shader
, ureg_writemask(fragment
, TGSI_WRITEMASK_XYZ
),
305 ureg_src(texel
), ureg_imm1f(shader
, scale
),
306 ureg_scalar(ureg_src(field
), TGSI_SWIZZLE_X
));
308 ureg_ADD(shader
, ureg_writemask(fragment
, TGSI_WRITEMASK_XYZ
),
309 ureg_src(texel
), ureg_scalar(ureg_src(field
), TGSI_SWIZZLE_X
));
311 ureg_fixup_label(shader
, label
, ureg_get_instruction_number(shader
));
314 ureg_release_temporary(shader
, t_tc
);
315 ureg_release_temporary(shader
, texel
);
317 return ureg_create_shader_and_destroy(shader
, r
->pipe
);
321 create_ref_frag_shader(struct vl_mc
*r
)
323 const float y_scale
=
324 r
->buffer_height
/ 2 *
325 r
->macroblock_size
/ MACROBLOCK_HEIGHT
;
327 struct ureg_program
*shader
;
328 struct ureg_src tc
[2], sampler
;
329 struct ureg_dst ref
, field
;
330 struct ureg_dst fragment
;
333 shader
= ureg_create(TGSI_PROCESSOR_FRAGMENT
);
337 tc
[0] = ureg_DECL_fs_input(shader
, TGSI_SEMANTIC_GENERIC
, VS_O_VTOP
, TGSI_INTERPOLATE_LINEAR
);
338 tc
[1] = ureg_DECL_fs_input(shader
, TGSI_SEMANTIC_GENERIC
, VS_O_VBOTTOM
, TGSI_INTERPOLATE_LINEAR
);
340 sampler
= ureg_DECL_sampler(shader
, 0);
341 ref
= ureg_DECL_temporary(shader
);
343 fragment
= ureg_DECL_output(shader
, TGSI_SEMANTIC_COLOR
, 0);
345 field
= calc_field(shader
);
348 * ref = field.z ? tc[1] : tc[0]
350 * // Adjust tc acording to top/bottom field selection
353 * ref.y = floor(ref.y)
357 * fragment.xyz = tex(ref, sampler[0])
359 ureg_CMP(shader
, ureg_writemask(ref
, TGSI_WRITEMASK_XYZ
),
360 ureg_negate(ureg_scalar(ureg_src(field
), TGSI_SWIZZLE_Y
)),
362 ureg_CMP(shader
, ureg_writemask(fragment
, TGSI_WRITEMASK_W
),
363 ureg_negate(ureg_scalar(ureg_src(field
), TGSI_SWIZZLE_Y
)),
366 ureg_IF(shader
, ureg_scalar(ureg_src(ref
), TGSI_SWIZZLE_Z
), &label
);
368 ureg_MUL(shader
, ureg_writemask(ref
, TGSI_WRITEMASK_Y
),
369 ureg_src(ref
), ureg_imm1f(shader
, y_scale
));
370 ureg_FLR(shader
, ureg_writemask(ref
, TGSI_WRITEMASK_Y
), ureg_src(ref
));
371 ureg_ADD(shader
, ureg_writemask(ref
, TGSI_WRITEMASK_Y
),
372 ureg_src(ref
), ureg_scalar(ureg_src(ref
), TGSI_SWIZZLE_Z
));
373 ureg_MUL(shader
, ureg_writemask(ref
, TGSI_WRITEMASK_Y
),
374 ureg_src(ref
), ureg_imm1f(shader
, 1.0f
/ y_scale
));
376 ureg_fixup_label(shader
, label
, ureg_get_instruction_number(shader
));
379 ureg_TEX(shader
, ureg_writemask(fragment
, TGSI_WRITEMASK_XYZ
), TGSI_TEXTURE_2D
, ureg_src(ref
), sampler
);
381 ureg_release_temporary(shader
, ref
);
383 ureg_release_temporary(shader
, field
);
386 return ureg_create_shader_and_destroy(shader
, r
->pipe
);
390 init_pipe_state(struct vl_mc
*r
)
392 struct pipe_sampler_state sampler
;
393 struct pipe_blend_state blend
;
394 struct pipe_rasterizer_state rs_state
;
398 memset(&sampler
, 0, sizeof(sampler
));
399 sampler
.wrap_s
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
400 sampler
.wrap_t
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
401 sampler
.wrap_r
= PIPE_TEX_WRAP_CLAMP_TO_BORDER
;
402 sampler
.min_img_filter
= PIPE_TEX_FILTER_LINEAR
;
403 sampler
.min_mip_filter
= PIPE_TEX_MIPFILTER_NONE
;
404 sampler
.mag_img_filter
= PIPE_TEX_FILTER_LINEAR
;
405 sampler
.compare_mode
= PIPE_TEX_COMPARE_NONE
;
406 sampler
.compare_func
= PIPE_FUNC_ALWAYS
;
407 sampler
.normalized_coords
= 1;
408 r
->sampler_ref
= r
->pipe
->create_sampler_state(r
->pipe
, &sampler
);
410 goto error_sampler_ref
;
412 sampler
.min_img_filter
= PIPE_TEX_FILTER_NEAREST
;
413 sampler
.mag_img_filter
= PIPE_TEX_FILTER_NEAREST
;
414 r
->sampler_ycbcr
= r
->pipe
->create_sampler_state(r
->pipe
, &sampler
);
415 if (!r
->sampler_ycbcr
)
416 goto error_sampler_ycbcr
;
418 memset(&blend
, 0, sizeof blend
);
419 blend
.independent_blend_enable
= 0;
420 blend
.rt
[0].blend_enable
= 1;
421 blend
.rt
[0].rgb_func
= PIPE_BLEND_ADD
;
422 blend
.rt
[0].rgb_src_factor
= PIPE_BLENDFACTOR_SRC_ALPHA
;
423 blend
.rt
[0].rgb_dst_factor
= PIPE_BLENDFACTOR_ZERO
;
424 blend
.rt
[0].alpha_func
= PIPE_BLEND_ADD
;
425 blend
.rt
[0].alpha_src_factor
= PIPE_BLENDFACTOR_SRC_ALPHA
;
426 blend
.rt
[0].alpha_dst_factor
= PIPE_BLENDFACTOR_ZERO
;
427 blend
.logicop_enable
= 0;
428 blend
.logicop_func
= PIPE_LOGICOP_CLEAR
;
429 blend
.rt
[0].colormask
= PIPE_MASK_RGBA
;
431 r
->blend_clear
= r
->pipe
->create_blend_state(r
->pipe
, &blend
);
433 goto error_blend_clear
;
435 blend
.rt
[0].rgb_dst_factor
= PIPE_BLENDFACTOR_ONE
;
436 blend
.rt
[0].alpha_dst_factor
= PIPE_BLENDFACTOR_ONE
;
437 r
->blend_add
= r
->pipe
->create_blend_state(r
->pipe
, &blend
);
439 goto error_blend_add
;
441 memset(&rs_state
, 0, sizeof(rs_state
));
442 /*rs_state.sprite_coord_enable */
443 rs_state
.sprite_coord_mode
= PIPE_SPRITE_COORD_UPPER_LEFT
;
444 rs_state
.point_quad_rasterization
= true;
445 rs_state
.point_size
= BLOCK_WIDTH
;
446 rs_state
.gl_rasterization_rules
= true;
447 r
->rs_state
= r
->pipe
->create_rasterizer_state(r
->pipe
, &rs_state
);
454 r
->pipe
->delete_blend_state(r
->pipe
, r
->blend_add
);
457 r
->pipe
->delete_blend_state(r
->pipe
, r
->blend_clear
);
460 r
->pipe
->delete_sampler_state(r
->pipe
, r
->sampler_ref
);
463 r
->pipe
->delete_sampler_state(r
->pipe
, r
->sampler_ycbcr
);
470 cleanup_pipe_state(struct vl_mc
*r
)
474 r
->pipe
->delete_sampler_state(r
->pipe
, r
->sampler_ref
);
475 r
->pipe
->delete_sampler_state(r
->pipe
, r
->sampler_ycbcr
);
476 r
->pipe
->delete_blend_state(r
->pipe
, r
->blend_clear
);
477 r
->pipe
->delete_blend_state(r
->pipe
, r
->blend_add
);
478 r
->pipe
->delete_rasterizer_state(r
->pipe
, r
->rs_state
);
482 vl_mc_init(struct vl_mc
*renderer
, struct pipe_context
*pipe
,
483 unsigned buffer_width
, unsigned buffer_height
,
484 unsigned macroblock_size
, float scale
)
489 memset(renderer
, 0, sizeof(struct vl_mc
));
491 renderer
->pipe
= pipe
;
492 renderer
->buffer_width
= buffer_width
;
493 renderer
->buffer_height
= buffer_height
;
494 renderer
->macroblock_size
= macroblock_size
;
496 if (!init_pipe_state(renderer
))
497 goto error_pipe_state
;
499 renderer
->vs_ref
= create_ref_vert_shader(renderer
);
500 if (!renderer
->vs_ref
)
503 renderer
->vs_ycbcr
= create_ycbcr_vert_shader(renderer
);
504 if (!renderer
->vs_ycbcr
)
507 renderer
->fs_ref
= create_ref_frag_shader(renderer
);
508 if (!renderer
->fs_ref
)
511 renderer
->fs_ycbcr
= create_ycbcr_frag_shader(renderer
, scale
);
512 if (!renderer
->fs_ycbcr
)
518 renderer
->pipe
->delete_fs_state(renderer
->pipe
, renderer
->fs_ref
);
521 renderer
->pipe
->delete_vs_state(renderer
->pipe
, renderer
->vs_ycbcr
);
524 renderer
->pipe
->delete_vs_state(renderer
->pipe
, renderer
->vs_ref
);
527 cleanup_pipe_state(renderer
);
534 vl_mc_cleanup(struct vl_mc
*renderer
)
538 cleanup_pipe_state(renderer
);
540 renderer
->pipe
->delete_vs_state(renderer
->pipe
, renderer
->vs_ref
);
541 renderer
->pipe
->delete_vs_state(renderer
->pipe
, renderer
->vs_ycbcr
);
542 renderer
->pipe
->delete_fs_state(renderer
->pipe
, renderer
->fs_ref
);
543 renderer
->pipe
->delete_fs_state(renderer
->pipe
, renderer
->fs_ycbcr
);
547 vl_mc_init_buffer(struct vl_mc
*renderer
, struct vl_mc_buffer
*buffer
,
548 struct pipe_sampler_view
*source
)
550 assert(renderer
&& buffer
);
553 buffer
->renderer
= renderer
;
555 buffer
->viewport
.scale
[2] = 1;
556 buffer
->viewport
.scale
[3] = 1;
557 buffer
->viewport
.translate
[0] = 0;
558 buffer
->viewport
.translate
[1] = 0;
559 buffer
->viewport
.translate
[2] = 0;
560 buffer
->viewport
.translate
[3] = 0;
562 buffer
->fb_state
.nr_cbufs
= 1;
563 buffer
->fb_state
.zsbuf
= NULL
;
565 pipe_sampler_view_reference(&buffer
->source
, source
);
571 vl_mc_cleanup_buffer(struct vl_mc_buffer
*buffer
)
575 pipe_sampler_view_reference(&buffer
->source
, NULL
);
579 vl_mc_set_surface(struct vl_mc_buffer
*buffer
, struct pipe_surface
*surface
)
581 assert(buffer
&& surface
);
583 buffer
->surface_cleared
= false;
585 buffer
->viewport
.scale
[0] = surface
->width
;
586 buffer
->viewport
.scale
[1] = surface
->height
;
588 buffer
->fb_state
.width
= surface
->width
;
589 buffer
->fb_state
.height
= surface
->height
;
590 buffer
->fb_state
.cbufs
[0] = surface
;
594 prepare_pipe_4_rendering(struct vl_mc_buffer
*buffer
)
596 struct vl_mc
*renderer
;
600 renderer
= buffer
->renderer
;
601 renderer
->pipe
->bind_rasterizer_state(renderer
->pipe
, renderer
->rs_state
);
603 if (buffer
->surface_cleared
)
604 renderer
->pipe
->bind_blend_state(renderer
->pipe
, renderer
->blend_add
);
606 renderer
->pipe
->bind_blend_state(renderer
->pipe
, renderer
->blend_clear
);
607 buffer
->surface_cleared
= true;
610 renderer
->pipe
->set_framebuffer_state(renderer
->pipe
, &buffer
->fb_state
);
611 renderer
->pipe
->set_viewport_state(renderer
->pipe
, &buffer
->viewport
);
615 vl_mc_render_ref(struct vl_mc_buffer
*buffer
, struct pipe_sampler_view
*ref
)
617 struct vl_mc
*renderer
;
619 assert(buffer
&& ref
);
621 prepare_pipe_4_rendering(buffer
);
623 renderer
= buffer
->renderer
;
625 renderer
->pipe
->bind_vs_state(renderer
->pipe
, renderer
->vs_ref
);
626 renderer
->pipe
->bind_fs_state(renderer
->pipe
, renderer
->fs_ref
);
628 renderer
->pipe
->set_fragment_sampler_views(renderer
->pipe
, 1, &ref
);
629 renderer
->pipe
->bind_fragment_sampler_states(renderer
->pipe
, 1, &renderer
->sampler_ref
);
631 util_draw_arrays_instanced(renderer
->pipe
, PIPE_PRIM_QUADS
, 0, 4, 0,
632 renderer
->buffer_width
/ MACROBLOCK_WIDTH
*
633 renderer
->buffer_height
/ MACROBLOCK_HEIGHT
);
637 vl_mc_render_ycbcr(struct vl_mc_buffer
*buffer
, unsigned num_instances
)
639 struct vl_mc
*renderer
;
643 if (num_instances
== 0)
646 prepare_pipe_4_rendering(buffer
);
648 renderer
= buffer
->renderer
;
650 renderer
->pipe
->bind_vs_state(renderer
->pipe
, renderer
->vs_ycbcr
);
651 renderer
->pipe
->bind_fs_state(renderer
->pipe
, renderer
->fs_ycbcr
);
653 renderer
->pipe
->set_fragment_sampler_views(renderer
->pipe
, 1, &buffer
->source
);
654 renderer
->pipe
->bind_fragment_sampler_states(renderer
->pipe
, 1, &renderer
->sampler_ycbcr
);
656 util_draw_arrays_instanced(renderer
->pipe
, PIPE_PRIM_QUADS
, 0, 4, 0, num_instances
);