1 /**************************************************************************
2 *
3 * Copyright 2009 VMware, Inc. All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
15 * of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 **************************************************************************/
26
27 #ifndef ASM_FILL_H
28 #define ASM_FILL_H
29
30 #include "tgsi/tgsi_ureg.h"
31
32 typedef void (* ureg_func)( struct ureg_program *ureg,
33 struct ureg_dst *out,
34 struct ureg_src *in,
35 struct ureg_src *sampler,
36 struct ureg_dst *temp,
37 struct ureg_src *constant);
38
39 static INLINE void
solid_fill(struct ureg_program * ureg,struct ureg_dst * out,struct ureg_src * in,struct ureg_src * sampler,struct ureg_dst * temp,struct ureg_src * constant)40 solid_fill( struct ureg_program *ureg,
41 struct ureg_dst *out,
42 struct ureg_src *in,
43 struct ureg_src *sampler,
44 struct ureg_dst *temp,
45 struct ureg_src *constant)
46 {
47 ureg_MOV(ureg, *out, constant[2]);
48 }
49
50 /**
51 * Perform frag-coord-to-paint-coord transform. The transformation is in
52 * CONST[4..6].
53 */
54 #define PAINT_TRANSFORM \
55 ureg_MOV(ureg, ureg_writemask(temp[0], TGSI_WRITEMASK_XY), in[0]); \
56 ureg_MOV(ureg, \
57 ureg_writemask(temp[0], TGSI_WRITEMASK_Z), \
58 ureg_scalar(constant[3], TGSI_SWIZZLE_Y)); \
59 ureg_DP3(ureg, temp[1], constant[4], ureg_src(temp[0])); \
60 ureg_DP3(ureg, temp[2], constant[5], ureg_src(temp[0])); \
61 ureg_DP3(ureg, temp[3], constant[6], ureg_src(temp[0])); \
62 ureg_RCP(ureg, temp[3], ureg_src(temp[3])); \
63 ureg_MUL(ureg, temp[1], ureg_src(temp[1]), ureg_src(temp[3])); \
64 ureg_MUL(ureg, temp[2], ureg_src(temp[2]), ureg_src(temp[3])); \
65 ureg_MOV(ureg, \
66 ureg_writemask(temp[4], TGSI_WRITEMASK_X), \
67 ureg_src(temp[1])); \
68 ureg_MOV(ureg, \
69 ureg_writemask(temp[4], TGSI_WRITEMASK_Y), \
70 ureg_src(temp[2]));
71
72 static INLINE void
linear_grad(struct ureg_program * ureg,struct ureg_dst * out,struct ureg_src * in,struct ureg_src * sampler,struct ureg_dst * temp,struct ureg_src * constant)73 linear_grad( struct ureg_program *ureg,
74 struct ureg_dst *out,
75 struct ureg_src *in,
76 struct ureg_src *sampler,
77 struct ureg_dst *temp,
78 struct ureg_src *constant)
79 {
80 PAINT_TRANSFORM
81
82 /* grad = DP2((x, y), CONST[2].xy) * CONST[2].z */
83 ureg_MUL(ureg, temp[0],
84 ureg_scalar(constant[2], TGSI_SWIZZLE_Y),
85 ureg_scalar(ureg_src(temp[4]), TGSI_SWIZZLE_Y));
86 ureg_MAD(ureg, temp[1],
87 ureg_scalar(constant[2], TGSI_SWIZZLE_X),
88 ureg_scalar(ureg_src(temp[4]), TGSI_SWIZZLE_X),
89 ureg_src(temp[0]));
90 ureg_MUL(ureg, temp[2], ureg_src(temp[1]),
91 ureg_scalar(constant[2], TGSI_SWIZZLE_Z));
92
93 ureg_TEX(ureg, *out, TGSI_TEXTURE_1D, ureg_src(temp[2]), sampler[0]);
94 }
95
96 static INLINE void
radial_grad(struct ureg_program * ureg,struct ureg_dst * out,struct ureg_src * in,struct ureg_src * sampler,struct ureg_dst * temp,struct ureg_src * constant)97 radial_grad( struct ureg_program *ureg,
98 struct ureg_dst *out,
99 struct ureg_src *in,
100 struct ureg_src *sampler,
101 struct ureg_dst *temp,
102 struct ureg_src *constant)
103 {
104 PAINT_TRANSFORM
105
106 /*
107 * Calculate (sqrt(B^2 + AC) - B) / A, where
108 *
109 * A is CONST[2].z,
110 * B is DP2((x, y), CONST[2].xy), and
111 * C is DP2((x, y), (x, y)).
112 */
113
114 /* B and C */
115 ureg_DP2(ureg, temp[0], ureg_src(temp[4]), constant[2]);
116 ureg_DP2(ureg, temp[1], ureg_src(temp[4]), ureg_src(temp[4]));
117
118 /* the square root */
119 ureg_MUL(ureg, temp[2], ureg_src(temp[0]), ureg_src(temp[0]));
120 ureg_MAD(ureg, temp[3], ureg_src(temp[1]),
121 ureg_scalar(constant[2], TGSI_SWIZZLE_Z), ureg_src(temp[2]));
122 ureg_RSQ(ureg, temp[3], ureg_src(temp[3]));
123 ureg_RCP(ureg, temp[3], ureg_src(temp[3]));
124
125 ureg_SUB(ureg, temp[3], ureg_src(temp[3]), ureg_src(temp[0]));
126 ureg_RCP(ureg, temp[0], ureg_scalar(constant[2], TGSI_SWIZZLE_Z));
127 ureg_MUL(ureg, temp[0], ureg_src(temp[0]), ureg_src(temp[3]));
128
129 ureg_TEX(ureg, *out, TGSI_TEXTURE_1D, ureg_src(temp[0]), sampler[0]);
130 }
131
132
133 static INLINE void
pattern(struct ureg_program * ureg,struct ureg_dst * out,struct ureg_src * in,struct ureg_src * sampler,struct ureg_dst * temp,struct ureg_src * constant)134 pattern( struct ureg_program *ureg,
135 struct ureg_dst *out,
136 struct ureg_src *in,
137 struct ureg_src *sampler,
138 struct ureg_dst *temp,
139 struct ureg_src *constant)
140 {
141 PAINT_TRANSFORM
142
143 /* (s, t) = (x / tex_width, y / tex_height) */
144 ureg_RCP(ureg, temp[0],
145 ureg_swizzle(constant[3],
146 TGSI_SWIZZLE_Z,
147 TGSI_SWIZZLE_W,
148 TGSI_SWIZZLE_Z,
149 TGSI_SWIZZLE_W));
150 ureg_MOV(ureg, temp[1], ureg_src(temp[4]));
151 ureg_MUL(ureg,
152 ureg_writemask(temp[1], TGSI_WRITEMASK_X),
153 ureg_src(temp[1]),
154 ureg_src(temp[0]));
155 ureg_MUL(ureg,
156 ureg_writemask(temp[1], TGSI_WRITEMASK_Y),
157 ureg_src(temp[1]),
158 ureg_src(temp[0]));
159
160 ureg_TEX(ureg, *out, TGSI_TEXTURE_2D, ureg_src(temp[1]), sampler[0]);
161 }
162
163 static INLINE void
paint_degenerate(struct ureg_program * ureg,struct ureg_dst * out,struct ureg_src * in,struct ureg_src * sampler,struct ureg_dst * temp,struct ureg_src * constant)164 paint_degenerate( struct ureg_program *ureg,
165 struct ureg_dst *out,
166 struct ureg_src *in,
167 struct ureg_src *sampler,
168 struct ureg_dst *temp,
169 struct ureg_src *constant)
170 {
171 /* CONST[3].y is 1.0f */
172 ureg_MOV(ureg, temp[1], ureg_scalar(constant[3], TGSI_SWIZZLE_Y));
173 ureg_TEX(ureg, *out, TGSI_TEXTURE_1D, ureg_src(temp[1]), sampler[0]);
174 }
175
176 static INLINE void
image_normal(struct ureg_program * ureg,struct ureg_dst * out,struct ureg_src * in,struct ureg_src * sampler,struct ureg_dst * temp,struct ureg_src * constant)177 image_normal( struct ureg_program *ureg,
178 struct ureg_dst *out,
179 struct ureg_src *in,
180 struct ureg_src *sampler,
181 struct ureg_dst *temp,
182 struct ureg_src *constant)
183 {
184 /* store and pass image color in TEMP[1] */
185 ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[1], sampler[3]);
186 ureg_MOV(ureg, *out, ureg_src(temp[1]));
187 }
188
189
190 static INLINE void
image_multiply(struct ureg_program * ureg,struct ureg_dst * out,struct ureg_src * in,struct ureg_src * sampler,struct ureg_dst * temp,struct ureg_src * constant)191 image_multiply( struct ureg_program *ureg,
192 struct ureg_dst *out,
193 struct ureg_src *in,
194 struct ureg_src *sampler,
195 struct ureg_dst *temp,
196 struct ureg_src *constant)
197 {
198 /* store and pass image color in TEMP[1] */
199 ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[1], sampler[3]);
200 ureg_MUL(ureg, *out, ureg_src(temp[0]), ureg_src(temp[1]));
201 }
202
203
204 static INLINE void
image_stencil(struct ureg_program * ureg,struct ureg_dst * out,struct ureg_src * in,struct ureg_src * sampler,struct ureg_dst * temp,struct ureg_src * constant)205 image_stencil( struct ureg_program *ureg,
206 struct ureg_dst *out,
207 struct ureg_src *in,
208 struct ureg_src *sampler,
209 struct ureg_dst *temp,
210 struct ureg_src *constant)
211 {
212 /* store and pass image color in TEMP[1] */
213 ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[1], sampler[3]);
214 ureg_MOV(ureg, *out, ureg_src(temp[0]));
215 }
216
217 static INLINE void
color_transform(struct ureg_program * ureg,struct ureg_dst * out,struct ureg_src * in,struct ureg_src * sampler,struct ureg_dst * temp,struct ureg_src * constant)218 color_transform( struct ureg_program *ureg,
219 struct ureg_dst *out,
220 struct ureg_src *in,
221 struct ureg_src *sampler,
222 struct ureg_dst *temp,
223 struct ureg_src *constant)
224 {
225 /* note that TEMP[1] may already be used for image color */
226
227 ureg_MAD(ureg, temp[2], ureg_src(temp[0]), constant[0], constant[1]);
228 /* clamp to [0.0f, 1.0f] */
229 ureg_CLAMP(ureg, temp[2],
230 ureg_src(temp[2]),
231 ureg_scalar(constant[3], TGSI_SWIZZLE_X),
232 ureg_scalar(constant[3], TGSI_SWIZZLE_Y));
233 ureg_MOV(ureg, *out, ureg_src(temp[2]));
234 }
235
236 static INLINE void
alpha_normal(struct ureg_program * ureg,struct ureg_dst * out,struct ureg_src * in,struct ureg_src * sampler,struct ureg_dst * temp,struct ureg_src * constant)237 alpha_normal( struct ureg_program *ureg,
238 struct ureg_dst *out,
239 struct ureg_src *in,
240 struct ureg_src *sampler,
241 struct ureg_dst *temp,
242 struct ureg_src *constant)
243 {
244 /* save per-channel alpha in TEMP[1] */
245 ureg_MOV(ureg, temp[1], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W));
246
247 ureg_MOV(ureg, *out, ureg_src(temp[0]));
248 }
249
250 static INLINE void
alpha_per_channel(struct ureg_program * ureg,struct ureg_dst * out,struct ureg_src * in,struct ureg_src * sampler,struct ureg_dst * temp,struct ureg_src * constant)251 alpha_per_channel( struct ureg_program *ureg,
252 struct ureg_dst *out,
253 struct ureg_src *in,
254 struct ureg_src *sampler,
255 struct ureg_dst *temp,
256 struct ureg_src *constant)
257 {
258 /* save per-channel alpha in TEMP[1] */
259 ureg_MUL(ureg,
260 ureg_writemask(temp[1], TGSI_WRITEMASK_W),
261 ureg_src(temp[0]),
262 ureg_src(temp[1]));
263 ureg_MUL(ureg,
264 ureg_writemask(temp[1], TGSI_WRITEMASK_XYZ),
265 ureg_src(temp[1]),
266 ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
267
268 /* update alpha */
269 ureg_MOV(ureg,
270 ureg_writemask(temp[0], TGSI_WRITEMASK_W),
271 ureg_src(temp[1]));
272 ureg_MOV(ureg, *out, ureg_src(temp[0]));
273 }
274
275 /**
276 * Premultiply src and dst.
277 */
278 static INLINE void
blend_premultiply(struct ureg_program * ureg,struct ureg_src src,struct ureg_src src_channel_alpha,struct ureg_src dst)279 blend_premultiply( struct ureg_program *ureg,
280 struct ureg_src src,
281 struct ureg_src src_channel_alpha,
282 struct ureg_src dst)
283 {
284 /* premultiply src */
285 ureg_MUL(ureg,
286 ureg_writemask(ureg_dst(src), TGSI_WRITEMASK_XYZ),
287 src,
288 src_channel_alpha);
289 /* premultiply dst */
290 ureg_MUL(ureg,
291 ureg_writemask(ureg_dst(dst), TGSI_WRITEMASK_XYZ),
292 dst,
293 ureg_scalar(dst, TGSI_SWIZZLE_W));
294 }
295
296 /**
297 * Unpremultiply src.
298 */
299 static INLINE void
blend_unpremultiply(struct ureg_program * ureg,struct ureg_src src,struct ureg_src one,struct ureg_dst temp[1])300 blend_unpremultiply( struct ureg_program *ureg,
301 struct ureg_src src,
302 struct ureg_src one,
303 struct ureg_dst temp[1])
304 {
305 /* replace 0.0f by 1.0f before calculating reciprocal */
306 ureg_CMP(ureg,
307 temp[0],
308 ureg_negate(ureg_scalar(src, TGSI_SWIZZLE_W)),
309 ureg_scalar(src, TGSI_SWIZZLE_W),
310 one);
311 ureg_RCP(ureg, temp[0], ureg_src(temp[0]));
312
313 ureg_MUL(ureg,
314 ureg_writemask(ureg_dst(src), TGSI_WRITEMASK_XYZ),
315 src,
316 ureg_src(temp[0]));
317 }
318
319 /**
320 * Emit instructions for the specified blend mode. Colors will be
321 * unpremultiplied. Two temporary registers are required.
322 *
323 * The output is written back to src.
324 */
325 static INLINE void
blend_generic(struct ureg_program * ureg,VGBlendMode mode,struct ureg_src src,struct ureg_src src_channel_alpha,struct ureg_src dst,struct ureg_src one,struct ureg_dst temp[2])326 blend_generic(struct ureg_program *ureg,
327 VGBlendMode mode,
328 struct ureg_src src,
329 struct ureg_src src_channel_alpha,
330 struct ureg_src dst,
331 struct ureg_src one,
332 struct ureg_dst temp[2])
333 {
334 struct ureg_dst out;
335
336 blend_premultiply(ureg, src, src_channel_alpha, dst);
337
338 /* blend in-place */
339 out = ureg_dst(src);
340
341 switch (mode) {
342 case VG_BLEND_SRC:
343 ureg_MOV(ureg, out, src);
344 break;
345 case VG_BLEND_SRC_OVER:
346 /* RGBA_out = RGBA_src + (1 - A_src) * RGBA_dst */
347 ureg_SUB(ureg, temp[0], one, src_channel_alpha);
348 ureg_MAD(ureg, out, ureg_src(temp[0]), dst, src);
349 break;
350 case VG_BLEND_DST_OVER:
351 /* RGBA_out = RGBA_dst + (1 - A_dst) * RGBA_src */
352 ureg_SUB(ureg, temp[0], one, ureg_scalar(dst, TGSI_SWIZZLE_W));
353 ureg_MAD(ureg, out, ureg_src(temp[0]), src, dst);
354 break;
355 case VG_BLEND_SRC_IN:
356 ureg_MUL(ureg, out, src, ureg_scalar(dst, TGSI_SWIZZLE_W));
357 break;
358 case VG_BLEND_DST_IN:
359 ureg_MUL(ureg, out, dst, src_channel_alpha);
360 break;
361 case VG_BLEND_MULTIPLY:
362 /*
363 * RGB_out = (1 - A_dst) * RGB_src + (1 - A_src) * RGB_dst +
364 * RGB_src * RGB_dst
365 */
366 ureg_MAD(ureg, temp[0],
367 ureg_scalar(dst, TGSI_SWIZZLE_W), ureg_negate(src), src);
368 ureg_MAD(ureg, temp[1],
369 src_channel_alpha, ureg_negate(dst), dst);
370 ureg_MAD(ureg, temp[0], src, dst, ureg_src(temp[0]));
371 ureg_ADD(ureg, out, ureg_src(temp[0]), ureg_src(temp[1]));
372 /* alpha is src over */
373 ureg_ADD(ureg, ureg_writemask(out, TGSI_WRITEMASK_W),
374 src, ureg_src(temp[1]));
375 break;
376 case VG_BLEND_SCREEN:
377 /* RGBA_out = RGBA_src + (1 - RGBA_src) * RGBA_dst */
378 ureg_SUB(ureg, temp[0], one, src);
379 ureg_MAD(ureg, out, ureg_src(temp[0]), dst, src);
380 break;
381 case VG_BLEND_DARKEN:
382 case VG_BLEND_LIGHTEN:
383 /* src over */
384 ureg_SUB(ureg, temp[0], one, src_channel_alpha);
385 ureg_MAD(ureg, temp[0], ureg_src(temp[0]), dst, src);
386 /* dst over */
387 ureg_SUB(ureg, temp[1], one, ureg_scalar(dst, TGSI_SWIZZLE_W));
388 ureg_MAD(ureg, temp[1], ureg_src(temp[1]), src, dst);
389 /* take min/max for colors */
390 if (mode == VG_BLEND_DARKEN) {
391 ureg_MIN(ureg, ureg_writemask(out, TGSI_WRITEMASK_XYZ),
392 ureg_src(temp[0]), ureg_src(temp[1]));
393 }
394 else {
395 ureg_MAX(ureg, ureg_writemask(out, TGSI_WRITEMASK_XYZ),
396 ureg_src(temp[0]), ureg_src(temp[1]));
397 }
398 break;
399 case VG_BLEND_ADDITIVE:
400 /* RGBA_out = RGBA_src + RGBA_dst */
401 ureg_ADD(ureg, temp[0], src, dst);
402 ureg_MIN(ureg, out, ureg_src(temp[0]), one);
403 break;
404 default:
405 assert(0);
406 break;
407 }
408
409 blend_unpremultiply(ureg, src, one, temp);
410 }
411
412 #define BLEND_GENERIC(mode) \
413 do { \
414 ureg_TEX(ureg, temp[2], TGSI_TEXTURE_2D, in[0], sampler[2]); \
415 blend_generic(ureg, (mode), ureg_src(temp[0]), ureg_src(temp[1]), \
416 ureg_src(temp[2]), \
417 ureg_scalar(constant[3], TGSI_SWIZZLE_Y), temp + 3); \
418 ureg_MOV(ureg, *out, ureg_src(temp[0])); \
419 } while (0)
420
421 static INLINE void
blend_src(struct ureg_program * ureg,struct ureg_dst * out,struct ureg_src * in,struct ureg_src * sampler,struct ureg_dst * temp,struct ureg_src * constant)422 blend_src( struct ureg_program *ureg,
423 struct ureg_dst *out,
424 struct ureg_src *in,
425 struct ureg_src *sampler,
426 struct ureg_dst *temp,
427 struct ureg_src *constant)
428 {
429 BLEND_GENERIC(VG_BLEND_SRC);
430 }
431
432 static INLINE void
blend_src_over(struct ureg_program * ureg,struct ureg_dst * out,struct ureg_src * in,struct ureg_src * sampler,struct ureg_dst * temp,struct ureg_src * constant)433 blend_src_over( struct ureg_program *ureg,
434 struct ureg_dst *out,
435 struct ureg_src *in,
436 struct ureg_src *sampler,
437 struct ureg_dst *temp,
438 struct ureg_src *constant)
439 {
440 BLEND_GENERIC(VG_BLEND_SRC_OVER);
441 }
442
443 static INLINE void
blend_dst_over(struct ureg_program * ureg,struct ureg_dst * out,struct ureg_src * in,struct ureg_src * sampler,struct ureg_dst * temp,struct ureg_src * constant)444 blend_dst_over( struct ureg_program *ureg,
445 struct ureg_dst *out,
446 struct ureg_src *in,
447 struct ureg_src *sampler,
448 struct ureg_dst *temp,
449 struct ureg_src *constant)
450 {
451 BLEND_GENERIC(VG_BLEND_DST_OVER);
452 }
453
454 static INLINE void
blend_src_in(struct ureg_program * ureg,struct ureg_dst * out,struct ureg_src * in,struct ureg_src * sampler,struct ureg_dst * temp,struct ureg_src * constant)455 blend_src_in( struct ureg_program *ureg,
456 struct ureg_dst *out,
457 struct ureg_src *in,
458 struct ureg_src *sampler,
459 struct ureg_dst *temp,
460 struct ureg_src *constant)
461 {
462 BLEND_GENERIC(VG_BLEND_SRC_IN);
463 }
464
465 static INLINE void
blend_dst_in(struct ureg_program * ureg,struct ureg_dst * out,struct ureg_src * in,struct ureg_src * sampler,struct ureg_dst * temp,struct ureg_src * constant)466 blend_dst_in( struct ureg_program *ureg,
467 struct ureg_dst *out,
468 struct ureg_src *in,
469 struct ureg_src *sampler,
470 struct ureg_dst *temp,
471 struct ureg_src *constant)
472 {
473 BLEND_GENERIC(VG_BLEND_DST_IN);
474 }
475
476 static INLINE void
blend_multiply(struct ureg_program * ureg,struct ureg_dst * out,struct ureg_src * in,struct ureg_src * sampler,struct ureg_dst * temp,struct ureg_src * constant)477 blend_multiply( struct ureg_program *ureg,
478 struct ureg_dst *out,
479 struct ureg_src *in,
480 struct ureg_src *sampler,
481 struct ureg_dst *temp,
482 struct ureg_src *constant)
483 {
484 BLEND_GENERIC(VG_BLEND_MULTIPLY);
485 }
486
487 static INLINE void
blend_screen(struct ureg_program * ureg,struct ureg_dst * out,struct ureg_src * in,struct ureg_src * sampler,struct ureg_dst * temp,struct ureg_src * constant)488 blend_screen( struct ureg_program *ureg,
489 struct ureg_dst *out,
490 struct ureg_src *in,
491 struct ureg_src *sampler,
492 struct ureg_dst *temp,
493 struct ureg_src *constant)
494 {
495 BLEND_GENERIC(VG_BLEND_SCREEN);
496 }
497
498 static INLINE void
blend_darken(struct ureg_program * ureg,struct ureg_dst * out,struct ureg_src * in,struct ureg_src * sampler,struct ureg_dst * temp,struct ureg_src * constant)499 blend_darken( struct ureg_program *ureg,
500 struct ureg_dst *out,
501 struct ureg_src *in,
502 struct ureg_src *sampler,
503 struct ureg_dst *temp,
504 struct ureg_src *constant)
505 {
506 BLEND_GENERIC(VG_BLEND_DARKEN);
507 }
508
509 static INLINE void
blend_lighten(struct ureg_program * ureg,struct ureg_dst * out,struct ureg_src * in,struct ureg_src * sampler,struct ureg_dst * temp,struct ureg_src * constant)510 blend_lighten( struct ureg_program *ureg,
511 struct ureg_dst *out,
512 struct ureg_src *in,
513 struct ureg_src *sampler,
514 struct ureg_dst *temp,
515 struct ureg_src *constant)
516 {
517 BLEND_GENERIC(VG_BLEND_LIGHTEN);
518 }
519
520 static INLINE void
blend_additive(struct ureg_program * ureg,struct ureg_dst * out,struct ureg_src * in,struct ureg_src * sampler,struct ureg_dst * temp,struct ureg_src * constant)521 blend_additive( struct ureg_program *ureg,
522 struct ureg_dst *out,
523 struct ureg_src *in,
524 struct ureg_src *sampler,
525 struct ureg_dst *temp,
526 struct ureg_src *constant)
527 {
528 BLEND_GENERIC(VG_BLEND_ADDITIVE);
529 }
530
531 static INLINE void
mask(struct ureg_program * ureg,struct ureg_dst * out,struct ureg_src * in,struct ureg_src * sampler,struct ureg_dst * temp,struct ureg_src * constant)532 mask( struct ureg_program *ureg,
533 struct ureg_dst *out,
534 struct ureg_src *in,
535 struct ureg_src *sampler,
536 struct ureg_dst *temp,
537 struct ureg_src *constant)
538 {
539 ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[0], sampler[1]);
540 ureg_MUL(ureg, ureg_writemask(temp[0], TGSI_WRITEMASK_W),
541 ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
542 ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
543 ureg_MOV(ureg, *out, ureg_src(temp[0]));
544 }
545
546 static INLINE void
premultiply(struct ureg_program * ureg,struct ureg_dst * out,struct ureg_src * in,struct ureg_src * sampler,struct ureg_dst * temp,struct ureg_src * constant)547 premultiply( struct ureg_program *ureg,
548 struct ureg_dst *out,
549 struct ureg_src *in,
550 struct ureg_src *sampler,
551 struct ureg_dst *temp,
552 struct ureg_src *constant)
553 {
554 ureg_MUL(ureg,
555 ureg_writemask(temp[0], TGSI_WRITEMASK_XYZ),
556 ureg_src(temp[0]),
557 ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W));
558 }
559
560 static INLINE void
unpremultiply(struct ureg_program * ureg,struct ureg_dst * out,struct ureg_src * in,struct ureg_src * sampler,struct ureg_dst * temp,struct ureg_src * constant)561 unpremultiply( struct ureg_program *ureg,
562 struct ureg_dst *out,
563 struct ureg_src *in,
564 struct ureg_src *sampler,
565 struct ureg_dst *temp,
566 struct ureg_src *constant)
567 {
568 ureg_TEX(ureg, temp[0], TGSI_TEXTURE_2D, in[0], sampler[1]);
569 }
570
571
572 static INLINE void
color_bw(struct ureg_program * ureg,struct ureg_dst * out,struct ureg_src * in,struct ureg_src * sampler,struct ureg_dst * temp,struct ureg_src * constant)573 color_bw( struct ureg_program *ureg,
574 struct ureg_dst *out,
575 struct ureg_src *in,
576 struct ureg_src *sampler,
577 struct ureg_dst *temp,
578 struct ureg_src *constant)
579 {
580 ureg_ADD(ureg, temp[1],
581 ureg_scalar(constant[3], TGSI_SWIZZLE_Y),
582 ureg_scalar(constant[3], TGSI_SWIZZLE_Y));
583 ureg_RCP(ureg, temp[2], ureg_src(temp[1]));
584 ureg_ADD(ureg, temp[1],
585 ureg_scalar(constant[3], TGSI_SWIZZLE_Y),
586 ureg_src(temp[2]));
587 ureg_ADD(ureg, ureg_writemask(temp[2], TGSI_WRITEMASK_X),
588 ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_X),
589 ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_Y));
590 ureg_ADD(ureg, ureg_writemask(temp[2], TGSI_WRITEMASK_X),
591 ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_Z),
592 ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_X));
593 ureg_SGE(ureg,
594 ureg_writemask(temp[0], TGSI_WRITEMASK_XYZ),
595 ureg_scalar(ureg_src(temp[2]), TGSI_SWIZZLE_X),
596 ureg_src(temp[1]));
597 ureg_SGE(ureg,
598 ureg_writemask(temp[0], TGSI_WRITEMASK_W),
599 ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
600 ureg_scalar(ureg_src(temp[2]), TGSI_SWIZZLE_Y));
601 ureg_MOV(ureg, *out, ureg_src(temp[0]));
602 }
603
604
605 struct shader_asm_info {
606 VGint id;
607 ureg_func func;
608
609 VGboolean needs_position;
610
611 VGint start_const;
612 VGint num_consts;
613
614 VGint start_sampler;
615 VGint num_samplers;
616
617 VGint start_temp;
618 VGint num_temps;
619 };
620
621
622 /* paint types */
623 static const struct shader_asm_info shaders_paint_asm[] = {
624 {VEGA_SOLID_FILL_SHADER, solid_fill,
625 VG_FALSE, 2, 1, 0, 0, 0, 0},
626 {VEGA_LINEAR_GRADIENT_SHADER, linear_grad,
627 VG_TRUE, 2, 5, 0, 1, 0, 5},
628 {VEGA_RADIAL_GRADIENT_SHADER, radial_grad,
629 VG_TRUE, 2, 5, 0, 1, 0, 5},
630 {VEGA_PATTERN_SHADER, pattern,
631 VG_TRUE, 3, 4, 0, 1, 0, 5},
632 {VEGA_PAINT_DEGENERATE_SHADER, paint_degenerate,
633 VG_FALSE, 3, 1, 0, 1, 0, 2}
634 };
635
636 /* image draw modes */
637 static const struct shader_asm_info shaders_image_asm[] = {
638 {VEGA_IMAGE_NORMAL_SHADER, image_normal,
639 VG_TRUE, 0, 0, 3, 1, 0, 2},
640 {VEGA_IMAGE_MULTIPLY_SHADER, image_multiply,
641 VG_TRUE, 0, 0, 3, 1, 0, 2},
642 {VEGA_IMAGE_STENCIL_SHADER, image_stencil,
643 VG_TRUE, 0, 0, 3, 1, 0, 2}
644 };
645
646 static const struct shader_asm_info shaders_color_transform_asm[] = {
647 {VEGA_COLOR_TRANSFORM_SHADER, color_transform,
648 VG_FALSE, 0, 4, 0, 0, 0, 3}
649 };
650
651 static const struct shader_asm_info shaders_alpha_asm[] = {
652 {VEGA_ALPHA_NORMAL_SHADER, alpha_normal,
653 VG_FALSE, 0, 0, 0, 0, 0, 2},
654 {VEGA_ALPHA_PER_CHANNEL_SHADER, alpha_per_channel,
655 VG_FALSE, 0, 0, 0, 0, 0, 2}
656 };
657
658 /* extra blend modes */
659 static const struct shader_asm_info shaders_blend_asm[] = {
660 #define BLEND_ASM_INFO(id, func) { (id), (func), VG_TRUE, 3, 1, 2, 1, 0, 5 }
661 BLEND_ASM_INFO(VEGA_BLEND_SRC_SHADER, blend_src),
662 BLEND_ASM_INFO(VEGA_BLEND_SRC_OVER_SHADER, blend_src_over),
663 BLEND_ASM_INFO(VEGA_BLEND_DST_OVER_SHADER, blend_dst_over),
664 BLEND_ASM_INFO(VEGA_BLEND_SRC_IN_SHADER, blend_src_in),
665 BLEND_ASM_INFO(VEGA_BLEND_DST_IN_SHADER, blend_dst_in),
666 BLEND_ASM_INFO(VEGA_BLEND_MULTIPLY_SHADER, blend_multiply),
667 BLEND_ASM_INFO(VEGA_BLEND_SCREEN_SHADER, blend_screen),
668 BLEND_ASM_INFO(VEGA_BLEND_DARKEN_SHADER, blend_darken),
669 BLEND_ASM_INFO(VEGA_BLEND_LIGHTEN_SHADER, blend_lighten),
670 BLEND_ASM_INFO(VEGA_BLEND_ADDITIVE_SHADER, blend_additive)
671 #undef BLEND_ASM_INFO
672 };
673
674 static const struct shader_asm_info shaders_mask_asm[] = {
675 {VEGA_MASK_SHADER, mask,
676 VG_TRUE, 0, 0, 1, 1, 0, 2}
677 };
678
679 /* premultiply */
680 static const struct shader_asm_info shaders_premultiply_asm[] = {
681 {VEGA_PREMULTIPLY_SHADER, premultiply,
682 VG_FALSE, 0, 0, 0, 0, 0, 1},
683 {VEGA_UNPREMULTIPLY_SHADER, unpremultiply,
684 VG_FALSE, 0, 0, 0, 0, 0, 1},
685 };
686
687 /* color transform to black and white */
688 static const struct shader_asm_info shaders_bw_asm[] = {
689 {VEGA_BW_SHADER, color_bw,
690 VG_FALSE, 3, 1, 0, 0, 0, 3},
691 };
692
693 #endif
694