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"
48 static struct ureg_dst
49 calc_position(struct vl_mc
*r
, struct ureg_program
*shader
, struct ureg_src block_scale
)
51 struct ureg_src vrect
, vpos
;
52 struct ureg_dst t_vpos
;
53 struct ureg_dst o_vpos
;
55 vrect
= ureg_DECL_vs_input(shader
, VS_I_RECT
);
56 vpos
= ureg_DECL_vs_input(shader
, VS_I_VPOS
);
58 t_vpos
= ureg_DECL_temporary(shader
);
60 o_vpos
= ureg_DECL_output(shader
, TGSI_SEMANTIC_POSITION
, VS_O_VPOS
);
63 * block_scale = (MACROBLOCK_WIDTH, MACROBLOCK_HEIGHT) / (dst.width, dst.height)
65 * t_vpos = (vpos + vrect) * block_scale
69 ureg_ADD(shader
, ureg_writemask(t_vpos
, TGSI_WRITEMASK_XY
), vpos
, vrect
);
70 ureg_MUL(shader
, ureg_writemask(t_vpos
, TGSI_WRITEMASK_XY
), ureg_src(t_vpos
), block_scale
);
71 ureg_MOV(shader
, ureg_writemask(o_vpos
, TGSI_WRITEMASK_XY
), ureg_src(t_vpos
));
72 ureg_MOV(shader
, ureg_writemask(o_vpos
, TGSI_WRITEMASK_ZW
), ureg_imm1f(shader
, 1.0f
));
77 static struct ureg_dst
78 calc_line(struct ureg_program
*shader
)
83 tmp
= ureg_DECL_temporary(shader
);
85 pos
= ureg_DECL_fs_input(shader
, TGSI_SEMANTIC_POSITION
, VS_O_VPOS
, TGSI_INTERPOLATE_LINEAR
);
88 * tmp.y = fraction(pos.y / 2) >= 0.5 ? 1 : 0
90 ureg_MUL(shader
, ureg_writemask(tmp
, TGSI_WRITEMASK_Y
), pos
, ureg_imm1f(shader
, 0.5f
));
91 ureg_FRC(shader
, ureg_writemask(tmp
, TGSI_WRITEMASK_Y
), ureg_src(tmp
));
92 ureg_SGE(shader
, ureg_writemask(tmp
, TGSI_WRITEMASK_Y
), ureg_src(tmp
), ureg_imm1f(shader
, 0.5f
));
98 create_ref_vert_shader(struct vl_mc
*r
)
100 struct ureg_program
*shader
;
101 struct ureg_src mv_scale
;
102 struct ureg_src vrect
, vmv
[2];
103 struct ureg_dst t_vpos
;
104 struct ureg_dst o_vpos
, o_vmv
[2];
107 shader
= ureg_create(TGSI_PROCESSOR_VERTEX
);
111 vrect
= ureg_DECL_vs_input(shader
, VS_I_RECT
);
112 vmv
[0] = ureg_DECL_vs_input(shader
, VS_I_MV_TOP
);
113 vmv
[1] = ureg_DECL_vs_input(shader
, VS_I_MV_BOTTOM
);
115 t_vpos
= calc_position(r
, shader
, ureg_imm2f(shader
,
116 (float)MACROBLOCK_WIDTH
/ r
->buffer_width
,
117 (float)MACROBLOCK_HEIGHT
/ r
->buffer_height
)
120 o_vpos
= ureg_DECL_output(shader
, TGSI_SEMANTIC_POSITION
, VS_O_VPOS
);
121 o_vmv
[0] = ureg_DECL_output(shader
, TGSI_SEMANTIC_GENERIC
, VS_O_VTOP
);
122 o_vmv
[1] = ureg_DECL_output(shader
, TGSI_SEMANTIC_GENERIC
, VS_O_VBOTTOM
);
125 * mv_scale.xy = 0.5 / (dst.width, dst.height);
126 * mv_scale.z = 1.0f / 4.0f
127 * mv_scale.w = 1.0f / 255.0f
129 * // Apply motion vectors
130 * o_vmv[0..1].xy = vmv[0..1] * mv_scale + t_vpos
131 * o_vmv[0..1].zw = vmv[0..1] * mv_scale
135 mv_scale
= ureg_imm4f(shader
,
136 0.5f
/ r
->buffer_width
,
137 0.5f
/ r
->buffer_height
,
139 1.0f
/ PIPE_VIDEO_MV_WEIGHT_MAX
);
141 for (i
= 0; i
< 2; ++i
) {
142 ureg_MAD(shader
, ureg_writemask(o_vmv
[i
], TGSI_WRITEMASK_XY
), mv_scale
, vmv
[i
], ureg_src(t_vpos
));
143 ureg_MUL(shader
, ureg_writemask(o_vmv
[i
], TGSI_WRITEMASK_ZW
), mv_scale
, vmv
[i
]);
146 ureg_release_temporary(shader
, t_vpos
);
150 return ureg_create_shader_and_destroy(shader
, r
->pipe
);
154 create_ref_frag_shader(struct vl_mc
*r
)
156 const float y_scale
=
157 r
->buffer_height
/ 2 *
158 r
->macroblock_size
/ MACROBLOCK_HEIGHT
;
160 struct ureg_program
*shader
;
161 struct ureg_src tc
[2], sampler
;
162 struct ureg_dst ref
, field
;
163 struct ureg_dst fragment
;
166 shader
= ureg_create(TGSI_PROCESSOR_FRAGMENT
);
170 tc
[0] = ureg_DECL_fs_input(shader
, TGSI_SEMANTIC_GENERIC
, VS_O_VTOP
, TGSI_INTERPOLATE_LINEAR
);
171 tc
[1] = ureg_DECL_fs_input(shader
, TGSI_SEMANTIC_GENERIC
, VS_O_VBOTTOM
, TGSI_INTERPOLATE_LINEAR
);
173 sampler
= ureg_DECL_sampler(shader
, 0);
174 ref
= ureg_DECL_temporary(shader
);
176 fragment
= ureg_DECL_output(shader
, TGSI_SEMANTIC_COLOR
, 0);
178 field
= calc_line(shader
);
181 * ref = field.z ? tc[1] : tc[0]
183 * // Adjust tc acording to top/bottom field selection
186 * ref.y = floor(ref.y)
190 * fragment.xyz = tex(ref, sampler[0])
192 ureg_CMP(shader
, ureg_writemask(ref
, TGSI_WRITEMASK_XYZ
),
193 ureg_negate(ureg_scalar(ureg_src(field
), TGSI_SWIZZLE_Y
)),
195 ureg_CMP(shader
, ureg_writemask(fragment
, TGSI_WRITEMASK_W
),
196 ureg_negate(ureg_scalar(ureg_src(field
), TGSI_SWIZZLE_Y
)),
199 ureg_IF(shader
, ureg_scalar(ureg_src(ref
), TGSI_SWIZZLE_Z
), &label
);
201 ureg_MUL(shader
, ureg_writemask(ref
, TGSI_WRITEMASK_Y
),
202 ureg_src(ref
), ureg_imm1f(shader
, y_scale
));
203 ureg_FLR(shader
, ureg_writemask(ref
, TGSI_WRITEMASK_Y
), ureg_src(ref
));
204 ureg_ADD(shader
, ureg_writemask(ref
, TGSI_WRITEMASK_Y
),
205 ureg_src(ref
), ureg_scalar(ureg_src(ref
), TGSI_SWIZZLE_Z
));
206 ureg_MUL(shader
, ureg_writemask(ref
, TGSI_WRITEMASK_Y
),
207 ureg_src(ref
), ureg_imm1f(shader
, 1.0f
/ y_scale
));
209 ureg_fixup_label(shader
, label
, ureg_get_instruction_number(shader
));
212 ureg_TEX(shader
, ureg_writemask(fragment
, TGSI_WRITEMASK_XYZ
), TGSI_TEXTURE_2D
, ureg_src(ref
), sampler
);
214 ureg_release_temporary(shader
, ref
);
216 ureg_release_temporary(shader
, field
);
219 return ureg_create_shader_and_destroy(shader
, r
->pipe
);
223 create_ycbcr_vert_shader(struct vl_mc
*r
)
225 struct ureg_program
*shader
;
227 struct ureg_src vrect
, vpos
;
228 struct ureg_dst t_vpos
, t_vtex
;
229 struct ureg_dst o_vpos
, o_vtex
;
231 struct vertex2f scale
= {
232 (float)BLOCK_WIDTH
/ r
->buffer_width
* MACROBLOCK_WIDTH
/ r
->macroblock_size
,
233 (float)BLOCK_HEIGHT
/ r
->buffer_height
* MACROBLOCK_HEIGHT
/ r
->macroblock_size
238 shader
= ureg_create(TGSI_PROCESSOR_VERTEX
);
242 vrect
= ureg_DECL_vs_input(shader
, VS_I_RECT
);
243 vpos
= ureg_DECL_vs_input(shader
, VS_I_VPOS
);
245 t_vpos
= calc_position(r
, shader
, ureg_imm2f(shader
, scale
.x
, scale
.y
));
246 t_vtex
= ureg_DECL_temporary(shader
);
248 o_vpos
= ureg_DECL_output(shader
, TGSI_SEMANTIC_POSITION
, VS_O_VPOS
);
249 o_vtex
= ureg_DECL_output(shader
, TGSI_SEMANTIC_GENERIC
, VS_O_VTOP
);
253 * o_vtex.z = intra * 0.5
256 * t_vtex.xy = vrect.y ? { 0, scale.y } : { -scale.y : 0 }
257 * t_vtex.z = vpos.y % 2
258 * t_vtex.y = t_vtex.z ? t_vtex.x : t_vtex.y
259 * o_vpos.y = t_vtex.y + t_vpos.y
261 * o_vtex.w = t_vtex.z ? 0 : 1
265 ureg_MOV(shader
, ureg_writemask(o_vtex
, TGSI_WRITEMASK_XY
), ureg_src(t_vpos
));
266 ureg_MUL(shader
, ureg_writemask(o_vtex
, TGSI_WRITEMASK_Z
),
267 ureg_scalar(vpos
, TGSI_SWIZZLE_Z
), ureg_imm1f(shader
, 0.5f
));
268 ureg_MOV(shader
, ureg_writemask(o_vtex
, TGSI_WRITEMASK_W
), ureg_imm1f(shader
, -1.0f
));
270 if (r
->macroblock_size
== MACROBLOCK_HEIGHT
) { //TODO
271 ureg_IF(shader
, ureg_scalar(vpos
, TGSI_SWIZZLE_W
), &label
);
273 ureg_CMP(shader
, ureg_writemask(t_vtex
, TGSI_WRITEMASK_XY
),
274 ureg_negate(ureg_scalar(vrect
, TGSI_SWIZZLE_Y
)),
275 ureg_imm2f(shader
, 0.0f
, scale
.y
),
276 ureg_imm2f(shader
, -scale
.y
, 0.0f
));
277 ureg_MUL(shader
, ureg_writemask(t_vtex
, TGSI_WRITEMASK_Z
),
278 ureg_scalar(vpos
, TGSI_SWIZZLE_Y
), ureg_imm1f(shader
, 0.5f
));
280 ureg_FRC(shader
, ureg_writemask(t_vtex
, TGSI_WRITEMASK_Z
), ureg_src(t_vtex
));
282 ureg_CMP(shader
, ureg_writemask(t_vtex
, TGSI_WRITEMASK_Y
),
283 ureg_negate(ureg_scalar(ureg_src(t_vtex
), TGSI_SWIZZLE_Z
)),
284 ureg_scalar(ureg_src(t_vtex
), TGSI_SWIZZLE_X
),
285 ureg_scalar(ureg_src(t_vtex
), TGSI_SWIZZLE_Y
));
286 ureg_ADD(shader
, ureg_writemask(o_vpos
, TGSI_WRITEMASK_Y
),
287 ureg_src(t_vpos
), ureg_src(t_vtex
));
289 ureg_CMP(shader
, ureg_writemask(o_vtex
, TGSI_WRITEMASK_W
),
290 ureg_negate(ureg_scalar(ureg_src(t_vtex
), TGSI_SWIZZLE_Z
)),
291 ureg_imm1f(shader
, 0.0f
), ureg_imm1f(shader
, 1.0f
));
293 ureg_fixup_label(shader
, label
, ureg_get_instruction_number(shader
));
297 ureg_release_temporary(shader
, t_vtex
);
298 ureg_release_temporary(shader
, t_vpos
);
302 return ureg_create_shader_and_destroy(shader
, r
->pipe
);
306 create_ycbcr_frag_shader(struct vl_mc
*r
, float scale
)
308 struct ureg_program
*shader
;
309 struct ureg_src tc
, sampler
;
311 struct ureg_dst fragment
;
314 shader
= ureg_create(TGSI_PROCESSOR_FRAGMENT
);
318 tc
= ureg_DECL_fs_input(shader
, TGSI_SEMANTIC_GENERIC
, VS_O_VTOP
, TGSI_INTERPOLATE_LINEAR
);
320 sampler
= ureg_DECL_sampler(shader
, 0);
322 fragment
= ureg_DECL_output(shader
, TGSI_SEMANTIC_COLOR
, 0);
324 tmp
= calc_line(shader
);
330 * fragment.xyz = tex(tc, sampler) * scale + tc.z
335 ureg_SEQ(shader
, ureg_writemask(tmp
, TGSI_WRITEMASK_Y
),
336 ureg_scalar(tc
, TGSI_SWIZZLE_W
), ureg_src(tmp
));
338 ureg_IF(shader
, ureg_scalar(ureg_src(tmp
), TGSI_SWIZZLE_Y
), &label
);
342 ureg_fixup_label(shader
, label
, ureg_get_instruction_number(shader
));
343 ureg_ELSE(shader
, &label
);
345 ureg_TEX(shader
, tmp
, TGSI_TEXTURE_2D
, tc
, sampler
);
348 ureg_MAD(shader
, ureg_writemask(fragment
, TGSI_WRITEMASK_XYZ
),
349 ureg_src(tmp
), ureg_imm1f(shader
, scale
),
350 ureg_scalar(tc
, TGSI_SWIZZLE_Z
));
352 ureg_ADD(shader
, ureg_writemask(fragment
, TGSI_WRITEMASK_XYZ
),
353 ureg_src(tmp
), ureg_scalar(tc
, TGSI_SWIZZLE_Z
));
355 ureg_MOV(shader
, ureg_writemask(fragment
, TGSI_WRITEMASK_W
), ureg_imm1f(shader
, 1.0f
));
357 ureg_fixup_label(shader
, label
, ureg_get_instruction_number(shader
));
360 ureg_release_temporary(shader
, tmp
);
362 return ureg_create_shader_and_destroy(shader
, r
->pipe
);
366 init_pipe_state(struct vl_mc
*r
)
368 struct pipe_sampler_state sampler
;
369 struct pipe_blend_state blend
;
370 struct pipe_rasterizer_state rs_state
;
374 memset(&sampler
, 0, sizeof(sampler
));
375 sampler
.wrap_s
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
376 sampler
.wrap_t
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
377 sampler
.wrap_r
= PIPE_TEX_WRAP_CLAMP_TO_BORDER
;
378 sampler
.min_img_filter
= PIPE_TEX_FILTER_LINEAR
;
379 sampler
.min_mip_filter
= PIPE_TEX_MIPFILTER_NONE
;
380 sampler
.mag_img_filter
= PIPE_TEX_FILTER_LINEAR
;
381 sampler
.compare_mode
= PIPE_TEX_COMPARE_NONE
;
382 sampler
.compare_func
= PIPE_FUNC_ALWAYS
;
383 sampler
.normalized_coords
= 1;
384 r
->sampler_ref
= r
->pipe
->create_sampler_state(r
->pipe
, &sampler
);
386 goto error_sampler_ref
;
388 sampler
.min_img_filter
= PIPE_TEX_FILTER_NEAREST
;
389 sampler
.mag_img_filter
= PIPE_TEX_FILTER_NEAREST
;
390 r
->sampler_ycbcr
= r
->pipe
->create_sampler_state(r
->pipe
, &sampler
);
391 if (!r
->sampler_ycbcr
)
392 goto error_sampler_ycbcr
;
394 memset(&blend
, 0, sizeof blend
);
395 blend
.independent_blend_enable
= 0;
396 blend
.rt
[0].blend_enable
= 1;
397 blend
.rt
[0].rgb_func
= PIPE_BLEND_ADD
;
398 blend
.rt
[0].rgb_src_factor
= PIPE_BLENDFACTOR_SRC_ALPHA
;
399 blend
.rt
[0].rgb_dst_factor
= PIPE_BLENDFACTOR_ZERO
;
400 blend
.rt
[0].alpha_func
= PIPE_BLEND_ADD
;
401 blend
.rt
[0].alpha_src_factor
= PIPE_BLENDFACTOR_SRC_ALPHA
;
402 blend
.rt
[0].alpha_dst_factor
= PIPE_BLENDFACTOR_ZERO
;
403 blend
.logicop_enable
= 0;
404 blend
.logicop_func
= PIPE_LOGICOP_CLEAR
;
405 blend
.rt
[0].colormask
= PIPE_MASK_RGBA
;
407 r
->blend_clear
= r
->pipe
->create_blend_state(r
->pipe
, &blend
);
409 goto error_blend_clear
;
411 blend
.rt
[0].rgb_dst_factor
= PIPE_BLENDFACTOR_ONE
;
412 blend
.rt
[0].alpha_dst_factor
= PIPE_BLENDFACTOR_ONE
;
413 r
->blend_add
= r
->pipe
->create_blend_state(r
->pipe
, &blend
);
415 goto error_blend_add
;
417 memset(&rs_state
, 0, sizeof(rs_state
));
418 /*rs_state.sprite_coord_enable */
419 rs_state
.sprite_coord_mode
= PIPE_SPRITE_COORD_UPPER_LEFT
;
420 rs_state
.point_quad_rasterization
= true;
421 rs_state
.point_size
= BLOCK_WIDTH
;
422 rs_state
.gl_rasterization_rules
= true;
423 r
->rs_state
= r
->pipe
->create_rasterizer_state(r
->pipe
, &rs_state
);
430 r
->pipe
->delete_blend_state(r
->pipe
, r
->blend_add
);
433 r
->pipe
->delete_blend_state(r
->pipe
, r
->blend_clear
);
436 r
->pipe
->delete_sampler_state(r
->pipe
, r
->sampler_ref
);
439 r
->pipe
->delete_sampler_state(r
->pipe
, r
->sampler_ycbcr
);
446 cleanup_pipe_state(struct vl_mc
*r
)
450 r
->pipe
->delete_sampler_state(r
->pipe
, r
->sampler_ref
);
451 r
->pipe
->delete_sampler_state(r
->pipe
, r
->sampler_ycbcr
);
452 r
->pipe
->delete_blend_state(r
->pipe
, r
->blend_clear
);
453 r
->pipe
->delete_blend_state(r
->pipe
, r
->blend_add
);
454 r
->pipe
->delete_rasterizer_state(r
->pipe
, r
->rs_state
);
458 vl_mc_init(struct vl_mc
*renderer
, struct pipe_context
*pipe
,
459 unsigned buffer_width
, unsigned buffer_height
,
460 unsigned macroblock_size
, float scale
)
465 memset(renderer
, 0, sizeof(struct vl_mc
));
467 renderer
->pipe
= pipe
;
468 renderer
->buffer_width
= buffer_width
;
469 renderer
->buffer_height
= buffer_height
;
470 renderer
->macroblock_size
= macroblock_size
;
472 if (!init_pipe_state(renderer
))
473 goto error_pipe_state
;
475 renderer
->vs_ref
= create_ref_vert_shader(renderer
);
476 if (!renderer
->vs_ref
)
479 renderer
->vs_ycbcr
= create_ycbcr_vert_shader(renderer
);
480 if (!renderer
->vs_ycbcr
)
483 renderer
->fs_ref
= create_ref_frag_shader(renderer
);
484 if (!renderer
->fs_ref
)
487 renderer
->fs_ycbcr
= create_ycbcr_frag_shader(renderer
, scale
);
488 if (!renderer
->fs_ycbcr
)
494 renderer
->pipe
->delete_fs_state(renderer
->pipe
, renderer
->fs_ref
);
497 renderer
->pipe
->delete_vs_state(renderer
->pipe
, renderer
->vs_ycbcr
);
500 renderer
->pipe
->delete_vs_state(renderer
->pipe
, renderer
->vs_ref
);
503 cleanup_pipe_state(renderer
);
510 vl_mc_cleanup(struct vl_mc
*renderer
)
514 cleanup_pipe_state(renderer
);
516 renderer
->pipe
->delete_vs_state(renderer
->pipe
, renderer
->vs_ref
);
517 renderer
->pipe
->delete_vs_state(renderer
->pipe
, renderer
->vs_ycbcr
);
518 renderer
->pipe
->delete_fs_state(renderer
->pipe
, renderer
->fs_ref
);
519 renderer
->pipe
->delete_fs_state(renderer
->pipe
, renderer
->fs_ycbcr
);
523 vl_mc_init_buffer(struct vl_mc
*renderer
, struct vl_mc_buffer
*buffer
,
524 struct pipe_sampler_view
*source
)
526 assert(renderer
&& buffer
);
529 buffer
->renderer
= renderer
;
531 buffer
->viewport
.scale
[2] = 1;
532 buffer
->viewport
.scale
[3] = 1;
533 buffer
->viewport
.translate
[0] = 0;
534 buffer
->viewport
.translate
[1] = 0;
535 buffer
->viewport
.translate
[2] = 0;
536 buffer
->viewport
.translate
[3] = 0;
538 buffer
->fb_state
.nr_cbufs
= 1;
539 buffer
->fb_state
.zsbuf
= NULL
;
541 pipe_sampler_view_reference(&buffer
->source
, source
);
547 vl_mc_cleanup_buffer(struct vl_mc_buffer
*buffer
)
551 pipe_sampler_view_reference(&buffer
->source
, NULL
);
555 vl_mc_set_surface(struct vl_mc_buffer
*buffer
, struct pipe_surface
*surface
)
557 assert(buffer
&& surface
);
559 buffer
->surface_cleared
= false;
561 buffer
->viewport
.scale
[0] = surface
->width
;
562 buffer
->viewport
.scale
[1] = surface
->height
;
564 buffer
->fb_state
.width
= surface
->width
;
565 buffer
->fb_state
.height
= surface
->height
;
566 buffer
->fb_state
.cbufs
[0] = surface
;
570 prepare_pipe_4_rendering(struct vl_mc_buffer
*buffer
)
572 struct vl_mc
*renderer
;
576 renderer
= buffer
->renderer
;
577 renderer
->pipe
->bind_rasterizer_state(renderer
->pipe
, renderer
->rs_state
);
579 if (buffer
->surface_cleared
)
580 renderer
->pipe
->bind_blend_state(renderer
->pipe
, renderer
->blend_add
);
582 renderer
->pipe
->bind_blend_state(renderer
->pipe
, renderer
->blend_clear
);
583 buffer
->surface_cleared
= true;
586 renderer
->pipe
->set_framebuffer_state(renderer
->pipe
, &buffer
->fb_state
);
587 renderer
->pipe
->set_viewport_state(renderer
->pipe
, &buffer
->viewport
);
591 vl_mc_render_ref(struct vl_mc_buffer
*buffer
, struct pipe_sampler_view
*ref
)
593 struct vl_mc
*renderer
;
595 assert(buffer
&& ref
);
597 prepare_pipe_4_rendering(buffer
);
599 renderer
= buffer
->renderer
;
601 renderer
->pipe
->bind_vs_state(renderer
->pipe
, renderer
->vs_ref
);
602 renderer
->pipe
->bind_fs_state(renderer
->pipe
, renderer
->fs_ref
);
604 renderer
->pipe
->set_fragment_sampler_views(renderer
->pipe
, 1, &ref
);
605 renderer
->pipe
->bind_fragment_sampler_states(renderer
->pipe
, 1, &renderer
->sampler_ref
);
607 util_draw_arrays_instanced(renderer
->pipe
, PIPE_PRIM_QUADS
, 0, 4, 0,
608 renderer
->buffer_width
/ MACROBLOCK_WIDTH
*
609 renderer
->buffer_height
/ MACROBLOCK_HEIGHT
);
613 vl_mc_render_ycbcr(struct vl_mc_buffer
*buffer
, unsigned num_instances
)
615 struct vl_mc
*renderer
;
619 if (num_instances
== 0)
622 prepare_pipe_4_rendering(buffer
);
624 renderer
= buffer
->renderer
;
626 renderer
->pipe
->bind_vs_state(renderer
->pipe
, renderer
->vs_ycbcr
);
627 renderer
->pipe
->bind_fs_state(renderer
->pipe
, renderer
->fs_ycbcr
);
629 renderer
->pipe
->set_fragment_sampler_views(renderer
->pipe
, 1, &buffer
->source
);
630 renderer
->pipe
->bind_fragment_sampler_states(renderer
->pipe
, 1, &renderer
->sampler_ycbcr
);
632 util_draw_arrays_instanced(renderer
->pipe
, PIPE_PRIM_QUADS
, 0, 4, 0, num_instances
);