Merge branch '7.8' into master
[mesa.git] / src / gallium / state_trackers / xorg / xorg_exa_tgsi.c
1 #include "xorg_exa_tgsi.h"
2
3 /*### stupidity defined in X11/extensions/XI.h */
4 #undef Absolute
5
6 #include "pipe/p_format.h"
7 #include "pipe/p_context.h"
8 #include "pipe/p_state.h"
9 #include "pipe/p_shader_tokens.h"
10
11 #include "util/u_memory.h"
12
13 #include "tgsi/tgsi_ureg.h"
14
15 #include "cso_cache/cso_context.h"
16 #include "cso_cache/cso_hash.h"
17
18 /* Vertex shader:
19 * IN[0] = vertex pos
20 * IN[1] = src tex coord | solid fill color
21 * IN[2] = mask tex coord
22 * IN[3] = dst tex coord
23 * CONST[0] = (2/dst_width, 2/dst_height, 1, 1)
24 * CONST[1] = (-1, -1, 0, 0)
25 *
26 * OUT[0] = vertex pos
27 * OUT[1] = src tex coord | solid fill color
28 * OUT[2] = mask tex coord
29 * OUT[3] = dst tex coord
30 */
31
32 /* Fragment shader:
33 * SAMP[0] = src
34 * SAMP[1] = mask
35 * SAMP[2] = dst
36 * IN[0] = pos src | solid fill color
37 * IN[1] = pos mask
38 * IN[2] = pos dst
39 * CONST[0] = (0, 0, 0, 1)
40 *
41 * OUT[0] = color
42 */
43
44 static void
45 print_fs_traits(int fs_traits)
46 {
47 const char *strings[] = {
48 "FS_COMPOSITE", /* = 1 << 0, */
49 "FS_MASK", /* = 1 << 1, */
50 "FS_SOLID_FILL", /* = 1 << 2, */
51 "FS_LINGRAD_FILL", /* = 1 << 3, */
52 "FS_RADGRAD_FILL", /* = 1 << 4, */
53 "FS_CA_FULL", /* = 1 << 5, */ /* src.rgba * mask.rgba */
54 "FS_CA_SRCALPHA", /* = 1 << 6, */ /* src.aaaa * mask.rgba */
55 "FS_YUV", /* = 1 << 7, */
56 "FS_SRC_REPEAT_NONE", /* = 1 << 8, */
57 "FS_MASK_REPEAT_NONE",/* = 1 << 9, */
58 "FS_SRC_SWIZZLE_RGB", /* = 1 << 10, */
59 "FS_MASK_SWIZZLE_RGB",/* = 1 << 11, */
60 "FS_SRC_SET_ALPHA", /* = 1 << 12, */
61 "FS_MASK_SET_ALPHA", /* = 1 << 13, */
62 "FS_SRC_LUMINANCE", /* = 1 << 14, */
63 "FS_MASK_LUMINANCE", /* = 1 << 15, */
64 };
65 int i, k;
66 debug_printf("%s: ", __func__);
67
68 for (i = 0, k = 1; k < (1 << 16); i++, k <<= 1) {
69 if (fs_traits & k)
70 debug_printf("%s, ", strings[i]);
71 }
72
73 debug_printf("\n");
74 }
75
76 struct xorg_shaders {
77 struct xorg_renderer *r;
78
79 struct cso_hash *vs_hash;
80 struct cso_hash *fs_hash;
81 };
82
83 static INLINE void
84 src_in_mask(struct ureg_program *ureg,
85 struct ureg_dst dst,
86 struct ureg_src src,
87 struct ureg_src mask,
88 unsigned component_alpha,
89 unsigned mask_luminance)
90 {
91 if (component_alpha == FS_CA_FULL) {
92 ureg_MUL(ureg, dst, src, mask);
93 } else if (component_alpha == FS_CA_SRCALPHA) {
94 ureg_MUL(ureg, dst,
95 ureg_scalar(src, TGSI_SWIZZLE_W), mask);
96 }
97 else {
98 if (mask_luminance)
99 ureg_MUL(ureg, dst, src,
100 ureg_scalar(mask, TGSI_SWIZZLE_X));
101 else
102 ureg_MUL(ureg, dst, src,
103 ureg_scalar(mask, TGSI_SWIZZLE_W));
104 }
105 }
106
107 static struct ureg_src
108 vs_normalize_coords(struct ureg_program *ureg, struct ureg_src coords,
109 struct ureg_src const0, struct ureg_src const1)
110 {
111 struct ureg_dst tmp = ureg_DECL_temporary(ureg);
112 struct ureg_src ret;
113 ureg_MAD(ureg, tmp, coords, const0, const1);
114 ret = ureg_src(tmp);
115 ureg_release_temporary(ureg, tmp);
116 return ret;
117 }
118
119 static void
120 linear_gradient(struct ureg_program *ureg,
121 struct ureg_dst out,
122 struct ureg_src pos,
123 struct ureg_src sampler,
124 struct ureg_src coords,
125 struct ureg_src const0124,
126 struct ureg_src matrow0,
127 struct ureg_src matrow1,
128 struct ureg_src matrow2)
129 {
130 struct ureg_dst temp0 = ureg_DECL_temporary(ureg);
131 struct ureg_dst temp1 = ureg_DECL_temporary(ureg);
132 struct ureg_dst temp2 = ureg_DECL_temporary(ureg);
133 struct ureg_dst temp3 = ureg_DECL_temporary(ureg);
134 struct ureg_dst temp4 = ureg_DECL_temporary(ureg);
135 struct ureg_dst temp5 = ureg_DECL_temporary(ureg);
136
137 ureg_MOV(ureg,
138 ureg_writemask(temp0, TGSI_WRITEMASK_XY), pos);
139 ureg_MOV(ureg,
140 ureg_writemask(temp0, TGSI_WRITEMASK_Z),
141 ureg_scalar(const0124, TGSI_SWIZZLE_Y));
142
143 ureg_DP3(ureg, temp1, matrow0, ureg_src(temp0));
144 ureg_DP3(ureg, temp2, matrow1, ureg_src(temp0));
145 ureg_DP3(ureg, temp3, matrow2, ureg_src(temp0));
146 ureg_RCP(ureg, temp3, ureg_src(temp3));
147 ureg_MUL(ureg, temp1, ureg_src(temp1), ureg_src(temp3));
148 ureg_MUL(ureg, temp2, ureg_src(temp2), ureg_src(temp3));
149
150 ureg_MOV(ureg, ureg_writemask(temp4, TGSI_WRITEMASK_X),
151 ureg_src(temp1));
152 ureg_MOV(ureg, ureg_writemask(temp4, TGSI_WRITEMASK_Y),
153 ureg_src(temp2));
154
155 ureg_MUL(ureg, temp0,
156 ureg_scalar(coords, TGSI_SWIZZLE_Y),
157 ureg_scalar(ureg_src(temp4), TGSI_SWIZZLE_Y));
158 ureg_MAD(ureg, temp1,
159 ureg_scalar(coords, TGSI_SWIZZLE_X),
160 ureg_scalar(ureg_src(temp4), TGSI_SWIZZLE_X),
161 ureg_src(temp0));
162
163 ureg_MUL(ureg, temp2,
164 ureg_src(temp1),
165 ureg_scalar(coords, TGSI_SWIZZLE_Z));
166
167 ureg_TEX(ureg, out,
168 TGSI_TEXTURE_1D, ureg_src(temp2), sampler);
169
170 ureg_release_temporary(ureg, temp0);
171 ureg_release_temporary(ureg, temp1);
172 ureg_release_temporary(ureg, temp2);
173 ureg_release_temporary(ureg, temp3);
174 ureg_release_temporary(ureg, temp4);
175 ureg_release_temporary(ureg, temp5);
176 }
177
178
179 static void
180 radial_gradient(struct ureg_program *ureg,
181 struct ureg_dst out,
182 struct ureg_src pos,
183 struct ureg_src sampler,
184 struct ureg_src coords,
185 struct ureg_src const0124,
186 struct ureg_src matrow0,
187 struct ureg_src matrow1,
188 struct ureg_src matrow2)
189 {
190 struct ureg_dst temp0 = ureg_DECL_temporary(ureg);
191 struct ureg_dst temp1 = ureg_DECL_temporary(ureg);
192 struct ureg_dst temp2 = ureg_DECL_temporary(ureg);
193 struct ureg_dst temp3 = ureg_DECL_temporary(ureg);
194 struct ureg_dst temp4 = ureg_DECL_temporary(ureg);
195 struct ureg_dst temp5 = ureg_DECL_temporary(ureg);
196
197 ureg_MOV(ureg,
198 ureg_writemask(temp0, TGSI_WRITEMASK_XY),
199 pos);
200 ureg_MOV(ureg,
201 ureg_writemask(temp0, TGSI_WRITEMASK_Z),
202 ureg_scalar(const0124, TGSI_SWIZZLE_Y));
203
204 ureg_DP3(ureg, temp1, matrow0, ureg_src(temp0));
205 ureg_DP3(ureg, temp2, matrow1, ureg_src(temp0));
206 ureg_DP3(ureg, temp3, matrow2, ureg_src(temp0));
207 ureg_RCP(ureg, temp3, ureg_src(temp3));
208 ureg_MUL(ureg, temp1, ureg_src(temp1), ureg_src(temp3));
209 ureg_MUL(ureg, temp2, ureg_src(temp2), ureg_src(temp3));
210
211 ureg_MOV(ureg, ureg_writemask(temp5, TGSI_WRITEMASK_X),
212 ureg_src(temp1));
213 ureg_MOV(ureg, ureg_writemask(temp5, TGSI_WRITEMASK_Y),
214 ureg_src(temp2));
215
216 ureg_MUL(ureg, temp0, ureg_scalar(coords, TGSI_SWIZZLE_Y),
217 ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_Y));
218 ureg_MAD(ureg, temp1,
219 ureg_scalar(coords, TGSI_SWIZZLE_X),
220 ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_X),
221 ureg_src(temp0));
222 ureg_ADD(ureg, temp1,
223 ureg_src(temp1), ureg_src(temp1));
224 ureg_MUL(ureg, temp3,
225 ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_Y),
226 ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_Y));
227 ureg_MAD(ureg, temp4,
228 ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_X),
229 ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_X),
230 ureg_src(temp3));
231 ureg_MOV(ureg, temp4, ureg_negate(ureg_src(temp4)));
232 ureg_MUL(ureg, temp2,
233 ureg_scalar(coords, TGSI_SWIZZLE_Z),
234 ureg_src(temp4));
235 ureg_MUL(ureg, temp0,
236 ureg_scalar(const0124, TGSI_SWIZZLE_W),
237 ureg_src(temp2));
238 ureg_MUL(ureg, temp3,
239 ureg_src(temp1), ureg_src(temp1));
240 ureg_SUB(ureg, temp2,
241 ureg_src(temp3), ureg_src(temp0));
242 ureg_RSQ(ureg, temp2, ureg_abs(ureg_src(temp2)));
243 ureg_RCP(ureg, temp2, ureg_src(temp2));
244 ureg_SUB(ureg, temp1,
245 ureg_src(temp2), ureg_src(temp1));
246 ureg_ADD(ureg, temp0,
247 ureg_scalar(coords, TGSI_SWIZZLE_Z),
248 ureg_scalar(coords, TGSI_SWIZZLE_Z));
249 ureg_RCP(ureg, temp0, ureg_src(temp0));
250 ureg_MUL(ureg, temp2,
251 ureg_src(temp1), ureg_src(temp0));
252 ureg_TEX(ureg, out, TGSI_TEXTURE_1D,
253 ureg_src(temp2), sampler);
254
255 ureg_release_temporary(ureg, temp0);
256 ureg_release_temporary(ureg, temp1);
257 ureg_release_temporary(ureg, temp2);
258 ureg_release_temporary(ureg, temp3);
259 ureg_release_temporary(ureg, temp4);
260 ureg_release_temporary(ureg, temp5);
261 }
262
263 static void *
264 create_vs(struct pipe_context *pipe,
265 unsigned vs_traits)
266 {
267 struct ureg_program *ureg;
268 struct ureg_src src;
269 struct ureg_dst dst;
270 struct ureg_src const0, const1;
271 boolean is_fill = (vs_traits & VS_FILL) != 0;
272 boolean is_composite = (vs_traits & VS_COMPOSITE) != 0;
273 boolean has_mask = (vs_traits & VS_MASK) != 0;
274 boolean is_yuv = (vs_traits & VS_YUV) != 0;
275 unsigned input_slot = 0;
276
277 ureg = ureg_create(TGSI_PROCESSOR_VERTEX);
278 if (ureg == NULL)
279 return 0;
280
281 const0 = ureg_DECL_constant(ureg, 0);
282 const1 = ureg_DECL_constant(ureg, 1);
283
284 /* it has to be either a fill or a composite op */
285 debug_assert((is_fill ^ is_composite) ^ is_yuv);
286
287 src = ureg_DECL_vs_input(ureg, input_slot++);
288 dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0);
289 src = vs_normalize_coords(ureg, src,
290 const0, const1);
291 ureg_MOV(ureg, dst, src);
292
293 if (is_yuv) {
294 src = ureg_DECL_vs_input(ureg, input_slot++);
295 dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 0);
296 ureg_MOV(ureg, dst, src);
297 }
298
299 if (is_composite) {
300 src = ureg_DECL_vs_input(ureg, input_slot++);
301 dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 0);
302 ureg_MOV(ureg, dst, src);
303 }
304
305 if (is_fill) {
306 src = ureg_DECL_vs_input(ureg, input_slot++);
307 dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
308 ureg_MOV(ureg, dst, src);
309 }
310
311 if (has_mask) {
312 src = ureg_DECL_vs_input(ureg, input_slot++);
313 dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 1);
314 ureg_MOV(ureg, dst, src);
315 }
316
317 ureg_END(ureg);
318
319 return ureg_create_shader_and_destroy(ureg, pipe);
320 }
321
322 static void *
323 create_yuv_shader(struct pipe_context *pipe, struct ureg_program *ureg)
324 {
325 struct ureg_src y_sampler, u_sampler, v_sampler;
326 struct ureg_src pos;
327 struct ureg_src matrow0, matrow1, matrow2;
328 struct ureg_dst y, u, v, rgb;
329 struct ureg_dst out = ureg_DECL_output(ureg,
330 TGSI_SEMANTIC_COLOR,
331 0);
332
333 pos = ureg_DECL_fs_input(ureg,
334 TGSI_SEMANTIC_GENERIC,
335 0,
336 TGSI_INTERPOLATE_PERSPECTIVE);
337
338 rgb = ureg_DECL_temporary(ureg);
339 y = ureg_DECL_temporary(ureg);
340 u = ureg_DECL_temporary(ureg);
341 v = ureg_DECL_temporary(ureg);
342
343 y_sampler = ureg_DECL_sampler(ureg, 0);
344 u_sampler = ureg_DECL_sampler(ureg, 1);
345 v_sampler = ureg_DECL_sampler(ureg, 2);
346
347 matrow0 = ureg_DECL_constant(ureg, 0);
348 matrow1 = ureg_DECL_constant(ureg, 1);
349 matrow2 = ureg_DECL_constant(ureg, 2);
350
351 ureg_TEX(ureg, y,
352 TGSI_TEXTURE_2D, pos, y_sampler);
353 ureg_TEX(ureg, u,
354 TGSI_TEXTURE_2D, pos, u_sampler);
355 ureg_TEX(ureg, v,
356 TGSI_TEXTURE_2D, pos, v_sampler);
357
358 ureg_SUB(ureg, u, ureg_src(u),
359 ureg_scalar(matrow0, TGSI_SWIZZLE_W));
360 ureg_SUB(ureg, v, ureg_src(v),
361 ureg_scalar(matrow0, TGSI_SWIZZLE_W));
362
363 ureg_MUL(ureg, rgb,
364 ureg_scalar(ureg_src(y), TGSI_SWIZZLE_X),
365 matrow0);
366 ureg_MAD(ureg, rgb,
367 ureg_scalar(ureg_src(u), TGSI_SWIZZLE_X),
368 matrow1,
369 ureg_src(rgb));
370 ureg_MAD(ureg, rgb,
371 ureg_scalar(ureg_src(v), TGSI_SWIZZLE_X),
372 matrow2,
373 ureg_src(rgb));
374
375 /* rgb.a = 1; */
376 ureg_MOV(ureg, ureg_writemask(rgb, TGSI_WRITEMASK_W),
377 ureg_scalar(matrow0, TGSI_SWIZZLE_X));
378
379 ureg_MOV(ureg, out, ureg_src(rgb));
380
381 ureg_release_temporary(ureg, rgb);
382 ureg_release_temporary(ureg, y);
383 ureg_release_temporary(ureg, u);
384 ureg_release_temporary(ureg, v);
385
386 ureg_END(ureg);
387
388 return ureg_create_shader_and_destroy(ureg, pipe);
389 }
390
391
392 static INLINE void
393 xrender_tex(struct ureg_program *ureg,
394 struct ureg_dst dst,
395 struct ureg_src coords,
396 struct ureg_src sampler,
397 struct ureg_src imm0,
398 boolean repeat_none,
399 boolean swizzle,
400 boolean set_alpha)
401 {
402 if (repeat_none) {
403 struct ureg_dst tmp0 = ureg_DECL_temporary(ureg);
404 struct ureg_dst tmp1 = ureg_DECL_temporary(ureg);
405 ureg_SGT(ureg, tmp1, ureg_swizzle(coords,
406 TGSI_SWIZZLE_X,
407 TGSI_SWIZZLE_Y,
408 TGSI_SWIZZLE_X,
409 TGSI_SWIZZLE_Y),
410 ureg_scalar(imm0, TGSI_SWIZZLE_X));
411 ureg_SLT(ureg, tmp0, ureg_swizzle(coords,
412 TGSI_SWIZZLE_X,
413 TGSI_SWIZZLE_Y,
414 TGSI_SWIZZLE_X,
415 TGSI_SWIZZLE_Y),
416 ureg_scalar(imm0, TGSI_SWIZZLE_W));
417 ureg_MIN(ureg, tmp0, ureg_src(tmp0), ureg_src(tmp1));
418 ureg_MIN(ureg, tmp0, ureg_scalar(ureg_src(tmp0), TGSI_SWIZZLE_X),
419 ureg_scalar(ureg_src(tmp0), TGSI_SWIZZLE_Y));
420 ureg_TEX(ureg, tmp1, TGSI_TEXTURE_2D, coords, sampler);
421 if (swizzle)
422 ureg_MOV(ureg, tmp1, ureg_swizzle(ureg_src(tmp1),
423 TGSI_SWIZZLE_Z,
424 TGSI_SWIZZLE_Y,
425 TGSI_SWIZZLE_X,
426 TGSI_SWIZZLE_W));
427 if (set_alpha)
428 ureg_MOV(ureg,
429 ureg_writemask(tmp1, TGSI_WRITEMASK_W),
430 ureg_scalar(imm0, TGSI_SWIZZLE_W));
431 ureg_MUL(ureg, dst, ureg_src(tmp1), ureg_src(tmp0));
432 ureg_release_temporary(ureg, tmp0);
433 ureg_release_temporary(ureg, tmp1);
434 } else {
435 if (swizzle) {
436 struct ureg_dst tmp = ureg_DECL_temporary(ureg);
437 ureg_TEX(ureg, tmp, TGSI_TEXTURE_2D, coords, sampler);
438 ureg_MOV(ureg, dst, ureg_swizzle(ureg_src(tmp),
439 TGSI_SWIZZLE_Z,
440 TGSI_SWIZZLE_Y,
441 TGSI_SWIZZLE_X,
442 TGSI_SWIZZLE_W));
443 ureg_release_temporary(ureg, tmp);
444 } else {
445 ureg_TEX(ureg, dst, TGSI_TEXTURE_2D, coords, sampler);
446 }
447 if (set_alpha)
448 ureg_MOV(ureg,
449 ureg_writemask(dst, TGSI_WRITEMASK_W),
450 ureg_scalar(imm0, TGSI_SWIZZLE_W));
451 }
452 }
453
454 static void *
455 create_fs(struct pipe_context *pipe,
456 unsigned fs_traits)
457 {
458 struct ureg_program *ureg;
459 struct ureg_src /*dst_sampler,*/ src_sampler, mask_sampler;
460 struct ureg_src /*dst_pos,*/ src_input, mask_pos;
461 struct ureg_dst src, mask;
462 struct ureg_dst out;
463 struct ureg_src imm0 = { 0 };
464 unsigned has_mask = (fs_traits & FS_MASK) != 0;
465 unsigned is_fill = (fs_traits & FS_FILL) != 0;
466 unsigned is_composite = (fs_traits & FS_COMPOSITE) != 0;
467 unsigned is_solid = (fs_traits & FS_SOLID_FILL) != 0;
468 unsigned is_lingrad = (fs_traits & FS_LINGRAD_FILL) != 0;
469 unsigned is_radgrad = (fs_traits & FS_RADGRAD_FILL) != 0;
470 unsigned comp_alpha_mask = fs_traits & FS_COMPONENT_ALPHA;
471 unsigned is_yuv = (fs_traits & FS_YUV) != 0;
472 unsigned src_repeat_none = (fs_traits & FS_SRC_REPEAT_NONE) != 0;
473 unsigned mask_repeat_none = (fs_traits & FS_MASK_REPEAT_NONE) != 0;
474 unsigned src_swizzle = (fs_traits & FS_SRC_SWIZZLE_RGB) != 0;
475 unsigned mask_swizzle = (fs_traits & FS_MASK_SWIZZLE_RGB) != 0;
476 unsigned src_set_alpha = (fs_traits & FS_SRC_SET_ALPHA) != 0;
477 unsigned mask_set_alpha = (fs_traits & FS_MASK_SET_ALPHA) != 0;
478 unsigned src_luminance = (fs_traits & FS_SRC_LUMINANCE) != 0;
479 unsigned mask_luminance = (fs_traits & FS_MASK_LUMINANCE) != 0;
480
481 #if 0
482 print_fs_traits(fs_traits);
483 #else
484 (void)print_fs_traits;
485 #endif
486
487 ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT);
488 if (ureg == NULL)
489 return 0;
490
491 /* it has to be either a fill, a composite op or a yuv conversion */
492 debug_assert((is_fill ^ is_composite) ^ is_yuv);
493 (void) is_yuv;
494
495 out = ureg_DECL_output(ureg,
496 TGSI_SEMANTIC_COLOR,
497 0);
498
499 if (src_repeat_none || mask_repeat_none ||
500 src_set_alpha || mask_set_alpha ||
501 src_luminance) {
502 imm0 = ureg_imm4f(ureg, 0, 0, 0, 1);
503 }
504 if (is_composite) {
505 src_sampler = ureg_DECL_sampler(ureg, 0);
506 src_input = ureg_DECL_fs_input(ureg,
507 TGSI_SEMANTIC_GENERIC,
508 0,
509 TGSI_INTERPOLATE_PERSPECTIVE);
510 } else if (is_fill) {
511 if (is_solid)
512 src_input = ureg_DECL_fs_input(ureg,
513 TGSI_SEMANTIC_COLOR,
514 0,
515 TGSI_INTERPOLATE_PERSPECTIVE);
516 else
517 src_input = ureg_DECL_fs_input(ureg,
518 TGSI_SEMANTIC_POSITION,
519 0,
520 TGSI_INTERPOLATE_PERSPECTIVE);
521 } else {
522 debug_assert(is_yuv);
523 return create_yuv_shader(pipe, ureg);
524 }
525
526 if (has_mask) {
527 mask_sampler = ureg_DECL_sampler(ureg, 1);
528 mask_pos = ureg_DECL_fs_input(ureg,
529 TGSI_SEMANTIC_GENERIC,
530 1,
531 TGSI_INTERPOLATE_PERSPECTIVE);
532 }
533
534 #if 0 /* unused right now */
535 dst_sampler = ureg_DECL_sampler(ureg, 2);
536 dst_pos = ureg_DECL_fs_input(ureg,
537 TGSI_SEMANTIC_POSITION,
538 2,
539 TGSI_INTERPOLATE_PERSPECTIVE);
540 #endif
541
542
543 if (is_composite) {
544 if (has_mask || src_luminance)
545 src = ureg_DECL_temporary(ureg);
546 else
547 src = out;
548 xrender_tex(ureg, src, src_input, src_sampler, imm0,
549 src_repeat_none, src_swizzle, src_set_alpha);
550 } else if (is_fill) {
551 if (is_solid) {
552 if (has_mask || src_luminance)
553 src = ureg_dst(src_input);
554 else
555 ureg_MOV(ureg, out, src_input);
556 } else if (is_lingrad || is_radgrad) {
557 struct ureg_src coords, const0124,
558 matrow0, matrow1, matrow2;
559
560 if (has_mask || src_luminance)
561 src = ureg_DECL_temporary(ureg);
562 else
563 src = out;
564
565 coords = ureg_DECL_constant(ureg, 0);
566 const0124 = ureg_DECL_constant(ureg, 1);
567 matrow0 = ureg_DECL_constant(ureg, 2);
568 matrow1 = ureg_DECL_constant(ureg, 3);
569 matrow2 = ureg_DECL_constant(ureg, 4);
570
571 if (is_lingrad) {
572 linear_gradient(ureg, src,
573 src_input, src_sampler,
574 coords, const0124,
575 matrow0, matrow1, matrow2);
576 } else if (is_radgrad) {
577 radial_gradient(ureg, src,
578 src_input, src_sampler,
579 coords, const0124,
580 matrow0, matrow1, matrow2);
581 }
582 } else
583 debug_assert(!"Unknown fill type!");
584 }
585 if (src_luminance) {
586 ureg_MOV(ureg, src,
587 ureg_scalar(ureg_src(src), TGSI_SWIZZLE_X));
588 ureg_MOV(ureg, ureg_writemask(src, TGSI_WRITEMASK_XYZ),
589 ureg_scalar(imm0, TGSI_SWIZZLE_X));
590 if (!has_mask)
591 ureg_MOV(ureg, out, ureg_src(src));
592 }
593
594 if (has_mask) {
595 mask = ureg_DECL_temporary(ureg);
596 xrender_tex(ureg, mask, mask_pos, mask_sampler, imm0,
597 mask_repeat_none, mask_swizzle, mask_set_alpha);
598 /* src IN mask */
599 src_in_mask(ureg, out, ureg_src(src), ureg_src(mask),
600 comp_alpha_mask, mask_luminance);
601 ureg_release_temporary(ureg, mask);
602 }
603
604 ureg_END(ureg);
605
606 return ureg_create_shader_and_destroy(ureg, pipe);
607 }
608
609 struct xorg_shaders * xorg_shaders_create(struct xorg_renderer *r)
610 {
611 struct xorg_shaders *sc = CALLOC_STRUCT(xorg_shaders);
612
613 sc->r = r;
614 sc->vs_hash = cso_hash_create();
615 sc->fs_hash = cso_hash_create();
616
617 return sc;
618 }
619
620 static void
621 cache_destroy(struct cso_context *cso,
622 struct cso_hash *hash,
623 unsigned processor)
624 {
625 struct cso_hash_iter iter = cso_hash_first_node(hash);
626 while (!cso_hash_iter_is_null(iter)) {
627 void *shader = (void *)cso_hash_iter_data(iter);
628 if (processor == PIPE_SHADER_FRAGMENT) {
629 cso_delete_fragment_shader(cso, shader);
630 } else if (processor == PIPE_SHADER_VERTEX) {
631 cso_delete_vertex_shader(cso, shader);
632 }
633 iter = cso_hash_erase(hash, iter);
634 }
635 cso_hash_delete(hash);
636 }
637
638 void xorg_shaders_destroy(struct xorg_shaders *sc)
639 {
640 cache_destroy(sc->r->cso, sc->vs_hash,
641 PIPE_SHADER_VERTEX);
642 cache_destroy(sc->r->cso, sc->fs_hash,
643 PIPE_SHADER_FRAGMENT);
644
645 free(sc);
646 }
647
648 static INLINE void *
649 shader_from_cache(struct pipe_context *pipe,
650 unsigned type,
651 struct cso_hash *hash,
652 unsigned key)
653 {
654 void *shader = 0;
655
656 struct cso_hash_iter iter = cso_hash_find(hash, key);
657
658 if (cso_hash_iter_is_null(iter)) {
659 if (type == PIPE_SHADER_VERTEX)
660 shader = create_vs(pipe, key);
661 else
662 shader = create_fs(pipe, key);
663 cso_hash_insert(hash, key, shader);
664 } else
665 shader = (void *)cso_hash_iter_data(iter);
666
667 return shader;
668 }
669
670 struct xorg_shader xorg_shaders_get(struct xorg_shaders *sc,
671 unsigned vs_traits,
672 unsigned fs_traits)
673 {
674 struct xorg_shader shader = { NULL, NULL };
675 void *vs, *fs;
676
677 vs = shader_from_cache(sc->r->pipe, PIPE_SHADER_VERTEX,
678 sc->vs_hash, vs_traits);
679 fs = shader_from_cache(sc->r->pipe, PIPE_SHADER_FRAGMENT,
680 sc->fs_hash, fs_traits);
681
682 debug_assert(vs && fs);
683 if (!vs || !fs)
684 return shader;
685
686 shader.vs = vs;
687 shader.fs = fs;
688
689 return shader;
690 }