• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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