Subversion Repositories Kolibri OS

Rev

Rev 3769 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright ะน 2010-2011 Intel Corporation
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the "Software"),
  6.  * to deal in the Software without restriction, including without limitation
  7.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8.  * and/or sell copies of the Software, and to permit persons to whom the
  9.  * Software is furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice (including the next
  12.  * paragraph) shall be included in all copies or substantial portions of the
  13.  * Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  18.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20.  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  21.  * SOFTWARE.
  22.  *
  23.  * Authors:
  24.  *    Chris Wilson <chris@chris-wilson.co.uk>
  25.  *
  26.  */
  27.  
  28. #ifdef HAVE_CONFIG_H
  29. #include "config.h"
  30. #endif
  31.  
  32. #include "sna.h"
  33. #include "sna_render.h"
  34. #include "sna_render_inline.h"
  35. #include "sna_reg.h"
  36. //#include "sna_video.h"
  37.  
  38. #include "gen3_render.h"
  39.  
  40. #define NO_COMPOSITE 0
  41. #define NO_COMPOSITE_SPANS 0
  42. #define NO_COPY 0
  43. #define NO_COPY_BOXES 0
  44. #define NO_FILL 0
  45. #define NO_FILL_ONE 0
  46. #define NO_FILL_BOXES 0
  47.  
  48. #define PREFER_BLT_FILL 1
  49.  
  50. enum {
  51.         SHADER_NONE = 0,
  52.         SHADER_ZERO,
  53.         SHADER_BLACK,
  54.         SHADER_WHITE,
  55.         SHADER_CONSTANT,
  56.         SHADER_LINEAR,
  57.         SHADER_RADIAL,
  58.         SHADER_TEXTURE,
  59.         SHADER_OPACITY,
  60. };
  61.  
  62. #define MAX_3D_SIZE 2048
  63. #define MAX_3D_PITCH 8192
  64.  
  65. #define OUT_BATCH(v) batch_emit(sna, v)
  66. #define OUT_BATCH_F(v) batch_emit_float(sna, v)
  67. #define OUT_VERTEX(v) vertex_emit(sna, v)
  68.  
  69. enum gen3_radial_mode {
  70.         RADIAL_ONE,
  71.         RADIAL_TWO
  72. };
  73.  
  74. static const struct blendinfo {
  75.         bool dst_alpha;
  76.         bool src_alpha;
  77.         uint32_t src_blend;
  78.         uint32_t dst_blend;
  79. } gen3_blend_op[] = {
  80.         /* Clear */     {0, 0, BLENDFACT_ZERO, BLENDFACT_ZERO},
  81.         /* Src */       {0, 0, BLENDFACT_ONE, BLENDFACT_ZERO},
  82.         /* Dst */       {0, 0, BLENDFACT_ZERO, BLENDFACT_ONE},
  83.         /* Over */      {0, 1, BLENDFACT_ONE, BLENDFACT_INV_SRC_ALPHA},
  84.         /* OverReverse */ {1, 0, BLENDFACT_INV_DST_ALPHA, BLENDFACT_ONE},
  85.         /* In */        {1, 0, BLENDFACT_DST_ALPHA, BLENDFACT_ZERO},
  86.         /* InReverse */ {0, 1, BLENDFACT_ZERO, BLENDFACT_SRC_ALPHA},
  87.         /* Out */       {1, 0, BLENDFACT_INV_DST_ALPHA, BLENDFACT_ZERO},
  88.         /* OutReverse */ {0, 1, BLENDFACT_ZERO, BLENDFACT_INV_SRC_ALPHA},
  89.         /* Atop */      {1, 1, BLENDFACT_DST_ALPHA, BLENDFACT_INV_SRC_ALPHA},
  90.         /* AtopReverse */ {1, 1, BLENDFACT_INV_DST_ALPHA, BLENDFACT_SRC_ALPHA},
  91.         /* Xor */       {1, 1, BLENDFACT_INV_DST_ALPHA, BLENDFACT_INV_SRC_ALPHA},
  92.         /* Add */       {0, 0, BLENDFACT_ONE, BLENDFACT_ONE},
  93. };
  94.  
  95. #define S6_COLOR_WRITE_ONLY \
  96.         (S6_COLOR_WRITE_ENABLE | \
  97.          BLENDFUNC_ADD << S6_CBUF_BLEND_FUNC_SHIFT | \
  98.          BLENDFACT_ONE << S6_CBUF_SRC_BLEND_FACT_SHIFT | \
  99.          BLENDFACT_ZERO << S6_CBUF_DST_BLEND_FACT_SHIFT)
  100.  
  101. static const struct formatinfo {
  102.         unsigned int fmt, xfmt;
  103.         uint32_t card_fmt;
  104.         bool rb_reversed;
  105. } gen3_tex_formats[] = {
  106.         {PICT_a8, 0, MAPSURF_8BIT | MT_8BIT_A8, false},
  107.         {PICT_a8r8g8b8, 0, MAPSURF_32BIT | MT_32BIT_ARGB8888, false},
  108.         {PICT_x8r8g8b8, 0, MAPSURF_32BIT | MT_32BIT_XRGB8888, false},
  109.         {PICT_a8b8g8r8, 0, MAPSURF_32BIT | MT_32BIT_ABGR8888, false},
  110.         {PICT_x8b8g8r8, 0, MAPSURF_32BIT | MT_32BIT_XBGR8888, false}
  111. };
  112.  
  113. #define xFixedToDouble(f) pixman_fixed_to_double(f)
  114.  
  115. static inline bool too_large(int width, int height)
  116. {
  117.         return width > MAX_3D_SIZE || height > MAX_3D_SIZE;
  118. }
  119.  
  120. static inline uint32_t gen3_buf_tiling(uint32_t tiling)
  121. {
  122.         uint32_t v = 0;
  123.         switch (tiling) {
  124.         case I915_TILING_Y: v |= BUF_3D_TILE_WALK_Y;
  125.         case I915_TILING_X: v |= BUF_3D_TILED_SURFACE;
  126.         case I915_TILING_NONE: break;
  127.         }
  128.         return v;
  129. }
  130. static uint32_t gen3_get_blend_cntl(int op,
  131.                                     bool has_component_alpha,
  132.                                     uint32_t dst_format)
  133. {
  134.         uint32_t sblend;
  135.         uint32_t dblend;
  136.  
  137.     sblend = BLENDFACT_ONE;
  138.     dblend = BLENDFACT_INV_SRC_ALPHA;
  139.  
  140. #if 0
  141.         if (op <= PictOpSrc) /* for clear and src disable blending */
  142.                 return S6_COLOR_WRITE_ONLY;
  143.  
  144.         /* If there's no dst alpha channel, adjust the blend op so that we'll
  145.          * treat it as always 1.
  146.          */
  147.         if (gen3_blend_op[op].dst_alpha) {
  148.                 if (PICT_FORMAT_A(dst_format) == 0) {
  149.                         if (sblend == BLENDFACT_DST_ALPHA)
  150.                                 sblend = BLENDFACT_ONE;
  151.                         else if (sblend == BLENDFACT_INV_DST_ALPHA)
  152.                                 sblend = BLENDFACT_ZERO;
  153.                 }
  154.  
  155.                 /* gen3 engine reads 8bit color buffer into green channel
  156.                  * in cases like color buffer blending etc., and also writes
  157.                  * back green channel.  So with dst_alpha blend we should use
  158.                  * color factor. See spec on "8-bit rendering".
  159.                  */
  160.                 if (dst_format == PICT_a8) {
  161.                         if (sblend == BLENDFACT_DST_ALPHA)
  162.                                 sblend = BLENDFACT_DST_COLR;
  163.                         else if (sblend == BLENDFACT_INV_DST_ALPHA)
  164.                                 sblend = BLENDFACT_INV_DST_COLR;
  165.                 }
  166.         }
  167.  
  168.         /* If the source alpha is being used, then we should only be in a case
  169.          * where the source blend factor is 0, and the source blend value is the
  170.          * mask channels multiplied by the source picture's alpha.
  171.          */
  172.         if (has_component_alpha && gen3_blend_op[op].src_alpha) {
  173.                 if (dblend == BLENDFACT_SRC_ALPHA)
  174.                         dblend = BLENDFACT_SRC_COLR;
  175.                 else if (dblend == BLENDFACT_INV_SRC_ALPHA)
  176.                         dblend = BLENDFACT_INV_SRC_COLR;
  177.         }
  178. #endif
  179.  
  180.         return (S6_CBUF_BLEND_ENABLE | S6_COLOR_WRITE_ENABLE |
  181.                 BLENDFUNC_ADD << S6_CBUF_BLEND_FUNC_SHIFT |
  182.                 sblend << S6_CBUF_SRC_BLEND_FACT_SHIFT |
  183.                 dblend << S6_CBUF_DST_BLEND_FACT_SHIFT);
  184. }
  185. static bool gen3_dst_rb_reversed(uint32_t format)
  186. {
  187.         switch (format) {
  188.         case PICT_a8r8g8b8:
  189.         case PICT_x8r8g8b8:
  190.         case PICT_a8:
  191.                 return false;
  192.         default:
  193.                 return true;
  194.         }
  195. }
  196.  
  197. #define DSTORG_HORT_BIAS(x)             ((x)<<20)
  198. #define DSTORG_VERT_BIAS(x)             ((x)<<16)
  199.  
  200. static uint32_t gen3_get_dst_format(uint32_t format)
  201. {
  202. #define BIAS (DSTORG_HORT_BIAS(0x8) | DSTORG_VERT_BIAS(0x8))
  203.         switch (format) {
  204.         default:
  205.         case PICT_a8r8g8b8:
  206.         case PICT_x8r8g8b8:
  207.         case PICT_a8b8g8r8:
  208.         case PICT_x8b8g8r8:
  209.                 return BIAS | COLR_BUF_ARGB8888;
  210.         case PICT_a8:
  211.                 return BIAS | COLR_BUF_8BIT;
  212.         }
  213. #undef BIAS
  214. }
  215.  
  216.  
  217.  
  218. fastcall static void
  219. gen3_emit_composite_primitive_identity_source_mask(struct sna *sna,
  220.                                                    const struct sna_composite_op *op,
  221.                                                    const struct sna_composite_rectangles *r)
  222. {
  223.         float dst_x, dst_y;
  224.         float src_x, src_y;
  225.         float msk_x, msk_y;
  226.         float w, h;
  227.         float *v;
  228.  
  229.         dst_x = r->dst.x + op->dst.x;
  230.         dst_y = r->dst.y + op->dst.y;
  231.         src_x = r->src.x + op->src.offset[0];
  232.         src_y = r->src.y + op->src.offset[1];
  233.         msk_x = r->mask.x + op->mask.offset[0];
  234.         msk_y = r->mask.y + op->mask.offset[1];
  235.         w = r->width;
  236.         h = r->height;
  237.  
  238.         v = sna->render.vertices + sna->render.vertex_used;
  239.         sna->render.vertex_used += 18;
  240.  
  241.         v[0] = dst_x + w;
  242.         v[1] = dst_y + h;
  243.         v[2] = (src_x + w) * op->src.scale[0];
  244.         v[3] = (src_y + h) * op->src.scale[1];
  245.         v[4] = (msk_x + w) * op->mask.scale[0];
  246.         v[5] = (msk_y + h) * op->mask.scale[1];
  247.  
  248.         v[6] = dst_x;
  249.         v[7] = v[1];
  250.         v[8] = src_x * op->src.scale[0];
  251.         v[9] = v[3];
  252.         v[10] = msk_x * op->mask.scale[0];
  253.         v[11] =v[5];
  254.  
  255.         v[12] = v[6];
  256.         v[13] = dst_y;
  257.         v[14] = v[8];
  258.         v[15] = src_y * op->src.scale[1];
  259.         v[16] = v[10];
  260.         v[17] = msk_y * op->mask.scale[1];
  261. }
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270.  
  271.  
  272.  
  273.  
  274.  
  275.  
  276.  
  277.  
  278.  
  279.  
  280.  
  281.  
  282.  
  283.  
  284.  
  285.  
  286.  
  287.  
  288.  
  289.  
  290.  
  291.  
  292.  
  293.  
  294.  
  295.  
  296.  
  297.  
  298.  
  299.  
  300.  
  301.  
  302.  
  303.  
  304.  
  305.  
  306.  
  307.  
  308.  
  309.  
  310.  
  311.  
  312.  
  313.  
  314.  
  315.  
  316.  
  317.  
  318.  
  319.  
  320.  
  321.  
  322.  
  323.  
  324.  
  325. static inline void
  326. gen3_2d_perspective(struct sna *sna, int in, int out)
  327. {
  328.         gen3_fs_rcp(out, 0, gen3_fs_operand(in, W, W, W, W));
  329.         gen3_fs_mul(out,
  330.                     gen3_fs_operand(in, X, Y, ZERO, ONE),
  331.                     gen3_fs_operand_reg(out));
  332. }
  333.  
  334. static inline void
  335. gen3_linear_coord(struct sna *sna,
  336.                   const struct sna_composite_channel *channel,
  337.                   int in, int out)
  338. {
  339.         int c = channel->u.gen3.constants;
  340.  
  341.         if (!channel->is_affine) {
  342.                 gen3_2d_perspective(sna, in, FS_U0);
  343.                 in = FS_U0;
  344.         }
  345.  
  346.         gen3_fs_mov(out, gen3_fs_operand_zero());
  347.         gen3_fs_dp3(out, MASK_X,
  348.                     gen3_fs_operand(in, X, Y, ONE, ZERO),
  349.                     gen3_fs_operand_reg(c));
  350. }
  351.  
  352. static void
  353. gen3_radial_coord(struct sna *sna,
  354.                   const struct sna_composite_channel *channel,
  355.                   int in, int out)
  356. {
  357.         int c = channel->u.gen3.constants;
  358.  
  359.         if (!channel->is_affine) {
  360.                 gen3_2d_perspective(sna, in, FS_U0);
  361.                 in = FS_U0;
  362.         }
  363.  
  364.         switch (channel->u.gen3.mode) {
  365.         case RADIAL_ONE:
  366.                 /*
  367.                    pdx = (x - c1x) / dr, pdy = (y - c1y) / dr;
  368.                    r? = pdx*pdx + pdy*pdy
  369.                    t = r?/sqrt(r?) - r1/dr;
  370.                    */
  371.                 gen3_fs_mad(FS_U0, MASK_X | MASK_Y,
  372.                             gen3_fs_operand(in, X, Y, ZERO, ZERO),
  373.                             gen3_fs_operand(c, Z, Z, ZERO, ZERO),
  374.                             gen3_fs_operand(c, NEG_X, NEG_Y, ZERO, ZERO));
  375.                 gen3_fs_dp2add(FS_U0, MASK_X,
  376.                                gen3_fs_operand(FS_U0, X, Y, ZERO, ZERO),
  377.                                gen3_fs_operand(FS_U0, X, Y, ZERO, ZERO),
  378.                                gen3_fs_operand_zero());
  379.                 gen3_fs_rsq(out, MASK_X, gen3_fs_operand(FS_U0, X, X, X, X));
  380.                 gen3_fs_mad(out, 0,
  381.                             gen3_fs_operand(FS_U0, X, ZERO, ZERO, ZERO),
  382.                             gen3_fs_operand(out, X, ZERO, ZERO, ZERO),
  383.                             gen3_fs_operand(c, W, ZERO, ZERO, ZERO));
  384.                 break;
  385.  
  386.         case RADIAL_TWO:
  387.                 /*
  388.                    pdx = x - c1x, pdy = y - c1y;
  389.                    A = dx? + dy? - dr?
  390.                    B = -2*(pdx*dx + pdy*dy + r1*dr);
  391.                    C = pdx? + pdy? - r1?;
  392.                    det = B*B - 4*A*C;
  393.                    t = (-B + sqrt (det)) / (2 * A)
  394.                    */
  395.  
  396.                 /* u0.x = pdx, u0.y = pdy, u[0].z = r1; */
  397.                 gen3_fs_add(FS_U0,
  398.                             gen3_fs_operand(in, X, Y, ZERO, ZERO),
  399.                             gen3_fs_operand(c, X, Y, Z, ZERO));
  400.                 /* u0.x = pdx, u0.y = pdy, u[0].z = r1, u[0].w = B; */
  401.                 gen3_fs_dp3(FS_U0, MASK_W,
  402.                             gen3_fs_operand(FS_U0, X, Y, ONE, ZERO),
  403.                             gen3_fs_operand(c+1, X, Y, Z, ZERO));
  404.                 /* u1.x = pdx? + pdy? - r1?; [C] */
  405.                 gen3_fs_dp3(FS_U1, MASK_X,
  406.                             gen3_fs_operand(FS_U0, X, Y, Z, ZERO),
  407.                             gen3_fs_operand(FS_U0, X, Y, NEG_Z, ZERO));
  408.                 /* u1.x = C, u1.y = B, u1.z=-4*A; */
  409.                 gen3_fs_mov_masked(FS_U1, MASK_Y, gen3_fs_operand(FS_U0, W, W, W, W));
  410.                 gen3_fs_mov_masked(FS_U1, MASK_Z, gen3_fs_operand(c, W, W, W, W));
  411.                 /* u1.x = B? - 4*A*C */
  412.                 gen3_fs_dp2add(FS_U1, MASK_X,
  413.                                gen3_fs_operand(FS_U1, X, Y, ZERO, ZERO),
  414.                                gen3_fs_operand(FS_U1, Z, Y, ZERO, ZERO),
  415.                                gen3_fs_operand_zero());
  416.                 /* out.x = -B + sqrt (B? - 4*A*C), */
  417.                 gen3_fs_rsq(out, MASK_X, gen3_fs_operand(FS_U1, X, X, X, X));
  418.                 gen3_fs_mad(out, MASK_X,
  419.                             gen3_fs_operand(out, X, ZERO, ZERO, ZERO),
  420.                             gen3_fs_operand(FS_U1, X, ZERO, ZERO, ZERO),
  421.                             gen3_fs_operand(FS_U0, NEG_W, ZERO, ZERO, ZERO));
  422.                 /* out.x = (-B + sqrt (B? - 4*A*C)) / (2 * A), */
  423.                 gen3_fs_mul(out,
  424.                             gen3_fs_operand(out, X, ZERO, ZERO, ZERO),
  425.                             gen3_fs_operand(c+1, W, ZERO, ZERO, ZERO));
  426.                 break;
  427.         }
  428. }
  429.  
  430. static void
  431. gen3_composite_emit_shader(struct sna *sna,
  432.                            const struct sna_composite_op *op,
  433.                            uint8_t blend)
  434. {
  435.         bool dst_is_alpha = PIXMAN_FORMAT_RGB(op->dst.format) == 0;
  436.         const struct sna_composite_channel *src, *mask;
  437.         struct gen3_render_state *state = &sna->render_state.gen3;
  438.         uint32_t shader_offset, id;
  439.         int src_reg, mask_reg;
  440.         int t, length;
  441.  
  442.         src = &op->src;
  443.         mask = &op->mask;
  444.         if (mask->u.gen3.type == SHADER_NONE)
  445.                 mask = NULL;
  446.  
  447.         id = (src->u.gen3.type |
  448.               src->is_affine << 4 |
  449.               src->alpha_fixup << 5 |
  450.               src->rb_reversed << 6);
  451.         if (mask) {
  452.                 id |= (mask->u.gen3.type << 8 |
  453.                        mask->is_affine << 12 |
  454.                        gen3_blend_op[blend].src_alpha << 13 |
  455.                        op->has_component_alpha << 14 |
  456.                        mask->alpha_fixup << 15 |
  457.                        mask->rb_reversed << 16);
  458.         }
  459.         id |= dst_is_alpha << 24;
  460.         id |= op->rb_reversed << 25;
  461.  
  462.         if (id == state->last_shader)
  463.                 return;
  464.  
  465.         state->last_shader = id;
  466.  
  467.         shader_offset = sna->kgem.nbatch++;
  468.         t = 0;
  469.         switch (src->u.gen3.type) {
  470.         case SHADER_NONE:
  471.         case SHADER_OPACITY:
  472.                 assert(0);
  473.         case SHADER_ZERO:
  474.         case SHADER_BLACK:
  475.         case SHADER_WHITE:
  476.                 break;
  477.         case SHADER_CONSTANT:
  478.                 gen3_fs_dcl(FS_T8);
  479.                 src_reg = FS_T8;
  480.                 break;
  481.         case SHADER_TEXTURE:
  482.         case SHADER_RADIAL:
  483.         case SHADER_LINEAR:
  484.                 gen3_fs_dcl(FS_S0);
  485.                 gen3_fs_dcl(FS_T0);
  486.                 t++;
  487.                 break;
  488.         }
  489.  
  490.         if (mask == NULL) {
  491.                 switch (src->u.gen3.type) {
  492.                 case SHADER_ZERO:
  493.                         gen3_fs_mov(FS_OC, gen3_fs_operand_zero());
  494.                         goto done;
  495.                 case SHADER_BLACK:
  496.                         if (dst_is_alpha)
  497.                                 gen3_fs_mov(FS_OC, gen3_fs_operand_one());
  498.                         else
  499.                                 gen3_fs_mov(FS_OC, gen3_fs_operand(FS_R0, ZERO, ZERO, ZERO, ONE));
  500.                         goto done;
  501.                 case SHADER_WHITE:
  502.                         gen3_fs_mov(FS_OC, gen3_fs_operand_one());
  503.                         goto done;
  504.                 }
  505.                 if (src->alpha_fixup && dst_is_alpha) {
  506.                         gen3_fs_mov(FS_OC, gen3_fs_operand_one());
  507.                         goto done;
  508.                 }
  509.                 /* No mask, so load directly to output color */
  510.                 if (src->u.gen3.type != SHADER_CONSTANT) {
  511.                         if (dst_is_alpha || src->rb_reversed ^ op->rb_reversed)
  512.                                 src_reg = FS_R0;
  513.                         else
  514.                                 src_reg = FS_OC;
  515.                 }
  516.                 switch (src->u.gen3.type) {
  517.                 case SHADER_LINEAR:
  518.                         gen3_linear_coord(sna, src, FS_T0, FS_R0);
  519.                         gen3_fs_texld(src_reg, FS_S0, FS_R0);
  520.                         break;
  521.  
  522.                 case SHADER_RADIAL:
  523.                         gen3_radial_coord(sna, src, FS_T0, FS_R0);
  524.                         gen3_fs_texld(src_reg, FS_S0, FS_R0);
  525.                         break;
  526.  
  527.                 case SHADER_TEXTURE:
  528.                         if (src->is_affine)
  529.                                 gen3_fs_texld(src_reg, FS_S0, FS_T0);
  530.                         else
  531.                                 gen3_fs_texldp(src_reg, FS_S0, FS_T0);
  532.                         break;
  533.  
  534.                 case SHADER_NONE:
  535.                 case SHADER_WHITE:
  536.                 case SHADER_BLACK:
  537.                 case SHADER_ZERO:
  538.                         assert(0);
  539.                 case SHADER_CONSTANT:
  540.                         break;
  541.                 }
  542.  
  543.                 if (src_reg != FS_OC) {
  544.                         if (src->alpha_fixup)
  545.                                 gen3_fs_mov(FS_OC,
  546.                                             src->rb_reversed ^ op->rb_reversed ?
  547.                                             gen3_fs_operand(src_reg, Z, Y, X, ONE) :
  548.                                             gen3_fs_operand(src_reg, X, Y, Z, ONE));
  549.                         else if (dst_is_alpha)
  550.                                 gen3_fs_mov(FS_OC, gen3_fs_operand(src_reg, W, W, W, W));
  551.                         else if (src->rb_reversed ^ op->rb_reversed)
  552.                                 gen3_fs_mov(FS_OC, gen3_fs_operand(src_reg, Z, Y, X, W));
  553.                         else
  554.                                 gen3_fs_mov(FS_OC, gen3_fs_operand_reg(src_reg));
  555.                 } else if (src->alpha_fixup)
  556.                         gen3_fs_mov_masked(FS_OC, MASK_W, gen3_fs_operand_one());
  557.         } else {
  558.                 int out_reg = FS_OC;
  559.                 if (op->rb_reversed)
  560.                         out_reg = FS_U0;
  561.  
  562.                 switch (mask->u.gen3.type) {
  563.                 case SHADER_CONSTANT:
  564.                         gen3_fs_dcl(FS_T9);
  565.                         mask_reg = FS_T9;
  566.                         break;
  567.                 case SHADER_TEXTURE:
  568.                 case SHADER_LINEAR:
  569.                 case SHADER_RADIAL:
  570.                         gen3_fs_dcl(FS_S0 + t);
  571.                         /* fall through */
  572.                 case SHADER_OPACITY:
  573.                         gen3_fs_dcl(FS_T0 + t);
  574.                         break;
  575.                 case SHADER_ZERO:
  576.                 case SHADER_BLACK:
  577.                         assert(0);
  578.                 case SHADER_NONE:
  579.                 case SHADER_WHITE:
  580.                         break;
  581.                 }
  582.  
  583.                 t = 0;
  584.                 switch (src->u.gen3.type) {
  585.                 case SHADER_LINEAR:
  586.                         gen3_linear_coord(sna, src, FS_T0, FS_R0);
  587.                         gen3_fs_texld(FS_R0, FS_S0, FS_R0);
  588.                         src_reg = FS_R0;
  589.                         t++;
  590.                         break;
  591.  
  592.                 case SHADER_RADIAL:
  593.                         gen3_radial_coord(sna, src, FS_T0, FS_R0);
  594.                         gen3_fs_texld(FS_R0, FS_S0, FS_R0);
  595.                         src_reg = FS_R0;
  596.                         t++;
  597.                         break;
  598.  
  599.                 case SHADER_TEXTURE:
  600.                         if (src->is_affine)
  601.                                 gen3_fs_texld(FS_R0, FS_S0, FS_T0);
  602.                         else
  603.                                 gen3_fs_texldp(FS_R0, FS_S0, FS_T0);
  604.                         src_reg = FS_R0;
  605.                         t++;
  606.                         break;
  607.  
  608.                 case SHADER_CONSTANT:
  609.                 case SHADER_NONE:
  610.                 case SHADER_ZERO:
  611.                 case SHADER_BLACK:
  612.                 case SHADER_WHITE:
  613.                         break;
  614.                 }
  615.                 if (src->alpha_fixup)
  616.                         gen3_fs_mov_masked(src_reg, MASK_W, gen3_fs_operand_one());
  617.                 if (src->rb_reversed)
  618.                         gen3_fs_mov(src_reg, gen3_fs_operand(src_reg, Z, Y, X, W));
  619.  
  620.                 switch (mask->u.gen3.type) {
  621.                 case SHADER_LINEAR:
  622.                         gen3_linear_coord(sna, mask, FS_T0 + t, FS_R1);
  623.                         gen3_fs_texld(FS_R1, FS_S0 + t, FS_R1);
  624.                         mask_reg = FS_R1;
  625.                         break;
  626.  
  627.                 case SHADER_RADIAL:
  628.                         gen3_radial_coord(sna, mask, FS_T0 + t, FS_R1);
  629.                         gen3_fs_texld(FS_R1, FS_S0 + t, FS_R1);
  630.                         mask_reg = FS_R1;
  631.                         break;
  632.  
  633.                 case SHADER_TEXTURE:
  634.                         if (mask->is_affine)
  635.                                 gen3_fs_texld(FS_R1, FS_S0 + t, FS_T0 + t);
  636.                         else
  637.                                 gen3_fs_texldp(FS_R1, FS_S0 + t, FS_T0 + t);
  638.                         mask_reg = FS_R1;
  639.                         break;
  640.  
  641.                 case SHADER_OPACITY:
  642.                         switch (src->u.gen3.type) {
  643.                         case SHADER_BLACK:
  644.                         case SHADER_WHITE:
  645.                                 if (dst_is_alpha || src->u.gen3.type == SHADER_WHITE) {
  646.                                         gen3_fs_mov(out_reg,
  647.                                                     gen3_fs_operand(FS_T0 + t, X, X, X, X));
  648.                                 } else {
  649.                                         gen3_fs_mov(out_reg,
  650.                                                     gen3_fs_operand(FS_T0 + t, ZERO, ZERO, ZERO, X));
  651.                                 }
  652.                                 break;
  653.                         default:
  654.                                 if (dst_is_alpha) {
  655.                                         gen3_fs_mul(out_reg,
  656.                                                     gen3_fs_operand(src_reg, W, W, W, W),
  657.                                                     gen3_fs_operand(FS_T0 + t, X, X, X, X));
  658.                                 } else {
  659.                                         gen3_fs_mul(out_reg,
  660.                                                     gen3_fs_operand(src_reg, X, Y, Z, W),
  661.                                                     gen3_fs_operand(FS_T0 + t, X, X, X, X));
  662.                                 }
  663.                         }
  664.                         goto mask_done;
  665.  
  666.                 case SHADER_CONSTANT:
  667.                 case SHADER_ZERO:
  668.                 case SHADER_BLACK:
  669.                 case SHADER_WHITE:
  670.                 case SHADER_NONE:
  671.                         break;
  672.                 }
  673.                 if (mask->alpha_fixup)
  674.                         gen3_fs_mov_masked(mask_reg, MASK_W, gen3_fs_operand_one());
  675.                 if (mask->rb_reversed)
  676.                         gen3_fs_mov(mask_reg, gen3_fs_operand(mask_reg, Z, Y, X, W));
  677.  
  678.                 if (dst_is_alpha) {
  679.                         switch (src->u.gen3.type) {
  680.                         case SHADER_BLACK:
  681.                         case SHADER_WHITE:
  682.                                 gen3_fs_mov(out_reg,
  683.                                             gen3_fs_operand(mask_reg, W, W, W, W));
  684.                                 break;
  685.                         default:
  686.                                 gen3_fs_mul(out_reg,
  687.                                             gen3_fs_operand(src_reg, W, W, W, W),
  688.                                             gen3_fs_operand(mask_reg, W, W, W, W));
  689.                                 break;
  690.                         }
  691.                 } else {
  692.                         /* If component alpha is active in the mask and the blend
  693.                          * operation uses the source alpha, then we know we don't
  694.                          * need the source value (otherwise we would have hit a
  695.                          * fallback earlier), so we provide the source alpha (src.A *
  696.                          * mask.X) as output color.
  697.                          * Conversely, if CA is set and we don't need the source alpha,
  698.                          * then we produce the source value (src.X * mask.X) and the
  699.                          * source alpha is unused.  Otherwise, we provide the non-CA
  700.                          * source value (src.X * mask.A).
  701.                          */
  702.                         if (op->has_component_alpha) {
  703.                                 switch (src->u.gen3.type) {
  704.                                 case SHADER_BLACK:
  705.                                         if (gen3_blend_op[blend].src_alpha)
  706.                                                 gen3_fs_mov(out_reg,
  707.                                                             gen3_fs_operand_reg(mask_reg));
  708.                                         else
  709.                                                 gen3_fs_mov(out_reg,
  710.                                                             gen3_fs_operand(mask_reg, ZERO, ZERO, ZERO, W));
  711.                                         break;
  712.                                 case SHADER_WHITE:
  713.                                         gen3_fs_mov(out_reg,
  714.                                                     gen3_fs_operand_reg(mask_reg));
  715.                                         break;
  716.                                 default:
  717.                                         if (gen3_blend_op[blend].src_alpha)
  718.                                                 gen3_fs_mul(out_reg,
  719.                                                             gen3_fs_operand(src_reg, W, W, W, W),
  720.                                                             gen3_fs_operand_reg(mask_reg));
  721.                                         else
  722.                                                 gen3_fs_mul(out_reg,
  723.                                                             gen3_fs_operand_reg(src_reg),
  724.                                                             gen3_fs_operand_reg(mask_reg));
  725.                                         break;
  726.                                 }
  727.                         } else {
  728.                                 switch (src->u.gen3.type) {
  729.                                 case SHADER_WHITE:
  730.                                         gen3_fs_mov(out_reg,
  731.                                                     gen3_fs_operand(mask_reg, W, W, W, W));
  732.                                         break;
  733.                                 case SHADER_BLACK:
  734.                                         gen3_fs_mov(out_reg,
  735.                                                     gen3_fs_operand(mask_reg, ZERO, ZERO, ZERO, W));
  736.                                         break;
  737.                                 default:
  738.                                         gen3_fs_mul(out_reg,
  739.                                                     gen3_fs_operand_reg(src_reg),
  740.                                                     gen3_fs_operand(mask_reg, W, W, W, W));
  741.                                         break;
  742.                                 }
  743.                         }
  744.                 }
  745. mask_done:
  746.                 if (op->rb_reversed)
  747.                         gen3_fs_mov(FS_OC, gen3_fs_operand(FS_U0, Z, Y, X, W));
  748.         }
  749.  
  750. done:
  751.         length = sna->kgem.nbatch - shader_offset;
  752.         sna->kgem.batch[shader_offset] =
  753.                 _3DSTATE_PIXEL_SHADER_PROGRAM | (length - 2);
  754. }
  755.  
  756. static uint32_t gen3_ms_tiling(uint32_t tiling)
  757. {
  758.         uint32_t v = 0;
  759.         switch (tiling) {
  760.         case I915_TILING_Y: v |= MS3_TILE_WALK;
  761.         case I915_TILING_X: v |= MS3_TILED_SURFACE;
  762.         case I915_TILING_NONE: break;
  763.         }
  764.         return v;
  765. }
  766.  
  767. static void gen3_emit_invariant(struct sna *sna)
  768. {
  769.         /* Disable independent alpha blend */
  770.         OUT_BATCH(_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | IAB_MODIFY_ENABLE |
  771.                   IAB_MODIFY_FUNC | BLENDFUNC_ADD << IAB_FUNC_SHIFT |
  772.                   IAB_MODIFY_SRC_FACTOR | BLENDFACT_ONE << IAB_SRC_FACTOR_SHIFT |
  773.                   IAB_MODIFY_DST_FACTOR | BLENDFACT_ZERO << IAB_DST_FACTOR_SHIFT);
  774.  
  775.         OUT_BATCH(_3DSTATE_COORD_SET_BINDINGS |
  776.                   CSB_TCB(0, 0) |
  777.                   CSB_TCB(1, 1) |
  778.                   CSB_TCB(2, 2) |
  779.                   CSB_TCB(3, 3) |
  780.                   CSB_TCB(4, 4) |
  781.                   CSB_TCB(5, 5) |
  782.                   CSB_TCB(6, 6) |
  783.                   CSB_TCB(7, 7));
  784.  
  785.         OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | I1_LOAD_S(4) | I1_LOAD_S(5) | I1_LOAD_S(6) | 3);
  786.         OUT_BATCH(0); /* Disable texture coordinate wrap-shortest */
  787.         OUT_BATCH((1 << S4_POINT_WIDTH_SHIFT) |
  788.                   S4_LINE_WIDTH_ONE |
  789.                   S4_CULLMODE_NONE |
  790.                   S4_VFMT_XY);
  791.         OUT_BATCH(0); /* Disable fog/stencil. *Enable* write mask. */
  792.         OUT_BATCH(S6_COLOR_WRITE_ONLY); /* Disable blending, depth */
  793.  
  794.         OUT_BATCH(_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT);
  795.         OUT_BATCH(_3DSTATE_DEPTH_SUBRECT_DISABLE);
  796.  
  797.         OUT_BATCH(_3DSTATE_LOAD_INDIRECT);
  798.         OUT_BATCH(0x00000000);
  799.  
  800.         OUT_BATCH(_3DSTATE_STIPPLE);
  801.         OUT_BATCH(0x00000000);
  802.  
  803.         sna->render_state.gen3.need_invariant = false;
  804. }
  805.  
  806. #define MAX_OBJECTS 3 /* worst case: dst + src + mask  */
  807.  
  808. static void
  809. gen3_get_batch(struct sna *sna, const struct sna_composite_op *op)
  810. {
  811.         kgem_set_mode(&sna->kgem, KGEM_RENDER, op->dst.bo);
  812.  
  813.         if (!kgem_check_batch(&sna->kgem, 200)) {
  814.                 DBG(("%s: flushing batch: size %d > %d\n",
  815.                      __FUNCTION__, 200,
  816.                      sna->kgem.surface-sna->kgem.nbatch));
  817.                 kgem_submit(&sna->kgem);
  818.                 _kgem_set_mode(&sna->kgem, KGEM_RENDER);
  819.         }
  820.  
  821.         if (!kgem_check_reloc(&sna->kgem, MAX_OBJECTS)) {
  822.                 DBG(("%s: flushing batch: reloc %d >= %d\n",
  823.                      __FUNCTION__,
  824.                      sna->kgem.nreloc,
  825.                      (int)KGEM_RELOC_SIZE(&sna->kgem) - MAX_OBJECTS));
  826.                 kgem_submit(&sna->kgem);
  827.                 _kgem_set_mode(&sna->kgem, KGEM_RENDER);
  828.         }
  829.  
  830.         if (!kgem_check_exec(&sna->kgem, MAX_OBJECTS)) {
  831.                 DBG(("%s: flushing batch: exec %d >= %d\n",
  832.                      __FUNCTION__,
  833.                      sna->kgem.nexec,
  834.                      (int)KGEM_EXEC_SIZE(&sna->kgem) - MAX_OBJECTS - 1));
  835.                 kgem_submit(&sna->kgem);
  836.                 _kgem_set_mode(&sna->kgem, KGEM_RENDER);
  837.         }
  838.  
  839.         if (sna->render_state.gen3.need_invariant)
  840.                 gen3_emit_invariant(sna);
  841. #undef MAX_OBJECTS
  842. }
  843.  
  844. static void gen3_emit_target(struct sna *sna,
  845.                              struct kgem_bo *bo,
  846.                              int width,
  847.                              int height,
  848.                              int format)
  849. {
  850.         struct gen3_render_state *state = &sna->render_state.gen3;
  851.  
  852.         assert(!too_large(width, height));
  853.  
  854.         /* BUF_INFO is an implicit flush, so skip if the target is unchanged. */
  855.         assert(bo->unique_id != 0);
  856.         if (bo->unique_id != state->current_dst) {
  857.                 uint32_t v;
  858.  
  859.                 DBG(("%s: setting new target id=%d, handle=%d\n",
  860.                      __FUNCTION__, bo->unique_id, bo->handle));
  861.  
  862.                 OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
  863.                 OUT_BATCH(BUF_3D_ID_COLOR_BACK |
  864.                           gen3_buf_tiling(bo->tiling) |
  865.                           bo->pitch);
  866.                 OUT_BATCH(kgem_add_reloc(&sna->kgem, sna->kgem.nbatch,
  867.                                          bo,
  868.                                          I915_GEM_DOMAIN_RENDER << 16 |
  869.                                          I915_GEM_DOMAIN_RENDER,
  870.                                          0));
  871.  
  872.                 OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD);
  873.                 OUT_BATCH(gen3_get_dst_format(format));
  874.  
  875.                 v = DRAW_YMAX(height - 1) | DRAW_XMAX(width - 1);
  876.                 if (v != state->last_drawrect_limit) {
  877.                         OUT_BATCH(_3DSTATE_DRAW_RECT_CMD);
  878.                         OUT_BATCH(0); /* XXX dither origin? */
  879.                         OUT_BATCH(0);
  880.                         OUT_BATCH(v);
  881.                         OUT_BATCH(0);
  882.                         state->last_drawrect_limit = v;
  883.                 }
  884.  
  885.                 state->current_dst = bo->unique_id;
  886.         }
  887.         kgem_bo_mark_dirty(bo);
  888. }
  889.  
  890. static void gen3_emit_composite_state(struct sna *sna,
  891.                                       const struct sna_composite_op *op)
  892. {
  893.         struct gen3_render_state *state = &sna->render_state.gen3;
  894.         uint32_t map[4];
  895.         uint32_t sampler[4];
  896.         struct kgem_bo *bo[2];
  897.         unsigned int tex_count, n;
  898.         uint32_t ss2;
  899.  
  900.         gen3_get_batch(sna, op);
  901.  
  902.         if (kgem_bo_is_dirty(op->src.bo) || kgem_bo_is_dirty(op->mask.bo)) {
  903.                 if (op->src.bo == op->dst.bo || op->mask.bo == op->dst.bo)
  904.                         OUT_BATCH(MI_FLUSH | MI_INVALIDATE_MAP_CACHE);
  905.                 else
  906.                         OUT_BATCH(_3DSTATE_MODES_5_CMD |
  907.                                   PIPELINE_FLUSH_RENDER_CACHE |
  908.                                   PIPELINE_FLUSH_TEXTURE_CACHE);
  909.                 kgem_clear_dirty(&sna->kgem);
  910.         }
  911.  
  912.         gen3_emit_target(sna,
  913.                          op->dst.bo,
  914.                          op->dst.width,
  915.                          op->dst.height,
  916.                          op->dst.format);
  917.  
  918.         ss2 = ~0;
  919.         tex_count = 0;
  920.         switch (op->src.u.gen3.type) {
  921.         case SHADER_OPACITY:
  922.         case SHADER_NONE:
  923.                 assert(0);
  924.         case SHADER_ZERO:
  925.         case SHADER_BLACK:
  926.         case SHADER_WHITE:
  927.                 break;
  928.         case SHADER_CONSTANT:
  929.                 if (op->src.u.gen3.mode != state->last_diffuse) {
  930.                         OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD);
  931.                         OUT_BATCH(op->src.u.gen3.mode);
  932.                         state->last_diffuse = op->src.u.gen3.mode;
  933.                 }
  934.                 break;
  935.         case SHADER_LINEAR:
  936.         case SHADER_RADIAL:
  937.         case SHADER_TEXTURE:
  938.                 ss2 &= ~S2_TEXCOORD_FMT(tex_count, TEXCOORDFMT_NOT_PRESENT);
  939.                 ss2 |= S2_TEXCOORD_FMT(tex_count,
  940.                                        op->src.is_affine ? TEXCOORDFMT_2D : TEXCOORDFMT_4D);
  941.                 map[tex_count * 2 + 0] =
  942.                         op->src.card_format |
  943.                         gen3_ms_tiling(op->src.bo->tiling) |
  944.                         (op->src.height - 1) << MS3_HEIGHT_SHIFT |
  945.                         (op->src.width - 1) << MS3_WIDTH_SHIFT;
  946.                 map[tex_count * 2 + 1] =
  947.                         (op->src.bo->pitch / 4 - 1) << MS4_PITCH_SHIFT;
  948.  
  949.                 sampler[tex_count * 2 + 0] = op->src.filter;
  950.                 sampler[tex_count * 2 + 1] =
  951.                         op->src.repeat |
  952.                         tex_count << SS3_TEXTUREMAP_INDEX_SHIFT;
  953.                 bo[tex_count] = op->src.bo;
  954.                 tex_count++;
  955.                 break;
  956.         }
  957.         switch (op->mask.u.gen3.type) {
  958.         case SHADER_NONE:
  959.         case SHADER_ZERO:
  960.         case SHADER_BLACK:
  961.         case SHADER_WHITE:
  962.                 break;
  963.         case SHADER_CONSTANT:
  964.                 if (op->mask.u.gen3.mode != state->last_specular) {
  965.                         OUT_BATCH(_3DSTATE_DFLT_SPEC_CMD);
  966.                         OUT_BATCH(op->mask.u.gen3.mode);
  967.                         state->last_specular = op->mask.u.gen3.mode;
  968.                 }
  969.                 break;
  970.         case SHADER_LINEAR:
  971.         case SHADER_RADIAL:
  972.         case SHADER_TEXTURE:
  973.                 ss2 &= ~S2_TEXCOORD_FMT(tex_count, TEXCOORDFMT_NOT_PRESENT);
  974.                 ss2 |= S2_TEXCOORD_FMT(tex_count,
  975.                                        op->mask.is_affine ? TEXCOORDFMT_2D : TEXCOORDFMT_4D);
  976.                 map[tex_count * 2 + 0] =
  977.                         op->mask.card_format |
  978.                         gen3_ms_tiling(op->mask.bo->tiling) |
  979.                         (op->mask.height - 1) << MS3_HEIGHT_SHIFT |
  980.                         (op->mask.width - 1) << MS3_WIDTH_SHIFT;
  981.                 map[tex_count * 2 + 1] =
  982.                         (op->mask.bo->pitch / 4 - 1) << MS4_PITCH_SHIFT;
  983.  
  984.                 sampler[tex_count * 2 + 0] = op->mask.filter;
  985.                 sampler[tex_count * 2 + 1] =
  986.                         op->mask.repeat |
  987.                         tex_count << SS3_TEXTUREMAP_INDEX_SHIFT;
  988.                 bo[tex_count] = op->mask.bo;
  989.                 tex_count++;
  990.                 break;
  991.         case SHADER_OPACITY:
  992.                 ss2 &= ~S2_TEXCOORD_FMT(tex_count, TEXCOORDFMT_NOT_PRESENT);
  993.                 ss2 |= S2_TEXCOORD_FMT(tex_count, TEXCOORDFMT_1D);
  994.                 break;
  995.         }
  996.  
  997.         {
  998.                 uint32_t blend_offset = sna->kgem.nbatch;
  999.  
  1000.                 OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) | I1_LOAD_S(6) | 1);
  1001.                 OUT_BATCH(ss2);
  1002.                 OUT_BATCH(gen3_get_blend_cntl(op->op,
  1003.                                               op->has_component_alpha,
  1004.                                               op->dst.format));
  1005.  
  1006.                 if (memcmp(sna->kgem.batch + state->last_blend + 1,
  1007.                            sna->kgem.batch + blend_offset + 1,
  1008.                            2 * 4) == 0)
  1009.                         sna->kgem.nbatch = blend_offset;
  1010.                 else
  1011.                         state->last_blend = blend_offset;
  1012.         }
  1013.  
  1014.         if (op->u.gen3.num_constants) {
  1015.                 int count = op->u.gen3.num_constants;
  1016.                 if (state->last_constants) {
  1017.                         int last = sna->kgem.batch[state->last_constants+1];
  1018.                         if (last == (1 << (count >> 2)) - 1 &&
  1019.                             memcmp(&sna->kgem.batch[state->last_constants+2],
  1020.                                    op->u.gen3.constants,
  1021.                                    count * sizeof(uint32_t)) == 0)
  1022.                                 count = 0;
  1023.                 }
  1024.                 if (count) {
  1025.                         state->last_constants = sna->kgem.nbatch;
  1026.                         OUT_BATCH(_3DSTATE_PIXEL_SHADER_CONSTANTS | count);
  1027.                         OUT_BATCH((1 << (count >> 2)) - 1);
  1028.  
  1029.                         memcpy(sna->kgem.batch + sna->kgem.nbatch,
  1030.                                op->u.gen3.constants,
  1031.                                count * sizeof(uint32_t));
  1032.                         sna->kgem.nbatch += count;
  1033.                 }
  1034.         }
  1035.  
  1036.         if (tex_count != 0) {
  1037.                 uint32_t rewind;
  1038.  
  1039.                 n = 0;
  1040.                 if (tex_count == state->tex_count) {
  1041.                         for (; n < tex_count; n++) {
  1042.                                 if (map[2*n+0] != state->tex_map[2*n+0] ||
  1043.                                     map[2*n+1] != state->tex_map[2*n+1] ||
  1044.                                     state->tex_handle[n] != bo[n]->handle ||
  1045.                                     state->tex_delta[n] != bo[n]->delta)
  1046.                                         break;
  1047.                         }
  1048.                 }
  1049.                 if (n < tex_count) {
  1050.                         OUT_BATCH(_3DSTATE_MAP_STATE | (3 * tex_count));
  1051.                         OUT_BATCH((1 << tex_count) - 1);
  1052.                         for (n = 0; n < tex_count; n++) {
  1053.                                 OUT_BATCH(kgem_add_reloc(&sna->kgem,
  1054.                                                          sna->kgem.nbatch,
  1055.                                                          bo[n],
  1056.                                                          I915_GEM_DOMAIN_SAMPLER<< 16,
  1057.                                                          0));
  1058.                                 OUT_BATCH(map[2*n + 0]);
  1059.                                 OUT_BATCH(map[2*n + 1]);
  1060.  
  1061.                                 state->tex_map[2*n+0] = map[2*n+0];
  1062.                                 state->tex_map[2*n+1] = map[2*n+1];
  1063.                                 state->tex_handle[n] = bo[n]->handle;
  1064.                                 state->tex_delta[n] = bo[n]->delta;
  1065.                         }
  1066.                         state->tex_count = n;
  1067.                 }
  1068.  
  1069.                 rewind = sna->kgem.nbatch;
  1070.                 OUT_BATCH(_3DSTATE_SAMPLER_STATE | (3 * tex_count));
  1071.                 OUT_BATCH((1 << tex_count) - 1);
  1072.                 for (n = 0; n < tex_count; n++) {
  1073.                         OUT_BATCH(sampler[2*n + 0]);
  1074.                         OUT_BATCH(sampler[2*n + 1]);
  1075.                         OUT_BATCH(0);
  1076.                 }
  1077.                 if (state->last_sampler &&
  1078.                     memcmp(&sna->kgem.batch[state->last_sampler+1],
  1079.                            &sna->kgem.batch[rewind + 1],
  1080.                            (3*tex_count + 1)*sizeof(uint32_t)) == 0)
  1081.                         sna->kgem.nbatch = rewind;
  1082.                 else
  1083.                         state->last_sampler = rewind;
  1084.         }
  1085.  
  1086.         gen3_composite_emit_shader(sna, op, op->op);
  1087. }
  1088.  
  1089. static bool gen3_magic_ca_pass(struct sna *sna,
  1090.                                const struct sna_composite_op *op)
  1091. {
  1092.         if (!op->need_magic_ca_pass)
  1093.                 return false;
  1094.  
  1095.         DBG(("%s(%d)\n", __FUNCTION__,
  1096.              sna->render.vertex_index - sna->render.vertex_start));
  1097.  
  1098.         OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(6) | 0);
  1099.         OUT_BATCH(gen3_get_blend_cntl(PictOpAdd, true, op->dst.format));
  1100.         gen3_composite_emit_shader(sna, op, PictOpAdd);
  1101.  
  1102.         OUT_BATCH(PRIM3D_RECTLIST | PRIM3D_INDIRECT_SEQUENTIAL |
  1103.                   (sna->render.vertex_index - sna->render.vertex_start));
  1104.         OUT_BATCH(sna->render.vertex_start);
  1105.  
  1106.         sna->render_state.gen3.last_blend = 0;
  1107.         return true;
  1108. }
  1109.  
  1110. static void gen3_vertex_flush(struct sna *sna)
  1111. {
  1112.         assert(sna->render.vertex_offset);
  1113.  
  1114.         DBG(("%s[%x] = %d\n", __FUNCTION__,
  1115.              4*sna->render.vertex_offset,
  1116.              sna->render.vertex_index - sna->render.vertex_start));
  1117.  
  1118.         sna->kgem.batch[sna->render.vertex_offset] =
  1119.                 PRIM3D_RECTLIST | PRIM3D_INDIRECT_SEQUENTIAL |
  1120.                 (sna->render.vertex_index - sna->render.vertex_start);
  1121.         sna->kgem.batch[sna->render.vertex_offset + 1] =
  1122.                 sna->render.vertex_start;
  1123.  
  1124.         sna->render.vertex_offset = 0;
  1125. }
  1126.  
  1127. static int gen3_vertex_finish(struct sna *sna)
  1128. {
  1129.         struct kgem_bo *bo;
  1130.  
  1131.         DBG(("%s: used=%d/%d, vbo active? %d\n",
  1132.              __FUNCTION__, sna->render.vertex_used, sna->render.vertex_size,
  1133.              sna->render.vbo ? sna->render.vbo->handle : 0));
  1134.         assert(sna->render.vertex_offset == 0);
  1135.         assert(sna->render.vertex_used);
  1136.         assert(sna->render.vertex_used <= sna->render.vertex_size);
  1137.  
  1138.         sna_vertex_wait__locked(&sna->render);
  1139.  
  1140.         bo = sna->render.vbo;
  1141.         if (bo) {
  1142.                 DBG(("%s: reloc = %d\n", __FUNCTION__,
  1143.                      sna->render.vertex_reloc[0]));
  1144.  
  1145.                 if (sna->render.vertex_reloc[0]) {
  1146.                         sna->kgem.batch[sna->render.vertex_reloc[0]] =
  1147.                                 kgem_add_reloc(&sna->kgem, sna->render.vertex_reloc[0],
  1148.                                                bo, I915_GEM_DOMAIN_VERTEX << 16, 0);
  1149.  
  1150.                         sna->render.vertex_reloc[0] = 0;
  1151.                 }
  1152.                 sna->render.vertex_used = 0;
  1153.                 sna->render.vertex_index = 0;
  1154.                 sna->render.vbo = NULL;
  1155.  
  1156.                 kgem_bo_destroy(&sna->kgem, bo);
  1157.         }
  1158.  
  1159.         sna->render.vertices = NULL;
  1160.         sna->render.vbo = kgem_create_linear(&sna->kgem,
  1161.                                              256*1024, CREATE_GTT_MAP);
  1162.         if (sna->render.vbo)
  1163.                 sna->render.vertices = kgem_bo_map(&sna->kgem, sna->render.vbo);
  1164.         if (sna->render.vertices == NULL) {
  1165.                 if (sna->render.vbo)
  1166.                         kgem_bo_destroy(&sna->kgem, sna->render.vbo);
  1167.                 sna->render.vbo = NULL;
  1168.                 return 0;
  1169.         }
  1170.         assert(sna->render.vbo->snoop == false);
  1171.  
  1172.         if (sna->render.vertex_used) {
  1173.                 memcpy(sna->render.vertices,
  1174.                        sna->render.vertex_data,
  1175.                        sizeof(float)*sna->render.vertex_used);
  1176.         }
  1177.         sna->render.vertex_size = 64 * 1024 - 1;
  1178.         return sna->render.vertex_size - sna->render.vertex_used;
  1179. }
  1180.  
  1181. static void gen3_vertex_close(struct sna *sna)
  1182. {
  1183.         struct kgem_bo *bo, *free_bo = NULL;
  1184.         unsigned int delta = 0;
  1185.  
  1186.         assert(sna->render.vertex_offset == 0);
  1187.         if (sna->render.vertex_reloc[0] == 0)
  1188.                 return;
  1189.  
  1190.         DBG(("%s: used=%d/%d, vbo active? %d\n",
  1191.              __FUNCTION__, sna->render.vertex_used, sna->render.vertex_size,
  1192.              sna->render.vbo ? sna->render.vbo->handle : 0));
  1193.  
  1194.         bo = sna->render.vbo;
  1195.         if (bo) {
  1196.                 if (sna->render.vertex_size - sna->render.vertex_used < 64) {
  1197.                         DBG(("%s: discarding full vbo\n", __FUNCTION__));
  1198.                         sna->render.vbo = NULL;
  1199.                         sna->render.vertices = sna->render.vertex_data;
  1200.                         sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data);
  1201.                         free_bo = bo;
  1202.                 } else if (IS_CPU_MAP(bo->map)) {
  1203.                         DBG(("%s: converting CPU map to GTT\n", __FUNCTION__));
  1204.                         sna->render.vertices = kgem_bo_map__gtt(&sna->kgem, bo);
  1205.                         if (sna->render.vertices == NULL) {
  1206.                                 DBG(("%s: discarding non-mappable vertices\n",__FUNCTION__));
  1207.                                 sna->render.vbo = NULL;
  1208.                                 sna->render.vertices = sna->render.vertex_data;
  1209.                                 sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data);
  1210.                                 free_bo = bo;
  1211.                         }
  1212.                 }
  1213.         } else {
  1214.                 if (sna->kgem.nbatch + sna->render.vertex_used <= sna->kgem.surface) {
  1215.                         DBG(("%s: copy to batch: %d @ %d\n", __FUNCTION__,
  1216.                              sna->render.vertex_used, sna->kgem.nbatch));
  1217.                         memcpy(sna->kgem.batch + sna->kgem.nbatch,
  1218.                                sna->render.vertex_data,
  1219.                                sna->render.vertex_used * 4);
  1220.                         delta = sna->kgem.nbatch * 4;
  1221.                         bo = NULL;
  1222.                         sna->kgem.nbatch += sna->render.vertex_used;
  1223.                 } else {
  1224.                         DBG(("%s: new vbo: %d\n", __FUNCTION__,
  1225.                              sna->render.vertex_used));
  1226.                         bo = kgem_create_linear(&sna->kgem,
  1227.                                                 4*sna->render.vertex_used,
  1228.                                                 CREATE_NO_THROTTLE);
  1229.                         if (bo) {
  1230.                                 assert(bo->snoop == false);
  1231.                                 kgem_bo_write(&sna->kgem, bo,
  1232.                                               sna->render.vertex_data,
  1233.                                               4*sna->render.vertex_used);
  1234.                         }
  1235.                         free_bo = bo;
  1236.                 }
  1237.         }
  1238.  
  1239.         DBG(("%s: reloc = %d\n", __FUNCTION__, sna->render.vertex_reloc[0]));
  1240.         sna->kgem.batch[sna->render.vertex_reloc[0]] =
  1241.                 kgem_add_reloc(&sna->kgem, sna->render.vertex_reloc[0],
  1242.                                bo, I915_GEM_DOMAIN_VERTEX << 16, delta);
  1243.         sna->render.vertex_reloc[0] = 0;
  1244.  
  1245.         if (sna->render.vbo == NULL) {
  1246.                 DBG(("%s: resetting vbo\n", __FUNCTION__));
  1247.                 sna->render.vertex_used = 0;
  1248.                 sna->render.vertex_index = 0;
  1249.                 assert(sna->render.vertices == sna->render.vertex_data);
  1250.                 assert(sna->render.vertex_size == ARRAY_SIZE(sna->render.vertex_data));
  1251.         }
  1252.  
  1253.         if (free_bo)
  1254.                 kgem_bo_destroy(&sna->kgem, free_bo);
  1255. }
  1256.  
  1257. static bool gen3_rectangle_begin(struct sna *sna,
  1258.                                  const struct sna_composite_op *op)
  1259. {
  1260.         struct gen3_render_state *state = &sna->render_state.gen3;
  1261.         int ndwords, i1_cmd = 0, i1_len = 0;
  1262.  
  1263.         if (sna_vertex_wait__locked(&sna->render) && sna->render.vertex_offset)
  1264.                 return true;
  1265.  
  1266.         ndwords = 2;
  1267.         if (op->need_magic_ca_pass)
  1268.                 ndwords += 100;
  1269.         if (sna->render.vertex_reloc[0] == 0)
  1270.                 i1_len++, i1_cmd |= I1_LOAD_S(0), ndwords++;
  1271.         if (state->floats_per_vertex != op->floats_per_vertex)
  1272.                 i1_len++, i1_cmd |= I1_LOAD_S(1), ndwords++;
  1273.  
  1274.         if (!kgem_check_batch(&sna->kgem, ndwords+1))
  1275.                 return false;
  1276.  
  1277.         if (i1_cmd) {
  1278.                 OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | i1_cmd | (i1_len - 1));
  1279.                 if (sna->render.vertex_reloc[0] == 0)
  1280.                         sna->render.vertex_reloc[0] = sna->kgem.nbatch++;
  1281.                 if (state->floats_per_vertex != op->floats_per_vertex) {
  1282.                         state->floats_per_vertex = op->floats_per_vertex;
  1283.                         OUT_BATCH(state->floats_per_vertex << S1_VERTEX_WIDTH_SHIFT |
  1284.                                   state->floats_per_vertex << S1_VERTEX_PITCH_SHIFT);
  1285.                 }
  1286.         }
  1287.  
  1288.         if (sna->kgem.nbatch == 2 + state->last_vertex_offset &&
  1289.             !op->need_magic_ca_pass) {
  1290.                 sna->render.vertex_offset = state->last_vertex_offset;
  1291.         } else {
  1292.                 sna->render.vertex_offset = sna->kgem.nbatch;
  1293.                 OUT_BATCH(MI_NOOP); /* to be filled later */
  1294.                 OUT_BATCH(MI_NOOP);
  1295.                 sna->render.vertex_start = sna->render.vertex_index;
  1296.                 state->last_vertex_offset = sna->render.vertex_offset;
  1297.         }
  1298.  
  1299.         return true;
  1300. }
  1301.  
  1302. static int gen3_get_rectangles__flush(struct sna *sna,
  1303.                                       const struct sna_composite_op *op)
  1304. {
  1305.         /* Preventing discarding new vbo after lock contention */
  1306.         if (sna_vertex_wait__locked(&sna->render)) {
  1307.                 int rem = vertex_space(sna);
  1308.                 if (rem > op->floats_per_rect)
  1309.                         return rem;
  1310.         }
  1311.  
  1312.         if (!kgem_check_batch(&sna->kgem, op->need_magic_ca_pass ? 105: 5))
  1313.                 return 0;
  1314.         if (!kgem_check_reloc_and_exec(&sna->kgem, 1))
  1315.                 return 0;
  1316.  
  1317.         if (sna->render.vertex_offset) {
  1318.                 gen3_vertex_flush(sna);
  1319.                 if (gen3_magic_ca_pass(sna, op)) {
  1320.                         OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(6) | 0);
  1321.                         OUT_BATCH(gen3_get_blend_cntl(op->op,
  1322.                                                       op->has_component_alpha,
  1323.                                                       op->dst.format));
  1324.                         gen3_composite_emit_shader(sna, op, op->op);
  1325.                 }
  1326.         }
  1327.  
  1328.         return gen3_vertex_finish(sna);
  1329. }
  1330.  
  1331. inline static int gen3_get_rectangles(struct sna *sna,
  1332.                                       const struct sna_composite_op *op,
  1333.                                       int want)
  1334. {
  1335.         int rem;
  1336.  
  1337.         DBG(("%s: want=%d, rem=%d\n",
  1338.              __FUNCTION__, want*op->floats_per_rect, vertex_space(sna)));
  1339.  
  1340.         assert(want);
  1341.         assert(sna->render.vertex_index * op->floats_per_vertex == sna->render.vertex_used);
  1342.  
  1343. start:
  1344.         rem = vertex_space(sna);
  1345.         if (unlikely(op->floats_per_rect > rem)) {
  1346.                 DBG(("flushing vbo for %s: %d < %d\n",
  1347.                      __FUNCTION__, rem, op->floats_per_rect));
  1348.                 rem = gen3_get_rectangles__flush(sna, op);
  1349.                 if (unlikely(rem == 0))
  1350.                         goto flush;
  1351.         }
  1352.  
  1353.         if (unlikely(sna->render.vertex_offset == 0)) {
  1354.                 if (!gen3_rectangle_begin(sna, op))
  1355.                         goto flush;
  1356.                 else
  1357.                         goto start;
  1358.         }
  1359.  
  1360.         assert(op->floats_per_rect >= vertex_space(sna));
  1361.         assert(rem <= vertex_space(sna));
  1362.         if (want > 1 && want * op->floats_per_rect > rem)
  1363.                 want = rem / op->floats_per_rect;
  1364.         sna->render.vertex_index += 3*want;
  1365.  
  1366.         assert(want);
  1367.         assert(sna->render.vertex_index * op->floats_per_vertex <= sna->render.vertex_size);
  1368.         return want;
  1369.  
  1370. flush:
  1371.         DBG(("%s: flushing batch\n", __FUNCTION__));
  1372.         if (sna->render.vertex_offset) {
  1373.                 gen3_vertex_flush(sna);
  1374.                 gen3_magic_ca_pass(sna, op);
  1375.         }
  1376.         sna_vertex_wait__locked(&sna->render);
  1377.         _kgem_submit(&sna->kgem);
  1378.         gen3_emit_composite_state(sna, op);
  1379.         assert(sna->render.vertex_offset == 0);
  1380.         assert(sna->render.vertex_reloc[0] == 0);
  1381.         goto start;
  1382. }
  1383.  
  1384. fastcall static void
  1385. gen3_render_composite_blt(struct sna *sna,
  1386.                           const struct sna_composite_op *op,
  1387.                           const struct sna_composite_rectangles *r)
  1388. {
  1389.         DBG(("%s: src=(%d, %d)+(%d, %d), mask=(%d, %d)+(%d, %d), dst=(%d, %d)+(%d, %d), size=(%d, %d)\n", __FUNCTION__,
  1390.              r->src.x, r->src.y, op->src.offset[0], op->src.offset[1],
  1391.              r->mask.x, r->mask.y, op->mask.offset[0], op->mask.offset[1],
  1392.              r->dst.x, r->dst.y, op->dst.x, op->dst.y,
  1393.              r->width, r->height));
  1394.  
  1395.         gen3_get_rectangles(sna, op, 1);
  1396.  
  1397.         op->prim_emit(sna, op, r);
  1398. }
  1399.  
  1400. static void
  1401. gen3_render_composite_done(struct sna *sna,
  1402.                            const struct sna_composite_op *op)
  1403. {
  1404.         DBG(("%s()\n", __FUNCTION__));
  1405.  
  1406.         if (sna->render.vertex_offset) {
  1407.                 gen3_vertex_flush(sna);
  1408.                 gen3_magic_ca_pass(sna, op);
  1409.         }
  1410.  
  1411. }
  1412.  
  1413. static void
  1414. discard_vbo(struct sna *sna)
  1415. {
  1416.         kgem_bo_destroy(&sna->kgem, sna->render.vbo);
  1417.         sna->render.vbo = NULL;
  1418.         sna->render.vertices = sna->render.vertex_data;
  1419.         sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data);
  1420.         sna->render.vertex_used = 0;
  1421.         sna->render.vertex_index = 0;
  1422. }
  1423.  
  1424. static void
  1425. gen3_render_reset(struct sna *sna)
  1426. {
  1427.         struct gen3_render_state *state = &sna->render_state.gen3;
  1428.  
  1429.         state->need_invariant = true;
  1430.         state->current_dst = 0;
  1431.         state->tex_count = 0;
  1432.         state->last_drawrect_limit = ~0U;
  1433.         state->last_target = 0;
  1434.         state->last_blend = 0;
  1435.         state->last_constants = 0;
  1436.         state->last_sampler = 0;
  1437.         state->last_shader = 0x7fffffff;
  1438.         state->last_diffuse = 0xcc00ffee;
  1439.         state->last_specular = 0xcc00ffee;
  1440.  
  1441.         state->floats_per_vertex = 0;
  1442.         state->last_floats_per_vertex = 0;
  1443.         state->last_vertex_offset = 0;
  1444.  
  1445.         if (sna->render.vbo != NULL &&
  1446.             !kgem_bo_is_mappable(&sna->kgem, sna->render.vbo)) {
  1447.                 DBG(("%s: discarding vbo as next access will stall: %d\n",
  1448.                      __FUNCTION__, sna->render.vbo->presumed_offset));
  1449.                 discard_vbo(sna);
  1450.         }
  1451.  
  1452.         sna->render.vertex_reloc[0] = 0;
  1453.         sna->render.vertex_offset = 0;
  1454. }
  1455.  
  1456. static void
  1457. gen3_render_retire(struct kgem *kgem)
  1458. {
  1459.         struct sna *sna;
  1460.  
  1461.         sna = container_of(kgem, struct sna, kgem);
  1462.         if (sna->render.vertex_reloc[0] == 0 &&
  1463.             sna->render.vbo && !kgem_bo_is_busy(sna->render.vbo)) {
  1464.                 DBG(("%s: resetting idle vbo\n", __FUNCTION__));
  1465.                 sna->render.vertex_used = 0;
  1466.                 sna->render.vertex_index = 0;
  1467.         }
  1468. }
  1469.  
  1470. static void
  1471. gen3_render_expire(struct kgem *kgem)
  1472. {
  1473.         struct sna *sna;
  1474.  
  1475.         sna = container_of(kgem, struct sna, kgem);
  1476.         if (sna->render.vbo && !sna->render.vertex_used) {
  1477.                 DBG(("%s: discarding vbo\n", __FUNCTION__));
  1478.                 discard_vbo(sna);
  1479.         }
  1480. }
  1481.  
  1482. static bool gen3_composite_channel_set_format(struct sna_composite_channel *channel,
  1483.                                               CARD32 format)
  1484. {
  1485.         unsigned int i;
  1486.  
  1487.         for (i = 0; i < ARRAY_SIZE(gen3_tex_formats); i++) {
  1488.                 if (gen3_tex_formats[i].fmt == format) {
  1489.                         channel->card_format = gen3_tex_formats[i].card_fmt;
  1490.                         channel->rb_reversed = gen3_tex_formats[i].rb_reversed;
  1491.                         return true;
  1492.                 }
  1493.         }
  1494.         return false;
  1495. }
  1496.  
  1497.  
  1498.  
  1499.  
  1500.  
  1501.  
  1502.  
  1503.  
  1504.  
  1505.  
  1506.  
  1507.  
  1508.  
  1509.  
  1510.  
  1511.  
  1512.  
  1513.  
  1514.  
  1515.  
  1516.  
  1517.  
  1518.  
  1519.  
  1520.  
  1521.  
  1522.  
  1523.  
  1524.  
  1525.  
  1526.  
  1527.  
  1528.  
  1529.  
  1530.  
  1531.  
  1532.  
  1533.  
  1534.  
  1535.  
  1536.  
  1537.  
  1538.  
  1539.  
  1540.  
  1541.  
  1542.  
  1543.  
  1544.  
  1545.  
  1546.  
  1547.  
  1548.  
  1549.  
  1550.  
  1551.  
  1552.  
  1553.  
  1554.  
  1555. static void
  1556. gen3_align_vertex(struct sna *sna,
  1557.                   const struct sna_composite_op *op)
  1558. {
  1559.         if (op->floats_per_vertex != sna->render_state.gen3.last_floats_per_vertex) {
  1560.                 if (sna->render.vertex_size - sna->render.vertex_used < 2*op->floats_per_rect)
  1561.                         gen3_vertex_finish(sna);
  1562.  
  1563.                 DBG(("aligning vertex: was %d, now %d floats per vertex, %d->%d\n",
  1564.                      sna->render_state.gen3.last_floats_per_vertex,
  1565.                      op->floats_per_vertex,
  1566.                      sna->render.vertex_index,
  1567.                      (sna->render.vertex_used + op->floats_per_vertex - 1) / op->floats_per_vertex));
  1568.                 sna->render.vertex_index = (sna->render.vertex_used + op->floats_per_vertex - 1) / op->floats_per_vertex;
  1569.                 sna->render.vertex_used = sna->render.vertex_index * op->floats_per_vertex;
  1570.                 assert(sna->render.vertex_used < sna->render.vertex_size - op->floats_per_rect);
  1571.                 sna->render_state.gen3.last_floats_per_vertex = op->floats_per_vertex;
  1572.         }
  1573. }
  1574.  
  1575.  
  1576.  
  1577.  
  1578.  
  1579.  
  1580.  
  1581.  
  1582.  
  1583.  
  1584.  
  1585.  
  1586.  
  1587.  
  1588.  
  1589.  
  1590.  
  1591.  
  1592.  
  1593.  
  1594.  
  1595.  
  1596.  
  1597.  
  1598.  
  1599.  
  1600.  
  1601.  
  1602.  
  1603.  
  1604.  
  1605.  
  1606.  
  1607.  
  1608.  
  1609.  
  1610.  
  1611.  
  1612.  
  1613.  
  1614.  
  1615.  
  1616.  
  1617.  
  1618.  
  1619.  
  1620.  
  1621.  
  1622.  
  1623.  
  1624.  
  1625.  
  1626.  
  1627.  
  1628.  
  1629.  
  1630.  
  1631.  
  1632.  
  1633.  
  1634.  
  1635.  
  1636.  
  1637.  
  1638.  
  1639.  
  1640.  
  1641.  
  1642.  
  1643.  
  1644.  
  1645.  
  1646.  
  1647.  
  1648.  
  1649.  
  1650.  
  1651.  
  1652.  
  1653.  
  1654.  
  1655.  
  1656.  
  1657.  
  1658.  
  1659.  
  1660.  
  1661.  
  1662.  
  1663.  
  1664.  
  1665.  
  1666.  
  1667.  
  1668.  
  1669.  
  1670.  
  1671.  
  1672.  
  1673.  
  1674.  
  1675.  
  1676.  
  1677.  
  1678.  
  1679.  
  1680.  
  1681.  
  1682.  
  1683.  
  1684.  
  1685.  
  1686.  
  1687.  
  1688.  
  1689.  
  1690.  
  1691.  
  1692.  
  1693.  
  1694.  
  1695.  
  1696.  
  1697.  
  1698.  
  1699.  
  1700.  
  1701.  
  1702.  
  1703.  
  1704.  
  1705.  
  1706.  
  1707.  
  1708.  
  1709.  
  1710.  
  1711.  
  1712.  
  1713. static inline bool is_constant_ps(uint32_t type)
  1714. {
  1715.         switch (type) {
  1716.         case SHADER_NONE: /* be warned! */
  1717.         case SHADER_ZERO:
  1718.         case SHADER_BLACK:
  1719.         case SHADER_WHITE:
  1720.         case SHADER_CONSTANT:
  1721.                 return true;
  1722.         default:
  1723.                 return false;
  1724.         }
  1725. }
  1726.  
  1727.  
  1728.  
  1729.  
  1730.  
  1731.  
  1732.  
  1733.  
  1734.  
  1735.  
  1736.  
  1737.  
  1738.  
  1739.  
  1740.  
  1741.  
  1742.  
  1743.  
  1744.  
  1745.  
  1746.  
  1747.  
  1748.  
  1749.  
  1750.  
  1751.  
  1752.  
  1753.  
  1754.  
  1755.  
  1756.  
  1757.  
  1758.  
  1759.  
  1760.  
  1761.  
  1762.  
  1763.  
  1764.  
  1765.  
  1766.  
  1767.  
  1768.  
  1769.  
  1770.  
  1771.  
  1772.  
  1773.  
  1774.  
  1775.  
  1776.  
  1777.  
  1778.  
  1779.  
  1780.  
  1781.  
  1782.  
  1783.  
  1784.  
  1785.  
  1786.  
  1787.  
  1788.  
  1789.  
  1790.  
  1791.  
  1792.  
  1793.  
  1794.  
  1795.  
  1796.  
  1797.  
  1798.  
  1799.  
  1800.  
  1801.  
  1802.  
  1803.  
  1804.  
  1805.  
  1806.  
  1807.  
  1808.  
  1809.  
  1810.  
  1811.  
  1812.  
  1813.  
  1814.  
  1815.  
  1816.  
  1817.  
  1818.  
  1819.  
  1820.  
  1821.  
  1822.  
  1823.  
  1824.  
  1825.  
  1826.  
  1827.  
  1828.  
  1829.  
  1830.  
  1831.  
  1832.  
  1833.  
  1834.  
  1835. static bool
  1836. gen3_blit_tex(struct sna *sna,
  1837.               uint8_t op, bool scale,
  1838.                       PixmapPtr src, struct kgem_bo *src_bo,
  1839.                       PixmapPtr mask,struct kgem_bo *mask_bo,
  1840.                       PixmapPtr dst, struct kgem_bo *dst_bo,
  1841.               int32_t src_x, int32_t src_y,
  1842.               int32_t msk_x, int32_t msk_y,
  1843.               int32_t dst_x, int32_t dst_y,
  1844.               int32_t width, int32_t height,
  1845.               struct sna_composite_op *tmp)
  1846. {
  1847.  
  1848.     DBG(("%s: %dx%d, current mode=%d\n", __FUNCTION__,
  1849.          width, height, sna->kgem.ring));
  1850.  
  1851.     tmp->op = PictOpSrc;
  1852.  
  1853.     tmp->dst.pixmap = dst;
  1854.     tmp->dst.bo     = dst_bo;
  1855.     tmp->dst.width  = dst->drawable.width;
  1856.     tmp->dst.height = dst->drawable.height;
  1857.     tmp->dst.format = PICT_x8r8g8b8;
  1858.  
  1859.         tmp->rb_reversed = gen3_dst_rb_reversed(tmp->dst.format);
  1860.  
  1861.         tmp->u.gen3.num_constants = 0;
  1862.         tmp->src.u.gen3.type = SHADER_TEXTURE;
  1863.         tmp->src.is_affine = true;
  1864.  
  1865.  
  1866.         tmp->src.repeat = RepeatNone;
  1867.         tmp->src.filter = PictFilterNearest;
  1868.  
  1869.     tmp->src.bo = src_bo;
  1870.         tmp->src.pict_format = PICT_x8r8g8b8;
  1871.  
  1872.         gen3_composite_channel_set_format(&tmp->src, tmp->src.pict_format);
  1873.  
  1874.     tmp->src.width  = src->drawable.width;
  1875.     tmp->src.height = src->drawable.height;
  1876.  
  1877.         tmp->mask.u.gen3.type = SHADER_TEXTURE;
  1878.         tmp->mask.is_affine = true;
  1879.         tmp->need_magic_ca_pass = false;
  1880.         tmp->has_component_alpha = false;
  1881.  
  1882.  
  1883.         tmp->mask.repeat = RepeatNone;
  1884.         tmp->mask.filter = PictFilterNearest;
  1885.     tmp->mask.is_affine = true;
  1886.  
  1887.     tmp->mask.bo = mask_bo;
  1888.     tmp->mask.pict_format = PIXMAN_a8;
  1889.         gen3_composite_channel_set_format(&tmp->mask, tmp->mask.pict_format);
  1890.     tmp->mask.width  = mask->drawable.width;
  1891.     tmp->mask.height = mask->drawable.height;
  1892.  
  1893.     if( scale )
  1894.     {
  1895.         tmp->src.scale[0] = 1.f/width;
  1896.         tmp->src.scale[1] = 1.f/height;
  1897.     }
  1898.     else
  1899.     {
  1900.         tmp->src.scale[0] = 1.f/src->drawable.width;
  1901.         tmp->src.scale[1] = 1.f/src->drawable.height;
  1902.     }
  1903.  
  1904.     tmp->mask.scale[0] = 1.f/mask->drawable.width;
  1905.     tmp->mask.scale[1] = 1.f/mask->drawable.height;
  1906.  
  1907.         tmp->prim_emit = gen3_emit_composite_primitive_identity_source_mask;
  1908.  
  1909.  
  1910.         tmp->floats_per_vertex = 2;
  1911.         if (!is_constant_ps(tmp->src.u.gen3.type))
  1912.                 tmp->floats_per_vertex += tmp->src.is_affine ? 2 : 4;
  1913.         if (!is_constant_ps(tmp->mask.u.gen3.type))
  1914.                 tmp->floats_per_vertex += tmp->mask.is_affine ? 2 : 4;
  1915. //      DBG(("%s: floats_per_vertex = 2 + %d + %d = %d [specialised emitter? %d]\n", __FUNCTION__,
  1916. //           !is_constant_ps(tmp->src.u.gen3.type) ? tmp->src.is_affine ? 2 : 4 : 0,
  1917. //           !is_constant_ps(tmp->mask.u.gen3.type) ? tmp->mask.is_affine ? 2 : 4 : 0,
  1918. //           tmp->floats_per_vertex,
  1919. //           tmp->prim_emit != gen3_emit_composite_primitive));
  1920.         tmp->floats_per_rect = 3 * tmp->floats_per_vertex;
  1921.  
  1922.         tmp->blt   = gen3_render_composite_blt;
  1923.  
  1924.         tmp->done  = gen3_render_composite_done;
  1925.  
  1926.         if (!kgem_check_bo(&sna->kgem,
  1927.                            tmp->dst.bo, tmp->src.bo, tmp->mask.bo,
  1928.                            NULL)) {
  1929.                 kgem_submit(&sna->kgem);
  1930.         }
  1931.  
  1932.         gen3_emit_composite_state(sna, tmp);
  1933.         gen3_align_vertex(sna, tmp);
  1934.         return true;
  1935. }
  1936.  
  1937. static void gen3_render_flush(struct sna *sna)
  1938. {
  1939.         gen3_vertex_close(sna);
  1940.  
  1941.         assert(sna->render.vertex_reloc[0] == 0);
  1942.         assert(sna->render.vertex_offset == 0);
  1943. }
  1944.  
  1945. static void
  1946. gen3_render_fini(struct sna *sna)
  1947. {
  1948. }
  1949.  
  1950. bool gen3_render_init(struct sna *sna)
  1951. {
  1952.         struct sna_render *render = &sna->render;
  1953.  
  1954.  
  1955. //      render->video = gen3_render_video;
  1956.  
  1957.     render->blit_tex = gen3_blit_tex;
  1958.  
  1959.         render->reset = gen3_render_reset;
  1960.         render->flush = gen3_render_flush;
  1961.         render->fini = gen3_render_fini;
  1962.  
  1963.         render->max_3d_size = MAX_3D_SIZE;
  1964.         render->max_3d_pitch = MAX_3D_PITCH;
  1965.  
  1966.     render->caps = HW_BIT_BLIT | HW_TEX_BLIT;
  1967.  
  1968.         sna->kgem.retire = gen3_render_retire;
  1969.         sna->kgem.expire = gen3_render_expire;
  1970.         return true;
  1971. }
  1972.