Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  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.