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 VMWARE 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_compiler.h"
31 #include "pipe/p_context.h"
33 #include "util/u_memory.h"
34 #include "util/u_draw.h"
35 #include "util/u_surface.h"
36 #include "util/u_upload_mgr.h"
38 #include "tgsi/tgsi_ureg.h"
43 #include "vl_compositor_gfx.h"
55 create_vert_shader(struct vl_compositor
*c
)
57 struct ureg_program
*shader
;
58 struct ureg_src vpos
, vtex
, color
;
60 struct ureg_dst o_vpos
, o_vtex
, o_color
;
61 struct ureg_dst o_vtop
, o_vbottom
;
63 shader
= ureg_create(PIPE_SHADER_VERTEX
);
67 vpos
= ureg_DECL_vs_input(shader
, 0);
68 vtex
= ureg_DECL_vs_input(shader
, 1);
69 color
= ureg_DECL_vs_input(shader
, 2);
70 tmp
= ureg_DECL_temporary(shader
);
71 o_vpos
= ureg_DECL_output(shader
, TGSI_SEMANTIC_POSITION
, VS_O_VPOS
);
72 o_color
= ureg_DECL_output(shader
, TGSI_SEMANTIC_COLOR
, VS_O_COLOR
);
73 o_vtex
= ureg_DECL_output(shader
, TGSI_SEMANTIC_GENERIC
, VS_O_VTEX
);
74 o_vtop
= ureg_DECL_output(shader
, TGSI_SEMANTIC_GENERIC
, VS_O_VTOP
);
75 o_vbottom
= ureg_DECL_output(shader
, TGSI_SEMANTIC_GENERIC
, VS_O_VBOTTOM
);
82 ureg_MOV(shader
, o_vpos
, vpos
);
83 ureg_MOV(shader
, o_vtex
, vtex
);
84 ureg_MOV(shader
, o_color
, color
);
91 * o_vtop.y = vtex.y * tmp.x + 0.25f
92 * o_vtop.z = vtex.y * tmp.y + 0.25f
93 * o_vtop.w = 1 / tmp.x
95 * o_vbottom.x = vtex.x
96 * o_vbottom.y = vtex.y * tmp.x - 0.25f
97 * o_vbottom.z = vtex.y * tmp.y - 0.25f
98 * o_vbottom.w = 1 / tmp.y
100 ureg_MUL(shader
, ureg_writemask(tmp
, TGSI_WRITEMASK_X
),
101 ureg_scalar(vtex
, TGSI_SWIZZLE_W
), ureg_imm1f(shader
, 0.5f
));
102 ureg_MUL(shader
, ureg_writemask(tmp
, TGSI_WRITEMASK_Y
),
103 ureg_scalar(vtex
, TGSI_SWIZZLE_W
), ureg_imm1f(shader
, 0.25f
));
105 ureg_MOV(shader
, ureg_writemask(o_vtop
, TGSI_WRITEMASK_X
), vtex
);
106 ureg_MAD(shader
, ureg_writemask(o_vtop
, TGSI_WRITEMASK_Y
), ureg_scalar(vtex
, TGSI_SWIZZLE_Y
),
107 ureg_scalar(ureg_src(tmp
), TGSI_SWIZZLE_X
), ureg_imm1f(shader
, 0.25f
));
108 ureg_MAD(shader
, ureg_writemask(o_vtop
, TGSI_WRITEMASK_Z
), ureg_scalar(vtex
, TGSI_SWIZZLE_Y
),
109 ureg_scalar(ureg_src(tmp
), TGSI_SWIZZLE_Y
), ureg_imm1f(shader
, 0.25f
));
110 ureg_RCP(shader
, ureg_writemask(o_vtop
, TGSI_WRITEMASK_W
),
111 ureg_scalar(ureg_src(tmp
), TGSI_SWIZZLE_X
));
113 ureg_MOV(shader
, ureg_writemask(o_vbottom
, TGSI_WRITEMASK_X
), vtex
);
114 ureg_MAD(shader
, ureg_writemask(o_vbottom
, TGSI_WRITEMASK_Y
), ureg_scalar(vtex
, TGSI_SWIZZLE_Y
),
115 ureg_scalar(ureg_src(tmp
), TGSI_SWIZZLE_X
), ureg_imm1f(shader
, -0.25f
));
116 ureg_MAD(shader
, ureg_writemask(o_vbottom
, TGSI_WRITEMASK_Z
), ureg_scalar(vtex
, TGSI_SWIZZLE_Y
),
117 ureg_scalar(ureg_src(tmp
), TGSI_SWIZZLE_Y
), ureg_imm1f(shader
, -0.25f
));
118 ureg_RCP(shader
, ureg_writemask(o_vbottom
, TGSI_WRITEMASK_W
),
119 ureg_scalar(ureg_src(tmp
), TGSI_SWIZZLE_Y
));
123 return ureg_create_shader_and_destroy(shader
, c
->pipe
);
127 create_frag_shader_weave(struct ureg_program
*shader
, struct ureg_dst fragment
)
129 struct ureg_src i_tc
[2];
130 struct ureg_src sampler
[3];
131 struct ureg_dst t_tc
[2];
132 struct ureg_dst t_texel
[2];
135 i_tc
[0] = ureg_DECL_fs_input(shader
, TGSI_SEMANTIC_GENERIC
, VS_O_VTOP
, TGSI_INTERPOLATE_LINEAR
);
136 i_tc
[1] = ureg_DECL_fs_input(shader
, TGSI_SEMANTIC_GENERIC
, VS_O_VBOTTOM
, TGSI_INTERPOLATE_LINEAR
);
138 for (i
= 0; i
< 3; ++i
) {
139 sampler
[i
] = ureg_DECL_sampler(shader
, i
);
140 ureg_DECL_sampler_view(shader
, i
, TGSI_TEXTURE_2D_ARRAY
,
141 TGSI_RETURN_TYPE_FLOAT
,
142 TGSI_RETURN_TYPE_FLOAT
,
143 TGSI_RETURN_TYPE_FLOAT
,
144 TGSI_RETURN_TYPE_FLOAT
);
147 for (i
= 0; i
< 2; ++i
) {
148 t_tc
[i
] = ureg_DECL_temporary(shader
);
149 t_texel
[i
] = ureg_DECL_temporary(shader
);
152 /* calculate the texture offsets
154 * t_tc.y = (round(i_tc.y - 0.5) + 0.5) / height * 2
156 for (i
= 0; i
< 2; ++i
) {
157 ureg_MOV(shader
, ureg_writemask(t_tc
[i
], TGSI_WRITEMASK_X
), i_tc
[i
]);
158 ureg_ADD(shader
, ureg_writemask(t_tc
[i
], TGSI_WRITEMASK_YZ
),
159 i_tc
[i
], ureg_imm1f(shader
, -0.5f
));
160 ureg_ROUND(shader
, ureg_writemask(t_tc
[i
], TGSI_WRITEMASK_YZ
), ureg_src(t_tc
[i
]));
161 ureg_MOV(shader
, ureg_writemask(t_tc
[i
], TGSI_WRITEMASK_W
),
162 ureg_imm1f(shader
, i
? 1.0f
: 0.0f
));
163 ureg_ADD(shader
, ureg_writemask(t_tc
[i
], TGSI_WRITEMASK_YZ
),
164 ureg_src(t_tc
[i
]), ureg_imm1f(shader
, 0.5f
));
165 ureg_MUL(shader
, ureg_writemask(t_tc
[i
], TGSI_WRITEMASK_Y
),
166 ureg_src(t_tc
[i
]), ureg_scalar(i_tc
[0], TGSI_SWIZZLE_W
));
167 ureg_MUL(shader
, ureg_writemask(t_tc
[i
], TGSI_WRITEMASK_Z
),
168 ureg_src(t_tc
[i
]), ureg_scalar(i_tc
[1], TGSI_SWIZZLE_W
));
172 * texel[0..1].x = tex(t_tc[0..1][0])
173 * texel[0..1].y = tex(t_tc[0..1][1])
174 * texel[0..1].z = tex(t_tc[0..1][2])
176 for (i
= 0; i
< 2; ++i
)
177 for (j
= 0; j
< 3; ++j
) {
178 struct ureg_src src
= ureg_swizzle(ureg_src(t_tc
[i
]),
179 TGSI_SWIZZLE_X
, j
? TGSI_SWIZZLE_Z
: TGSI_SWIZZLE_Y
, TGSI_SWIZZLE_W
, TGSI_SWIZZLE_W
);
181 ureg_TEX(shader
, ureg_writemask(t_texel
[i
], TGSI_WRITEMASK_X
<< j
),
182 TGSI_TEXTURE_2D_ARRAY
, src
, sampler
[j
]);
185 /* calculate linear interpolation factor
186 * factor = |round(i_tc.y) - i_tc.y| * 2
188 ureg_ROUND(shader
, ureg_writemask(t_tc
[0], TGSI_WRITEMASK_YZ
), i_tc
[0]);
189 ureg_ADD(shader
, ureg_writemask(t_tc
[0], TGSI_WRITEMASK_YZ
),
190 ureg_src(t_tc
[0]), ureg_negate(i_tc
[0]));
191 ureg_MUL(shader
, ureg_writemask(t_tc
[0], TGSI_WRITEMASK_YZ
),
192 ureg_abs(ureg_src(t_tc
[0])), ureg_imm1f(shader
, 2.0f
));
193 ureg_LRP(shader
, fragment
, ureg_swizzle(ureg_src(t_tc
[0]),
194 TGSI_SWIZZLE_Y
, TGSI_SWIZZLE_Z
, TGSI_SWIZZLE_Z
, TGSI_SWIZZLE_Z
),
195 ureg_src(t_texel
[0]), ureg_src(t_texel
[1]));
197 for (i
= 0; i
< 2; ++i
) {
198 ureg_release_temporary(shader
, t_texel
[i
]);
199 ureg_release_temporary(shader
, t_tc
[i
]);
204 create_frag_shader_csc(struct ureg_program
*shader
, struct ureg_dst texel
,
205 struct ureg_dst fragment
)
207 struct ureg_src csc
[3];
208 struct ureg_src lumakey
;
209 struct ureg_dst temp
[2];
212 for (i
= 0; i
< 3; ++i
)
213 csc
[i
] = ureg_DECL_constant(shader
, i
);
215 lumakey
= ureg_DECL_constant(shader
, 3);
217 for (i
= 0; i
< 2; ++i
)
218 temp
[i
] = ureg_DECL_temporary(shader
);
220 ureg_MOV(shader
, ureg_writemask(texel
, TGSI_WRITEMASK_W
),
221 ureg_imm1f(shader
, 1.0f
));
223 for (i
= 0; i
< 3; ++i
)
224 ureg_DP4(shader
, ureg_writemask(fragment
, TGSI_WRITEMASK_X
<< i
), csc
[i
],
227 ureg_MOV(shader
, ureg_writemask(temp
[0], TGSI_WRITEMASK_W
),
228 ureg_scalar(ureg_src(texel
), TGSI_SWIZZLE_Z
));
229 ureg_SLE(shader
, ureg_writemask(temp
[1], TGSI_WRITEMASK_W
),
230 ureg_src(temp
[0]), ureg_scalar(lumakey
, TGSI_SWIZZLE_X
));
231 ureg_SGT(shader
, ureg_writemask(temp
[0], TGSI_WRITEMASK_W
),
232 ureg_src(temp
[0]), ureg_scalar(lumakey
, TGSI_SWIZZLE_Y
));
233 ureg_MAX(shader
, ureg_writemask(fragment
, TGSI_WRITEMASK_W
),
234 ureg_src(temp
[0]), ureg_src(temp
[1]));
236 for (i
= 0; i
< 2; ++i
)
237 ureg_release_temporary(shader
, temp
[i
]);
241 create_frag_shader_yuv(struct ureg_program
*shader
, struct ureg_dst texel
)
244 struct ureg_src sampler
[3];
247 tc
= ureg_DECL_fs_input(shader
, TGSI_SEMANTIC_GENERIC
, VS_O_VTEX
, TGSI_INTERPOLATE_LINEAR
);
248 for (i
= 0; i
< 3; ++i
) {
249 sampler
[i
] = ureg_DECL_sampler(shader
, i
);
250 ureg_DECL_sampler_view(shader
, i
, TGSI_TEXTURE_2D_ARRAY
,
251 TGSI_RETURN_TYPE_FLOAT
,
252 TGSI_RETURN_TYPE_FLOAT
,
253 TGSI_RETURN_TYPE_FLOAT
,
254 TGSI_RETURN_TYPE_FLOAT
);
258 * texel.xyz = tex(tc, sampler[i])
260 for (i
= 0; i
< 3; ++i
)
261 ureg_TEX(shader
, ureg_writemask(texel
, TGSI_WRITEMASK_X
<< i
), TGSI_TEXTURE_2D_ARRAY
, tc
, sampler
[i
]);
265 create_frag_shader_video_buffer(struct vl_compositor
*c
)
267 struct ureg_program
*shader
;
268 struct ureg_dst texel
;
269 struct ureg_dst fragment
;
271 shader
= ureg_create(PIPE_SHADER_FRAGMENT
);
275 texel
= ureg_DECL_temporary(shader
);
276 fragment
= ureg_DECL_output(shader
, TGSI_SEMANTIC_COLOR
, 0);
278 create_frag_shader_yuv(shader
, texel
);
279 create_frag_shader_csc(shader
, texel
, fragment
);
281 ureg_release_temporary(shader
, texel
);
284 return ureg_create_shader_and_destroy(shader
, c
->pipe
);
288 create_frag_shader_weave_rgb(struct vl_compositor
*c
)
290 struct ureg_program
*shader
;
291 struct ureg_dst texel
, fragment
;
293 shader
= ureg_create(PIPE_SHADER_FRAGMENT
);
297 texel
= ureg_DECL_temporary(shader
);
298 fragment
= ureg_DECL_output(shader
, TGSI_SEMANTIC_COLOR
, 0);
300 create_frag_shader_weave(shader
, texel
);
301 create_frag_shader_csc(shader
, texel
, fragment
);
303 ureg_release_temporary(shader
, texel
);
307 return ureg_create_shader_and_destroy(shader
, c
->pipe
);
311 create_frag_shader_deint_yuv(struct vl_compositor
*c
, bool y
, bool w
)
313 struct ureg_program
*shader
;
314 struct ureg_dst texel
, fragment
;
316 shader
= ureg_create(PIPE_SHADER_FRAGMENT
);
320 texel
= ureg_DECL_temporary(shader
);
321 fragment
= ureg_DECL_output(shader
, TGSI_SEMANTIC_COLOR
, 0);
324 create_frag_shader_weave(shader
, texel
);
326 create_frag_shader_yuv(shader
, texel
);
329 ureg_MOV(shader
, ureg_writemask(fragment
, TGSI_WRITEMASK_X
), ureg_src(texel
));
331 ureg_MOV(shader
, ureg_writemask(fragment
, TGSI_WRITEMASK_XY
),
332 ureg_swizzle(ureg_src(texel
), TGSI_SWIZZLE_Y
,
333 TGSI_SWIZZLE_Z
, TGSI_SWIZZLE_W
, TGSI_SWIZZLE_W
));
335 ureg_release_temporary(shader
, texel
);
339 return ureg_create_shader_and_destroy(shader
, c
->pipe
);
343 create_frag_shader_palette(struct vl_compositor
*c
, bool include_cc
)
345 struct ureg_program
*shader
;
346 struct ureg_src csc
[3];
348 struct ureg_src sampler
;
349 struct ureg_src palette
;
350 struct ureg_dst texel
;
351 struct ureg_dst fragment
;
354 shader
= ureg_create(PIPE_SHADER_FRAGMENT
);
358 for (i
= 0; include_cc
&& i
< 3; ++i
)
359 csc
[i
] = ureg_DECL_constant(shader
, i
);
361 tc
= ureg_DECL_fs_input(shader
, TGSI_SEMANTIC_GENERIC
, VS_O_VTEX
, TGSI_INTERPOLATE_LINEAR
);
362 sampler
= ureg_DECL_sampler(shader
, 0);
363 ureg_DECL_sampler_view(shader
, 0, TGSI_TEXTURE_2D
,
364 TGSI_RETURN_TYPE_FLOAT
,
365 TGSI_RETURN_TYPE_FLOAT
,
366 TGSI_RETURN_TYPE_FLOAT
,
367 TGSI_RETURN_TYPE_FLOAT
);
368 palette
= ureg_DECL_sampler(shader
, 1);
369 ureg_DECL_sampler_view(shader
, 1, TGSI_TEXTURE_1D
,
370 TGSI_RETURN_TYPE_FLOAT
,
371 TGSI_RETURN_TYPE_FLOAT
,
372 TGSI_RETURN_TYPE_FLOAT
,
373 TGSI_RETURN_TYPE_FLOAT
);
375 texel
= ureg_DECL_temporary(shader
);
376 fragment
= ureg_DECL_output(shader
, TGSI_SEMANTIC_COLOR
, 0);
379 * texel = tex(tc, sampler)
380 * fragment.xyz = tex(texel, palette) * csc
381 * fragment.a = texel.a
383 ureg_TEX(shader
, texel
, TGSI_TEXTURE_2D
, tc
, sampler
);
384 ureg_MOV(shader
, ureg_writemask(fragment
, TGSI_WRITEMASK_W
), ureg_src(texel
));
387 ureg_TEX(shader
, texel
, TGSI_TEXTURE_1D
, ureg_src(texel
), palette
);
388 for (i
= 0; i
< 3; ++i
)
389 ureg_DP4(shader
, ureg_writemask(fragment
, TGSI_WRITEMASK_X
<< i
), csc
[i
], ureg_src(texel
));
391 ureg_TEX(shader
, ureg_writemask(fragment
, TGSI_WRITEMASK_XYZ
),
392 TGSI_TEXTURE_1D
, ureg_src(texel
), palette
);
395 ureg_release_temporary(shader
, texel
);
398 return ureg_create_shader_and_destroy(shader
, c
->pipe
);
402 create_frag_shader_rgba(struct vl_compositor
*c
)
404 struct ureg_program
*shader
;
405 struct ureg_src tc
, color
, sampler
;
406 struct ureg_dst texel
, fragment
;
408 shader
= ureg_create(PIPE_SHADER_FRAGMENT
);
412 tc
= ureg_DECL_fs_input(shader
, TGSI_SEMANTIC_GENERIC
, VS_O_VTEX
, TGSI_INTERPOLATE_LINEAR
);
413 color
= ureg_DECL_fs_input(shader
, TGSI_SEMANTIC_COLOR
, VS_O_COLOR
, TGSI_INTERPOLATE_LINEAR
);
414 sampler
= ureg_DECL_sampler(shader
, 0);
415 ureg_DECL_sampler_view(shader
, 0, TGSI_TEXTURE_2D
,
416 TGSI_RETURN_TYPE_FLOAT
,
417 TGSI_RETURN_TYPE_FLOAT
,
418 TGSI_RETURN_TYPE_FLOAT
,
419 TGSI_RETURN_TYPE_FLOAT
);
420 texel
= ureg_DECL_temporary(shader
);
421 fragment
= ureg_DECL_output(shader
, TGSI_SEMANTIC_COLOR
, 0);
424 * fragment = tex(tc, sampler)
426 ureg_TEX(shader
, texel
, TGSI_TEXTURE_2D
, tc
, sampler
);
427 ureg_MUL(shader
, fragment
, ureg_src(texel
), color
);
430 return ureg_create_shader_and_destroy(shader
, c
->pipe
);
434 create_frag_shader_rgb_yuv(struct vl_compositor
*c
, bool y
)
436 struct ureg_program
*shader
;
437 struct ureg_src tc
, sampler
;
438 struct ureg_dst texel
, fragment
;
440 struct ureg_src csc
[3];
443 shader
= ureg_create(PIPE_SHADER_FRAGMENT
);
447 for (i
= 0; i
< 3; ++i
)
448 csc
[i
] = ureg_DECL_constant(shader
, i
);
450 sampler
= ureg_DECL_sampler(shader
, 0);
451 tc
= ureg_DECL_fs_input(shader
, TGSI_SEMANTIC_GENERIC
, VS_O_VTEX
, TGSI_INTERPOLATE_LINEAR
);
452 texel
= ureg_DECL_temporary(shader
);
453 fragment
= ureg_DECL_output(shader
, TGSI_SEMANTIC_COLOR
, 0);
455 ureg_TEX(shader
, texel
, TGSI_TEXTURE_2D
, tc
, sampler
);
458 ureg_DP4(shader
, ureg_writemask(fragment
, TGSI_WRITEMASK_X
), csc
[0], ureg_src(texel
));
460 for (i
= 0; i
< 2; ++i
)
461 ureg_DP4(shader
, ureg_writemask(fragment
, TGSI_WRITEMASK_X
<< i
), csc
[i
+ 1], ureg_src(texel
));
464 ureg_release_temporary(shader
, texel
);
467 return ureg_create_shader_and_destroy(shader
, c
->pipe
);
471 gen_rect_verts(struct vertex2f
*vb
, struct vl_compositor_layer
*layer
)
473 struct vertex2f tl
, tr
, br
, bl
;
477 switch (layer
->rotate
) {
479 case VL_COMPOSITOR_ROTATE_0
:
481 tr
.x
= layer
->dst
.br
.x
;
482 tr
.y
= layer
->dst
.tl
.y
;
484 bl
.x
= layer
->dst
.tl
.x
;
485 bl
.y
= layer
->dst
.br
.y
;
487 case VL_COMPOSITOR_ROTATE_90
:
488 tl
.x
= layer
->dst
.br
.x
;
489 tl
.y
= layer
->dst
.tl
.y
;
491 br
.x
= layer
->dst
.tl
.x
;
492 br
.y
= layer
->dst
.br
.y
;
495 case VL_COMPOSITOR_ROTATE_180
:
497 tr
.x
= layer
->dst
.tl
.x
;
498 tr
.y
= layer
->dst
.br
.y
;
500 bl
.x
= layer
->dst
.br
.x
;
501 bl
.y
= layer
->dst
.tl
.y
;
503 case VL_COMPOSITOR_ROTATE_270
:
504 tl
.x
= layer
->dst
.tl
.x
;
505 tl
.y
= layer
->dst
.br
.y
;
507 br
.x
= layer
->dst
.br
.x
;
508 br
.y
= layer
->dst
.tl
.y
;
515 vb
[ 1].x
= layer
->src
.tl
.x
;
516 vb
[ 1].y
= layer
->src
.tl
.y
;
518 vb
[ 3].x
= layer
->colors
[0].x
;
519 vb
[ 3].y
= layer
->colors
[0].y
;
520 vb
[ 4].x
= layer
->colors
[0].z
;
521 vb
[ 4].y
= layer
->colors
[0].w
;
525 vb
[ 6].x
= layer
->src
.br
.x
;
526 vb
[ 6].y
= layer
->src
.tl
.y
;
528 vb
[ 8].x
= layer
->colors
[1].x
;
529 vb
[ 8].y
= layer
->colors
[1].y
;
530 vb
[ 9].x
= layer
->colors
[1].z
;
531 vb
[ 9].y
= layer
->colors
[1].w
;
535 vb
[11].x
= layer
->src
.br
.x
;
536 vb
[11].y
= layer
->src
.br
.y
;
538 vb
[13].x
= layer
->colors
[2].x
;
539 vb
[13].y
= layer
->colors
[2].y
;
540 vb
[14].x
= layer
->colors
[2].z
;
541 vb
[14].y
= layer
->colors
[2].w
;
545 vb
[16].x
= layer
->src
.tl
.x
;
546 vb
[16].y
= layer
->src
.br
.y
;
548 vb
[18].x
= layer
->colors
[3].x
;
549 vb
[18].y
= layer
->colors
[3].y
;
550 vb
[19].x
= layer
->colors
[3].z
;
551 vb
[19].y
= layer
->colors
[3].w
;
554 static inline struct u_rect
555 calc_drawn_area(struct vl_compositor_state
*s
, struct vl_compositor_layer
*layer
)
557 struct vertex2f tl
, br
;
558 struct u_rect result
;
563 switch (layer
->rotate
) {
565 case VL_COMPOSITOR_ROTATE_0
:
569 case VL_COMPOSITOR_ROTATE_90
:
570 tl
.x
= layer
->dst
.br
.x
;
571 tl
.y
= layer
->dst
.tl
.y
;
572 br
.x
= layer
->dst
.tl
.x
;
573 br
.y
= layer
->dst
.br
.y
;
575 case VL_COMPOSITOR_ROTATE_180
:
579 case VL_COMPOSITOR_ROTATE_270
:
580 tl
.x
= layer
->dst
.tl
.x
;
581 tl
.y
= layer
->dst
.br
.y
;
582 br
.x
= layer
->dst
.br
.x
;
583 br
.y
= layer
->dst
.tl
.y
;
588 result
.x0
= tl
.x
* layer
->viewport
.scale
[0] + layer
->viewport
.translate
[0];
589 result
.y0
= tl
.y
* layer
->viewport
.scale
[1] + layer
->viewport
.translate
[1];
590 result
.x1
= br
.x
* layer
->viewport
.scale
[0] + layer
->viewport
.translate
[0];
591 result
.y1
= br
.y
* layer
->viewport
.scale
[1] + layer
->viewport
.translate
[1];
594 result
.x0
= MAX2(result
.x0
, s
->scissor
.minx
);
595 result
.y0
= MAX2(result
.y0
, s
->scissor
.miny
);
596 result
.x1
= MIN2(result
.x1
, s
->scissor
.maxx
);
597 result
.y1
= MIN2(result
.y1
, s
->scissor
.maxy
);
602 gen_vertex_data(struct vl_compositor
*c
, struct vl_compositor_state
*s
, struct u_rect
*dirty
)
609 /* Allocate new memory for vertices. */
610 u_upload_alloc(c
->pipe
->stream_uploader
, 0,
611 c
->vertex_buf
.stride
* VL_COMPOSITOR_MAX_LAYERS
* 4, /* size */
613 &c
->vertex_buf
.buffer_offset
, &c
->vertex_buf
.buffer
.resource
,
616 for (i
= 0; i
< VL_COMPOSITOR_MAX_LAYERS
; i
++) {
617 if (s
->used_layers
& (1 << i
)) {
618 struct vl_compositor_layer
*layer
= &s
->layers
[i
];
619 gen_rect_verts(vb
, layer
);
622 if (!layer
->viewport_valid
) {
623 layer
->viewport
.scale
[0] = c
->fb_state
.width
;
624 layer
->viewport
.scale
[1] = c
->fb_state
.height
;
625 layer
->viewport
.translate
[0] = 0;
626 layer
->viewport
.translate
[1] = 0;
629 if (dirty
&& layer
->clearing
) {
630 struct u_rect drawn
= calc_drawn_area(s
, layer
);
632 dirty
->x0
>= drawn
.x0
&&
633 dirty
->y0
>= drawn
.y0
&&
634 dirty
->x1
<= drawn
.x1
&&
635 dirty
->y1
<= drawn
.y1
) {
637 // We clear the dirty area anyway, no need for clear_render_target
638 dirty
->x0
= dirty
->y0
= VL_COMPOSITOR_MAX_DIRTY
;
639 dirty
->x1
= dirty
->y1
= VL_COMPOSITOR_MIN_DIRTY
;
645 u_upload_unmap(c
->pipe
->stream_uploader
);
649 draw_layers(struct vl_compositor
*c
, struct vl_compositor_state
*s
, struct u_rect
*dirty
)
651 unsigned vb_index
, i
;
655 for (i
= 0, vb_index
= 0; i
< VL_COMPOSITOR_MAX_LAYERS
; ++i
) {
656 if (s
->used_layers
& (1 << i
)) {
657 struct vl_compositor_layer
*layer
= &s
->layers
[i
];
658 struct pipe_sampler_view
**samplers
= &layer
->sampler_views
[0];
659 unsigned num_sampler_views
= !samplers
[1] ? 1 : !samplers
[2] ? 2 : 3;
660 void *blend
= layer
->blend
? layer
->blend
: i
? c
->blend_add
: c
->blend_clear
;
662 c
->pipe
->bind_blend_state(c
->pipe
, blend
);
663 c
->pipe
->set_viewport_states(c
->pipe
, 0, 1, &layer
->viewport
);
664 c
->pipe
->bind_fs_state(c
->pipe
, layer
->fs
);
665 c
->pipe
->bind_sampler_states(c
->pipe
, PIPE_SHADER_FRAGMENT
, 0,
666 num_sampler_views
, layer
->samplers
);
667 c
->pipe
->set_sampler_views(c
->pipe
, PIPE_SHADER_FRAGMENT
, 0,
668 num_sampler_views
, samplers
);
670 util_draw_arrays(c
->pipe
, PIPE_PRIM_QUADS
, vb_index
* 4, 4);
674 // Remember the currently drawn area as dirty for the next draw command
675 struct u_rect drawn
= calc_drawn_area(s
, layer
);
676 dirty
->x0
= MIN2(drawn
.x0
, dirty
->x0
);
677 dirty
->y0
= MIN2(drawn
.y0
, dirty
->y0
);
678 dirty
->x1
= MAX2(drawn
.x1
, dirty
->x1
);
679 dirty
->y1
= MAX2(drawn
.y1
, dirty
->y1
);
686 vl_compositor_gfx_render(struct vl_compositor_state
*s
,
687 struct vl_compositor
*c
,
688 struct pipe_surface
*dst_surface
,
689 struct u_rect
*dirty_area
,
695 c
->fb_state
.width
= dst_surface
->width
;
696 c
->fb_state
.height
= dst_surface
->height
;
697 c
->fb_state
.cbufs
[0] = dst_surface
;
699 if (!s
->scissor_valid
) {
702 s
->scissor
.maxx
= dst_surface
->width
;
703 s
->scissor
.maxy
= dst_surface
->height
;
705 c
->pipe
->set_scissor_states(c
->pipe
, 0, 1, &s
->scissor
);
707 gen_vertex_data(c
, s
, dirty_area
);
709 if (clear_dirty
&& dirty_area
&&
710 (dirty_area
->x0
< dirty_area
->x1
|| dirty_area
->y0
< dirty_area
->y1
)) {
712 c
->pipe
->clear_render_target(c
->pipe
, dst_surface
, &s
->clear_color
,
713 0, 0, dst_surface
->width
, dst_surface
->height
, false);
714 dirty_area
->x0
= dirty_area
->y0
= VL_COMPOSITOR_MAX_DIRTY
;
715 dirty_area
->x1
= dirty_area
->y1
= VL_COMPOSITOR_MIN_DIRTY
;
718 c
->pipe
->set_framebuffer_state(c
->pipe
, &c
->fb_state
);
719 c
->pipe
->bind_vs_state(c
->pipe
, c
->vs
);
720 c
->pipe
->set_vertex_buffers(c
->pipe
, 0, 1, &c
->vertex_buf
);
721 c
->pipe
->bind_vertex_elements_state(c
->pipe
, c
->vertex_elems_state
);
722 pipe_set_constant_buffer(c
->pipe
, PIPE_SHADER_FRAGMENT
, 0, s
->csc_matrix
);
723 c
->pipe
->bind_rasterizer_state(c
->pipe
, c
->rast
);
725 draw_layers(c
, s
, dirty_area
);