Home | History | Annotate | Download | only in vega
      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
     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
     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
     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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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