Subversion Repositories Kolibri OS

Rev

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