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