Subversion Repositories Kolibri OS

Rev

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

  1. #include "xorg_exa_tgsi.h"
  2.  
  3. /*### stupidity defined in X11/extensions/XI.h */
  4. #undef Absolute
  5.  
  6. #include "pipe/p_format.h"
  7. #include "pipe/p_context.h"
  8. #include "pipe/p_state.h"
  9. #include "pipe/p_shader_tokens.h"
  10.  
  11. #include "util/u_memory.h"
  12.  
  13. #include "tgsi/tgsi_ureg.h"
  14.  
  15. #include "cso_cache/cso_context.h"
  16. #include "cso_cache/cso_hash.h"
  17.  
  18. /* Vertex shader:
  19.  * IN[0]    = vertex pos
  20.  * IN[1]    = src tex coord | solid fill color
  21.  * IN[2]    = mask tex coord
  22.  * IN[3]    = dst tex coord
  23.  * CONST[0] = (2/dst_width, 2/dst_height, 1, 1)
  24.  * CONST[1] = (-1, -1, 0, 0)
  25.  *
  26.  * OUT[0]   = vertex pos
  27.  * OUT[1]   = src tex coord | solid fill color
  28.  * OUT[2]   = mask tex coord
  29.  * OUT[3]   = dst tex coord
  30.  */
  31.  
  32. /* Fragment shader:
  33.  * SAMP[0]  = src
  34.  * SAMP[1]  = mask
  35.  * SAMP[2]  = dst
  36.  * IN[0]    = pos src | solid fill color
  37.  * IN[1]    = pos mask
  38.  * IN[2]    = pos dst
  39.  * CONST[0] = (0, 0, 0, 1)
  40.  *
  41.  * OUT[0] = color
  42.  */
  43.  
  44. static void
  45. print_fs_traits(int fs_traits)
  46. {
  47.    const char *strings[] = {
  48.       "FS_COMPOSITE",       /* = 1 << 0, */
  49.       "FS_MASK",            /* = 1 << 1, */
  50.       "FS_SOLID_FILL",      /* = 1 << 2, */
  51.       "FS_LINGRAD_FILL",    /* = 1 << 3, */
  52.       "FS_RADGRAD_FILL",    /* = 1 << 4, */
  53.       "FS_CA_FULL",         /* = 1 << 5, */ /* src.rgba * mask.rgba */
  54.       "FS_CA_SRCALPHA",     /* = 1 << 6, */ /* src.aaaa * mask.rgba */
  55.       "FS_YUV",             /* = 1 << 7, */
  56.       "FS_SRC_REPEAT_NONE", /* = 1 << 8, */
  57.       "FS_MASK_REPEAT_NONE",/* = 1 << 9, */
  58.       "FS_SRC_SWIZZLE_RGB", /* = 1 << 10, */
  59.       "FS_MASK_SWIZZLE_RGB",/* = 1 << 11, */
  60.       "FS_SRC_SET_ALPHA",   /* = 1 << 12, */
  61.       "FS_MASK_SET_ALPHA",  /* = 1 << 13, */
  62.       "FS_SRC_LUMINANCE",   /* = 1 << 14, */
  63.       "FS_MASK_LUMINANCE",  /* = 1 << 15, */
  64.    };
  65.    int i, k;
  66.    debug_printf("%s: ", __func__);
  67.  
  68.    for (i = 0, k = 1; k < (1 << 16); i++, k <<= 1) {
  69.       if (fs_traits & k)
  70.          debug_printf("%s, ", strings[i]);
  71.    }
  72.  
  73.    debug_printf("\n");
  74. }
  75.  
  76. struct xorg_shaders {
  77.    struct xorg_renderer *r;
  78.  
  79.    struct cso_hash *vs_hash;
  80.    struct cso_hash *fs_hash;
  81. };
  82.  
  83. static INLINE void
  84. src_in_mask(struct ureg_program *ureg,
  85.             struct ureg_dst dst,
  86.             struct ureg_src src,
  87.             struct ureg_src mask,
  88.             unsigned component_alpha,
  89.             unsigned mask_luminance)
  90. {
  91.    if (component_alpha == FS_CA_FULL) {
  92.       ureg_MUL(ureg, dst, src, mask);
  93.    } else if (component_alpha == FS_CA_SRCALPHA) {
  94.       ureg_MUL(ureg, dst,
  95.                ureg_scalar(src, TGSI_SWIZZLE_W), mask);
  96.    }
  97.    else {
  98.       if (mask_luminance)
  99.          ureg_MUL(ureg, dst, src,
  100.                   ureg_scalar(mask, TGSI_SWIZZLE_X));
  101.       else
  102.          ureg_MUL(ureg, dst, src,
  103.                   ureg_scalar(mask, TGSI_SWIZZLE_W));
  104.    }
  105. }
  106.  
  107. static struct ureg_src
  108. vs_normalize_coords(struct ureg_program *ureg, struct ureg_src coords,
  109.                     struct ureg_src const0, struct ureg_src const1)
  110. {
  111.    struct ureg_dst tmp = ureg_DECL_temporary(ureg);
  112.    struct ureg_src ret;
  113.    ureg_MAD(ureg, tmp, coords, const0, const1);
  114.    ret = ureg_src(tmp);
  115.    ureg_release_temporary(ureg, tmp);
  116.    return ret;
  117. }
  118.  
  119. static void
  120. linear_gradient(struct ureg_program *ureg,
  121.                 struct ureg_dst out,
  122.                 struct ureg_src pos,
  123.                 struct ureg_src sampler,
  124.                 struct ureg_src coords,
  125.                 struct ureg_src const0124,
  126.                 struct ureg_src matrow0,
  127.                 struct ureg_src matrow1,
  128.                 struct ureg_src matrow2)
  129. {
  130.    struct ureg_dst temp0 = ureg_DECL_temporary(ureg);
  131.    struct ureg_dst temp1 = ureg_DECL_temporary(ureg);
  132.    struct ureg_dst temp2 = ureg_DECL_temporary(ureg);
  133.    struct ureg_dst temp3 = ureg_DECL_temporary(ureg);
  134.    struct ureg_dst temp4 = ureg_DECL_temporary(ureg);
  135.    struct ureg_dst temp5 = ureg_DECL_temporary(ureg);
  136.  
  137.    ureg_MOV(ureg,
  138.             ureg_writemask(temp0, TGSI_WRITEMASK_XY), pos);
  139.    ureg_MOV(ureg,
  140.             ureg_writemask(temp0, TGSI_WRITEMASK_Z),
  141.             ureg_scalar(const0124, TGSI_SWIZZLE_Y));
  142.  
  143.    ureg_DP3(ureg, temp1, matrow0, ureg_src(temp0));
  144.    ureg_DP3(ureg, temp2, matrow1, ureg_src(temp0));
  145.    ureg_DP3(ureg, temp3, matrow2, ureg_src(temp0));
  146.    ureg_RCP(ureg, temp3, ureg_src(temp3));
  147.    ureg_MUL(ureg, temp1, ureg_src(temp1), ureg_src(temp3));
  148.    ureg_MUL(ureg, temp2, ureg_src(temp2), ureg_src(temp3));
  149.  
  150.    ureg_MOV(ureg, ureg_writemask(temp4, TGSI_WRITEMASK_X),
  151.             ureg_src(temp1));
  152.    ureg_MOV(ureg, ureg_writemask(temp4, TGSI_WRITEMASK_Y),
  153.             ureg_src(temp2));
  154.  
  155.    ureg_MUL(ureg, temp0,
  156.             ureg_scalar(coords, TGSI_SWIZZLE_Y),
  157.             ureg_scalar(ureg_src(temp4), TGSI_SWIZZLE_Y));
  158.    ureg_MAD(ureg, temp1,
  159.             ureg_scalar(coords, TGSI_SWIZZLE_X),
  160.             ureg_scalar(ureg_src(temp4), TGSI_SWIZZLE_X),
  161.             ureg_src(temp0));
  162.  
  163.    ureg_MUL(ureg, temp2,
  164.             ureg_src(temp1),
  165.             ureg_scalar(coords, TGSI_SWIZZLE_Z));
  166.  
  167.    ureg_TEX(ureg, out,
  168.             TGSI_TEXTURE_1D, ureg_src(temp2), sampler);
  169.  
  170.    ureg_release_temporary(ureg, temp0);
  171.    ureg_release_temporary(ureg, temp1);
  172.    ureg_release_temporary(ureg, temp2);
  173.    ureg_release_temporary(ureg, temp3);
  174.    ureg_release_temporary(ureg, temp4);
  175.    ureg_release_temporary(ureg, temp5);
  176. }
  177.  
  178.  
  179. static void
  180. radial_gradient(struct ureg_program *ureg,
  181.                 struct ureg_dst out,
  182.                 struct ureg_src pos,
  183.                 struct ureg_src sampler,
  184.                 struct ureg_src coords,
  185.                 struct ureg_src const0124,
  186.                 struct ureg_src matrow0,
  187.                 struct ureg_src matrow1,
  188.                 struct ureg_src matrow2)
  189. {
  190.    struct ureg_dst temp0 = ureg_DECL_temporary(ureg);
  191.    struct ureg_dst temp1 = ureg_DECL_temporary(ureg);
  192.    struct ureg_dst temp2 = ureg_DECL_temporary(ureg);
  193.    struct ureg_dst temp3 = ureg_DECL_temporary(ureg);
  194.    struct ureg_dst temp4 = ureg_DECL_temporary(ureg);
  195.    struct ureg_dst temp5 = ureg_DECL_temporary(ureg);
  196.  
  197.    ureg_MOV(ureg,
  198.             ureg_writemask(temp0, TGSI_WRITEMASK_XY),
  199.             pos);
  200.    ureg_MOV(ureg,
  201.             ureg_writemask(temp0, TGSI_WRITEMASK_Z),
  202.             ureg_scalar(const0124, TGSI_SWIZZLE_Y));
  203.  
  204.    ureg_DP3(ureg, temp1, matrow0, ureg_src(temp0));
  205.    ureg_DP3(ureg, temp2, matrow1, ureg_src(temp0));
  206.    ureg_DP3(ureg, temp3, matrow2, ureg_src(temp0));
  207.    ureg_RCP(ureg, temp3, ureg_src(temp3));
  208.    ureg_MUL(ureg, temp1, ureg_src(temp1), ureg_src(temp3));
  209.    ureg_MUL(ureg, temp2, ureg_src(temp2), ureg_src(temp3));
  210.  
  211.    ureg_MOV(ureg, ureg_writemask(temp5, TGSI_WRITEMASK_X),
  212.             ureg_src(temp1));
  213.    ureg_MOV(ureg, ureg_writemask(temp5, TGSI_WRITEMASK_Y),
  214.             ureg_src(temp2));
  215.  
  216.    ureg_MUL(ureg, temp0, ureg_scalar(coords, TGSI_SWIZZLE_Y),
  217.             ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_Y));
  218.    ureg_MAD(ureg, temp1,
  219.             ureg_scalar(coords, TGSI_SWIZZLE_X),
  220.             ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_X),
  221.             ureg_src(temp0));
  222.    ureg_ADD(ureg, temp1,
  223.             ureg_src(temp1), ureg_src(temp1));
  224.    ureg_MUL(ureg, temp3,
  225.             ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_Y),
  226.             ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_Y));
  227.    ureg_MAD(ureg, temp4,
  228.             ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_X),
  229.             ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_X),
  230.             ureg_src(temp3));
  231.    ureg_MOV(ureg, temp4, ureg_negate(ureg_src(temp4)));
  232.    ureg_MUL(ureg, temp2,
  233.             ureg_scalar(coords, TGSI_SWIZZLE_Z),
  234.             ureg_src(temp4));
  235.    ureg_MUL(ureg, temp0,
  236.             ureg_scalar(const0124, TGSI_SWIZZLE_W),
  237.             ureg_src(temp2));
  238.    ureg_MUL(ureg, temp3,
  239.             ureg_src(temp1), ureg_src(temp1));
  240.    ureg_SUB(ureg, temp2,
  241.             ureg_src(temp3), ureg_src(temp0));
  242.    ureg_RSQ(ureg, temp2, ureg_abs(ureg_src(temp2)));
  243.    ureg_RCP(ureg, temp2, ureg_src(temp2));
  244.    ureg_SUB(ureg, temp1,
  245.             ureg_src(temp2), ureg_src(temp1));
  246.    ureg_ADD(ureg, temp0,
  247.             ureg_scalar(coords, TGSI_SWIZZLE_Z),
  248.             ureg_scalar(coords, TGSI_SWIZZLE_Z));
  249.    ureg_RCP(ureg, temp0, ureg_src(temp0));
  250.    ureg_MUL(ureg, temp2,
  251.             ureg_src(temp1), ureg_src(temp0));
  252.    ureg_TEX(ureg, out, TGSI_TEXTURE_1D,
  253.             ureg_src(temp2), sampler);
  254.  
  255.    ureg_release_temporary(ureg, temp0);
  256.    ureg_release_temporary(ureg, temp1);
  257.    ureg_release_temporary(ureg, temp2);
  258.    ureg_release_temporary(ureg, temp3);
  259.    ureg_release_temporary(ureg, temp4);
  260.    ureg_release_temporary(ureg, temp5);
  261. }
  262.  
  263. static void *
  264. create_vs(struct pipe_context *pipe,
  265.           unsigned vs_traits)
  266. {
  267.    struct ureg_program *ureg;
  268.    struct ureg_src src;
  269.    struct ureg_dst dst;
  270.    struct ureg_src const0, const1;
  271.    boolean is_fill = (vs_traits & VS_FILL) != 0;
  272.    boolean is_composite = (vs_traits & VS_COMPOSITE) != 0;
  273.    boolean has_mask = (vs_traits & VS_MASK) != 0;
  274.    boolean is_yuv = (vs_traits & VS_YUV) != 0;
  275.    unsigned input_slot = 0;
  276.  
  277.    ureg = ureg_create(TGSI_PROCESSOR_VERTEX);
  278.    if (ureg == NULL)
  279.       return 0;
  280.  
  281.    const0 = ureg_DECL_constant(ureg, 0);
  282.    const1 = ureg_DECL_constant(ureg, 1);
  283.  
  284.    /* it has to be either a fill or a composite op */
  285.    debug_assert((is_fill ^ is_composite) ^ is_yuv);
  286.  
  287.    src = ureg_DECL_vs_input(ureg, input_slot++);
  288.    dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0);
  289.    src = vs_normalize_coords(ureg, src,
  290.                              const0, const1);
  291.    ureg_MOV(ureg, dst, src);
  292.  
  293.    if (is_yuv) {
  294.       src = ureg_DECL_vs_input(ureg, input_slot++);
  295.       dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 0);
  296.       ureg_MOV(ureg, dst, src);
  297.    }
  298.  
  299.    if (is_composite) {
  300.       src = ureg_DECL_vs_input(ureg, input_slot++);
  301.       dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 0);
  302.       ureg_MOV(ureg, dst, src);
  303.    }
  304.  
  305.    if (is_fill) {
  306.       src = ureg_DECL_vs_input(ureg, input_slot++);
  307.       dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
  308.       ureg_MOV(ureg, dst, src);
  309.    }
  310.  
  311.    if (has_mask) {
  312.       src = ureg_DECL_vs_input(ureg, input_slot++);
  313.       dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 1);
  314.       ureg_MOV(ureg, dst, src);
  315.    }
  316.  
  317.    ureg_END(ureg);
  318.  
  319.    return ureg_create_shader_and_destroy(ureg, pipe);
  320. }
  321.  
  322. static void *
  323. create_yuv_shader(struct pipe_context *pipe, struct ureg_program *ureg)
  324. {
  325.    struct ureg_src y_sampler, u_sampler, v_sampler;
  326.    struct ureg_src pos;
  327.    struct ureg_src matrow0, matrow1, matrow2;
  328.    struct ureg_dst y, u, v, rgb;
  329.    struct ureg_dst out = ureg_DECL_output(ureg,
  330.                                           TGSI_SEMANTIC_COLOR,
  331.                                           0);
  332.  
  333.    pos = ureg_DECL_fs_input(ureg,
  334.                             TGSI_SEMANTIC_GENERIC,
  335.                             0,
  336.                             TGSI_INTERPOLATE_PERSPECTIVE);
  337.  
  338.    rgb = ureg_DECL_temporary(ureg);
  339.    y = ureg_DECL_temporary(ureg);
  340.    u = ureg_DECL_temporary(ureg);
  341.    v = ureg_DECL_temporary(ureg);
  342.  
  343.    y_sampler = ureg_DECL_sampler(ureg, 0);
  344.    u_sampler = ureg_DECL_sampler(ureg, 1);
  345.    v_sampler = ureg_DECL_sampler(ureg, 2);
  346.  
  347.    matrow0 = ureg_DECL_constant(ureg, 0);
  348.    matrow1 = ureg_DECL_constant(ureg, 1);
  349.    matrow2 = ureg_DECL_constant(ureg, 2);
  350.  
  351.    ureg_TEX(ureg, y,
  352.             TGSI_TEXTURE_2D, pos, y_sampler);
  353.    ureg_TEX(ureg, u,
  354.             TGSI_TEXTURE_2D, pos, u_sampler);
  355.    ureg_TEX(ureg, v,
  356.             TGSI_TEXTURE_2D, pos, v_sampler);
  357.  
  358.    ureg_SUB(ureg, u, ureg_src(u),
  359.             ureg_scalar(matrow0, TGSI_SWIZZLE_W));
  360.    ureg_SUB(ureg, v, ureg_src(v),
  361.             ureg_scalar(matrow0, TGSI_SWIZZLE_W));
  362.  
  363.    ureg_MUL(ureg, rgb,
  364.             ureg_scalar(ureg_src(y), TGSI_SWIZZLE_X),
  365.             matrow0);
  366.    ureg_MAD(ureg, rgb,
  367.             ureg_scalar(ureg_src(u), TGSI_SWIZZLE_X),
  368.             matrow1,
  369.             ureg_src(rgb));
  370.    ureg_MAD(ureg, rgb,
  371.             ureg_scalar(ureg_src(v), TGSI_SWIZZLE_X),
  372.             matrow2,
  373.             ureg_src(rgb));
  374.  
  375.    /* rgb.a = 1; */
  376.    ureg_MOV(ureg, ureg_writemask(rgb, TGSI_WRITEMASK_W),
  377.             ureg_scalar(matrow0, TGSI_SWIZZLE_X));
  378.  
  379.    ureg_MOV(ureg, out, ureg_src(rgb));
  380.  
  381.    ureg_release_temporary(ureg, rgb);
  382.    ureg_release_temporary(ureg, y);
  383.    ureg_release_temporary(ureg, u);
  384.    ureg_release_temporary(ureg, v);
  385.  
  386.    ureg_END(ureg);
  387.  
  388.    return ureg_create_shader_and_destroy(ureg, pipe);
  389. }
  390.  
  391.  
  392. static INLINE void
  393. xrender_tex(struct ureg_program *ureg,
  394.             struct ureg_dst dst,
  395.             struct ureg_src coords,
  396.             struct ureg_src sampler,
  397.             struct ureg_src imm0,
  398.             boolean repeat_none,
  399.             boolean swizzle,
  400.             boolean set_alpha)
  401. {
  402.    if (repeat_none) {
  403.       struct ureg_dst tmp0 = ureg_DECL_temporary(ureg);
  404.       struct ureg_dst tmp1 = ureg_DECL_temporary(ureg);
  405.       ureg_SGT(ureg, tmp1, ureg_swizzle(coords,
  406.                                         TGSI_SWIZZLE_X,
  407.                                         TGSI_SWIZZLE_Y,
  408.                                         TGSI_SWIZZLE_X,
  409.                                         TGSI_SWIZZLE_Y),
  410.                ureg_scalar(imm0, TGSI_SWIZZLE_X));
  411.       ureg_SLT(ureg, tmp0, ureg_swizzle(coords,
  412.                                         TGSI_SWIZZLE_X,
  413.                                         TGSI_SWIZZLE_Y,
  414.                                         TGSI_SWIZZLE_X,
  415.                                         TGSI_SWIZZLE_Y),
  416.                ureg_scalar(imm0, TGSI_SWIZZLE_W));
  417.       ureg_MIN(ureg, tmp0, ureg_src(tmp0), ureg_src(tmp1));
  418.       ureg_MIN(ureg, tmp0, ureg_scalar(ureg_src(tmp0), TGSI_SWIZZLE_X),
  419.                ureg_scalar(ureg_src(tmp0), TGSI_SWIZZLE_Y));
  420.       ureg_TEX(ureg, tmp1, TGSI_TEXTURE_2D, coords, sampler);
  421.       if (swizzle)
  422.          ureg_MOV(ureg, tmp1, ureg_swizzle(ureg_src(tmp1),
  423.                                            TGSI_SWIZZLE_Z,
  424.                                            TGSI_SWIZZLE_Y,
  425.                                            TGSI_SWIZZLE_X,
  426.                                            TGSI_SWIZZLE_W));
  427.       if (set_alpha)
  428.          ureg_MOV(ureg,
  429.                   ureg_writemask(tmp1, TGSI_WRITEMASK_W),
  430.                   ureg_scalar(imm0, TGSI_SWIZZLE_W));
  431.       ureg_MUL(ureg, dst, ureg_src(tmp1), ureg_src(tmp0));
  432.       ureg_release_temporary(ureg, tmp0);
  433.       ureg_release_temporary(ureg, tmp1);
  434.    } else {
  435.       if (swizzle) {
  436.          struct ureg_dst tmp = ureg_DECL_temporary(ureg);
  437.          ureg_TEX(ureg, tmp, TGSI_TEXTURE_2D, coords, sampler);
  438.          ureg_MOV(ureg, dst, ureg_swizzle(ureg_src(tmp),
  439.                                           TGSI_SWIZZLE_Z,
  440.                                           TGSI_SWIZZLE_Y,
  441.                                           TGSI_SWIZZLE_X,
  442.                                           TGSI_SWIZZLE_W));
  443.          ureg_release_temporary(ureg, tmp);
  444.       } else {
  445.          ureg_TEX(ureg, dst, TGSI_TEXTURE_2D, coords, sampler);
  446.       }
  447.       if (set_alpha)
  448.          ureg_MOV(ureg,
  449.                   ureg_writemask(dst, TGSI_WRITEMASK_W),
  450.                   ureg_scalar(imm0, TGSI_SWIZZLE_W));
  451.    }
  452. }
  453.  
  454. static void *
  455. create_fs(struct pipe_context *pipe,
  456.           unsigned fs_traits)
  457. {
  458.    struct ureg_program *ureg;
  459.    struct ureg_src /*dst_sampler,*/ src_sampler, mask_sampler;
  460.    struct ureg_src /*dst_pos,*/ src_input, mask_pos;
  461.    struct ureg_dst src, mask;
  462.    struct ureg_dst out;
  463.    struct ureg_src imm0 = { 0 };
  464.    unsigned has_mask = (fs_traits & FS_MASK) != 0;
  465.    unsigned is_fill = (fs_traits & FS_FILL) != 0;
  466.    unsigned is_composite = (fs_traits & FS_COMPOSITE) != 0;
  467.    unsigned is_solid   = (fs_traits & FS_SOLID_FILL) != 0;
  468.    unsigned is_lingrad = (fs_traits & FS_LINGRAD_FILL) != 0;
  469.    unsigned is_radgrad = (fs_traits & FS_RADGRAD_FILL) != 0;
  470.    unsigned comp_alpha_mask = fs_traits & FS_COMPONENT_ALPHA;
  471.    unsigned is_yuv = (fs_traits & FS_YUV) != 0;
  472.    unsigned src_repeat_none = (fs_traits & FS_SRC_REPEAT_NONE) != 0;
  473.    unsigned mask_repeat_none = (fs_traits & FS_MASK_REPEAT_NONE) != 0;
  474.    unsigned src_swizzle = (fs_traits & FS_SRC_SWIZZLE_RGB) != 0;
  475.    unsigned mask_swizzle = (fs_traits & FS_MASK_SWIZZLE_RGB) != 0;
  476.    unsigned src_set_alpha = (fs_traits & FS_SRC_SET_ALPHA) != 0;
  477.    unsigned mask_set_alpha = (fs_traits & FS_MASK_SET_ALPHA) != 0;
  478.    unsigned src_luminance = (fs_traits & FS_SRC_LUMINANCE) != 0;
  479.    unsigned mask_luminance = (fs_traits & FS_MASK_LUMINANCE) != 0;
  480.  
  481. #if 0
  482.    print_fs_traits(fs_traits);
  483. #else
  484.    (void)print_fs_traits;
  485. #endif
  486.  
  487.    ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT);
  488.    if (ureg == NULL)
  489.       return 0;
  490.  
  491.    /* it has to be either a fill, a composite op or a yuv conversion */
  492.    debug_assert((is_fill ^ is_composite) ^ is_yuv);
  493.    (void) is_yuv;
  494.  
  495.    out = ureg_DECL_output(ureg,
  496.                           TGSI_SEMANTIC_COLOR,
  497.                           0);
  498.  
  499.    if (src_repeat_none || mask_repeat_none ||
  500.        src_set_alpha || mask_set_alpha ||
  501.        src_luminance) {
  502.       imm0 = ureg_imm4f(ureg, 0, 0, 0, 1);
  503.    }
  504.    if (is_composite) {
  505.       src_sampler = ureg_DECL_sampler(ureg, 0);
  506.       src_input = ureg_DECL_fs_input(ureg,
  507.                                      TGSI_SEMANTIC_GENERIC,
  508.                                      0,
  509.                                      TGSI_INTERPOLATE_PERSPECTIVE);
  510.    } else if (is_fill) {
  511.       if (is_solid)
  512.          src_input = ureg_DECL_fs_input(ureg,
  513.                                         TGSI_SEMANTIC_COLOR,
  514.                                         0,
  515.                                         TGSI_INTERPOLATE_PERSPECTIVE);
  516.       else
  517.          src_input = ureg_DECL_fs_input(ureg,
  518.                                         TGSI_SEMANTIC_POSITION,
  519.                                         0,
  520.                                         TGSI_INTERPOLATE_PERSPECTIVE);
  521.    } else {
  522.       debug_assert(is_yuv);
  523.       return create_yuv_shader(pipe, ureg);
  524.    }
  525.  
  526.    if (has_mask) {
  527.       mask_sampler = ureg_DECL_sampler(ureg, 1);
  528.       mask_pos = ureg_DECL_fs_input(ureg,
  529.                                     TGSI_SEMANTIC_GENERIC,
  530.                                     1,
  531.                                     TGSI_INTERPOLATE_PERSPECTIVE);
  532.    }
  533.  
  534. #if 0  /* unused right now */
  535.    dst_sampler = ureg_DECL_sampler(ureg, 2);
  536.    dst_pos = ureg_DECL_fs_input(ureg,
  537.                                 TGSI_SEMANTIC_POSITION,
  538.                                 2,
  539.                                 TGSI_INTERPOLATE_PERSPECTIVE);
  540. #endif
  541.  
  542.  
  543.    if (is_composite) {
  544.       if (has_mask || src_luminance)
  545.          src = ureg_DECL_temporary(ureg);
  546.       else
  547.          src = out;
  548.       xrender_tex(ureg, src, src_input, src_sampler, imm0,
  549.                   src_repeat_none, src_swizzle, src_set_alpha);
  550.    } else if (is_fill) {
  551.       if (is_solid) {
  552.          if (has_mask || src_luminance)
  553.             src = ureg_dst(src_input);
  554.          else
  555.             ureg_MOV(ureg, out, src_input);
  556.       } else if (is_lingrad || is_radgrad) {
  557.          struct ureg_src coords, const0124,
  558.             matrow0, matrow1, matrow2;
  559.  
  560.          if (has_mask || src_luminance)
  561.             src = ureg_DECL_temporary(ureg);
  562.          else
  563.             src = out;
  564.  
  565.          coords = ureg_DECL_constant(ureg, 0);
  566.          const0124 = ureg_DECL_constant(ureg, 1);
  567.          matrow0 = ureg_DECL_constant(ureg, 2);
  568.          matrow1 = ureg_DECL_constant(ureg, 3);
  569.          matrow2 = ureg_DECL_constant(ureg, 4);
  570.  
  571.          if (is_lingrad) {
  572.             linear_gradient(ureg, src,
  573.                             src_input, src_sampler,
  574.                             coords, const0124,
  575.                             matrow0, matrow1, matrow2);
  576.          } else if (is_radgrad) {
  577.             radial_gradient(ureg, src,
  578.                             src_input, src_sampler,
  579.                             coords, const0124,
  580.                             matrow0, matrow1, matrow2);
  581.          }
  582.       } else
  583.          debug_assert(!"Unknown fill type!");
  584.    }
  585.    if (src_luminance) {
  586.       ureg_MOV(ureg, src,
  587.                ureg_scalar(ureg_src(src), TGSI_SWIZZLE_X));
  588.       ureg_MOV(ureg, ureg_writemask(src, TGSI_WRITEMASK_XYZ),
  589.                ureg_scalar(imm0, TGSI_SWIZZLE_X));
  590.       if (!has_mask)
  591.          ureg_MOV(ureg, out, ureg_src(src));
  592.    }
  593.  
  594.    if (has_mask) {
  595.       mask = ureg_DECL_temporary(ureg);
  596.       xrender_tex(ureg, mask, mask_pos, mask_sampler, imm0,
  597.                   mask_repeat_none, mask_swizzle, mask_set_alpha);
  598.       /* src IN mask */
  599.       src_in_mask(ureg, out, ureg_src(src), ureg_src(mask),
  600.                   comp_alpha_mask, mask_luminance);
  601.       ureg_release_temporary(ureg, mask);
  602.    }
  603.  
  604.    ureg_END(ureg);
  605.  
  606.    return ureg_create_shader_and_destroy(ureg, pipe);
  607. }
  608.  
  609. struct xorg_shaders * xorg_shaders_create(struct xorg_renderer *r)
  610. {
  611.    struct xorg_shaders *sc = CALLOC_STRUCT(xorg_shaders);
  612.  
  613.    sc->r = r;
  614.    sc->vs_hash = cso_hash_create();
  615.    sc->fs_hash = cso_hash_create();
  616.  
  617.    return sc;
  618. }
  619.  
  620. static void
  621. cache_destroy(struct cso_context *cso,
  622.               struct cso_hash *hash,
  623.               unsigned processor)
  624. {
  625.    struct cso_hash_iter iter = cso_hash_first_node(hash);
  626.    while (!cso_hash_iter_is_null(iter)) {
  627.       void *shader = (void *)cso_hash_iter_data(iter);
  628.       if (processor == PIPE_SHADER_FRAGMENT) {
  629.          cso_delete_fragment_shader(cso, shader);
  630.       } else if (processor == PIPE_SHADER_VERTEX) {
  631.          cso_delete_vertex_shader(cso, shader);
  632.       }
  633.       iter = cso_hash_erase(hash, iter);
  634.    }
  635.    cso_hash_delete(hash);
  636. }
  637.  
  638. void xorg_shaders_destroy(struct xorg_shaders *sc)
  639. {
  640.    cache_destroy(sc->r->cso, sc->vs_hash,
  641.                  PIPE_SHADER_VERTEX);
  642.    cache_destroy(sc->r->cso, sc->fs_hash,
  643.                  PIPE_SHADER_FRAGMENT);
  644.  
  645.    FREE(sc);
  646. }
  647.  
  648. static INLINE void *
  649. shader_from_cache(struct pipe_context *pipe,
  650.                   unsigned type,
  651.                   struct cso_hash *hash,
  652.                   unsigned key)
  653. {
  654.    void *shader = 0;
  655.  
  656.    struct cso_hash_iter iter = cso_hash_find(hash, key);
  657.  
  658.    if (cso_hash_iter_is_null(iter)) {
  659.       if (type == PIPE_SHADER_VERTEX)
  660.          shader = create_vs(pipe, key);
  661.       else
  662.          shader = create_fs(pipe, key);
  663.       cso_hash_insert(hash, key, shader);
  664.    } else
  665.       shader = (void *)cso_hash_iter_data(iter);
  666.  
  667.    return shader;
  668. }
  669.  
  670. struct xorg_shader xorg_shaders_get(struct xorg_shaders *sc,
  671.                                     unsigned vs_traits,
  672.                                     unsigned fs_traits)
  673. {
  674.    struct xorg_shader shader = { NULL, NULL };
  675.    void *vs, *fs;
  676.  
  677.    vs = shader_from_cache(sc->r->pipe, PIPE_SHADER_VERTEX,
  678.                           sc->vs_hash, vs_traits);
  679.    fs = shader_from_cache(sc->r->pipe, PIPE_SHADER_FRAGMENT,
  680.                           sc->fs_hash, fs_traits);
  681.  
  682.    debug_assert(vs && fs);
  683.    if (!vs || !fs)
  684.       return shader;
  685.  
  686.    shader.vs = vs;
  687.    shader.fs = fs;
  688.  
  689.    return shader;
  690. }
  691.