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
32typedef 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
39static INLINE void
40solid_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
72static INLINE void
73linear_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
96static INLINE void
97radial_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
133static INLINE void
134pattern( 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
163static INLINE void
164paint_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
176static INLINE void
177image_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
190static INLINE void
191image_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
204static INLINE void
205image_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
217static INLINE void
218color_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
236static INLINE void
237alpha_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
250static INLINE void
251alpha_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 */
278static INLINE void
279blend_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 */
299static INLINE void
300blend_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 */
325static INLINE void
326blend_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
421static INLINE void
422blend_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
432static INLINE void
433blend_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
443static INLINE void
444blend_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
454static INLINE void
455blend_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
465static INLINE void
466blend_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
476static INLINE void
477blend_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
487static INLINE void
488blend_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
498static INLINE void
499blend_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
509static INLINE void
510blend_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
520static INLINE void
521blend_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
531static INLINE void
532mask( 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
546static INLINE void
547premultiply( 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
560static INLINE void
561unpremultiply( 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
572static INLINE void
573color_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
605struct 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 */
623static 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 */
637static 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
646static 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
651static 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 */
659static 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
674static 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 */
680static 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 */
688static 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