Subversion Repositories Kolibri OS

Rev

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