1 /**********************************************************
2 * Copyright 2009-2011 VMware, Inc. All rights reserved.
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use, copy,
8 * modify, merge, publish, distribute, sublicense, and/or sell copies
9 * of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 *********************************************************
26 * Zack Rusin <zackr-at-vmware-dot-com>
30 #include "pipe/p_format.h"
31 #include "pipe/p_context.h"
32 #include "pipe/p_state.h"
33 #include "pipe/p_shader_tokens.h"
35 #include "util/u_memory.h"
37 #include "tgsi/tgsi_ureg.h"
39 #include "cso_cache/cso_context.h"
40 #include "cso_cache/cso_hash.h"
44 * IN[1] = src tex coord | solid fill color
45 * IN[2] = mask tex coord
46 * IN[3] = dst tex coord
47 * CONST[0] = (2/dst_width, 2/dst_height, 1, 1)
48 * CONST[1] = (-1, -1, 0, 0)
51 * OUT[1] = src tex coord | solid fill color
52 * OUT[2] = mask tex coord
53 * OUT[3] = dst tex coord
60 * IN[0] = pos src | solid fill color
63 * CONST[0] = (0, 0, 0, 1)
69 print_fs_traits(int fs_traits
)
71 const char *strings
[] = {
72 "FS_COMPOSITE", /* = 1 << 0, */
73 "FS_MASK", /* = 1 << 1, */
74 "FS_SOLID_FILL", /* = 1 << 2, */
75 "FS_LINGRAD_FILL", /* = 1 << 3, */
76 "FS_RADGRAD_FILL", /* = 1 << 4, */
77 "FS_CA_FULL", /* = 1 << 5, *//* src.rgba * mask.rgba */
78 "FS_CA_SRCALPHA", /* = 1 << 6, *//* src.aaaa * mask.rgba */
79 "FS_YUV", /* = 1 << 7, */
80 "FS_SRC_REPEAT_NONE", /* = 1 << 8, */
81 "FS_MASK_REPEAT_NONE", /* = 1 << 9, */
82 "FS_SRC_SWIZZLE_RGB", /* = 1 << 10, */
83 "FS_MASK_SWIZZLE_RGB", /* = 1 << 11, */
84 "FS_SRC_SET_ALPHA", /* = 1 << 12, */
85 "FS_MASK_SET_ALPHA", /* = 1 << 13, */
86 "FS_SRC_LUMINANCE", /* = 1 << 14, */
87 "FS_MASK_LUMINANCE", /* = 1 << 15, */
88 "FS_DST_LUMINANCE", /* = 1 << 15, */
92 debug_printf("%s: ", __func__
);
94 for (i
= 0, k
= 1; k
< (1 << 16); i
++, k
<<= 1) {
96 debug_printf("%s, ", strings
[i
]);
103 struct xa_context
*r
;
105 struct cso_hash
*vs_hash
;
106 struct cso_hash
*fs_hash
;
110 src_in_mask(struct ureg_program
*ureg
,
113 struct ureg_src mask
,
114 unsigned component_alpha
, unsigned mask_luminance
)
116 if (component_alpha
== FS_CA_FULL
) {
117 ureg_MUL(ureg
, dst
, src
, mask
);
118 } else if (component_alpha
== FS_CA_SRCALPHA
) {
119 ureg_MUL(ureg
, dst
, ureg_scalar(src
, TGSI_SWIZZLE_W
), mask
);
122 ureg_MUL(ureg
, dst
, src
, ureg_scalar(mask
, TGSI_SWIZZLE_X
));
124 ureg_MUL(ureg
, dst
, src
, ureg_scalar(mask
, TGSI_SWIZZLE_W
));
128 static struct ureg_src
129 vs_normalize_coords(struct ureg_program
*ureg
,
130 struct ureg_src coords
,
131 struct ureg_src const0
, struct ureg_src const1
)
133 struct ureg_dst tmp
= ureg_DECL_temporary(ureg
);
136 ureg_MAD(ureg
, tmp
, coords
, const0
, const1
);
138 ureg_release_temporary(ureg
, tmp
);
143 linear_gradient(struct ureg_program
*ureg
,
146 struct ureg_src sampler
,
147 struct ureg_src coords
,
148 struct ureg_src const0124
,
149 struct ureg_src matrow0
,
150 struct ureg_src matrow1
, struct ureg_src matrow2
)
152 struct ureg_dst temp0
= ureg_DECL_temporary(ureg
);
153 struct ureg_dst temp1
= ureg_DECL_temporary(ureg
);
154 struct ureg_dst temp2
= ureg_DECL_temporary(ureg
);
155 struct ureg_dst temp3
= ureg_DECL_temporary(ureg
);
156 struct ureg_dst temp4
= ureg_DECL_temporary(ureg
);
157 struct ureg_dst temp5
= ureg_DECL_temporary(ureg
);
159 ureg_MOV(ureg
, ureg_writemask(temp0
, TGSI_WRITEMASK_XY
), pos
);
161 ureg_writemask(temp0
, TGSI_WRITEMASK_Z
),
162 ureg_scalar(const0124
, TGSI_SWIZZLE_Y
));
164 ureg_DP3(ureg
, temp1
, matrow0
, ureg_src(temp0
));
165 ureg_DP3(ureg
, temp2
, matrow1
, ureg_src(temp0
));
166 ureg_DP3(ureg
, temp3
, matrow2
, ureg_src(temp0
));
167 ureg_RCP(ureg
, temp3
, ureg_src(temp3
));
168 ureg_MUL(ureg
, temp1
, ureg_src(temp1
), ureg_src(temp3
));
169 ureg_MUL(ureg
, temp2
, ureg_src(temp2
), ureg_src(temp3
));
171 ureg_MOV(ureg
, ureg_writemask(temp4
, TGSI_WRITEMASK_X
), ureg_src(temp1
));
172 ureg_MOV(ureg
, ureg_writemask(temp4
, TGSI_WRITEMASK_Y
), ureg_src(temp2
));
174 ureg_MUL(ureg
, temp0
,
175 ureg_scalar(coords
, TGSI_SWIZZLE_Y
),
176 ureg_scalar(ureg_src(temp4
), TGSI_SWIZZLE_Y
));
177 ureg_MAD(ureg
, temp1
,
178 ureg_scalar(coords
, TGSI_SWIZZLE_X
),
179 ureg_scalar(ureg_src(temp4
), TGSI_SWIZZLE_X
), ureg_src(temp0
));
181 ureg_MUL(ureg
, temp2
, ureg_src(temp1
), ureg_scalar(coords
, TGSI_SWIZZLE_Z
));
183 ureg_TEX(ureg
, out
, TGSI_TEXTURE_1D
, ureg_src(temp2
), sampler
);
185 ureg_release_temporary(ureg
, temp0
);
186 ureg_release_temporary(ureg
, temp1
);
187 ureg_release_temporary(ureg
, temp2
);
188 ureg_release_temporary(ureg
, temp3
);
189 ureg_release_temporary(ureg
, temp4
);
190 ureg_release_temporary(ureg
, temp5
);
194 radial_gradient(struct ureg_program
*ureg
,
197 struct ureg_src sampler
,
198 struct ureg_src coords
,
199 struct ureg_src const0124
,
200 struct ureg_src matrow0
,
201 struct ureg_src matrow1
, struct ureg_src matrow2
)
203 struct ureg_dst temp0
= ureg_DECL_temporary(ureg
);
204 struct ureg_dst temp1
= ureg_DECL_temporary(ureg
);
205 struct ureg_dst temp2
= ureg_DECL_temporary(ureg
);
206 struct ureg_dst temp3
= ureg_DECL_temporary(ureg
);
207 struct ureg_dst temp4
= ureg_DECL_temporary(ureg
);
208 struct ureg_dst temp5
= ureg_DECL_temporary(ureg
);
210 ureg_MOV(ureg
, ureg_writemask(temp0
, TGSI_WRITEMASK_XY
), pos
);
212 ureg_writemask(temp0
, TGSI_WRITEMASK_Z
),
213 ureg_scalar(const0124
, TGSI_SWIZZLE_Y
));
215 ureg_DP3(ureg
, temp1
, matrow0
, ureg_src(temp0
));
216 ureg_DP3(ureg
, temp2
, matrow1
, ureg_src(temp0
));
217 ureg_DP3(ureg
, temp3
, matrow2
, ureg_src(temp0
));
218 ureg_RCP(ureg
, temp3
, ureg_src(temp3
));
219 ureg_MUL(ureg
, temp1
, ureg_src(temp1
), ureg_src(temp3
));
220 ureg_MUL(ureg
, temp2
, ureg_src(temp2
), ureg_src(temp3
));
222 ureg_MOV(ureg
, ureg_writemask(temp5
, TGSI_WRITEMASK_X
), ureg_src(temp1
));
223 ureg_MOV(ureg
, ureg_writemask(temp5
, TGSI_WRITEMASK_Y
), ureg_src(temp2
));
225 ureg_MUL(ureg
, temp0
, ureg_scalar(coords
, TGSI_SWIZZLE_Y
),
226 ureg_scalar(ureg_src(temp5
), TGSI_SWIZZLE_Y
));
227 ureg_MAD(ureg
, temp1
,
228 ureg_scalar(coords
, TGSI_SWIZZLE_X
),
229 ureg_scalar(ureg_src(temp5
), TGSI_SWIZZLE_X
), ureg_src(temp0
));
230 ureg_ADD(ureg
, temp1
, ureg_src(temp1
), ureg_src(temp1
));
231 ureg_MUL(ureg
, temp3
,
232 ureg_scalar(ureg_src(temp5
), TGSI_SWIZZLE_Y
),
233 ureg_scalar(ureg_src(temp5
), TGSI_SWIZZLE_Y
));
234 ureg_MAD(ureg
, temp4
,
235 ureg_scalar(ureg_src(temp5
), TGSI_SWIZZLE_X
),
236 ureg_scalar(ureg_src(temp5
), TGSI_SWIZZLE_X
), ureg_src(temp3
));
237 ureg_MOV(ureg
, temp4
, ureg_negate(ureg_src(temp4
)));
238 ureg_MUL(ureg
, temp2
, ureg_scalar(coords
, TGSI_SWIZZLE_Z
), ureg_src(temp4
));
239 ureg_MUL(ureg
, temp0
,
240 ureg_scalar(const0124
, TGSI_SWIZZLE_W
), ureg_src(temp2
));
241 ureg_MUL(ureg
, temp3
, ureg_src(temp1
), ureg_src(temp1
));
242 ureg_SUB(ureg
, temp2
, ureg_src(temp3
), ureg_src(temp0
));
243 ureg_RSQ(ureg
, temp2
, ureg_abs(ureg_src(temp2
)));
244 ureg_RCP(ureg
, temp2
, ureg_src(temp2
));
245 ureg_SUB(ureg
, temp1
, 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
, ureg_src(temp1
), ureg_src(temp0
));
251 ureg_TEX(ureg
, out
, TGSI_TEXTURE_1D
, ureg_src(temp2
), sampler
);
253 ureg_release_temporary(ureg
, temp0
);
254 ureg_release_temporary(ureg
, temp1
);
255 ureg_release_temporary(ureg
, temp2
);
256 ureg_release_temporary(ureg
, temp3
);
257 ureg_release_temporary(ureg
, temp4
);
258 ureg_release_temporary(ureg
, temp5
);
262 create_vs(struct pipe_context
*pipe
, unsigned vs_traits
)
264 struct ureg_program
*ureg
;
267 struct ureg_src const0
, const1
;
268 boolean is_fill
= (vs_traits
& VS_FILL
) != 0;
269 boolean is_composite
= (vs_traits
& VS_COMPOSITE
) != 0;
270 boolean has_mask
= (vs_traits
& VS_MASK
) != 0;
271 boolean is_yuv
= (vs_traits
& VS_YUV
) != 0;
272 unsigned input_slot
= 0;
274 ureg
= ureg_create(TGSI_PROCESSOR_VERTEX
);
278 const0
= ureg_DECL_constant(ureg
, 0);
279 const1
= ureg_DECL_constant(ureg
, 1);
281 /* it has to be either a fill or a composite op */
282 debug_assert((is_fill
^ is_composite
) ^ is_yuv
);
284 src
= ureg_DECL_vs_input(ureg
, input_slot
++);
285 dst
= ureg_DECL_output(ureg
, TGSI_SEMANTIC_POSITION
, 0);
286 src
= vs_normalize_coords(ureg
, src
, const0
, const1
);
287 ureg_MOV(ureg
, dst
, src
);
290 src
= ureg_DECL_vs_input(ureg
, input_slot
++);
291 dst
= ureg_DECL_output(ureg
, TGSI_SEMANTIC_GENERIC
, 0);
292 ureg_MOV(ureg
, dst
, src
);
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
);
302 src
= ureg_DECL_vs_input(ureg
, input_slot
++);
303 dst
= ureg_DECL_output(ureg
, TGSI_SEMANTIC_COLOR
, 0);
304 ureg_MOV(ureg
, dst
, src
);
308 src
= ureg_DECL_vs_input(ureg
, input_slot
++);
309 dst
= ureg_DECL_output(ureg
, TGSI_SEMANTIC_GENERIC
, 1);
310 ureg_MOV(ureg
, dst
, src
);
315 return ureg_create_shader_and_destroy(ureg
, pipe
);
319 create_yuv_shader(struct pipe_context
*pipe
, struct ureg_program
*ureg
)
321 struct ureg_src y_sampler
, u_sampler
, v_sampler
;
323 struct ureg_src matrow0
, matrow1
, matrow2
, matrow3
;
324 struct ureg_dst y
, u
, v
, rgb
;
325 struct ureg_dst out
= ureg_DECL_output(ureg
,
329 pos
= ureg_DECL_fs_input(ureg
,
330 TGSI_SEMANTIC_GENERIC
, 0,
331 TGSI_INTERPOLATE_PERSPECTIVE
);
333 rgb
= ureg_DECL_temporary(ureg
);
334 y
= ureg_DECL_temporary(ureg
);
335 u
= ureg_DECL_temporary(ureg
);
336 v
= ureg_DECL_temporary(ureg
);
338 y_sampler
= ureg_DECL_sampler(ureg
, 0);
339 u_sampler
= ureg_DECL_sampler(ureg
, 1);
340 v_sampler
= ureg_DECL_sampler(ureg
, 2);
342 matrow0
= ureg_DECL_constant(ureg
, 0);
343 matrow1
= ureg_DECL_constant(ureg
, 1);
344 matrow2
= ureg_DECL_constant(ureg
, 2);
345 matrow3
= ureg_DECL_constant(ureg
, 3);
347 ureg_TEX(ureg
, y
, TGSI_TEXTURE_2D
, pos
, y_sampler
);
348 ureg_TEX(ureg
, u
, TGSI_TEXTURE_2D
, pos
, u_sampler
);
349 ureg_TEX(ureg
, v
, TGSI_TEXTURE_2D
, pos
, v_sampler
);
351 ureg_MOV(ureg
, rgb
, matrow3
);
353 ureg_scalar(ureg_src(y
), TGSI_SWIZZLE_X
), matrow0
, ureg_src(rgb
));
355 ureg_scalar(ureg_src(u
), TGSI_SWIZZLE_X
), matrow1
, ureg_src(rgb
));
357 ureg_scalar(ureg_src(v
), TGSI_SWIZZLE_X
), matrow2
, ureg_src(rgb
));
359 ureg_MOV(ureg
, out
, ureg_src(rgb
));
361 ureg_release_temporary(ureg
, rgb
);
362 ureg_release_temporary(ureg
, y
);
363 ureg_release_temporary(ureg
, u
);
364 ureg_release_temporary(ureg
, v
);
368 return ureg_create_shader_and_destroy(ureg
, pipe
);
372 xrender_tex(struct ureg_program
*ureg
,
374 struct ureg_src coords
,
375 struct ureg_src sampler
,
376 struct ureg_src imm0
,
377 boolean repeat_none
, boolean swizzle
, boolean set_alpha
)
380 struct ureg_dst tmp0
= ureg_DECL_temporary(ureg
);
381 struct ureg_dst tmp1
= ureg_DECL_temporary(ureg
);
383 ureg_SGT(ureg
, tmp1
, ureg_swizzle(coords
,
387 TGSI_SWIZZLE_Y
), ureg_scalar(imm0
,
390 ureg_swizzle(coords
, TGSI_SWIZZLE_X
, TGSI_SWIZZLE_Y
,
391 TGSI_SWIZZLE_X
, TGSI_SWIZZLE_Y
), ureg_scalar(imm0
,
393 ureg_MIN(ureg
, tmp0
, ureg_src(tmp0
), ureg_src(tmp1
));
394 ureg_MIN(ureg
, tmp0
, ureg_scalar(ureg_src(tmp0
), TGSI_SWIZZLE_X
),
395 ureg_scalar(ureg_src(tmp0
), TGSI_SWIZZLE_Y
));
396 ureg_TEX(ureg
, tmp1
, TGSI_TEXTURE_2D
, coords
, sampler
);
398 ureg_MOV(ureg
, tmp1
, ureg_swizzle(ureg_src(tmp1
),
400 TGSI_SWIZZLE_Y
, TGSI_SWIZZLE_X
,
404 ureg_writemask(tmp1
, TGSI_WRITEMASK_W
),
405 ureg_scalar(imm0
, TGSI_SWIZZLE_W
));
406 ureg_MUL(ureg
, dst
, ureg_src(tmp1
), ureg_src(tmp0
));
407 ureg_release_temporary(ureg
, tmp0
);
408 ureg_release_temporary(ureg
, tmp1
);
411 struct ureg_dst tmp
= ureg_DECL_temporary(ureg
);
413 ureg_TEX(ureg
, tmp
, TGSI_TEXTURE_2D
, coords
, sampler
);
414 ureg_MOV(ureg
, dst
, ureg_swizzle(ureg_src(tmp
),
416 TGSI_SWIZZLE_Y
, TGSI_SWIZZLE_X
,
418 ureg_release_temporary(ureg
, tmp
);
420 ureg_TEX(ureg
, dst
, TGSI_TEXTURE_2D
, coords
, sampler
);
424 ureg_writemask(dst
, TGSI_WRITEMASK_W
),
425 ureg_scalar(imm0
, TGSI_SWIZZLE_W
));
430 create_fs(struct pipe_context
*pipe
, unsigned fs_traits
)
432 struct ureg_program
*ureg
;
433 struct ureg_src
/*dst_sampler, */ src_sampler
, mask_sampler
;
434 struct ureg_src
/*dst_pos, */ src_input
, mask_pos
;
435 struct ureg_dst src
, mask
;
437 struct ureg_src imm0
= { 0 };
438 unsigned has_mask
= (fs_traits
& FS_MASK
) != 0;
439 unsigned is_fill
= (fs_traits
& FS_FILL
) != 0;
440 unsigned is_composite
= (fs_traits
& FS_COMPOSITE
) != 0;
441 unsigned is_solid
= (fs_traits
& FS_SOLID_FILL
) != 0;
442 unsigned is_lingrad
= (fs_traits
& FS_LINGRAD_FILL
) != 0;
443 unsigned is_radgrad
= (fs_traits
& FS_RADGRAD_FILL
) != 0;
444 unsigned comp_alpha_mask
= fs_traits
& FS_COMPONENT_ALPHA
;
445 unsigned is_yuv
= (fs_traits
& FS_YUV
) != 0;
446 unsigned src_repeat_none
= (fs_traits
& FS_SRC_REPEAT_NONE
) != 0;
447 unsigned mask_repeat_none
= (fs_traits
& FS_MASK_REPEAT_NONE
) != 0;
448 unsigned src_swizzle
= (fs_traits
& FS_SRC_SWIZZLE_RGB
) != 0;
449 unsigned mask_swizzle
= (fs_traits
& FS_MASK_SWIZZLE_RGB
) != 0;
450 unsigned src_set_alpha
= (fs_traits
& FS_SRC_SET_ALPHA
) != 0;
451 unsigned mask_set_alpha
= (fs_traits
& FS_MASK_SET_ALPHA
) != 0;
452 unsigned src_luminance
= (fs_traits
& FS_SRC_LUMINANCE
) != 0;
453 unsigned mask_luminance
= (fs_traits
& FS_MASK_LUMINANCE
) != 0;
454 unsigned dst_luminance
= (fs_traits
& FS_DST_LUMINANCE
) != 0;
457 print_fs_traits(fs_traits
);
459 (void)print_fs_traits
;
462 ureg
= ureg_create(TGSI_PROCESSOR_FRAGMENT
);
466 /* it has to be either a fill, a composite op or a yuv conversion */
467 debug_assert((is_fill
^ is_composite
) ^ is_yuv
);
470 out
= ureg_DECL_output(ureg
, TGSI_SEMANTIC_COLOR
, 0);
472 if (src_repeat_none
|| mask_repeat_none
||
473 src_set_alpha
|| mask_set_alpha
|| src_luminance
) {
474 imm0
= ureg_imm4f(ureg
, 0, 0, 0, 1);
477 src_sampler
= ureg_DECL_sampler(ureg
, 0);
478 src_input
= ureg_DECL_fs_input(ureg
,
479 TGSI_SEMANTIC_GENERIC
, 0,
480 TGSI_INTERPOLATE_PERSPECTIVE
);
481 } else if (is_fill
) {
483 src_input
= ureg_DECL_fs_input(ureg
,
484 TGSI_SEMANTIC_COLOR
, 0,
485 TGSI_INTERPOLATE_PERSPECTIVE
);
487 src_input
= ureg_DECL_fs_input(ureg
,
488 TGSI_SEMANTIC_POSITION
, 0,
489 TGSI_INTERPOLATE_PERSPECTIVE
);
491 debug_assert(is_yuv
);
492 return create_yuv_shader(pipe
, ureg
);
496 mask_sampler
= ureg_DECL_sampler(ureg
, 1);
497 mask_pos
= ureg_DECL_fs_input(ureg
,
498 TGSI_SEMANTIC_GENERIC
, 1,
499 TGSI_INTERPOLATE_PERSPECTIVE
);
501 #if 0 /* unused right now */
502 dst_sampler
= ureg_DECL_sampler(ureg
, 2);
503 dst_pos
= ureg_DECL_fs_input(ureg
,
504 TGSI_SEMANTIC_POSITION
, 2,
505 TGSI_INTERPOLATE_PERSPECTIVE
);
509 if (has_mask
|| src_luminance
|| dst_luminance
)
510 src
= ureg_DECL_temporary(ureg
);
513 xrender_tex(ureg
, src
, src_input
, src_sampler
, imm0
,
514 src_repeat_none
, src_swizzle
, src_set_alpha
);
515 } else if (is_fill
) {
517 if (has_mask
|| src_luminance
|| dst_luminance
)
518 src
= ureg_dst(src_input
);
520 ureg_MOV(ureg
, out
, src_input
);
521 } else if (is_lingrad
|| is_radgrad
) {
522 struct ureg_src coords
, const0124
, matrow0
, matrow1
, matrow2
;
524 if (has_mask
|| src_luminance
|| dst_luminance
)
525 src
= ureg_DECL_temporary(ureg
);
529 coords
= ureg_DECL_constant(ureg
, 0);
530 const0124
= ureg_DECL_constant(ureg
, 1);
531 matrow0
= ureg_DECL_constant(ureg
, 2);
532 matrow1
= ureg_DECL_constant(ureg
, 3);
533 matrow2
= ureg_DECL_constant(ureg
, 4);
536 linear_gradient(ureg
, src
,
537 src_input
, src_sampler
,
538 coords
, const0124
, matrow0
, matrow1
, matrow2
);
539 } else if (is_radgrad
) {
540 radial_gradient(ureg
, src
,
541 src_input
, src_sampler
,
542 coords
, const0124
, matrow0
, matrow1
, matrow2
);
545 debug_assert(!"Unknown fill type!");
548 ureg_MOV(ureg
, src
, ureg_scalar(ureg_src(src
), TGSI_SWIZZLE_X
));
549 ureg_MOV(ureg
, ureg_writemask(src
, TGSI_WRITEMASK_XYZ
),
550 ureg_scalar(imm0
, TGSI_SWIZZLE_X
));
551 if (!has_mask
&& !dst_luminance
)
552 ureg_MOV(ureg
, out
, ureg_src(src
));
556 mask
= ureg_DECL_temporary(ureg
);
557 xrender_tex(ureg
, mask
, mask_pos
, mask_sampler
, imm0
,
558 mask_repeat_none
, mask_swizzle
, mask_set_alpha
);
561 src_in_mask(ureg
, (dst_luminance
) ? src
: out
, ureg_src(src
),
563 comp_alpha_mask
, mask_luminance
);
565 ureg_release_temporary(ureg
, mask
);
570 * Make sure the alpha channel goes into the output L8 surface.
572 ureg_MOV(ureg
, out
, ureg_scalar(ureg_src(src
), TGSI_SWIZZLE_W
));
577 return ureg_create_shader_and_destroy(ureg
, pipe
);
581 xa_shaders_create(struct xa_context
*r
)
583 struct xa_shaders
*sc
= CALLOC_STRUCT(xa_shaders
);
586 sc
->vs_hash
= cso_hash_create();
587 sc
->fs_hash
= cso_hash_create();
593 cache_destroy(struct cso_context
*cso
,
594 struct cso_hash
*hash
, unsigned processor
)
596 struct cso_hash_iter iter
= cso_hash_first_node(hash
);
598 while (!cso_hash_iter_is_null(iter
)) {
599 void *shader
= (void *)cso_hash_iter_data(iter
);
601 if (processor
== PIPE_SHADER_FRAGMENT
) {
602 cso_delete_fragment_shader(cso
, shader
);
603 } else if (processor
== PIPE_SHADER_VERTEX
) {
604 cso_delete_vertex_shader(cso
, shader
);
606 iter
= cso_hash_erase(hash
, iter
);
608 cso_hash_delete(hash
);
612 xa_shaders_destroy(struct xa_shaders
*sc
)
614 cache_destroy(sc
->r
->cso
, sc
->vs_hash
, PIPE_SHADER_VERTEX
);
615 cache_destroy(sc
->r
->cso
, sc
->fs_hash
, PIPE_SHADER_FRAGMENT
);
621 shader_from_cache(struct pipe_context
*pipe
,
622 unsigned type
, struct cso_hash
*hash
, unsigned key
)
626 struct cso_hash_iter iter
= cso_hash_find(hash
, key
);
628 if (cso_hash_iter_is_null(iter
)) {
629 if (type
== PIPE_SHADER_VERTEX
)
630 shader
= create_vs(pipe
, key
);
632 shader
= create_fs(pipe
, key
);
633 cso_hash_insert(hash
, key
, shader
);
635 shader
= (void *)cso_hash_iter_data(iter
);
641 xa_shaders_get(struct xa_shaders
*sc
, unsigned vs_traits
, unsigned fs_traits
)
643 struct xa_shader shader
= { NULL
, NULL
};
646 vs
= shader_from_cache(sc
->r
->pipe
, PIPE_SHADER_VERTEX
,
647 sc
->vs_hash
, vs_traits
);
648 fs
= shader_from_cache(sc
->r
->pipe
, PIPE_SHADER_FRAGMENT
,
649 sc
->fs_hash
, fs_traits
);
651 debug_assert(vs
&& fs
);