1 #include "xorg_exa_tgsi.h"
3 /*### stupidity defined in X11/extensions/XI.h */
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"
11 #include "util/u_memory.h"
13 #include "tgsi/tgsi_ureg.h"
15 #include "cso_cache/cso_context.h"
16 #include "cso_cache/cso_hash.h"
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)
27 * OUT[1] = src tex coord | solid fill color
28 * OUT[2] = mask tex coord
29 * OUT[3] = dst tex coord
36 * IN[0] = pos src | solid fill color
39 * CONST[0] = (0, 0, 0, 1)
45 print_fs_traits(int fs_traits)
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, */
66 debug_printf("%s: ", __func__);
68 for (i = 0, k = 1; k < (1 << 16); i++, k <<= 1) {
70 debug_printf("%s, ", strings[i]);
77 struct xorg_renderer *r;
79 struct cso_hash *vs_hash;
80 struct cso_hash *fs_hash;
84 src_in_mask(struct ureg_program *ureg,
88 unsigned component_alpha,
89 unsigned mask_luminance)
91 if (component_alpha == FS_CA_FULL) {
92 ureg_MUL(ureg, dst, src, mask);
93 } else if (component_alpha == FS_CA_SRCALPHA) {
95 ureg_scalar(src, TGSI_SWIZZLE_W), mask);
99 ureg_MUL(ureg, dst, src,
100 ureg_scalar(mask, TGSI_SWIZZLE_X));
102 ureg_MUL(ureg, dst, src,
103 ureg_scalar(mask, TGSI_SWIZZLE_W));
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)
111 struct ureg_dst tmp = ureg_DECL_temporary(ureg);
113 ureg_MAD(ureg, tmp, coords, const0, const1);
115 ureg_release_temporary(ureg, tmp);
120 linear_gradient(struct ureg_program *ureg,
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)
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);
138 ureg_writemask(temp0, TGSI_WRITEMASK_XY), pos);
140 ureg_writemask(temp0, TGSI_WRITEMASK_Z),
141 ureg_scalar(const0124, TGSI_SWIZZLE_Y));
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));
150 ureg_MOV(ureg, ureg_writemask(temp4, TGSI_WRITEMASK_X),
152 ureg_MOV(ureg, ureg_writemask(temp4, TGSI_WRITEMASK_Y),
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),
163 ureg_MUL(ureg, temp2,
165 ureg_scalar(coords, TGSI_SWIZZLE_Z));
168 TGSI_TEXTURE_1D, ureg_src(temp2), sampler);
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);
180 radial_gradient(struct ureg_program *ureg,
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)
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);
198 ureg_writemask(temp0, TGSI_WRITEMASK_XY),
201 ureg_writemask(temp0, TGSI_WRITEMASK_Z),
202 ureg_scalar(const0124, TGSI_SWIZZLE_Y));
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));
211 ureg_MOV(ureg, ureg_writemask(temp5, TGSI_WRITEMASK_X),
213 ureg_MOV(ureg, ureg_writemask(temp5, TGSI_WRITEMASK_Y),
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),
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),
231 ureg_MOV(ureg, temp4, ureg_negate(ureg_src(temp4)));
232 ureg_MUL(ureg, temp2,
233 ureg_scalar(coords, TGSI_SWIZZLE_Z),
235 ureg_MUL(ureg, temp0,
236 ureg_scalar(const0124, TGSI_SWIZZLE_W),
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);
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);
264 create_vs(struct pipe_context *pipe,
267 struct ureg_program *ureg;
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;
277 ureg = ureg_create(TGSI_PROCESSOR_VERTEX);
281 const0 = ureg_DECL_constant(ureg, 0);
282 const1 = ureg_DECL_constant(ureg, 1);
284 /* it has to be either a fill or a composite op */
285 debug_assert((is_fill ^ is_composite) ^ is_yuv);
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,
291 ureg_MOV(ureg, dst, src);
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);
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);
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);
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);
319 return ureg_create_shader_and_destroy(ureg, pipe);
323 create_yuv_shader(struct pipe_context *pipe, struct ureg_program *ureg)
325 struct ureg_src y_sampler, u_sampler, v_sampler;
327 struct ureg_src matrow0, matrow1, matrow2;
328 struct ureg_dst y, u, v, rgb;
329 struct ureg_dst out = ureg_DECL_output(ureg,
333 pos = ureg_DECL_fs_input(ureg,
334 TGSI_SEMANTIC_GENERIC,
336 TGSI_INTERPOLATE_PERSPECTIVE);
338 rgb = ureg_DECL_temporary(ureg);
339 y = ureg_DECL_temporary(ureg);
340 u = ureg_DECL_temporary(ureg);
341 v = ureg_DECL_temporary(ureg);
343 y_sampler = ureg_DECL_sampler(ureg, 0);
344 u_sampler = ureg_DECL_sampler(ureg, 1);
345 v_sampler = ureg_DECL_sampler(ureg, 2);
347 matrow0 = ureg_DECL_constant(ureg, 0);
348 matrow1 = ureg_DECL_constant(ureg, 1);
349 matrow2 = ureg_DECL_constant(ureg, 2);
352 TGSI_TEXTURE_2D, pos, y_sampler);
354 TGSI_TEXTURE_2D, pos, u_sampler);
356 TGSI_TEXTURE_2D, pos, v_sampler);
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));
364 ureg_scalar(ureg_src(y), TGSI_SWIZZLE_X),
367 ureg_scalar(ureg_src(u), TGSI_SWIZZLE_X),
371 ureg_scalar(ureg_src(v), TGSI_SWIZZLE_X),
376 ureg_MOV(ureg, ureg_writemask(rgb, TGSI_WRITEMASK_W),
377 ureg_scalar(matrow0, TGSI_SWIZZLE_X));
379 ureg_MOV(ureg, out, ureg_src(rgb));
381 ureg_release_temporary(ureg, rgb);
382 ureg_release_temporary(ureg, y);
383 ureg_release_temporary(ureg, u);
384 ureg_release_temporary(ureg, v);
388 return ureg_create_shader_and_destroy(ureg, pipe);
393 xrender_tex(struct ureg_program *ureg,
395 struct ureg_src coords,
396 struct ureg_src sampler,
397 struct ureg_src imm0,
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,
410 ureg_scalar(imm0, TGSI_SWIZZLE_X));
411 ureg_SLT(ureg, tmp0, ureg_swizzle(coords,
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);
422 ureg_MOV(ureg, tmp1, ureg_swizzle(ureg_src(tmp1),
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);
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),
443 ureg_release_temporary(ureg, tmp);
445 ureg_TEX(ureg, dst, TGSI_TEXTURE_2D, coords, sampler);
449 ureg_writemask(dst, TGSI_WRITEMASK_W),
450 ureg_scalar(imm0, TGSI_SWIZZLE_W));
455 create_fs(struct pipe_context *pipe,
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;
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;
482 print_fs_traits(fs_traits);
484 (void)print_fs_traits;
487 ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT);
491 /* it has to be either a fill, a composite op or a yuv conversion */
492 debug_assert((is_fill ^ is_composite) ^ is_yuv);
495 out = ureg_DECL_output(ureg,
499 if (src_repeat_none || mask_repeat_none ||
500 src_set_alpha || mask_set_alpha ||
502 imm0 = ureg_imm4f(ureg, 0, 0, 0, 1);
505 src_sampler = ureg_DECL_sampler(ureg, 0);
506 src_input = ureg_DECL_fs_input(ureg,
507 TGSI_SEMANTIC_GENERIC,
509 TGSI_INTERPOLATE_PERSPECTIVE);
510 } else if (is_fill) {
512 src_input = ureg_DECL_fs_input(ureg,
515 TGSI_INTERPOLATE_PERSPECTIVE);
517 src_input = ureg_DECL_fs_input(ureg,
518 TGSI_SEMANTIC_POSITION,
520 TGSI_INTERPOLATE_PERSPECTIVE);
522 debug_assert(is_yuv);
523 return create_yuv_shader(pipe, ureg);
527 mask_sampler = ureg_DECL_sampler(ureg, 1);
528 mask_pos = ureg_DECL_fs_input(ureg,
529 TGSI_SEMANTIC_GENERIC,
531 TGSI_INTERPOLATE_PERSPECTIVE);
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,
539 TGSI_INTERPOLATE_PERSPECTIVE);
544 if (has_mask || src_luminance)
545 src = ureg_DECL_temporary(ureg);
548 xrender_tex(ureg, src, src_input, src_sampler, imm0,
549 src_repeat_none, src_swizzle, src_set_alpha);
550 } else if (is_fill) {
552 if (has_mask || src_luminance)
553 src = ureg_dst(src_input);
555 ureg_MOV(ureg, out, src_input);
556 } else if (is_lingrad || is_radgrad) {
557 struct ureg_src coords, const0124,
558 matrow0, matrow1, matrow2;
560 if (has_mask || src_luminance)
561 src = ureg_DECL_temporary(ureg);
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);
572 linear_gradient(ureg, src,
573 src_input, src_sampler,
575 matrow0, matrow1, matrow2);
576 } else if (is_radgrad) {
577 radial_gradient(ureg, src,
578 src_input, src_sampler,
580 matrow0, matrow1, matrow2);
583 debug_assert(!"Unknown fill type!");
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));
591 ureg_MOV(ureg, out, ureg_src(src));
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);
599 src_in_mask(ureg, out, ureg_src(src), ureg_src(mask),
600 comp_alpha_mask, mask_luminance);
601 ureg_release_temporary(ureg, mask);
606 return ureg_create_shader_and_destroy(ureg, pipe);
609 struct xorg_shaders * xorg_shaders_create(struct xorg_renderer *r)
611 struct xorg_shaders *sc = CALLOC_STRUCT(xorg_shaders);
614 sc->vs_hash = cso_hash_create();
615 sc->fs_hash = cso_hash_create();
621 cache_destroy(struct cso_context *cso,
622 struct cso_hash *hash,
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);
633 iter = cso_hash_erase(hash, iter);
635 cso_hash_delete(hash);
638 void xorg_shaders_destroy(struct xorg_shaders *sc)
640 cache_destroy(sc->r->cso, sc->vs_hash,
642 cache_destroy(sc->r->cso, sc->fs_hash,
643 PIPE_SHADER_FRAGMENT);
649 shader_from_cache(struct pipe_context *pipe,
651 struct cso_hash *hash,
656 struct cso_hash_iter iter = cso_hash_find(hash, key);
658 if (cso_hash_iter_is_null(iter)) {
659 if (type == PIPE_SHADER_VERTEX)
660 shader = create_vs(pipe, key);
662 shader = create_fs(pipe, key);
663 cso_hash_insert(hash, key, shader);
665 shader = (void *)cso_hash_iter_data(iter);
670 struct xorg_shader xorg_shaders_get(struct xorg_shaders *sc,
674 struct xorg_shader shader = { NULL, NULL };
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);
682 debug_assert(vs && fs);