Subversion Repositories Kolibri OS

Rev

Rev 2360 | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright © 2006,2008,2011 Intel Corporation
  3.  * Copyright © 2007 Red Hat, Inc.
  4.  *
  5.  * Permission is hereby granted, free of charge, to any person obtaining a
  6.  * copy of this software and associated documentation files (the "Software"),
  7.  * to deal in the Software without restriction, including without limitation
  8.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9.  * and/or sell copies of the Software, and to permit persons to whom the
  10.  * Software is furnished to do so, subject to the following conditions:
  11.  *
  12.  * The above copyright notice and this permission notice (including the next
  13.  * paragraph) shall be included in all copies or substantial portions of the
  14.  * Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  19.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21.  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  22.  * SOFTWARE.
  23.  *
  24.  * Authors:
  25.  *    Wang Zhenyu <zhenyu.z.wang@sna.com>
  26.  *    Eric Anholt <eric@anholt.net>
  27.  *    Carl Worth <cworth@redhat.com>
  28.  *    Keith Packard <keithp@keithp.com>
  29.  *    Chris Wilson <chris@chris-wilson.co.uk>
  30.  *
  31.  */
  32.  
  33. #include <drmP.h>
  34. #include <drm.h>
  35. #include "i915_drm.h"
  36. #include "i915_drv.h"
  37. #include "intel_drv.h"
  38.  
  39. #include <linux/kernel.h>
  40. #include <linux/module.h>
  41. #include <errno-base.h>
  42. #include <memory.h>
  43.  
  44. #include <syscall.h>
  45.  
  46. #include "../bitmap.h"
  47.  
  48. #include "sna.h"
  49. //#include "sna_reg.h"
  50. #include "sna_render.h"
  51. //#include "sna_render_inline.h"
  52. //#include "sna_video.h"
  53.  
  54. #include "gen6_render.h"
  55.  
  56.  
  57. #define NO_COMPOSITE 0
  58. #define NO_COMPOSITE_SPANS 0
  59. #define NO_COPY 0
  60. #define NO_COPY_BOXES 0
  61. #define NO_FILL 0
  62. #define NO_FILL_BOXES 0
  63. #define NO_CLEAR 0
  64.  
  65. #define NO_RING_SWITCH 1
  66.  
  67. #define GEN6_MAX_SIZE 8192
  68.  
  69. static const uint32_t ps_kernel_nomask_affine[][4] = {
  70. #include "exa_wm_src_affine.g6b"
  71. #include "exa_wm_src_sample_argb.g6b"
  72. #include "exa_wm_write.g6b"
  73. };
  74.  
  75. static const uint32_t ps_kernel_masknoca_affine[][4] = {
  76. #include "exa_wm_src_affine.g6b"
  77. #include "exa_wm_src_sample_argb.g6b"
  78. #include "exa_wm_mask_affine.g6b"
  79. #include "exa_wm_mask_sample_a.g6b"
  80. #include "exa_wm_noca.g6b"
  81. #include "exa_wm_write.g6b"
  82. };
  83.  
  84.  
  85. #define KERNEL(kernel_enum, kernel, masked) \
  86.     [GEN6_WM_KERNEL_##kernel_enum] = {#kernel_enum, kernel, sizeof(kernel), masked}
  87. static const struct wm_kernel_info {
  88.         const char *name;
  89.         const void *data;
  90.         unsigned int size;
  91.         Bool has_mask;
  92. } wm_kernels[] = {
  93. //   KERNEL(NOMASK, ps_kernel_nomask_affine, FALSE),
  94. //    KERNEL(MASK, ps_kernel_masknoca_affine, TRUE),
  95.     KERNEL(NOMASK, ps_kernel_masknoca_affine, TRUE),
  96.     KERNEL(MASK, ps_kernel_masknoca_affine, TRUE),
  97. };
  98. #undef KERNEL
  99.  
  100. static const struct blendinfo {
  101.         Bool src_alpha;
  102.         uint32_t src_blend;
  103.         uint32_t dst_blend;
  104. } gen6_blend_op[] = {
  105.         /* Clear */     {0, GEN6_BLENDFACTOR_ZERO, GEN6_BLENDFACTOR_ZERO},
  106.         /* Src */       {0, GEN6_BLENDFACTOR_ONE, GEN6_BLENDFACTOR_ZERO},
  107.         /* Dst */       {0, GEN6_BLENDFACTOR_ZERO, GEN6_BLENDFACTOR_ONE},
  108.         /* Over */      {1, GEN6_BLENDFACTOR_ONE, GEN6_BLENDFACTOR_INV_SRC_ALPHA},
  109.         /* OverReverse */ {0, GEN6_BLENDFACTOR_INV_DST_ALPHA, GEN6_BLENDFACTOR_ONE},
  110.         /* In */        {0, GEN6_BLENDFACTOR_DST_ALPHA, GEN6_BLENDFACTOR_ZERO},
  111.         /* InReverse */ {1, GEN6_BLENDFACTOR_ZERO, GEN6_BLENDFACTOR_SRC_ALPHA},
  112.         /* Out */       {0, GEN6_BLENDFACTOR_INV_DST_ALPHA, GEN6_BLENDFACTOR_ZERO},
  113.         /* OutReverse */ {1, GEN6_BLENDFACTOR_ZERO, GEN6_BLENDFACTOR_INV_SRC_ALPHA},
  114.         /* Atop */      {1, GEN6_BLENDFACTOR_DST_ALPHA, GEN6_BLENDFACTOR_INV_SRC_ALPHA},
  115.         /* AtopReverse */ {1, GEN6_BLENDFACTOR_INV_DST_ALPHA, GEN6_BLENDFACTOR_SRC_ALPHA},
  116.         /* Xor */       {1, GEN6_BLENDFACTOR_INV_DST_ALPHA, GEN6_BLENDFACTOR_INV_SRC_ALPHA},
  117.         /* Add */       {0, GEN6_BLENDFACTOR_ONE, GEN6_BLENDFACTOR_ONE},
  118. };
  119.  
  120.  
  121. /**
  122.  * Highest-valued BLENDFACTOR used in gen6_blend_op.
  123.  *
  124.  * This leaves out GEN6_BLENDFACTOR_INV_DST_COLOR,
  125.  * GEN6_BLENDFACTOR_INV_CONST_{COLOR,ALPHA},
  126.  * GEN6_BLENDFACTOR_INV_SRC1_{COLOR,ALPHA}
  127.  */
  128. #define GEN6_BLENDFACTOR_COUNT (GEN6_BLENDFACTOR_INV_DST_ALPHA + 1)
  129.  
  130. /* FIXME: surface format defined in gen6_defines.h, shared Sampling engine
  131.  * 1.7.2
  132.  
  133. static const struct formatinfo {
  134.         CARD32 pict_fmt;
  135.         uint32_t card_fmt;
  136. } gen6_tex_formats[] = {
  137.         {PICT_a8, GEN6_SURFACEFORMAT_A8_UNORM},
  138.         {PICT_a8r8g8b8, GEN6_SURFACEFORMAT_B8G8R8A8_UNORM},
  139.         {PICT_x8r8g8b8, GEN6_SURFACEFORMAT_B8G8R8X8_UNORM},
  140.         {PICT_a8b8g8r8, GEN6_SURFACEFORMAT_R8G8B8A8_UNORM},
  141.         {PICT_x8b8g8r8, GEN6_SURFACEFORMAT_R8G8B8X8_UNORM},
  142.         {PICT_r8g8b8, GEN6_SURFACEFORMAT_R8G8B8_UNORM},
  143.         {PICT_r5g6b5, GEN6_SURFACEFORMAT_B5G6R5_UNORM},
  144.         {PICT_a1r5g5b5, GEN6_SURFACEFORMAT_B5G5R5A1_UNORM},
  145.         {PICT_a2r10g10b10, GEN6_SURFACEFORMAT_B10G10R10A2_UNORM},
  146.         {PICT_x2r10g10b10, GEN6_SURFACEFORMAT_B10G10R10X2_UNORM},
  147.         {PICT_a2b10g10r10, GEN6_SURFACEFORMAT_R10G10B10A2_UNORM},
  148.         {PICT_x2r10g10b10, GEN6_SURFACEFORMAT_B10G10R10X2_UNORM},
  149.         {PICT_a4r4g4b4, GEN6_SURFACEFORMAT_B4G4R4A4_UNORM},
  150. };
  151.  */
  152.  
  153. #define GEN6_BLEND_STATE_PADDED_SIZE    ALIGN(sizeof(struct gen6_blend_state), 64)
  154.  
  155. #define BLEND_OFFSET(s, d) \
  156.         (((s) * GEN6_BLENDFACTOR_COUNT + (d)) * GEN6_BLEND_STATE_PADDED_SIZE)
  157.  
  158. #define SAMPLER_OFFSET(sf, se, mf, me) \
  159.         (((((sf) * EXTEND_COUNT + (se)) * FILTER_COUNT + (mf)) * EXTEND_COUNT + (me)) * 2 * sizeof(struct gen6_sampler_state))
  160.  
  161. #define OUT_BATCH(v) batch_emit(sna, v)
  162. #define OUT_VERTEX(x,y) vertex_emit_2s(sna, x,y)
  163. #define OUT_VERTEX_F(v) vertex_emit(sna, v)
  164.  
  165. static inline bool too_large(int width, int height)
  166. {
  167.         return width > GEN6_MAX_SIZE || height > GEN6_MAX_SIZE;
  168. }
  169.  
  170. static uint32_t gen6_get_blend(int op,
  171.                                bool has_component_alpha,
  172.                                uint32_t dst_format)
  173. {
  174.         uint32_t src, dst;
  175.  
  176. //    src = GEN6_BLENDFACTOR_ONE; //gen6_blend_op[op].src_blend;
  177. //    dst = GEN6_BLENDFACTOR_ZERO; //gen6_blend_op[op].dst_blend;
  178.  
  179.     src = GEN6_BLENDFACTOR_ONE; //gen6_blend_op[op].src_blend;
  180.     dst = GEN6_BLENDFACTOR_INV_SRC_ALPHA; //gen6_blend_op[op].dst_blend;
  181.  
  182. #if 0
  183.         /* If there's no dst alpha channel, adjust the blend op so that
  184.          * we'll treat it always as 1.
  185.          */
  186.         if (PICT_FORMAT_A(dst_format) == 0) {
  187.                 if (src == GEN6_BLENDFACTOR_DST_ALPHA)
  188.                         src = GEN6_BLENDFACTOR_ONE;
  189.                 else if (src == GEN6_BLENDFACTOR_INV_DST_ALPHA)
  190.                         src = GEN6_BLENDFACTOR_ZERO;
  191.         }
  192.  
  193.         /* If the source alpha is being used, then we should only be in a
  194.          * case where the source blend factor is 0, and the source blend
  195.          * value is the mask channels multiplied by the source picture's alpha.
  196.          */
  197.         if (has_component_alpha && gen6_blend_op[op].src_alpha) {
  198.                 if (dst == GEN6_BLENDFACTOR_SRC_ALPHA)
  199.                         dst = GEN6_BLENDFACTOR_SRC_COLOR;
  200.                 else if (dst == GEN6_BLENDFACTOR_INV_SRC_ALPHA)
  201.                         dst = GEN6_BLENDFACTOR_INV_SRC_COLOR;
  202.         }
  203.  
  204.         DBG(("blend op=%d, dst=%x [A=%d] => src=%d, dst=%d => offset=%x\n",
  205.              op, dst_format, PICT_FORMAT_A(dst_format),
  206.              src, dst, (int)BLEND_OFFSET(src, dst)));
  207. #endif
  208.  
  209.         return BLEND_OFFSET(src, dst);
  210. }
  211.  
  212. static uint32_t gen6_get_dest_format(CARD32 format)
  213. {
  214.     return GEN6_SURFACEFORMAT_B8G8R8A8_UNORM;
  215.  
  216. /*
  217.         switch (format) {
  218.         default:
  219.                 assert(0);
  220.         case PICT_a8r8g8b8:
  221.         case PICT_x8r8g8b8:
  222.                 return GEN6_SURFACEFORMAT_B8G8R8A8_UNORM;
  223.         case PICT_a8b8g8r8:
  224.         case PICT_x8b8g8r8:
  225.                 return GEN6_SURFACEFORMAT_R8G8B8A8_UNORM;
  226.         case PICT_a2r10g10b10:
  227.         case PICT_x2r10g10b10:
  228.                 return GEN6_SURFACEFORMAT_B10G10R10A2_UNORM;
  229.         case PICT_r5g6b5:
  230.                 return GEN6_SURFACEFORMAT_B5G6R5_UNORM;
  231.         case PICT_x1r5g5b5:
  232.         case PICT_a1r5g5b5:
  233.                 return GEN6_SURFACEFORMAT_B5G5R5A1_UNORM;
  234.         case PICT_a8:
  235.                 return GEN6_SURFACEFORMAT_A8_UNORM;
  236.         case PICT_a4r4g4b4:
  237.         case PICT_x4r4g4b4:
  238.                 return GEN6_SURFACEFORMAT_B4G4R4A4_UNORM;
  239.         }
  240.  */
  241. }
  242.  
  243. #if 0
  244. static Bool gen6_check_dst_format(PictFormat format)
  245. {
  246.         switch (format) {
  247.         case PICT_a8r8g8b8:
  248.         case PICT_x8r8g8b8:
  249.         case PICT_a8b8g8r8:
  250.         case PICT_x8b8g8r8:
  251.         case PICT_a2r10g10b10:
  252.         case PICT_x2r10g10b10:
  253.         case PICT_r5g6b5:
  254.         case PICT_x1r5g5b5:
  255.         case PICT_a1r5g5b5:
  256.         case PICT_a8:
  257.         case PICT_a4r4g4b4:
  258.         case PICT_x4r4g4b4:
  259.                 return TRUE;
  260.         }
  261.         return FALSE;
  262. }
  263.  
  264. static bool gen6_check_format(uint32_t format)
  265. {
  266.         switch (format) {
  267.         case PICT_a8r8g8b8:
  268.         case PICT_x8r8g8b8:
  269.         case PICT_a8b8g8r8:
  270.         case PICT_x8b8g8r8:
  271.         case PICT_a2r10g10b10:
  272.         case PICT_x2r10g10b10:
  273.         case PICT_r8g8b8:
  274.         case PICT_r5g6b5:
  275.         case PICT_a1r5g5b5:
  276.         case PICT_a8:
  277.         case PICT_a4r4g4b4:
  278.         case PICT_x4r4g4b4:
  279.                 return true;
  280.         default:
  281.                 DBG(("%s: unhandled format: %x\n", __FUNCTION__, format));
  282.                 return false;
  283.         }
  284. }
  285.  
  286. static uint32_t gen6_filter(uint32_t filter)
  287. {
  288.         switch (filter) {
  289.         default:
  290.                 assert(0);
  291.         case PictFilterNearest:
  292.                 return SAMPLER_FILTER_NEAREST;
  293.         case PictFilterBilinear:
  294.                 return SAMPLER_FILTER_BILINEAR;
  295.         }
  296. }
  297.  
  298. static uint32_t gen6_check_filter(PicturePtr picture)
  299. {
  300.         switch (picture->filter) {
  301.         case PictFilterNearest:
  302.         case PictFilterBilinear:
  303.                 return TRUE;
  304.         default:
  305.                 return FALSE;
  306.         }
  307. }
  308.  
  309. static uint32_t gen6_repeat(uint32_t repeat)
  310. {
  311.         switch (repeat) {
  312.         default:
  313.                 assert(0);
  314.         case RepeatNone:
  315.                 return SAMPLER_EXTEND_NONE;
  316.         case RepeatNormal:
  317.                 return SAMPLER_EXTEND_REPEAT;
  318.         case RepeatPad:
  319.                 return SAMPLER_EXTEND_PAD;
  320.         case RepeatReflect:
  321.                 return SAMPLER_EXTEND_REFLECT;
  322.         }
  323. }
  324.  
  325. static bool gen6_check_repeat(PicturePtr picture)
  326. {
  327.         if (!picture->repeat)
  328.                 return TRUE;
  329.  
  330.         switch (picture->repeatType) {
  331.         case RepeatNone:
  332.         case RepeatNormal:
  333.         case RepeatPad:
  334.         case RepeatReflect:
  335.                 return TRUE;
  336.         default:
  337.                 return FALSE;
  338.         }
  339. }
  340. #endif
  341.  
  342. static int
  343. gen6_choose_composite_kernel(int op, Bool has_mask, Bool is_ca, Bool is_affine)
  344. {
  345.         int base;
  346.  
  347.         if (has_mask) {
  348. /*
  349.                 if (is_ca) {
  350.                         if (gen6_blend_op[op].src_alpha)
  351.                                 base = GEN6_WM_KERNEL_MASKCA_SRCALPHA;
  352.                         else
  353.                                 base = GEN6_WM_KERNEL_MASKCA;
  354.                 } else
  355.                         base = GEN6_WM_KERNEL_MASK;
  356. */
  357.         } else
  358.                 base = GEN6_WM_KERNEL_NOMASK;
  359.  
  360.         return base + !is_affine;
  361. }
  362.  
  363. static void
  364. gen6_emit_urb(struct sna *sna)
  365. {
  366.         OUT_BATCH(GEN6_3DSTATE_URB | (3 - 2));
  367.         OUT_BATCH(((1 - 1) << GEN6_3DSTATE_URB_VS_SIZE_SHIFT) |
  368.                   (24 << GEN6_3DSTATE_URB_VS_ENTRIES_SHIFT)); /* at least 24 on GEN6 */
  369.         OUT_BATCH((0 << GEN6_3DSTATE_URB_GS_SIZE_SHIFT) |
  370.                   (0 << GEN6_3DSTATE_URB_GS_ENTRIES_SHIFT)); /* no GS thread */
  371. }
  372.  
  373. static void
  374. gen6_emit_state_base_address(struct sna *sna)
  375. {
  376.         OUT_BATCH(GEN6_STATE_BASE_ADDRESS | (10 - 2));
  377.         OUT_BATCH(0); /* general */
  378.  
  379.     OUT_BATCH((sna->kgem.batch_obj->gtt_offset+
  380.               sna->kgem.batch_idx*4096)|BASE_ADDRESS_MODIFY);
  381.  
  382.     OUT_BATCH(sna->render_state.gen6.general_bo->gaddr|BASE_ADDRESS_MODIFY);
  383.  
  384.         OUT_BATCH(0); /* indirect */
  385.  
  386.     OUT_BATCH(sna->render_state.gen6.general_bo->gaddr|BASE_ADDRESS_MODIFY);
  387.  
  388.         /* upper bounds, disable */
  389.         OUT_BATCH(0);
  390.         OUT_BATCH(BASE_ADDRESS_MODIFY);
  391.         OUT_BATCH(0);
  392.         OUT_BATCH(BASE_ADDRESS_MODIFY);
  393. }
  394.  
  395. static void
  396. gen6_emit_viewports(struct sna *sna)
  397. {
  398.         OUT_BATCH(GEN6_3DSTATE_VIEWPORT_STATE_POINTERS |
  399.                   GEN6_3DSTATE_VIEWPORT_STATE_MODIFY_CC |
  400.                   (4 - 2));
  401.         OUT_BATCH(0);
  402.         OUT_BATCH(0);
  403.         OUT_BATCH(sna->render_state.gen6.cc_vp);
  404. }
  405.  
  406. static void
  407. gen6_emit_vs(struct sna *sna)
  408. {
  409.         /* disable VS constant buffer */
  410.         OUT_BATCH(GEN6_3DSTATE_CONSTANT_VS | (5 - 2));
  411.         OUT_BATCH(0);
  412.         OUT_BATCH(0);
  413.         OUT_BATCH(0);
  414.         OUT_BATCH(0);
  415.  
  416.         OUT_BATCH(GEN6_3DSTATE_VS | (6 - 2));
  417.         OUT_BATCH(0); /* no VS kernel */
  418.         OUT_BATCH(0);
  419.         OUT_BATCH(0);
  420.         OUT_BATCH(0);
  421.         OUT_BATCH(0); /* pass-through */
  422. }
  423.  
  424. static void
  425. gen6_emit_gs(struct sna *sna)
  426. {
  427.         /* disable GS constant buffer */
  428.         OUT_BATCH(GEN6_3DSTATE_CONSTANT_GS | (5 - 2));
  429.         OUT_BATCH(0);
  430.         OUT_BATCH(0);
  431.         OUT_BATCH(0);
  432.         OUT_BATCH(0);
  433.  
  434.         OUT_BATCH(GEN6_3DSTATE_GS | (7 - 2));
  435.         OUT_BATCH(0); /* no GS kernel */
  436.         OUT_BATCH(0);
  437.         OUT_BATCH(0);
  438.         OUT_BATCH(0);
  439.         OUT_BATCH(0);
  440.         OUT_BATCH(0); /* pass-through */
  441. }
  442.  
  443. static void
  444. gen6_emit_clip(struct sna *sna)
  445. {
  446.         OUT_BATCH(GEN6_3DSTATE_CLIP | (4 - 2));
  447.         OUT_BATCH(0);
  448.         OUT_BATCH(0); /* pass-through */
  449.         OUT_BATCH(0);
  450. }
  451.  
  452. static void
  453. gen6_emit_wm_constants(struct sna *sna)
  454. {
  455.         /* disable WM constant buffer */
  456.         OUT_BATCH(GEN6_3DSTATE_CONSTANT_PS | (5 - 2));
  457.         OUT_BATCH(0);
  458.         OUT_BATCH(0);
  459.         OUT_BATCH(0);
  460.         OUT_BATCH(0);
  461. }
  462.  
  463. static void
  464. gen6_emit_null_depth_buffer(struct sna *sna)
  465. {
  466.         OUT_BATCH(GEN6_3DSTATE_DEPTH_BUFFER | (7 - 2));
  467.         OUT_BATCH(GEN6_SURFACE_NULL << GEN6_3DSTATE_DEPTH_BUFFER_TYPE_SHIFT |
  468.                   GEN6_DEPTHFORMAT_D32_FLOAT << GEN6_3DSTATE_DEPTH_BUFFER_FORMAT_SHIFT);
  469.         OUT_BATCH(0);
  470.         OUT_BATCH(0);
  471.         OUT_BATCH(0);
  472.         OUT_BATCH(0);
  473.         OUT_BATCH(0);
  474.  
  475.         OUT_BATCH(GEN6_3DSTATE_CLEAR_PARAMS | (2 - 2));
  476.         OUT_BATCH(0);
  477. }
  478.  
  479. static void
  480. gen6_emit_invariant(struct sna *sna)
  481. {
  482.         OUT_BATCH(GEN6_PIPELINE_SELECT | PIPELINE_SELECT_3D);
  483.  
  484.         OUT_BATCH(GEN6_3DSTATE_MULTISAMPLE | (3 - 2));
  485.         OUT_BATCH(GEN6_3DSTATE_MULTISAMPLE_PIXEL_LOCATION_CENTER |
  486.               GEN6_3DSTATE_MULTISAMPLE_NUMSAMPLES_1); /* 1 sample/pixel */
  487.         OUT_BATCH(0);
  488.  
  489.         OUT_BATCH(GEN6_3DSTATE_SAMPLE_MASK | (2 - 2));
  490.         OUT_BATCH(1);
  491.  
  492.         gen6_emit_urb(sna);
  493.  
  494.         gen6_emit_state_base_address(sna);
  495.  
  496.         gen6_emit_viewports(sna);
  497.         gen6_emit_vs(sna);
  498.         gen6_emit_gs(sna);
  499.         gen6_emit_clip(sna);
  500.         gen6_emit_wm_constants(sna);
  501.         gen6_emit_null_depth_buffer(sna);
  502.  
  503.         sna->render_state.gen6.needs_invariant = FALSE;
  504. }
  505.  
  506. static bool
  507. gen6_emit_cc(struct sna *sna,
  508.              int op, bool has_component_alpha, uint32_t dst_format)
  509. {
  510.         struct gen6_render_state *render = &sna->render_state.gen6;
  511.         uint32_t blend;
  512.  
  513.         blend = gen6_get_blend(op, has_component_alpha, dst_format);
  514.  
  515.         DBG(("%s(op=%d, ca=%d, format=%x): new=%x, current=%x\n",
  516.              __FUNCTION__,
  517.              op, has_component_alpha, dst_format,
  518.              blend, render->blend));
  519.         if (render->blend == blend)
  520.                 return op <= PictOpSrc;
  521.  
  522.         OUT_BATCH(GEN6_3DSTATE_CC_STATE_POINTERS | (4 - 2));
  523.         OUT_BATCH((render->cc_blend + blend) | 1);
  524.         if (render->blend == (unsigned)-1) {
  525.                 OUT_BATCH(1);
  526.                 OUT_BATCH(1);
  527.         } else {
  528.                 OUT_BATCH(0);
  529.                 OUT_BATCH(0);
  530.         }
  531.  
  532.         render->blend = blend;
  533.         return op <= PictOpSrc;
  534. }
  535.  
  536. static void
  537. gen6_emit_sampler(struct sna *sna, uint32_t state)
  538. {
  539.         assert(state <
  540.                2 * sizeof(struct gen6_sampler_state) *
  541.                FILTER_COUNT * EXTEND_COUNT *
  542.                FILTER_COUNT * EXTEND_COUNT);
  543.  
  544.         if (sna->render_state.gen6.samplers == state)
  545.                 return;
  546.  
  547.         sna->render_state.gen6.samplers = state;
  548.  
  549.         OUT_BATCH(GEN6_3DSTATE_SAMPLER_STATE_POINTERS |
  550.                   GEN6_3DSTATE_SAMPLER_STATE_MODIFY_PS |
  551.                   (4 - 2));
  552.         OUT_BATCH(0); /* VS */
  553.         OUT_BATCH(0); /* GS */
  554.         OUT_BATCH(sna->render_state.gen6.wm_state + state);
  555. }
  556.  
  557. static void
  558. gen6_emit_sf(struct sna *sna, Bool has_mask)
  559. {
  560.         int num_sf_outputs = has_mask ? 2 : 1;
  561.  
  562.         if (sna->render_state.gen6.num_sf_outputs == num_sf_outputs)
  563.                 return;
  564.  
  565.         DBG(("%s: num_sf_outputs=%d, read_length=%d, read_offset=%d\n",
  566.              __FUNCTION__, num_sf_outputs, 1, 0));
  567.  
  568.         sna->render_state.gen6.num_sf_outputs = num_sf_outputs;
  569.  
  570.         OUT_BATCH(GEN6_3DSTATE_SF | (20 - 2));
  571.         OUT_BATCH(num_sf_outputs << GEN6_3DSTATE_SF_NUM_OUTPUTS_SHIFT |
  572.                   1 << GEN6_3DSTATE_SF_URB_ENTRY_READ_LENGTH_SHIFT |
  573.                   1 << GEN6_3DSTATE_SF_URB_ENTRY_READ_OFFSET_SHIFT);
  574.         OUT_BATCH(0);
  575.         OUT_BATCH(GEN6_3DSTATE_SF_CULL_NONE);
  576.         OUT_BATCH(2 << GEN6_3DSTATE_SF_TRIFAN_PROVOKE_SHIFT); /* DW4 */
  577.         OUT_BATCH(0);
  578.         OUT_BATCH(0);
  579.         OUT_BATCH(0);
  580.         OUT_BATCH(0);
  581.         OUT_BATCH(0); /* DW9 */
  582.         OUT_BATCH(0);
  583.         OUT_BATCH(0);
  584.         OUT_BATCH(0);
  585.         OUT_BATCH(0);
  586.         OUT_BATCH(0); /* DW14 */
  587.         OUT_BATCH(0);
  588.         OUT_BATCH(0);
  589.         OUT_BATCH(0);
  590.         OUT_BATCH(0);
  591.         OUT_BATCH(0); /* DW19 */
  592. }
  593.  
  594. static void
  595. gen6_emit_wm(struct sna *sna, unsigned int kernel, int nr_surfaces, int nr_inputs)
  596. {
  597.         if (sna->render_state.gen6.kernel == kernel)
  598.                 return;
  599.  
  600.         sna->render_state.gen6.kernel = kernel;
  601.  
  602.         DBG(("%s: switching to %s\n", __FUNCTION__, wm_kernels[kernel].name));
  603.  
  604.         OUT_BATCH(GEN6_3DSTATE_WM | (9 - 2));
  605.         OUT_BATCH(sna->render_state.gen6.wm_kernel[kernel]);
  606.         OUT_BATCH(1 << GEN6_3DSTATE_WM_SAMPLER_COUNT_SHIFT |
  607.                   nr_surfaces << GEN6_3DSTATE_WM_BINDING_TABLE_ENTRY_COUNT_SHIFT);
  608.         OUT_BATCH(0);
  609.         OUT_BATCH(6 << GEN6_3DSTATE_WM_DISPATCH_START_GRF_0_SHIFT); /* DW4 */
  610.         OUT_BATCH((40 - 1) << GEN6_3DSTATE_WM_MAX_THREADS_SHIFT |
  611.                   GEN6_3DSTATE_WM_DISPATCH_ENABLE |
  612.                   GEN6_3DSTATE_WM_16_DISPATCH_ENABLE);
  613.         OUT_BATCH(nr_inputs << GEN6_3DSTATE_WM_NUM_SF_OUTPUTS_SHIFT |
  614.                   GEN6_3DSTATE_WM_PERSPECTIVE_PIXEL_BARYCENTRIC);
  615.         OUT_BATCH(0);
  616.         OUT_BATCH(0);
  617. }
  618.  
  619. static bool
  620. gen6_emit_binding_table(struct sna *sna, uint16_t offset)
  621. {
  622.         if (sna->render_state.gen6.surface_table == offset)
  623.                 return false;
  624.  
  625.         /* Binding table pointers */
  626.         OUT_BATCH(GEN6_3DSTATE_BINDING_TABLE_POINTERS |
  627.                   GEN6_3DSTATE_BINDING_TABLE_MODIFY_PS |
  628.                   (4 - 2));
  629.         OUT_BATCH(0);           /* vs */
  630.         OUT_BATCH(0);           /* gs */
  631.         /* Only the PS uses the binding table */
  632.         OUT_BATCH(offset*4);
  633.  
  634.         sna->render_state.gen6.surface_table = offset;
  635.         return true;
  636. }
  637.  
  638. static bool
  639. gen6_emit_drawing_rectangle(struct sna *sna,
  640.                             const struct sna_composite_op *op)
  641. {
  642.         uint32_t limit = (op->dst.height - 1) << 16 | (op->dst.width - 1);
  643.         uint32_t offset = (uint16_t)op->dst.y << 16 | (uint16_t)op->dst.x;
  644.  
  645.         assert(!too_large(op->dst.x, op->dst.y));
  646.         assert(!too_large(op->dst.width, op->dst.height));
  647.  
  648.         if (sna->render_state.gen6.drawrect_limit  == limit &&
  649.             sna->render_state.gen6.drawrect_offset == offset)
  650.                 return false;
  651.  
  652.         /* [DevSNB-C+{W/A}] Before any depth stall flush (including those
  653.          * produced by non-pipelined state commands), software needs to first
  654.          * send a PIPE_CONTROL with no bits set except Post-Sync Operation !=
  655.          * 0.
  656.          *
  657.          * [Dev-SNB{W/A}]: Pipe-control with CS-stall bit set must be sent
  658.          * BEFORE the pipe-control with a post-sync op and no write-cache
  659.          * flushes.
  660.          */
  661.         OUT_BATCH(GEN6_PIPE_CONTROL | (4 - 2));
  662.         OUT_BATCH(GEN6_PIPE_CONTROL_CS_STALL |
  663.                   GEN6_PIPE_CONTROL_STALL_AT_SCOREBOARD);
  664.         OUT_BATCH(0);
  665.         OUT_BATCH(0);
  666.  
  667.         OUT_BATCH(GEN6_PIPE_CONTROL | (4 - 2));
  668.         OUT_BATCH(GEN6_PIPE_CONTROL_WRITE_TIME);
  669.  
  670.     OUT_BATCH(sna->render_state.gen6.general_bo->gaddr+64);
  671.  
  672.         OUT_BATCH(0);
  673.  
  674.         OUT_BATCH(GEN6_3DSTATE_DRAWING_RECTANGLE | (4 - 2));
  675.         OUT_BATCH(0);
  676.         OUT_BATCH(limit);
  677.         OUT_BATCH(offset);
  678.  
  679.         sna->render_state.gen6.drawrect_offset = offset;
  680.         sna->render_state.gen6.drawrect_limit = limit;
  681.         return true;
  682. }
  683.  
  684. static void
  685. gen6_emit_vertex_elements(struct sna *sna,
  686.                           const struct sna_composite_op *op)
  687. {
  688.         /*
  689.          * vertex data in vertex buffer
  690.          *    position: (x, y)
  691.          *    texture coordinate 0: (u0, v0) if (is_affine is TRUE) else (u0, v0, w0)
  692.          *    texture coordinate 1 if (has_mask is TRUE): same as above
  693.          */
  694.         struct gen6_render_state *render = &sna->render_state.gen6;
  695.         int nelem = op->mask.bo ? 2 : 1;
  696.         int selem = op->is_affine ? 2 : 3;
  697.         uint32_t w_component;
  698.         uint32_t src_format;
  699.         int id = op->u.gen6.ve_id;
  700.  
  701.         if (render->ve_id == id)
  702.                 return;
  703.         render->ve_id = id;
  704.  
  705.         if (op->is_affine) {
  706.                 src_format = GEN6_SURFACEFORMAT_R32G32_FLOAT;
  707.                 w_component = GEN6_VFCOMPONENT_STORE_1_FLT;
  708.         } else {
  709.                 src_format = GEN6_SURFACEFORMAT_R32G32B32_FLOAT;
  710.                 w_component = GEN6_VFCOMPONENT_STORE_SRC;
  711.         }
  712.  
  713.         /* The VUE layout
  714.          *    dword 0-3: pad (0.0, 0.0, 0.0. 0.0)
  715.          *    dword 4-7: position (x, y, 1.0, 1.0),
  716.          *    dword 8-11: texture coordinate 0 (u0, v0, w0, 1.0)
  717.          *    dword 12-15: texture coordinate 1 (u1, v1, w1, 1.0)
  718.          *
  719.          * dword 4-15 are fetched from vertex buffer
  720.          */
  721.         OUT_BATCH(GEN6_3DSTATE_VERTEX_ELEMENTS |
  722.                 ((2 * (2 + nelem)) + 1 - 2));
  723.  
  724.         OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID |
  725.                   GEN6_SURFACEFORMAT_R32G32B32A32_FLOAT << VE0_FORMAT_SHIFT |
  726.                   0 << VE0_OFFSET_SHIFT);
  727.         OUT_BATCH(GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_0_SHIFT |
  728.                   GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_1_SHIFT |
  729.                   GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT |
  730.                   GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_3_SHIFT);
  731.  
  732.         /* x,y */
  733.         OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID |
  734.                   GEN6_SURFACEFORMAT_R16G16_SSCALED << VE0_FORMAT_SHIFT |
  735.                   0 << VE0_OFFSET_SHIFT); /* offsets vb in bytes */
  736.         OUT_BATCH(GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT |
  737.                   GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT |
  738.                   GEN6_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT |
  739.                   GEN6_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT);
  740.  
  741.         /* u0, v0, w0 */
  742.         OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID |
  743.                   src_format << VE0_FORMAT_SHIFT |
  744.                   4 << VE0_OFFSET_SHIFT);       /* offset vb in bytes */
  745.         OUT_BATCH(GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT |
  746.                   GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT |
  747.                   w_component << VE1_VFCOMPONENT_2_SHIFT |
  748.                   GEN6_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT);
  749.  
  750.         /* u1, v1, w1 */
  751.         if (op->mask.bo) {
  752.                 OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID |
  753.                           src_format << VE0_FORMAT_SHIFT |
  754.                           ((1 + selem) * 4) << VE0_OFFSET_SHIFT); /* vb offset in bytes */
  755.                 OUT_BATCH(GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT |
  756.                           GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT |
  757.                           w_component << VE1_VFCOMPONENT_2_SHIFT |
  758.                           GEN6_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT);
  759.         }
  760. }
  761.  
  762. static void
  763. gen6_emit_flush(struct sna *sna)
  764. {
  765.         OUT_BATCH(GEN6_PIPE_CONTROL | (4 - 2));
  766.         OUT_BATCH(GEN6_PIPE_CONTROL_WC_FLUSH |
  767.                   GEN6_PIPE_CONTROL_TC_FLUSH |
  768.                   GEN6_PIPE_CONTROL_CS_STALL);
  769.         OUT_BATCH(0);
  770.         OUT_BATCH(0);
  771. }
  772.  
  773. static void
  774. gen6_emit_state(struct sna *sna,
  775.                 const struct sna_composite_op *op,
  776.                 uint16_t wm_binding_table)
  777. {
  778.         bool need_stall = wm_binding_table & 1;
  779.  
  780.         if (gen6_emit_cc(sna, op->op, op->has_component_alpha, op->dst.format))
  781.                 need_stall = false;
  782.         gen6_emit_sampler(sna,
  783.                           SAMPLER_OFFSET(op->src.filter,
  784.                                          op->src.repeat,
  785.                                          op->mask.filter,
  786.                                          op->mask.repeat));
  787.         gen6_emit_sf(sna, op->mask.bo != NULL);
  788.         gen6_emit_wm(sna,
  789.                      op->u.gen6.wm_kernel,
  790.                      op->u.gen6.nr_surfaces,
  791.                      op->u.gen6.nr_inputs);
  792.         gen6_emit_vertex_elements(sna, op);
  793.         need_stall |= gen6_emit_binding_table(sna, wm_binding_table & ~1);
  794.         if (gen6_emit_drawing_rectangle(sna, op))
  795.                 need_stall = false;
  796. //    if (kgem_bo_is_dirty(op->src.bo) || kgem_bo_is_dirty(op->mask.bo)) {
  797.         gen6_emit_flush(sna);
  798.         kgem_clear_dirty(&sna->kgem);
  799.                 kgem_bo_mark_dirty(op->dst.bo);
  800.                 need_stall = false;
  801. //   }
  802.         if (need_stall) {
  803.                 OUT_BATCH(GEN6_PIPE_CONTROL | (4 - 2));
  804.                 OUT_BATCH(GEN6_PIPE_CONTROL_CS_STALL |
  805.                           GEN6_PIPE_CONTROL_STALL_AT_SCOREBOARD);
  806.                 OUT_BATCH(0);
  807.                 OUT_BATCH(0);
  808.         }
  809. }
  810.  
  811. static void gen6_magic_ca_pass(struct sna *sna,
  812.                                const struct sna_composite_op *op)
  813. {
  814.         struct gen6_render_state *state = &sna->render_state.gen6;
  815.  
  816.         if (!op->need_magic_ca_pass)
  817.                 return;
  818.  
  819.         DBG(("%s: CA fixup (%d -> %d)\n", __FUNCTION__,
  820.              sna->render.vertex_start, sna->render.vertex_index));
  821.  
  822.         gen6_emit_flush(sna);
  823.  
  824.         gen6_emit_cc(sna, PictOpAdd, TRUE, op->dst.format);
  825.         gen6_emit_wm(sna,
  826.                      gen6_choose_composite_kernel(PictOpAdd,
  827.                                                   TRUE, TRUE,
  828.                                                   op->is_affine),
  829.                      3, 2);
  830.  
  831.         OUT_BATCH(GEN6_3DPRIMITIVE |
  832.                   GEN6_3DPRIMITIVE_VERTEX_SEQUENTIAL |
  833.                   _3DPRIM_RECTLIST << GEN6_3DPRIMITIVE_TOPOLOGY_SHIFT |
  834.                   0 << 9 |
  835.                   4);
  836.         OUT_BATCH(sna->render.vertex_index - sna->render.vertex_start);
  837.         OUT_BATCH(sna->render.vertex_start);
  838.         OUT_BATCH(1);   /* single instance */
  839.         OUT_BATCH(0);   /* start instance location */
  840.         OUT_BATCH(0);   /* index buffer offset, ignored */
  841.  
  842.         state->last_primitive = sna->kgem.nbatch;
  843. }
  844.  
  845. static void gen6_vertex_flush(struct sna *sna)
  846. {
  847.         assert(sna->render_state.gen6.vertex_offset);
  848.  
  849.         DBG(("%s[%x] = %d\n", __FUNCTION__,
  850.              4*sna->render_state.gen6.vertex_offset,
  851.              sna->render.vertex_index - sna->render.vertex_start));
  852.         sna->kgem.batch[sna->render_state.gen6.vertex_offset] =
  853.                 sna->render.vertex_index - sna->render.vertex_start;
  854.         sna->render_state.gen6.vertex_offset = 0;
  855. }
  856.  
  857. static int gen6_vertex_finish(struct sna *sna)
  858. {
  859.         struct kgem_bo *bo;
  860.         unsigned int i;
  861.  
  862.         DBG(("%s: used=%d / %d\n", __FUNCTION__,
  863.              sna->render.vertex_used, sna->render.vertex_size));
  864.         assert(sna->render.vertex_used);
  865.  
  866.         /* Note: we only need dword alignment (currently) */
  867. /*
  868.         bo = sna->render.vbo;
  869.         if (bo) {
  870.                 for (i = 0; i < ARRAY_SIZE(sna->render.vertex_reloc); i++) {
  871.                         if (sna->render.vertex_reloc[i]) {
  872.                                 DBG(("%s: reloc[%d] = %d\n", __FUNCTION__,
  873.                                      i, sna->render.vertex_reloc[i]));
  874.  
  875.                                 sna->kgem.batch[sna->render.vertex_reloc[i]] =
  876.                                         kgem_add_reloc(&sna->kgem,
  877.                                                        sna->render.vertex_reloc[i],
  878.                                                        bo,
  879.                                                        I915_GEM_DOMAIN_VERTEX << 16,
  880.                                                        0);
  881.                                 sna->kgem.batch[sna->render.vertex_reloc[i]+1] =
  882.                                         kgem_add_reloc(&sna->kgem,
  883.                                                        sna->render.vertex_reloc[i]+1,
  884.                                                        bo,
  885.                                                        I915_GEM_DOMAIN_VERTEX << 16,
  886.                                                        0 + sna->render.vertex_used * 4 - 1);
  887.                                 sna->render.vertex_reloc[i] = 0;
  888.                         }
  889.                 }
  890.  
  891.                 sna->render.vertex_used = 0;
  892.                 sna->render.vertex_index = 0;
  893.                 sna->render_state.gen6.vb_id = 0;
  894.  
  895.                 kgem_bo_destroy(&sna->kgem, bo);
  896.         }
  897. */
  898.         sna->render.vertices = NULL;
  899.         sna->render.vbo = kgem_create_linear(&sna->kgem, 256*1024);
  900.         if (sna->render.vbo)
  901.                 sna->render.vertices = kgem_bo_map__cpu(&sna->kgem, sna->render.vbo);
  902.         if (sna->render.vertices == NULL) {
  903.                 kgem_bo_destroy(&sna->kgem, sna->render.vbo);
  904.                 sna->render.vbo = NULL;
  905.                 return 0;
  906.         }
  907.  
  908. //   kgem_bo_sync__cpu(&sna->kgem, sna->render.vbo);
  909.         if (sna->render.vertex_used) {
  910.                 DBG(("%s: copying initial buffer x %d to handle=%d\n",
  911.                      __FUNCTION__,
  912.                      sna->render.vertex_used,
  913.                      sna->render.vbo->handle));
  914.                 memcpy(sna->render.vertices,
  915.                        sna->render.vertex_data,
  916.                        sizeof(float)*sna->render.vertex_used);
  917.         }
  918.         sna->render.vertex_size = 64 * 1024 - 1;
  919.         return sna->render.vertex_size - sna->render.vertex_used;
  920. }
  921.  
  922. static void gen6_vertex_close(struct sna *sna)
  923. {
  924.         struct kgem_bo *bo;
  925.         unsigned int i, delta = 0;
  926.  
  927.         if (!sna->render.vertex_used) {
  928.                 assert(sna->render.vbo == NULL);
  929.                 assert(sna->render.vertices == sna->render.vertex_data);
  930.                 assert(sna->render.vertex_size == ARRAY_SIZE(sna->render.vertex_data));
  931.                 return;
  932.         }
  933.  
  934.         DBG(("%s: used=%d / %d\n", __FUNCTION__,
  935.              sna->render.vertex_used, sna->render.vertex_size));
  936.  
  937.         bo = sna->render.vbo;
  938.         if (bo == NULL) {
  939.                 assert(sna->render.vertices == sna->render.vertex_data);
  940.                 assert(sna->render.vertex_used < ARRAY_SIZE(sna->render.vertex_data));
  941.                 if (sna->kgem.nbatch + sna->render.vertex_used <= sna->kgem.surface) {
  942.                         DBG(("%s: copy to batch: %d @ %d\n", __FUNCTION__,
  943.                              sna->render.vertex_used, sna->kgem.nbatch));
  944.                         memcpy(sna->kgem.batch + sna->kgem.nbatch,
  945.                                sna->render.vertex_data,
  946.                                sna->render.vertex_used * 4);
  947.                         delta = sna->kgem.nbatch * 4;
  948.                         bo = NULL;
  949.                         sna->kgem.nbatch += sna->render.vertex_used;
  950.                 } else {
  951.                         bo = kgem_create_linear(&sna->kgem, 4*sna->render.vertex_used);
  952.                         if (bo && !kgem_bo_write(&sna->kgem, bo,
  953.                                                  sna->render.vertex_data,
  954.                                                  4*sna->render.vertex_used)) {
  955.                                 kgem_bo_destroy(&sna->kgem, bo);
  956.                                 goto reset;
  957.                         }
  958.                         DBG(("%s: new vbo: %d\n", __FUNCTION__,
  959.                              sna->render.vertex_used));
  960.                 }
  961.         }
  962.  
  963.         for (i = 0; i < ARRAY_SIZE(sna->render.vertex_reloc); i++) {
  964.                 if (sna->render.vertex_reloc[i]) {
  965.                         DBG(("%s: reloc[%d] = %d\n", __FUNCTION__,
  966.                              i, sna->render.vertex_reloc[i]));
  967.  
  968.             sna->kgem.batch[sna->render.vertex_reloc[i]] =
  969.                             sna->kgem.batch_obj->gtt_offset+delta+
  970.                             sna->kgem.batch_idx*4096;
  971.  
  972.             sna->kgem.batch[sna->render.vertex_reloc[i]+1] =
  973.                             sna->kgem.batch_obj->gtt_offset+delta+
  974.                             sna->kgem.batch_idx*4096+
  975.                             sna->render.vertex_used * 4 - 1;
  976.  
  977.                         sna->render.vertex_reloc[i] = 0;
  978.                 }
  979.         }
  980.  
  981. //   if (bo)
  982. //       kgem_bo_destroy(&sna->kgem, bo);
  983.  
  984. reset:
  985.         sna->render.vertex_used = 0;
  986.         sna->render.vertex_index = 0;
  987.         sna->render_state.gen6.vb_id = 0;
  988.  
  989.         sna->render.vbo = NULL;
  990.         sna->render.vertices = sna->render.vertex_data;
  991.         sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data);
  992. }
  993.  
  994. typedef struct gen6_surface_state_padded {
  995.         struct gen6_surface_state state;
  996.         char pad[32 - sizeof(struct gen6_surface_state)];
  997. } gen6_surface_state_padded;
  998.  
  999. static void null_create(struct sna_static_stream *stream)
  1000. {
  1001.         /* A bunch of zeros useful for legacy border color and depth-stencil */
  1002.         sna_static_stream_map(stream, 64, 64);
  1003. }
  1004.  
  1005. static void scratch_create(struct sna_static_stream *stream)
  1006. {
  1007.         /* 64 bytes of scratch space for random writes, such as
  1008.          * the pipe-control w/a.
  1009.          */
  1010.         sna_static_stream_map(stream, 64, 64);
  1011. }
  1012.  
  1013. static void
  1014. sampler_state_init(struct gen6_sampler_state *sampler_state,
  1015.                    sampler_filter_t filter,
  1016.                    sampler_extend_t extend)
  1017. {
  1018.         sampler_state->ss0.lod_preclamp = 1;    /* GL mode */
  1019.  
  1020.         /* We use the legacy mode to get the semantics specified by
  1021.          * the Render extension. */
  1022.         sampler_state->ss0.border_color_mode = GEN6_BORDER_COLOR_MODE_LEGACY;
  1023.  
  1024.         switch (filter) {
  1025.         default:
  1026.         case SAMPLER_FILTER_NEAREST:
  1027.                 sampler_state->ss0.min_filter = GEN6_MAPFILTER_NEAREST;
  1028.                 sampler_state->ss0.mag_filter = GEN6_MAPFILTER_NEAREST;
  1029.                 break;
  1030.         case SAMPLER_FILTER_BILINEAR:
  1031.                 sampler_state->ss0.min_filter = GEN6_MAPFILTER_LINEAR;
  1032.                 sampler_state->ss0.mag_filter = GEN6_MAPFILTER_LINEAR;
  1033.                 break;
  1034.         }
  1035.  
  1036.         switch (extend) {
  1037.         default:
  1038.         case SAMPLER_EXTEND_NONE:
  1039.                 sampler_state->ss1.r_wrap_mode = GEN6_TEXCOORDMODE_CLAMP_BORDER;
  1040.                 sampler_state->ss1.s_wrap_mode = GEN6_TEXCOORDMODE_CLAMP_BORDER;
  1041.                 sampler_state->ss1.t_wrap_mode = GEN6_TEXCOORDMODE_CLAMP_BORDER;
  1042.                 break;
  1043.         case SAMPLER_EXTEND_REPEAT:
  1044.                 sampler_state->ss1.r_wrap_mode = GEN6_TEXCOORDMODE_WRAP;
  1045.                 sampler_state->ss1.s_wrap_mode = GEN6_TEXCOORDMODE_WRAP;
  1046.                 sampler_state->ss1.t_wrap_mode = GEN6_TEXCOORDMODE_WRAP;
  1047.                 break;
  1048.         case SAMPLER_EXTEND_PAD:
  1049.                 sampler_state->ss1.r_wrap_mode = GEN6_TEXCOORDMODE_CLAMP;
  1050.                 sampler_state->ss1.s_wrap_mode = GEN6_TEXCOORDMODE_CLAMP;
  1051.                 sampler_state->ss1.t_wrap_mode = GEN6_TEXCOORDMODE_CLAMP;
  1052.                 break;
  1053.         case SAMPLER_EXTEND_REFLECT:
  1054.                 sampler_state->ss1.r_wrap_mode = GEN6_TEXCOORDMODE_MIRROR;
  1055.                 sampler_state->ss1.s_wrap_mode = GEN6_TEXCOORDMODE_MIRROR;
  1056.                 sampler_state->ss1.t_wrap_mode = GEN6_TEXCOORDMODE_MIRROR;
  1057.                 break;
  1058.         }
  1059. }
  1060.  
  1061. static uint32_t gen6_create_cc_viewport(struct sna_static_stream *stream)
  1062. {
  1063.         struct gen6_cc_viewport vp;
  1064.  
  1065.         vp.min_depth = -1.e35;
  1066.         vp.max_depth = 1.e35;
  1067.  
  1068.         return sna_static_stream_add(stream, &vp, sizeof(vp), 32);
  1069. }
  1070.  
  1071. #if 0
  1072.  
  1073. static uint32_t gen6_get_card_format(PictFormat format)
  1074. {
  1075.         unsigned int i;
  1076.  
  1077.         for (i = 0; i < ARRAY_SIZE(gen6_tex_formats); i++) {
  1078.                 if (gen6_tex_formats[i].pict_fmt == format)
  1079.                         return gen6_tex_formats[i].card_fmt;
  1080.         }
  1081.         return -1;
  1082. }
  1083. #endif
  1084.  
  1085. static uint32_t
  1086. gen6_tiling_bits(uint32_t tiling)
  1087. {
  1088.     return 0;
  1089. /*
  1090.         switch (tiling) {
  1091.         default: assert(0);
  1092.         case I915_TILING_NONE: return 0;
  1093.         case I915_TILING_X: return GEN6_SURFACE_TILED;
  1094.         case I915_TILING_Y: return GEN6_SURFACE_TILED | GEN6_SURFACE_TILED_Y;
  1095.         }
  1096. */
  1097. }
  1098.  
  1099. /**
  1100.  * Sets up the common fields for a surface state buffer for the given
  1101.  * picture in the given surface state buffer.
  1102.  */
  1103. static int
  1104. gen6_bind_bo(struct sna *sna,
  1105.          struct kgem_bo *bo,
  1106.              uint32_t width,
  1107.              uint32_t height,
  1108.              uint32_t format,
  1109.              Bool is_dst)
  1110. {
  1111.         uint32_t *ss;
  1112.         uint32_t domains;
  1113.         uint16_t offset;
  1114.  
  1115.         /* After the first bind, we manage the cache domains within the batch */
  1116.         if (is_dst) {
  1117.                 domains = I915_GEM_DOMAIN_RENDER << 16 |I915_GEM_DOMAIN_RENDER;
  1118. //       kgem_bo_mark_dirty(bo);
  1119.         } else
  1120.                 domains = I915_GEM_DOMAIN_SAMPLER << 16;
  1121.  
  1122. //   offset = kgem_bo_get_binding(bo, format);
  1123. //   if (offset) {
  1124. //        DBG(("[%x]  bo(handle=%x), format=%d, reuse %s binding\n",
  1125. //            offset, bo->handle, format,
  1126. //            domains & 0xffff ? "render" : "sampler"));
  1127. //       return offset;
  1128. //   }
  1129.  
  1130.         offset = sna->kgem.surface - sizeof(struct gen6_surface_state_padded) / sizeof(uint32_t);
  1131.         offset *= sizeof(uint32_t);
  1132.  
  1133.         sna->kgem.surface -=
  1134.                 sizeof(struct gen6_surface_state_padded) / sizeof(uint32_t);
  1135.         ss = sna->kgem.batch + sna->kgem.surface;
  1136.         ss[0] = (GEN6_SURFACE_2D << GEN6_SURFACE_TYPE_SHIFT |
  1137.                  GEN6_SURFACE_BLEND_ENABLED |
  1138.                  format << GEN6_SURFACE_FORMAT_SHIFT);
  1139.     ss[1] = bo->gaddr;
  1140.         ss[2] = ((width - 1)  << GEN6_SURFACE_WIDTH_SHIFT |
  1141.                  (height - 1) << GEN6_SURFACE_HEIGHT_SHIFT);
  1142.         assert(bo->pitch <= (1 << 18));
  1143.     ss[3] = (gen6_tiling_bits(0) |
  1144.                  (bo->pitch - 1) << GEN6_SURFACE_PITCH_SHIFT);
  1145.         ss[4] = 0;
  1146.         ss[5] = 0;
  1147.  
  1148. //   kgem_bo_set_binding(bo, format, offset);
  1149.  
  1150.         DBG(("[%x] bind bo(handle=%d, addr=%d), format=%d, width=%d, height=%d, pitch=%d, tiling=%d -> %s\n",
  1151.              offset, bo->handle, ss[1],
  1152.              format, width, height, bo->pitch, bo->tiling,
  1153.              domains & 0xffff ? "render" : "sampler"));
  1154.  
  1155.         return offset;
  1156. }
  1157.  
  1158.  
  1159. static void gen6_emit_vertex_buffer(struct sna *sna,
  1160.                                     const struct sna_composite_op *op)
  1161. {
  1162.         int id = op->u.gen6.ve_id;
  1163.  
  1164.         OUT_BATCH(GEN6_3DSTATE_VERTEX_BUFFERS | 3);
  1165.         OUT_BATCH(id << VB0_BUFFER_INDEX_SHIFT | VB0_VERTEXDATA |
  1166.                   4*op->floats_per_vertex << VB0_BUFFER_PITCH_SHIFT);
  1167.         sna->render.vertex_reloc[id] = sna->kgem.nbatch;
  1168.         OUT_BATCH(0);
  1169.         OUT_BATCH(0);
  1170.         OUT_BATCH(0);
  1171.  
  1172.         sna->render_state.gen6.vb_id |= 1 << id;
  1173. }
  1174.  
  1175. static void gen6_emit_primitive(struct sna *sna)
  1176. {
  1177.         if (sna->kgem.nbatch == sna->render_state.gen6.last_primitive) {
  1178.                 DBG(("%s: continuing previous primitive, start=%d, index=%d\n",
  1179.                      __FUNCTION__,
  1180.                      sna->render.vertex_start,
  1181.                      sna->render.vertex_index));
  1182.                 sna->render_state.gen6.vertex_offset = sna->kgem.nbatch - 5;
  1183.                 return;
  1184.         }
  1185.  
  1186.         OUT_BATCH(GEN6_3DPRIMITIVE |
  1187.                   GEN6_3DPRIMITIVE_VERTEX_SEQUENTIAL |
  1188.                   _3DPRIM_RECTLIST << GEN6_3DPRIMITIVE_TOPOLOGY_SHIFT |
  1189.                   0 << 9 |
  1190.                   4);
  1191.         sna->render_state.gen6.vertex_offset = sna->kgem.nbatch;
  1192.         OUT_BATCH(0);   /* vertex count, to be filled in later */
  1193.         OUT_BATCH(sna->render.vertex_index);
  1194.         OUT_BATCH(1);   /* single instance */
  1195.         OUT_BATCH(0);   /* start instance location */
  1196.         OUT_BATCH(0);   /* index buffer offset, ignored */
  1197.         sna->render.vertex_start = sna->render.vertex_index;
  1198.         DBG(("%s: started new primitive: index=%d\n",
  1199.              __FUNCTION__, sna->render.vertex_start));
  1200.  
  1201.         sna->render_state.gen6.last_primitive = sna->kgem.nbatch;
  1202. }
  1203.  
  1204. static bool gen6_rectangle_begin(struct sna *sna,
  1205.                                  const struct sna_composite_op *op)
  1206. {
  1207.         int id = 1 << op->u.gen6.ve_id;
  1208.         int ndwords;
  1209.  
  1210.         ndwords = op->need_magic_ca_pass ? 60 : 6;
  1211.         if ((sna->render_state.gen6.vb_id & id) == 0)
  1212.                 ndwords += 5;
  1213.         if (!kgem_check_batch(&sna->kgem, ndwords))
  1214.                 return false;
  1215.  
  1216.         if ((sna->render_state.gen6.vb_id & id) == 0)
  1217.                 gen6_emit_vertex_buffer(sna, op);
  1218.  
  1219.         gen6_emit_primitive(sna);
  1220.         return true;
  1221. }
  1222.  
  1223. static int gen6_get_rectangles__flush(struct sna *sna,
  1224.                                       const struct sna_composite_op *op)
  1225. {
  1226.         if (sna->render_state.gen6.vertex_offset) {
  1227.                 gen6_vertex_flush(sna);
  1228.                 gen6_magic_ca_pass(sna, op);
  1229.         }
  1230.  
  1231.         if (!kgem_check_batch(&sna->kgem, op->need_magic_ca_pass ? 65 : 5))
  1232.                 return 0;
  1233.         if (sna->kgem.nexec > KGEM_EXEC_SIZE(&sna->kgem) - 1)
  1234.                 return 0;
  1235.         if (sna->kgem.nreloc > KGEM_RELOC_SIZE(&sna->kgem) - 2)
  1236.                 return 0;
  1237.  
  1238.         return gen6_vertex_finish(sna);
  1239. }
  1240.  
  1241. inline static int gen6_get_rectangles(struct sna *sna,
  1242.                                       const struct sna_composite_op *op,
  1243.                                       int want)
  1244. {
  1245.         int rem = vertex_space(sna);
  1246.  
  1247.         if (rem < op->floats_per_rect) {
  1248.                 DBG(("flushing vbo for %s: %d < %d\n",
  1249.                      __FUNCTION__, rem, op->floats_per_rect));
  1250.                 rem = gen6_get_rectangles__flush(sna, op);
  1251.                 if (rem == 0)
  1252.                         return 0;
  1253.         }
  1254.  
  1255.         if (sna->render_state.gen6.vertex_offset == 0 &&
  1256.             !gen6_rectangle_begin(sna, op))
  1257.                 return 0;
  1258.  
  1259.         if (want > 1 && want * op->floats_per_rect > rem)
  1260.                 want = rem / op->floats_per_rect;
  1261.  
  1262.         assert(want > 0);
  1263.         sna->render.vertex_index += 3*want;
  1264.         return want;
  1265. }
  1266.  
  1267. inline static uint32_t *gen6_composite_get_binding_table(struct sna *sna,
  1268.                                                          uint16_t *offset)
  1269. {
  1270.         uint32_t *table;
  1271.  
  1272.         sna->kgem.surface -=
  1273.                 sizeof(struct gen6_surface_state_padded) / sizeof(uint32_t);
  1274.         /* Clear all surplus entries to zero in case of prefetch */
  1275.         table = memset(sna->kgem.batch + sna->kgem.surface,
  1276.                        0, sizeof(struct gen6_surface_state_padded));
  1277.  
  1278.         DBG(("%s(%x)\n", __FUNCTION__, 4*sna->kgem.surface));
  1279.  
  1280.         *offset = sna->kgem.surface;
  1281.         return table;
  1282. }
  1283.  
  1284. static uint32_t
  1285. gen6_choose_composite_vertex_buffer(const struct sna_composite_op *op)
  1286. {
  1287.         int has_mask = op->mask.bo != NULL;
  1288.         int is_affine = op->is_affine;
  1289.         return has_mask << 1 | is_affine;
  1290. }
  1291.  
  1292. static void
  1293. gen6_get_batch(struct sna *sna)
  1294. {
  1295.         kgem_set_mode(&sna->kgem, KGEM_RENDER);
  1296. /*
  1297.         if (!kgem_check_batch_with_surfaces(&sna->kgem, 150, 4)) {
  1298.                 DBG(("%s: flushing batch: %d < %d+%d\n",
  1299.                      __FUNCTION__, sna->kgem.surface - sna->kgem.nbatch,
  1300.                      150, 4*8));
  1301.                 kgem_submit(&sna->kgem);
  1302.                 _kgem_set_mode(&sna->kgem, KGEM_RENDER);
  1303.         }
  1304. */
  1305.  
  1306.         if (sna->render_state.gen6.needs_invariant)
  1307.                 gen6_emit_invariant(sna);
  1308. }
  1309.  
  1310. static void gen6_emit_composite_state(struct sna *sna,
  1311.                       const struct sna_composite_op *op)
  1312. {
  1313.     uint32_t *binding_table;
  1314.     uint16_t offset;
  1315.     bool dirty;
  1316.  
  1317.     gen6_get_batch(sna);
  1318.     dirty = FALSE;
  1319.  
  1320.     binding_table = gen6_composite_get_binding_table(sna, &offset);
  1321.  
  1322.     binding_table[0] =
  1323.         gen6_bind_bo(sna,
  1324.                 op->dst.bo, op->dst.width, op->dst.height,
  1325.                 op->dst.format,
  1326.                 TRUE);
  1327.     binding_table[1] =
  1328.         gen6_bind_bo(sna,
  1329.                  op->src.bo, op->src.width, op->src.height,
  1330.                  op->src.card_format,
  1331.                  FALSE);
  1332.     if (op->mask.bo) {
  1333.         binding_table[2] =
  1334.             gen6_bind_bo(sna,
  1335.                      op->mask.bo,
  1336.                      op->mask.width,
  1337.                      op->mask.height,
  1338.                      op->mask.card_format,
  1339.                      FALSE);
  1340.     }
  1341.  
  1342.     if (sna->kgem.surface == offset &&
  1343.         *(uint64_t *)(sna->kgem.batch + sna->render_state.gen6.surface_table) == *(uint64_t*)binding_table &&
  1344.         (op->mask.bo == NULL ||
  1345.          sna->kgem.batch[sna->render_state.gen6.surface_table+2] == binding_table[2])) {
  1346.         sna->kgem.surface += sizeof(struct gen6_surface_state_padded) / sizeof(uint32_t);
  1347.         offset = sna->render_state.gen6.surface_table;
  1348.     }
  1349.  
  1350.     gen6_emit_state(sna, op, offset | dirty);
  1351. }
  1352.  
  1353.  
  1354.  
  1355. static void
  1356. gen6_align_vertex(struct sna *sna, const struct sna_composite_op *op)
  1357. {
  1358.         assert (sna->render_state.gen6.vertex_offset == 0);
  1359.         if (op->floats_per_vertex != sna->render_state.gen6.floats_per_vertex) {
  1360.                 if (sna->render.vertex_size - sna->render.vertex_used < 2*op->floats_per_rect)
  1361.                         /* XXX propagate failure */
  1362.                         gen6_vertex_finish(sna);
  1363.  
  1364.                 DBG(("aligning vertex: was %d, now %d floats per vertex, %d->%d\n",
  1365.                      sna->render_state.gen6.floats_per_vertex,
  1366.                      op->floats_per_vertex,
  1367.                      sna->render.vertex_index,
  1368.                      (sna->render.vertex_used + op->floats_per_vertex - 1) / op->floats_per_vertex));
  1369.                 sna->render.vertex_index = (sna->render.vertex_used + op->floats_per_vertex - 1) / op->floats_per_vertex;
  1370.                 sna->render.vertex_used = sna->render.vertex_index * op->floats_per_vertex;
  1371.                 sna->render_state.gen6.floats_per_vertex = op->floats_per_vertex;
  1372.         }
  1373. }
  1374.  
  1375.  
  1376. #ifndef MAX
  1377. #define MAX(a,b) ((a) > (b) ? (a) : (b))
  1378. #endif
  1379.  
  1380. static uint32_t
  1381. gen6_composite_create_blend_state(struct sna_static_stream *stream)
  1382. {
  1383.         char *base, *ptr;
  1384.         int src, dst;
  1385.  
  1386.         base = sna_static_stream_map(stream,
  1387.                                      GEN6_BLENDFACTOR_COUNT * GEN6_BLENDFACTOR_COUNT * GEN6_BLEND_STATE_PADDED_SIZE,
  1388.                                      64);
  1389.  
  1390.         ptr = base;
  1391.         for (src = 0; src < GEN6_BLENDFACTOR_COUNT; src++) {
  1392.                 for (dst= 0; dst < GEN6_BLENDFACTOR_COUNT; dst++) {
  1393.                         struct gen6_blend_state *blend =
  1394.                                 (struct gen6_blend_state *)ptr;
  1395.  
  1396.                         blend->blend0.dest_blend_factor = dst;
  1397.                         blend->blend0.source_blend_factor = src;
  1398.                         blend->blend0.blend_func = GEN6_BLENDFUNCTION_ADD;
  1399.                         blend->blend0.blend_enable =
  1400.                                 !(dst == GEN6_BLENDFACTOR_ZERO && src == GEN6_BLENDFACTOR_ONE);
  1401.  
  1402.                         blend->blend1.post_blend_clamp_enable = 1;
  1403.                         blend->blend1.pre_blend_clamp_enable = 1;
  1404.  
  1405.                         ptr += GEN6_BLEND_STATE_PADDED_SIZE;
  1406.                 }
  1407.         }
  1408.  
  1409.         return sna_static_stream_offsetof(stream, base);
  1410. }
  1411.  
  1412. #if 0
  1413. static uint32_t gen6_bind_video_source(struct sna *sna,
  1414.                                        struct kgem_bo *src_bo,
  1415.                                        uint32_t src_offset,
  1416.                                        int src_width,
  1417.                                        int src_height,
  1418.                                        int src_pitch,
  1419.                                        uint32_t src_surf_format)
  1420. {
  1421.         struct gen6_surface_state *ss;
  1422.  
  1423.         sna->kgem.surface -= sizeof(struct gen6_surface_state_padded) / sizeof(uint32_t);
  1424.  
  1425.         ss = memset(sna->kgem.batch + sna->kgem.surface, 0, sizeof(*ss));
  1426.         ss->ss0.surface_type = GEN6_SURFACE_2D;
  1427.         ss->ss0.surface_format = src_surf_format;
  1428.  
  1429.         ss->ss1.base_addr =
  1430.                 kgem_add_reloc(&sna->kgem,
  1431.                                sna->kgem.surface + 1,
  1432.                                src_bo,
  1433.                                I915_GEM_DOMAIN_SAMPLER << 16,
  1434.                                src_offset);
  1435.  
  1436.         ss->ss2.width  = src_width - 1;
  1437.         ss->ss2.height = src_height - 1;
  1438.         ss->ss3.pitch  = src_pitch - 1;
  1439.  
  1440.         return sna->kgem.surface * sizeof(uint32_t);
  1441. }
  1442.  
  1443. static void gen6_emit_video_state(struct sna *sna,
  1444.                                   struct sna_composite_op *op,
  1445.                                   struct sna_video_frame *frame)
  1446. {
  1447.         uint32_t src_surf_format;
  1448.         uint32_t src_surf_base[6];
  1449.         int src_width[6];
  1450.         int src_height[6];
  1451.         int src_pitch[6];
  1452.         uint32_t *binding_table;
  1453.         uint16_t offset;
  1454.         bool dirty;
  1455.         int n_src, n;
  1456.  
  1457.         gen6_get_batch(sna);
  1458.         dirty = kgem_bo_is_dirty(op->dst.bo);
  1459.  
  1460.         src_surf_base[0] = 0;
  1461.         src_surf_base[1] = 0;
  1462.         src_surf_base[2] = frame->VBufOffset;
  1463.         src_surf_base[3] = frame->VBufOffset;
  1464.         src_surf_base[4] = frame->UBufOffset;
  1465.         src_surf_base[5] = frame->UBufOffset;
  1466.  
  1467.         if (is_planar_fourcc(frame->id)) {
  1468.                 src_surf_format = GEN6_SURFACEFORMAT_R8_UNORM;
  1469.                 src_width[1]  = src_width[0]  = frame->width;
  1470.                 src_height[1] = src_height[0] = frame->height;
  1471.                 src_pitch[1]  = src_pitch[0]  = frame->pitch[1];
  1472.                 src_width[4]  = src_width[5]  = src_width[2]  = src_width[3] =
  1473.                         frame->width / 2;
  1474.                 src_height[4] = src_height[5] = src_height[2] = src_height[3] =
  1475.                         frame->height / 2;
  1476.                 src_pitch[4]  = src_pitch[5]  = src_pitch[2]  = src_pitch[3] =
  1477.                         frame->pitch[0];
  1478.                 n_src = 6;
  1479.         } else {
  1480.                 if (frame->id == FOURCC_UYVY)
  1481.                         src_surf_format = GEN6_SURFACEFORMAT_YCRCB_SWAPY;
  1482.                 else
  1483.                         src_surf_format = GEN6_SURFACEFORMAT_YCRCB_NORMAL;
  1484.  
  1485.                 src_width[0]  = frame->width;
  1486.                 src_height[0] = frame->height;
  1487.                 src_pitch[0]  = frame->pitch[0];
  1488.                 n_src = 1;
  1489.         }
  1490.  
  1491.         binding_table = gen6_composite_get_binding_table(sna, &offset);
  1492.  
  1493.         binding_table[0] =
  1494.                 gen6_bind_bo(sna,
  1495.                              op->dst.bo, op->dst.width, op->dst.height,
  1496.                              gen6_get_dest_format(op->dst.format),
  1497.                              TRUE);
  1498.         for (n = 0; n < n_src; n++) {
  1499.                 binding_table[1+n] =
  1500.                         gen6_bind_video_source(sna,
  1501.                                                frame->bo,
  1502.                                                src_surf_base[n],
  1503.                                                src_width[n],
  1504.                                                src_height[n],
  1505.                                                src_pitch[n],
  1506.                                                src_surf_format);
  1507.         }
  1508.  
  1509.         gen6_emit_state(sna, op, offset | dirty);
  1510. }
  1511.  
  1512. static Bool
  1513. gen6_render_video(struct sna *sna,
  1514.                   struct sna_video *video,
  1515.                   struct sna_video_frame *frame,
  1516.                   RegionPtr dstRegion,
  1517.                   short src_w, short src_h,
  1518.                   short drw_w, short drw_h,
  1519.                   PixmapPtr pixmap)
  1520. {
  1521.         struct sna_composite_op tmp;
  1522.         int nbox, dxo, dyo, pix_xoff, pix_yoff;
  1523.         float src_scale_x, src_scale_y;
  1524.         struct sna_pixmap *priv;
  1525.         BoxPtr box;
  1526.  
  1527.         DBG(("%s: src=(%d, %d), dst=(%d, %d), %dx[(%d, %d), (%d, %d)...]\n",
  1528.              __FUNCTION__, src_w, src_h, drw_w, drw_h,
  1529.              REGION_NUM_RECTS(dstRegion),
  1530.              REGION_EXTENTS(NULL, dstRegion)->x1,
  1531.              REGION_EXTENTS(NULL, dstRegion)->y1,
  1532.              REGION_EXTENTS(NULL, dstRegion)->x2,
  1533.              REGION_EXTENTS(NULL, dstRegion)->y2));
  1534.  
  1535.         priv = sna_pixmap_force_to_gpu(pixmap, MOVE_READ | MOVE_WRITE);
  1536.         if (priv == NULL)
  1537.                 return FALSE;
  1538.  
  1539.         memset(&tmp, 0, sizeof(tmp));
  1540.  
  1541.         tmp.op = PictOpSrc;
  1542.         tmp.dst.pixmap = pixmap;
  1543.         tmp.dst.width  = pixmap->drawable.width;
  1544.         tmp.dst.height = pixmap->drawable.height;
  1545.         tmp.dst.format = sna_render_format_for_depth(pixmap->drawable.depth);
  1546.         tmp.dst.bo = priv->gpu_bo;
  1547.  
  1548.         tmp.src.bo = frame->bo;
  1549.         tmp.src.filter = SAMPLER_FILTER_BILINEAR;
  1550.         tmp.src.repeat = SAMPLER_EXTEND_PAD;
  1551.  
  1552.         tmp.mask.bo = NULL;
  1553.  
  1554.         tmp.is_affine = TRUE;
  1555.         tmp.floats_per_vertex = 3;
  1556.         tmp.floats_per_rect = 9;
  1557.  
  1558.         if (is_planar_fourcc(frame->id)) {
  1559.                 tmp.u.gen6.wm_kernel = GEN6_WM_KERNEL_VIDEO_PLANAR;
  1560.                 tmp.u.gen6.nr_surfaces = 7;
  1561.         } else {
  1562.                 tmp.u.gen6.wm_kernel = GEN6_WM_KERNEL_VIDEO_PACKED;
  1563.                 tmp.u.gen6.nr_surfaces = 2;
  1564.         }
  1565.         tmp.u.gen6.nr_inputs = 1;
  1566.         tmp.u.gen6.ve_id = 1;
  1567.  
  1568.         kgem_set_mode(&sna->kgem, KGEM_RENDER);
  1569.         if (!kgem_check_bo(&sna->kgem, tmp.dst.bo, frame->bo, NULL)) {
  1570.                 kgem_submit(&sna->kgem);
  1571.                 assert(kgem_check_bo(&sna->kgem, tmp.dst.bo, frame->bo, NULL));
  1572.                 _kgem_set_mode(&sna->kgem, KGEM_RENDER);
  1573.         }
  1574.  
  1575.         gen6_emit_video_state(sna, &tmp, frame);
  1576.         gen6_align_vertex(sna, &tmp);
  1577.  
  1578.         /* Set up the offset for translating from the given region (in screen
  1579.          * coordinates) to the backing pixmap.
  1580.          */
  1581. #ifdef COMPOSITE
  1582.         pix_xoff = -pixmap->screen_x + pixmap->drawable.x;
  1583.         pix_yoff = -pixmap->screen_y + pixmap->drawable.y;
  1584. #else
  1585.         pix_xoff = 0;
  1586.         pix_yoff = 0;
  1587. #endif
  1588.  
  1589.         dxo = dstRegion->extents.x1;
  1590.         dyo = dstRegion->extents.y1;
  1591.  
  1592.         /* Use normalized texture coordinates */
  1593.         src_scale_x = ((float)src_w / frame->width) / (float)drw_w;
  1594.         src_scale_y = ((float)src_h / frame->height) / (float)drw_h;
  1595.  
  1596.         box = REGION_RECTS(dstRegion);
  1597.         nbox = REGION_NUM_RECTS(dstRegion);
  1598.         while (nbox--) {
  1599.                 BoxRec r;
  1600.  
  1601.                 r.x1 = box->x1 + pix_xoff;
  1602.                 r.x2 = box->x2 + pix_xoff;
  1603.                 r.y1 = box->y1 + pix_yoff;
  1604.                 r.y2 = box->y2 + pix_yoff;
  1605.  
  1606.                 if (unlikely(!gen6_get_rectangles(sna, &tmp, 1))) {
  1607.                         _kgem_submit(&sna->kgem);
  1608.                         gen6_emit_video_state(sna, &tmp, frame);
  1609.                         gen6_get_rectangles(sna, &tmp, 1);
  1610.                 }
  1611.  
  1612.                 OUT_VERTEX(r.x2, r.y2);
  1613.                 OUT_VERTEX_F((box->x2 - dxo) * src_scale_x);
  1614.                 OUT_VERTEX_F((box->y2 - dyo) * src_scale_y);
  1615.  
  1616.                 OUT_VERTEX(r.x1, r.y2);
  1617.                 OUT_VERTEX_F((box->x1 - dxo) * src_scale_x);
  1618.                 OUT_VERTEX_F((box->y2 - dyo) * src_scale_y);
  1619.  
  1620.                 OUT_VERTEX(r.x1, r.y1);
  1621.                 OUT_VERTEX_F((box->x1 - dxo) * src_scale_x);
  1622.                 OUT_VERTEX_F((box->y1 - dyo) * src_scale_y);
  1623.  
  1624.                 if (!DAMAGE_IS_ALL(priv->gpu_damage)) {
  1625.                         sna_damage_add_box(&priv->gpu_damage, &r);
  1626.                         sna_damage_subtract_box(&priv->cpu_damage, &r);
  1627.                 }
  1628.                 box++;
  1629.         }
  1630.         priv->clear = false;
  1631.  
  1632.         gen6_vertex_flush(sna);
  1633.         return TRUE;
  1634. }
  1635.  
  1636. #endif
  1637.  
  1638.  
  1639. fastcall static void
  1640. gen6_emit_composite_primitive_identity_source_mask(struct sna *sna,
  1641.                            const struct sna_composite_op *op,
  1642.                            const struct sna_composite_rectangles *r)
  1643. {
  1644.     union {
  1645.         struct sna_coordinate p;
  1646.         float f;
  1647.     } dst;
  1648.     float src_x, src_y;
  1649.     float msk_x, msk_y;
  1650.     float w, h;
  1651.     float *v;
  1652.  
  1653.     src_x = r->src.x + op->src.offset[0];
  1654.     src_y = r->src.y + op->src.offset[1];
  1655.     msk_x = r->mask.x + op->mask.offset[0];
  1656.     msk_y = r->mask.y + op->mask.offset[1];
  1657.     w = r->width;
  1658.     h = r->height;
  1659.  
  1660.     v = sna->render.vertices + sna->render.vertex_used;
  1661.     sna->render.vertex_used += 15;
  1662.  
  1663.     dst.p.x = r->dst.x + r->width;
  1664.     dst.p.y = r->dst.y + r->height;
  1665.     v[0] = dst.f;
  1666.     v[1] = (src_x + w) * op->src.scale[0];
  1667.     v[2] = (src_y + h) * op->src.scale[1];
  1668.     v[3] = (msk_x + w) * op->mask.scale[0];
  1669.     v[4] = (msk_y + h) * op->mask.scale[1];
  1670.  
  1671.     dst.p.x = r->dst.x;
  1672.     v[5] = dst.f;
  1673.     v[6] = src_x * op->src.scale[0];
  1674.     v[7] = v[2];
  1675.     v[8] = msk_x * op->mask.scale[0];
  1676.     v[9] = v[4];
  1677.  
  1678.     dst.p.y = r->dst.y;
  1679.     v[10] = dst.f;
  1680.     v[11] = v[6];
  1681.     v[12] = src_y * op->src.scale[1];
  1682.     v[13] = v[8];
  1683.     v[14] = msk_y * op->mask.scale[1];
  1684. }
  1685.  
  1686. fastcall static void
  1687. gen6_render_composite_box(struct sna *sna,
  1688.               const struct sna_composite_op *op,
  1689.               const BoxRec *box)
  1690. {
  1691.     struct sna_composite_rectangles r;
  1692.  
  1693.     if (unlikely(!gen6_get_rectangles(sna, op, 1))) {
  1694. //        _kgem_submit(&sna->kgem);
  1695. //        gen6_emit_composite_state(sna, op);
  1696. //        gen6_get_rectangles(sna, op, 1);
  1697.     }
  1698.  
  1699.     DBG(("  %s: (%d, %d), (%d, %d)\n",
  1700.          __FUNCTION__,
  1701.          box->x1, box->y1, box->x2, box->y2));
  1702.  
  1703.     r.dst.x = box->x1;
  1704.     r.dst.y = box->y1;
  1705.     r.width  = box->x2 - box->x1;
  1706.     r.height = box->y2 - box->y1;
  1707.     r.src = r.mask = r.dst;
  1708.  
  1709.     op->prim_emit(sna, op, &r);
  1710. }
  1711.  
  1712.  
  1713. static void gen6_render_composite_done(struct sna *sna,
  1714.                        const struct sna_composite_op *op)
  1715. {
  1716.     DBG(("%s\n", __FUNCTION__));
  1717.  
  1718.     if (sna->render_state.gen6.vertex_offset) {
  1719.         gen6_vertex_flush(sna);
  1720.         gen6_magic_ca_pass(sna, op);
  1721.     }
  1722.  
  1723. //   if (op->mask.bo)
  1724. //       kgem_bo_destroy(&sna->kgem, op->mask.bo);
  1725. //   if (op->src.bo)
  1726. //       kgem_bo_destroy(&sna->kgem, op->src.bo);
  1727.  
  1728. //   sna_render_composite_redirect_done(sna, op);
  1729. }
  1730.  
  1731.  
  1732. static Bool
  1733. gen6_render_composite(struct sna *sna,
  1734.               uint8_t op,
  1735.               bitmap_t *src,
  1736.               struct kgem_bo *src_bo,
  1737.               bitmap_t *mask,
  1738.               struct kgem_bo *mask_bo,
  1739.               bitmap_t *dst,
  1740.               struct kgem_bo *dst_bo,
  1741.               int16_t src_x, int16_t src_y,
  1742.               int16_t msk_x, int16_t msk_y,
  1743.               int16_t dst_x, int16_t dst_y,
  1744.               int16_t width, int16_t height,
  1745.               struct sna_composite_op *tmp)
  1746. {
  1747. //    if (op >= ARRAY_SIZE(gen6_blend_op))
  1748. //        return FALSE;
  1749.  
  1750. //    ENTER();
  1751.  
  1752.     DBG(("%s: %dx%d, current mode=%d\n", __FUNCTION__,
  1753.          width, height, sna->kgem.ring));
  1754.  
  1755.     tmp->op = PictOpSrc;
  1756.  
  1757.     tmp->dst.bo     = dst_bo;
  1758.     tmp->dst.width  = dst->width;
  1759.     tmp->dst.height = dst->height;
  1760.     tmp->dst.format = GEN6_SURFACEFORMAT_B8G8R8A8_UNORM;
  1761.  
  1762.  
  1763.     tmp->src.bo = src_bo;
  1764.     tmp->src.card_format = GEN6_SURFACEFORMAT_B8G8R8A8_UNORM;
  1765.     tmp->src.width  = src->width;
  1766.     tmp->src.height = src->height;
  1767.  
  1768.     tmp->src.scale[0] = 1.f/width;            //src->width;
  1769.     tmp->src.scale[1] = 1.f/height;            //src->height;
  1770.     tmp->src.filter = SAMPLER_FILTER_BILINEAR;
  1771.     tmp->src.repeat = SAMPLER_EXTEND_NONE;
  1772.     tmp->src.offset[0] = -dst_x;
  1773.     tmp->src.offset[1] = -dst_y;
  1774.     tmp->src.is_affine = TRUE;
  1775.  
  1776.  
  1777.     tmp->mask.bo = mask_bo;
  1778.     tmp->mask.card_format = GEN6_SURFACEFORMAT_A8_UNORM;
  1779.     tmp->mask.width  = mask->width;
  1780.     tmp->mask.height = mask->height;
  1781.  
  1782.     tmp->mask.scale[0] = 1.f/mask->width;
  1783.     tmp->mask.scale[1] = 1.f/mask->height;
  1784.     tmp->mask.filter = SAMPLER_FILTER_NEAREST;
  1785.     tmp->mask.repeat = SAMPLER_EXTEND_NONE;
  1786.     tmp->mask.offset[0] = -dst_x;
  1787.     tmp->mask.offset[1] = -dst_y;
  1788.     tmp->mask.is_affine = TRUE;
  1789.  
  1790.     tmp->is_affine = TRUE;
  1791.     tmp->has_component_alpha = FALSE;
  1792.     tmp->need_magic_ca_pass = FALSE;
  1793.  
  1794.     tmp->prim_emit = gen6_emit_composite_primitive_identity_source_mask;
  1795.  
  1796.     tmp->floats_per_vertex = 5 + 2 * !tmp->is_affine;
  1797.  
  1798.     tmp->floats_per_rect = 3 * tmp->floats_per_vertex;
  1799.  
  1800.     tmp->u.gen6.wm_kernel = GEN6_WM_KERNEL_MASK;
  1801.     tmp->u.gen6.nr_surfaces = 2 + 1;
  1802.     tmp->u.gen6.nr_inputs = 1 + 1;
  1803.     tmp->u.gen6.ve_id = gen6_choose_composite_vertex_buffer(tmp);
  1804.  
  1805.     tmp->need_magic_ca_pass = TRUE;
  1806.  
  1807. //    tmp->blt   = gen6_render_composite_blt;
  1808.     tmp->box   = gen6_render_composite_box;
  1809. //    tmp->boxes = gen6_render_composite_boxes;
  1810.     tmp->done  = gen6_render_composite_done;
  1811.  
  1812.     gen6_emit_composite_state(sna, tmp);
  1813.     gen6_align_vertex(sna, tmp);
  1814.  
  1815. //    LEAVE();
  1816.  
  1817.     return TRUE;
  1818. }
  1819.  
  1820.  
  1821. static void
  1822. gen6_emit_copy_state(struct sna *sna,
  1823.                      const struct sna_composite_op *op)
  1824. {
  1825.         uint32_t *binding_table;
  1826.         uint16_t offset;
  1827.         bool dirty;
  1828.  
  1829.         gen6_get_batch(sna);
  1830.  
  1831.         binding_table = gen6_composite_get_binding_table(sna, &offset);
  1832.  
  1833.         binding_table[0] =
  1834.                 gen6_bind_bo(sna,
  1835.                              op->dst.bo, op->dst.width, op->dst.height,
  1836.                  GEN6_SURFACEFORMAT_B8G8R8A8_UNORM,
  1837.                              TRUE);
  1838.         binding_table[1] =
  1839.                 gen6_bind_bo(sna,
  1840.                              op->src.bo, op->src.width, op->src.height,
  1841.                  GEN6_SURFACEFORMAT_B8G8R8A8_UNORM,
  1842.                              FALSE);
  1843.  
  1844.         if (sna->kgem.surface == offset &&
  1845.             *(uint64_t *)(sna->kgem.batch + sna->render_state.gen6.surface_table) == *(uint64_t*)binding_table) {
  1846.                 sna->kgem.surface += sizeof(struct gen6_surface_state_padded) / sizeof(uint32_t);
  1847.                 offset = sna->render_state.gen6.surface_table;
  1848.         }
  1849.  
  1850.         gen6_emit_state(sna, op, offset | dirty);
  1851. }
  1852.  
  1853.  
  1854. static void
  1855. gen6_render_copy_blt(struct sna *sna,
  1856.              const struct sna_composite_op *op,
  1857.                      int16_t sx, int16_t sy,
  1858.                      int16_t w,  int16_t h,
  1859.                      int16_t dx, int16_t dy)
  1860. {
  1861.     if (unlikely(!gen6_get_rectangles(sna, op, 1))) {
  1862. //       _kgem_submit(&sna->kgem);
  1863.         gen6_emit_copy_state(sna, op);
  1864.         gen6_get_rectangles(sna, op, 1);
  1865.         }
  1866.  
  1867.         OUT_VERTEX(dx+w, dy+h);
  1868.     OUT_VERTEX_F((sx+w)*op->src.scale[0]);
  1869.     OUT_VERTEX_F((sy+h)*op->src.scale[1]);
  1870.  
  1871.         OUT_VERTEX(dx, dy+h);
  1872.     OUT_VERTEX_F(sx*op->src.scale[0]);
  1873.     OUT_VERTEX_F((sy+h)*op->src.scale[1]);
  1874.  
  1875.         OUT_VERTEX(dx, dy);
  1876.     OUT_VERTEX_F(sx*op->src.scale[0]);
  1877.     OUT_VERTEX_F(sy*op->src.scale[1]);
  1878. }
  1879.  
  1880. static void
  1881. gen6_render_copy_done(struct sna *sna)
  1882. {
  1883.         DBG(("%s()\n", __FUNCTION__));
  1884.  
  1885.         if (sna->render_state.gen6.vertex_offset)
  1886.                 gen6_vertex_flush(sna);
  1887. }
  1888.  
  1889. static Bool
  1890. gen6_render_copy(struct sna *sna, uint8_t alu,
  1891.          bitmap_t *src, struct kgem_bo *src_bo,
  1892.          bitmap_t *dst, struct kgem_bo *dst_bo,
  1893.          int dst_x, int dst_y, int src_x, int src_y, int w, int h)
  1894. {
  1895.     struct sna_composite_op op;
  1896.  
  1897.     memset(&op, 0, sizeof(op));
  1898.  
  1899.         DBG(("%s (alu=%d, src=(%dx%d), dst=(%dx%d))\n",
  1900.              __FUNCTION__, alu,
  1901.          src->width, src->height,
  1902.          dst->width, dst->height));
  1903.  
  1904. //    printf("%s %dx%d  src=(%dx%d), dst=(%dx%d)\n",
  1905. //         __FUNCTION__,dst_x, dst_y,
  1906. //         src->width, src->height,
  1907. //         dst->width, dst->height);
  1908.  
  1909.     op.dst.format = 0;
  1910.     op.src.pict_format = 0;
  1911.  
  1912.     op.op = PictOpSrc;
  1913.  
  1914.     op.dst.pixmap = dst;
  1915.     op.dst.width  = dst->width;
  1916.     op.dst.height = dst->height;
  1917.     op.dst.bo = dst_bo;
  1918.  
  1919.     op.src.bo = src_bo;
  1920.     op.src.card_format = GEN6_SURFACEFORMAT_B8G8R8X8_UNORM;
  1921.     op.src.width  = src->width;
  1922.     op.src.height = src->height;
  1923.  
  1924.     op.src.scale[0] = 1.f/w;            //src->width;
  1925.     op.src.scale[1] = 1.f/h;            //src->height;
  1926.     op.src.filter = SAMPLER_FILTER_BILINEAR;
  1927.     op.src.repeat = SAMPLER_EXTEND_NONE;
  1928.  
  1929.     op.mask.bo = NULL;
  1930.  
  1931.     op.is_affine = true;
  1932.     op.floats_per_vertex = 3;
  1933.     op.floats_per_rect = 9;
  1934.  
  1935.     op.u.gen6.wm_kernel = GEN6_WM_KERNEL_NOMASK;
  1936.     op.u.gen6.nr_surfaces = 2;
  1937.     op.u.gen6.nr_inputs = 1;
  1938.     op.u.gen6.ve_id = 1;
  1939.  
  1940.     gen6_emit_copy_state(sna, &op);
  1941.     gen6_align_vertex(sna, &op);
  1942.  
  1943.     gen6_render_copy_blt(sna, &op, src_x, src_y, w, h, dst_x, dst_y);
  1944.     gen6_render_copy_done(sna);
  1945.  
  1946.         return TRUE;
  1947. }
  1948.  
  1949. static void
  1950. gen6_emit_fill_state(struct sna *sna, const struct sna_composite_op *op)
  1951. {
  1952.         uint32_t *binding_table;
  1953.         uint16_t offset;
  1954.         bool dirty;
  1955.  
  1956.         gen6_get_batch(sna);
  1957. //   dirty = kgem_bo_is_dirty(op->dst.bo);
  1958.  
  1959.         binding_table = gen6_composite_get_binding_table(sna, &offset);
  1960.  
  1961.         binding_table[0] =
  1962.                 gen6_bind_bo(sna,
  1963.                  op->dst.bo, 1024, 768,
  1964.                  GEN6_SURFACEFORMAT_B8G8R8A8_UNORM,
  1965.                              TRUE);
  1966.         binding_table[1] =
  1967.                 gen6_bind_bo(sna,
  1968.                              op->src.bo, 1, 1,
  1969.                              GEN6_SURFACEFORMAT_B8G8R8A8_UNORM,
  1970.                              FALSE);
  1971.  
  1972.         if (sna->kgem.surface == offset &&
  1973.             *(uint64_t *)(sna->kgem.batch + sna->render_state.gen6.surface_table) == *(uint64_t*)binding_table) {
  1974.                 sna->kgem.surface +=
  1975.                         sizeof(struct gen6_surface_state_padded)/sizeof(uint32_t);
  1976.                 offset = sna->render_state.gen6.surface_table;
  1977.         }
  1978.  
  1979.         gen6_emit_state(sna, op, offset | dirty);
  1980. }
  1981.  
  1982.  
  1983. static Bool
  1984. gen6_render_clear(struct sna *sna, bitmap_t *dst, struct kgem_bo *bo)
  1985. {
  1986.         struct sna_composite_op tmp;
  1987.  
  1988.  
  1989.         DBG(("%s: %dx%d\n",
  1990.              __FUNCTION__,
  1991.          dst->width,
  1992.          dst->height));
  1993.  
  1994.         tmp.op = PictOpSrc;
  1995.  
  1996.         tmp.dst.pixmap = dst;
  1997.     tmp.dst.width  = dst->width;
  1998.     tmp.dst.height = dst->height;
  1999.     tmp.dst.format = 0; //PICT_a8r8g8b8;
  2000.         tmp.dst.bo = bo;
  2001.         tmp.dst.x = tmp.dst.y = 0;
  2002.  
  2003. //   tmp.src.bo = sna_render_get_solid(sna, 0);
  2004.     tmp.src.bo     = bo;
  2005.         tmp.src.filter = SAMPLER_FILTER_NEAREST;
  2006.         tmp.src.repeat = SAMPLER_EXTEND_REPEAT;
  2007.  
  2008.         tmp.mask.bo = NULL;
  2009.         tmp.mask.filter = SAMPLER_FILTER_NEAREST;
  2010.         tmp.mask.repeat = SAMPLER_EXTEND_NONE;
  2011.  
  2012.         tmp.is_affine = TRUE;
  2013.         tmp.floats_per_vertex = 3;
  2014.         tmp.floats_per_rect = 9;
  2015.         tmp.has_component_alpha = 0;
  2016.         tmp.need_magic_ca_pass = FALSE;
  2017.  
  2018.         tmp.u.gen6.wm_kernel = GEN6_WM_KERNEL_NOMASK;
  2019.         tmp.u.gen6.nr_surfaces = 2;
  2020.         tmp.u.gen6.nr_inputs = 1;
  2021.         tmp.u.gen6.ve_id = 1;
  2022.  
  2023. //   if (!kgem_check_bo(&sna->kgem, bo, NULL)) {
  2024. //       _kgem_submit(&sna->kgem);
  2025. //       assert(kgem_check_bo(&sna->kgem, bo, NULL));
  2026. //   }
  2027.  
  2028.         gen6_emit_fill_state(sna, &tmp);
  2029.         gen6_align_vertex(sna, &tmp);
  2030.  
  2031.         if (unlikely(!gen6_get_rectangles(sna, &tmp, 1))) {
  2032. //       _kgem_submit(&sna->kgem);
  2033.                 gen6_emit_fill_state(sna, &tmp);
  2034.                 gen6_get_rectangles(sna, &tmp, 1);
  2035.         }
  2036.  
  2037.     OUT_VERTEX(dst->width, dst->height);
  2038.         OUT_VERTEX_F(1);
  2039.         OUT_VERTEX_F(1);
  2040.  
  2041.     OUT_VERTEX(0, dst->height);
  2042.         OUT_VERTEX_F(0);
  2043.         OUT_VERTEX_F(1);
  2044.  
  2045.         OUT_VERTEX(0, 0);
  2046.         OUT_VERTEX_F(0);
  2047.         OUT_VERTEX_F(0);
  2048.  
  2049.     gen6_vertex_flush(sna);
  2050. //   kgem_bo_destroy(&sna->kgem, tmp.src.bo);
  2051. //    gen6_render_composite_done(sna, &tmp);
  2052. //    _kgem_submit(&sna->kgem);
  2053.  
  2054.         return TRUE;
  2055. }
  2056.  
  2057. static void gen6_render_flush(struct sna *sna)
  2058. {
  2059.         gen6_vertex_close(sna);
  2060. }
  2061.  
  2062.  
  2063. static void
  2064. gen6_render_retire(struct kgem *kgem)
  2065. {
  2066.         if (kgem->ring && (kgem->has_semaphores || !kgem->need_retire))
  2067.                 kgem->ring = kgem->mode;
  2068. }
  2069.  
  2070. static void gen6_render_reset(struct sna *sna)
  2071. {
  2072.         sna->render_state.gen6.needs_invariant = TRUE;
  2073.         sna->render_state.gen6.vb_id = 0;
  2074.         sna->render_state.gen6.ve_id = -1;
  2075.         sna->render_state.gen6.last_primitive = -1;
  2076.  
  2077.         sna->render_state.gen6.num_sf_outputs = 0;
  2078.         sna->render_state.gen6.samplers = -1;
  2079.         sna->render_state.gen6.blend = -1;
  2080.         sna->render_state.gen6.kernel = -1;
  2081.         sna->render_state.gen6.drawrect_offset = -1;
  2082.         sna->render_state.gen6.drawrect_limit = -1;
  2083.         sna->render_state.gen6.surface_table = -1;
  2084. }
  2085.  
  2086. static void gen6_render_fini(struct sna *sna)
  2087. {
  2088. //   kgem_bo_destroy(&sna->kgem, sna->render_state.gen6.general_bo);
  2089. }
  2090.  
  2091. static Bool gen6_render_setup(struct sna *sna)
  2092. {
  2093.         struct gen6_render_state *state = &sna->render_state.gen6;
  2094.         struct sna_static_stream general;
  2095.         struct gen6_sampler_state *ss;
  2096.         int i, j, k, l, m;
  2097.  
  2098.     sna_static_stream_init(&general);
  2099.  
  2100.         /* Zero pad the start. If you see an offset of 0x0 in the batchbuffer
  2101.          * dumps, you know it points to zero.
  2102.          */
  2103.     null_create(&general);
  2104.     scratch_create(&general);
  2105.  
  2106.         for (m = 0; m < GEN6_KERNEL_COUNT; m++)
  2107.                 state->wm_kernel[m] =
  2108.                         sna_static_stream_add(&general,
  2109.                                                wm_kernels[m].data,
  2110.                                                wm_kernels[m].size,
  2111.                                                64);
  2112.  
  2113.         ss = sna_static_stream_map(&general,
  2114.                                    2 * sizeof(*ss) *
  2115.                                    FILTER_COUNT * EXTEND_COUNT *
  2116.                                    FILTER_COUNT * EXTEND_COUNT,
  2117.                                    32);
  2118.         state->wm_state = sna_static_stream_offsetof(&general, ss);
  2119.         for (i = 0; i < FILTER_COUNT; i++) {
  2120.                 for (j = 0; j < EXTEND_COUNT; j++) {
  2121.                         for (k = 0; k < FILTER_COUNT; k++) {
  2122.                                 for (l = 0; l < EXTEND_COUNT; l++) {
  2123.                                         sampler_state_init(ss++, i, j);
  2124.                                         sampler_state_init(ss++, k, l);
  2125.                                 }
  2126.                         }
  2127.                 }
  2128.         }
  2129.  
  2130.     state->cc_vp = gen6_create_cc_viewport(&general);
  2131.     state->cc_blend = gen6_composite_create_blend_state(&general);
  2132.  
  2133.     state->general_bo = sna_static_stream_fini(sna, &general);
  2134.     return state->general_bo != NULL;
  2135. }
  2136.  
  2137. Bool gen6_render_init(struct sna *sna)
  2138. {
  2139.     if (!gen6_render_setup(sna))
  2140.         return FALSE;
  2141.  
  2142. //    sna->kgem.context_switch = gen6_render_context_switch;
  2143.       sna->kgem.retire = gen6_render_retire;
  2144.  
  2145.     sna->render.composite = gen6_render_composite;
  2146. //    sna->render.video = gen6_render_video;
  2147.  
  2148. //    sna->render.copy_boxes = gen6_render_copy_boxes;
  2149.     sna->render.copy = gen6_render_copy;
  2150.  
  2151. //    sna->render.fill_boxes = gen6_render_fill_boxes;
  2152. //    sna->render.fill = gen6_render_fill;
  2153. //    sna->render.fill_one = gen6_render_fill_one;
  2154.     sna->render.clear = gen6_render_clear;
  2155.  
  2156.     sna->render.flush = gen6_render_flush;
  2157.     sna->render.reset = gen6_render_reset;
  2158. //    sna->render.fini = gen6_render_fini;
  2159.  
  2160.     sna->render.max_3d_size = GEN6_MAX_SIZE;
  2161.     sna->render.max_3d_pitch = 1 << 18;
  2162.     return TRUE;
  2163. }
  2164.