Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/auxiliary/vl/vl_compositor_gfx.c
4565 views
1
/**************************************************************************
2
*
3
* Copyright 2009 Younes Manton.
4
* All Rights Reserved.
5
*
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:
13
*
14
* The above copyright notice and this permission notice (including the
15
* next paragraph) shall be included in all copies or substantial portions
16
* of the Software.
17
*
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.
25
*
26
**************************************************************************/
27
28
#include <assert.h>
29
30
#include "pipe/p_compiler.h"
31
#include "pipe/p_context.h"
32
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"
37
38
#include "tgsi/tgsi_ureg.h"
39
40
#include "vl_csc.h"
41
#include "vl_types.h"
42
43
#include "vl_compositor_gfx.h"
44
45
enum VS_OUTPUT
46
{
47
VS_O_VPOS = 0,
48
VS_O_COLOR = 0,
49
VS_O_VTEX = 0,
50
VS_O_VTOP,
51
VS_O_VBOTTOM,
52
};
53
54
void *
55
create_vert_shader(struct vl_compositor *c)
56
{
57
struct ureg_program *shader;
58
struct ureg_src vpos, vtex, color;
59
struct ureg_dst tmp;
60
struct ureg_dst o_vpos, o_vtex, o_color;
61
struct ureg_dst o_vtop, o_vbottom;
62
63
shader = ureg_create(PIPE_SHADER_VERTEX);
64
if (!shader)
65
return false;
66
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);
76
77
/*
78
* o_vpos = vpos
79
* o_vtex = vtex
80
* o_color = color
81
*/
82
ureg_MOV(shader, o_vpos, vpos);
83
ureg_MOV(shader, o_vtex, vtex);
84
ureg_MOV(shader, o_color, color);
85
86
/*
87
* tmp.x = vtex.w / 2
88
* tmp.y = vtex.w / 4
89
*
90
* o_vtop.x = vtex.x
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
94
*
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
99
*/
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));
104
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));
112
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));
120
121
ureg_END(shader);
122
123
return ureg_create_shader_and_destroy(shader, c->pipe);
124
}
125
126
static void
127
create_frag_shader_weave(struct ureg_program *shader, struct ureg_dst fragment)
128
{
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];
133
unsigned i, j;
134
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);
137
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);
145
}
146
147
for (i = 0; i < 2; ++i) {
148
t_tc[i] = ureg_DECL_temporary(shader);
149
t_texel[i] = ureg_DECL_temporary(shader);
150
}
151
152
/* calculate the texture offsets
153
* t_tc.x = i_tc.x
154
* t_tc.y = (round(i_tc.y - 0.5) + 0.5) / height * 2
155
*/
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));
169
}
170
171
/* fetch the texels
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])
175
*/
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);
180
181
ureg_TEX(shader, ureg_writemask(t_texel[i], TGSI_WRITEMASK_X << j),
182
TGSI_TEXTURE_2D_ARRAY, src, sampler[j]);
183
}
184
185
/* calculate linear interpolation factor
186
* factor = |round(i_tc.y) - i_tc.y| * 2
187
*/
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]));
196
197
for (i = 0; i < 2; ++i) {
198
ureg_release_temporary(shader, t_texel[i]);
199
ureg_release_temporary(shader, t_tc[i]);
200
}
201
}
202
203
static void
204
create_frag_shader_csc(struct ureg_program *shader, struct ureg_dst texel,
205
struct ureg_dst fragment)
206
{
207
struct ureg_src csc[3];
208
struct ureg_src lumakey;
209
struct ureg_dst temp[2];
210
unsigned i;
211
212
for (i = 0; i < 3; ++i)
213
csc[i] = ureg_DECL_constant(shader, i);
214
215
lumakey = ureg_DECL_constant(shader, 3);
216
217
for (i = 0; i < 2; ++i)
218
temp[i] = ureg_DECL_temporary(shader);
219
220
ureg_MOV(shader, ureg_writemask(texel, TGSI_WRITEMASK_W),
221
ureg_imm1f(shader, 1.0f));
222
223
for (i = 0; i < 3; ++i)
224
ureg_DP4(shader, ureg_writemask(fragment, TGSI_WRITEMASK_X << i), csc[i],
225
ureg_src(texel));
226
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]));
235
236
for (i = 0; i < 2; ++i)
237
ureg_release_temporary(shader, temp[i]);
238
}
239
240
static void
241
create_frag_shader_yuv(struct ureg_program *shader, struct ureg_dst texel)
242
{
243
struct ureg_src tc;
244
struct ureg_src sampler[3];
245
unsigned i;
246
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);
255
}
256
257
/*
258
* texel.xyz = tex(tc, sampler[i])
259
*/
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]);
262
}
263
264
void *
265
create_frag_shader_video_buffer(struct vl_compositor *c)
266
{
267
struct ureg_program *shader;
268
struct ureg_dst texel;
269
struct ureg_dst fragment;
270
271
shader = ureg_create(PIPE_SHADER_FRAGMENT);
272
if (!shader)
273
return false;
274
275
texel = ureg_DECL_temporary(shader);
276
fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);
277
278
create_frag_shader_yuv(shader, texel);
279
create_frag_shader_csc(shader, texel, fragment);
280
281
ureg_release_temporary(shader, texel);
282
ureg_END(shader);
283
284
return ureg_create_shader_and_destroy(shader, c->pipe);
285
}
286
287
void *
288
create_frag_shader_weave_rgb(struct vl_compositor *c)
289
{
290
struct ureg_program *shader;
291
struct ureg_dst texel, fragment;
292
293
shader = ureg_create(PIPE_SHADER_FRAGMENT);
294
if (!shader)
295
return false;
296
297
texel = ureg_DECL_temporary(shader);
298
fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);
299
300
create_frag_shader_weave(shader, texel);
301
create_frag_shader_csc(shader, texel, fragment);
302
303
ureg_release_temporary(shader, texel);
304
305
ureg_END(shader);
306
307
return ureg_create_shader_and_destroy(shader, c->pipe);
308
}
309
310
void *
311
create_frag_shader_deint_yuv(struct vl_compositor *c, bool y, bool w)
312
{
313
struct ureg_program *shader;
314
struct ureg_dst texel, fragment;
315
316
shader = ureg_create(PIPE_SHADER_FRAGMENT);
317
if (!shader)
318
return false;
319
320
texel = ureg_DECL_temporary(shader);
321
fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);
322
323
if (w)
324
create_frag_shader_weave(shader, texel);
325
else
326
create_frag_shader_yuv(shader, texel);
327
328
if (y)
329
ureg_MOV(shader, ureg_writemask(fragment, TGSI_WRITEMASK_X), ureg_src(texel));
330
else
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));
334
335
ureg_release_temporary(shader, texel);
336
337
ureg_END(shader);
338
339
return ureg_create_shader_and_destroy(shader, c->pipe);
340
}
341
342
void *
343
create_frag_shader_palette(struct vl_compositor *c, bool include_cc)
344
{
345
struct ureg_program *shader;
346
struct ureg_src csc[3];
347
struct ureg_src tc;
348
struct ureg_src sampler;
349
struct ureg_src palette;
350
struct ureg_dst texel;
351
struct ureg_dst fragment;
352
unsigned i;
353
354
shader = ureg_create(PIPE_SHADER_FRAGMENT);
355
if (!shader)
356
return false;
357
358
for (i = 0; include_cc && i < 3; ++i)
359
csc[i] = ureg_DECL_constant(shader, i);
360
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);
374
375
texel = ureg_DECL_temporary(shader);
376
fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);
377
378
/*
379
* texel = tex(tc, sampler)
380
* fragment.xyz = tex(texel, palette) * csc
381
* fragment.a = texel.a
382
*/
383
ureg_TEX(shader, texel, TGSI_TEXTURE_2D, tc, sampler);
384
ureg_MOV(shader, ureg_writemask(fragment, TGSI_WRITEMASK_W), ureg_src(texel));
385
386
if (include_cc) {
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));
390
} else {
391
ureg_TEX(shader, ureg_writemask(fragment, TGSI_WRITEMASK_XYZ),
392
TGSI_TEXTURE_1D, ureg_src(texel), palette);
393
}
394
395
ureg_release_temporary(shader, texel);
396
ureg_END(shader);
397
398
return ureg_create_shader_and_destroy(shader, c->pipe);
399
}
400
401
void *
402
create_frag_shader_rgba(struct vl_compositor *c)
403
{
404
struct ureg_program *shader;
405
struct ureg_src tc, color, sampler;
406
struct ureg_dst texel, fragment;
407
408
shader = ureg_create(PIPE_SHADER_FRAGMENT);
409
if (!shader)
410
return false;
411
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);
422
423
/*
424
* fragment = tex(tc, sampler)
425
*/
426
ureg_TEX(shader, texel, TGSI_TEXTURE_2D, tc, sampler);
427
ureg_MUL(shader, fragment, ureg_src(texel), color);
428
ureg_END(shader);
429
430
return ureg_create_shader_and_destroy(shader, c->pipe);
431
}
432
433
void *
434
create_frag_shader_rgb_yuv(struct vl_compositor *c, bool y)
435
{
436
struct ureg_program *shader;
437
struct ureg_src tc, sampler;
438
struct ureg_dst texel, fragment;
439
440
struct ureg_src csc[3];
441
unsigned i;
442
443
shader = ureg_create(PIPE_SHADER_FRAGMENT);
444
if (!shader)
445
return false;
446
447
for (i = 0; i < 3; ++i)
448
csc[i] = ureg_DECL_constant(shader, i);
449
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);
454
455
ureg_TEX(shader, texel, TGSI_TEXTURE_2D, tc, sampler);
456
457
if (y) {
458
ureg_DP4(shader, ureg_writemask(fragment, TGSI_WRITEMASK_X), csc[0], ureg_src(texel));
459
} else {
460
for (i = 0; i < 2; ++i)
461
ureg_DP4(shader, ureg_writemask(fragment, TGSI_WRITEMASK_X << i), csc[i + 1], ureg_src(texel));
462
}
463
464
ureg_release_temporary(shader, texel);
465
ureg_END(shader);
466
467
return ureg_create_shader_and_destroy(shader, c->pipe);
468
}
469
470
static void
471
gen_rect_verts(struct vertex2f *vb, struct vl_compositor_layer *layer)
472
{
473
struct vertex2f tl, tr, br, bl;
474
475
assert(vb && layer);
476
477
switch (layer->rotate) {
478
default:
479
case VL_COMPOSITOR_ROTATE_0:
480
tl = layer->dst.tl;
481
tr.x = layer->dst.br.x;
482
tr.y = layer->dst.tl.y;
483
br = layer->dst.br;
484
bl.x = layer->dst.tl.x;
485
bl.y = layer->dst.br.y;
486
break;
487
case VL_COMPOSITOR_ROTATE_90:
488
tl.x = layer->dst.br.x;
489
tl.y = layer->dst.tl.y;
490
tr = layer->dst.br;
491
br.x = layer->dst.tl.x;
492
br.y = layer->dst.br.y;
493
bl = layer->dst.tl;
494
break;
495
case VL_COMPOSITOR_ROTATE_180:
496
tl = layer->dst.br;
497
tr.x = layer->dst.tl.x;
498
tr.y = layer->dst.br.y;
499
br = layer->dst.tl;
500
bl.x = layer->dst.br.x;
501
bl.y = layer->dst.tl.y;
502
break;
503
case VL_COMPOSITOR_ROTATE_270:
504
tl.x = layer->dst.tl.x;
505
tl.y = layer->dst.br.y;
506
tr = layer->dst.tl;
507
br.x = layer->dst.br.x;
508
br.y = layer->dst.tl.y;
509
bl = layer->dst.br;
510
break;
511
}
512
513
vb[ 0].x = tl.x;
514
vb[ 0].y = tl.y;
515
vb[ 1].x = layer->src.tl.x;
516
vb[ 1].y = layer->src.tl.y;
517
vb[ 2] = layer->zw;
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;
522
523
vb[ 5].x = tr.x;
524
vb[ 5].y = tr.y;
525
vb[ 6].x = layer->src.br.x;
526
vb[ 6].y = layer->src.tl.y;
527
vb[ 7] = layer->zw;
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;
532
533
vb[10].x = br.x;
534
vb[10].y = br.y;
535
vb[11].x = layer->src.br.x;
536
vb[11].y = layer->src.br.y;
537
vb[12] = layer->zw;
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;
542
543
vb[15].x = bl.x;
544
vb[15].y = bl.y;
545
vb[16].x = layer->src.tl.x;
546
vb[16].y = layer->src.br.y;
547
vb[17] = layer->zw;
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;
552
}
553
554
static inline struct u_rect
555
calc_drawn_area(struct vl_compositor_state *s, struct vl_compositor_layer *layer)
556
{
557
struct vertex2f tl, br;
558
struct u_rect result;
559
560
assert(s && layer);
561
562
// rotate
563
switch (layer->rotate) {
564
default:
565
case VL_COMPOSITOR_ROTATE_0:
566
tl = layer->dst.tl;
567
br = layer->dst.br;
568
break;
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;
574
break;
575
case VL_COMPOSITOR_ROTATE_180:
576
tl = layer->dst.br;
577
br = layer->dst.tl;
578
break;
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;
584
break;
585
}
586
587
// scale
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];
592
593
// and clip
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);
598
return result;
599
}
600
601
static void
602
gen_vertex_data(struct vl_compositor *c, struct vl_compositor_state *s, struct u_rect *dirty)
603
{
604
struct vertex2f *vb;
605
unsigned i;
606
607
assert(c);
608
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 */
612
4, /* alignment */
613
&c->vertex_buf.buffer_offset, &c->vertex_buf.buffer.resource,
614
(void **)&vb);
615
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);
620
vb += 20;
621
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;
627
}
628
629
if (dirty && layer->clearing) {
630
struct u_rect drawn = calc_drawn_area(s, layer);
631
if (
632
dirty->x0 >= drawn.x0 &&
633
dirty->y0 >= drawn.y0 &&
634
dirty->x1 <= drawn.x1 &&
635
dirty->y1 <= drawn.y1) {
636
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;
640
}
641
}
642
}
643
}
644
645
u_upload_unmap(c->pipe->stream_uploader);
646
}
647
648
static void
649
draw_layers(struct vl_compositor *c, struct vl_compositor_state *s, struct u_rect *dirty)
650
{
651
unsigned vb_index, i;
652
653
assert(c);
654
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;
661
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, 0, samplers);
669
670
util_draw_arrays(c->pipe, PIPE_PRIM_QUADS, vb_index * 4, 4);
671
vb_index++;
672
673
if (dirty) {
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);
680
}
681
}
682
}
683
}
684
685
void
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,
690
bool clear_dirty)
691
{
692
assert(c);
693
assert(dst_surface);
694
695
c->fb_state.width = dst_surface->width;
696
c->fb_state.height = dst_surface->height;
697
c->fb_state.cbufs[0] = dst_surface;
698
699
if (!s->scissor_valid) {
700
s->scissor.minx = 0;
701
s->scissor.miny = 0;
702
s->scissor.maxx = dst_surface->width;
703
s->scissor.maxy = dst_surface->height;
704
}
705
c->pipe->set_scissor_states(c->pipe, 0, 1, &s->scissor);
706
707
gen_vertex_data(c, s, dirty_area);
708
709
if (clear_dirty && dirty_area &&
710
(dirty_area->x0 < dirty_area->x1 || dirty_area->y0 < dirty_area->y1)) {
711
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;
716
}
717
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, 0, false, &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->shader_params);
723
c->pipe->bind_rasterizer_state(c->pipe, c->rast);
724
725
draw_layers(c, s, dirty_area);
726
}
727
728