Subversion Repositories Kolibri OS

Rev

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. #ifdef HAVE_CONFIG_H
  34. #include "config.h"
  35. #endif
  36.  
  37. #include "sna.h"
  38. #include "sna_reg.h"
  39. #include "sna_render.h"
  40. #include "sna_render_inline.h"
  41. //#include "sna_video.h"
  42.  
  43. #include "brw/brw.h"
  44. #include "gen7_render.h"
  45. #include "gen4_source.h"
  46. #include "gen4_vertex.h"
  47.  
  48. #define NO_COMPOSITE 0
  49. #define NO_COMPOSITE_SPANS 0
  50. #define NO_COPY 0
  51. #define NO_COPY_BOXES 0
  52. #define NO_FILL 0
  53. #define NO_FILL_BOXES 0
  54. #define NO_FILL_ONE 0
  55. #define NO_FILL_CLEAR 0
  56.  
  57. #define NO_RING_SWITCH 0
  58.  
  59. #define USE_8_PIXEL_DISPATCH 1
  60. #define USE_16_PIXEL_DISPATCH 1
  61. #define USE_32_PIXEL_DISPATCH 0
  62.  
  63. #if !USE_8_PIXEL_DISPATCH && !USE_16_PIXEL_DISPATCH && !USE_32_PIXEL_DISPATCH
  64. #error "Must select at least 8, 16 or 32 pixel dispatch"
  65. #endif
  66.  
  67. #define GEN7_MAX_SIZE 16384
  68.  
  69. /* XXX Todo
  70.  *
  71.  * STR (software tiled rendering) mode. No, really.
  72.  * 64x32 pixel blocks align with the rendering cache. Worth considering.
  73.  */
  74.  
  75. #define is_aligned(x, y) (((x) & ((y) - 1)) == 0)
  76.  
  77. struct gt_info {
  78.         uint32_t max_vs_threads;
  79.         uint32_t max_gs_threads;
  80.         uint32_t max_wm_threads;
  81.         struct {
  82.                 int size;
  83.                 int max_vs_entries;
  84.                 int max_gs_entries;
  85.         } urb;
  86. };
  87.  
  88. static const struct gt_info ivb_gt_info = {
  89.         .max_vs_threads = 16,
  90.         .max_gs_threads = 16,
  91.         .max_wm_threads = (16-1) << IVB_PS_MAX_THREADS_SHIFT,
  92.         .urb = { 128, 64, 64 },
  93. };
  94.  
  95. static const struct gt_info ivb_gt1_info = {
  96.         .max_vs_threads = 36,
  97.         .max_gs_threads = 36,
  98.         .max_wm_threads = (48-1) << IVB_PS_MAX_THREADS_SHIFT,
  99.         .urb = { 128, 512, 192 },
  100. };
  101.  
  102. static const struct gt_info ivb_gt2_info = {
  103.         .max_vs_threads = 128,
  104.         .max_gs_threads = 128,
  105.         .max_wm_threads = (172-1) << IVB_PS_MAX_THREADS_SHIFT,
  106.         .urb = { 256, 704, 320 },
  107. };
  108.  
  109. static const struct gt_info hsw_gt_info = {
  110.         .max_vs_threads = 8,
  111.         .max_gs_threads = 8,
  112.         .max_wm_threads =
  113.                 (8 - 1) << HSW_PS_MAX_THREADS_SHIFT |
  114.                 1 << HSW_PS_SAMPLE_MASK_SHIFT,
  115.         .urb = { 128, 64, 64 },
  116. };
  117.  
  118. static const struct gt_info hsw_gt1_info = {
  119.         .max_vs_threads = 70,
  120.         .max_gs_threads = 70,
  121.         .max_wm_threads =
  122.                 (102 - 1) << HSW_PS_MAX_THREADS_SHIFT |
  123.                 1 << HSW_PS_SAMPLE_MASK_SHIFT,
  124.         .urb = { 128, 640, 256 },
  125. };
  126.  
  127. static const struct gt_info hsw_gt2_info = {
  128.         .max_vs_threads = 280,
  129.         .max_gs_threads = 280,
  130.         .max_wm_threads =
  131.                 (204 - 1) << HSW_PS_MAX_THREADS_SHIFT |
  132.                 1 << HSW_PS_SAMPLE_MASK_SHIFT,
  133.         .urb = { 256, 1664, 640 },
  134. };
  135.  
  136. static const uint32_t ps_kernel_packed[][4] = {
  137. #include "exa_wm_src_affine.g7b"
  138. #include "exa_wm_src_sample_argb.g7b"
  139. #include "exa_wm_yuv_rgb.g7b"
  140. #include "exa_wm_write.g7b"
  141. };
  142.  
  143. static const uint32_t ps_kernel_planar[][4] = {
  144. #include "exa_wm_src_affine.g7b"
  145. #include "exa_wm_src_sample_planar.g7b"
  146. #include "exa_wm_yuv_rgb.g7b"
  147. #include "exa_wm_write.g7b"
  148. };
  149.  
  150. #define KERNEL(kernel_enum, kernel, num_surfaces) \
  151.     [GEN7_WM_KERNEL_##kernel_enum] = {#kernel_enum, kernel, sizeof(kernel), num_surfaces}
  152. #define NOKERNEL(kernel_enum, func, num_surfaces) \
  153.     [GEN7_WM_KERNEL_##kernel_enum] = {#kernel_enum, (void *)func, 0, num_surfaces}
  154. static const struct wm_kernel_info {
  155.         const char *name;
  156.         const void *data;
  157.         unsigned int size;
  158.         int num_surfaces;
  159. } wm_kernels[] = {
  160.         NOKERNEL(NOMASK, brw_wm_kernel__affine, 2),
  161.         NOKERNEL(NOMASK_P, brw_wm_kernel__projective, 2),
  162.  
  163.         NOKERNEL(MASK, brw_wm_kernel__affine_mask, 3),
  164.         NOKERNEL(MASK_P, brw_wm_kernel__projective_mask, 3),
  165.  
  166.         NOKERNEL(MASKCA, brw_wm_kernel__affine_mask_ca, 3),
  167.         NOKERNEL(MASKCA_P, brw_wm_kernel__projective_mask_ca, 3),
  168.  
  169.         NOKERNEL(MASKSA, brw_wm_kernel__affine_mask_sa, 3),
  170.         NOKERNEL(MASKSA_P, brw_wm_kernel__projective_mask_sa, 3),
  171.  
  172.         NOKERNEL(OPACITY, brw_wm_kernel__affine_opacity, 2),
  173.         NOKERNEL(OPACITY_P, brw_wm_kernel__projective_opacity, 2),
  174.  
  175.         KERNEL(VIDEO_PLANAR, ps_kernel_planar, 7),
  176.         KERNEL(VIDEO_PACKED, ps_kernel_packed, 2),
  177. };
  178. #undef KERNEL
  179.  
  180. static const struct blendinfo {
  181.         bool src_alpha;
  182.         uint32_t src_blend;
  183.         uint32_t dst_blend;
  184. } gen7_blend_op[] = {
  185.         /* Clear */     {0, GEN7_BLENDFACTOR_ZERO, GEN7_BLENDFACTOR_ZERO},
  186.         /* Src */       {0, GEN7_BLENDFACTOR_ONE, GEN7_BLENDFACTOR_ZERO},
  187.         /* Dst */       {0, GEN7_BLENDFACTOR_ZERO, GEN7_BLENDFACTOR_ONE},
  188.         /* Over */      {1, GEN7_BLENDFACTOR_ONE, GEN7_BLENDFACTOR_INV_SRC_ALPHA},
  189.         /* OverReverse */ {0, GEN7_BLENDFACTOR_INV_DST_ALPHA, GEN7_BLENDFACTOR_ONE},
  190.         /* In */        {0, GEN7_BLENDFACTOR_DST_ALPHA, GEN7_BLENDFACTOR_ZERO},
  191.         /* InReverse */ {1, GEN7_BLENDFACTOR_ZERO, GEN7_BLENDFACTOR_SRC_ALPHA},
  192.         /* Out */       {0, GEN7_BLENDFACTOR_INV_DST_ALPHA, GEN7_BLENDFACTOR_ZERO},
  193.         /* OutReverse */ {1, GEN7_BLENDFACTOR_ZERO, GEN7_BLENDFACTOR_INV_SRC_ALPHA},
  194.         /* Atop */      {1, GEN7_BLENDFACTOR_DST_ALPHA, GEN7_BLENDFACTOR_INV_SRC_ALPHA},
  195.         /* AtopReverse */ {1, GEN7_BLENDFACTOR_INV_DST_ALPHA, GEN7_BLENDFACTOR_SRC_ALPHA},
  196.         /* Xor */       {1, GEN7_BLENDFACTOR_INV_DST_ALPHA, GEN7_BLENDFACTOR_INV_SRC_ALPHA},
  197.         /* Add */       {0, GEN7_BLENDFACTOR_ONE, GEN7_BLENDFACTOR_ONE},
  198. };
  199.  
  200. /**
  201.  * Highest-valued BLENDFACTOR used in gen7_blend_op.
  202.  *
  203.  * This leaves out GEN7_BLENDFACTOR_INV_DST_COLOR,
  204.  * GEN7_BLENDFACTOR_INV_CONST_{COLOR,ALPHA},
  205.  * GEN7_BLENDFACTOR_INV_SRC1_{COLOR,ALPHA}
  206.  */
  207. #define GEN7_BLENDFACTOR_COUNT (GEN7_BLENDFACTOR_INV_DST_ALPHA + 1)
  208.  
  209. #define GEN7_BLEND_STATE_PADDED_SIZE    ALIGN(sizeof(struct gen7_blend_state), 64)
  210.  
  211. #define BLEND_OFFSET(s, d) \
  212.         ((d != GEN7_BLENDFACTOR_ZERO) << 15 | \
  213.          (((s) * GEN7_BLENDFACTOR_COUNT + (d)) * GEN7_BLEND_STATE_PADDED_SIZE))
  214.  
  215. #define NO_BLEND BLEND_OFFSET(GEN7_BLENDFACTOR_ONE, GEN7_BLENDFACTOR_ZERO)
  216. #define CLEAR BLEND_OFFSET(GEN7_BLENDFACTOR_ZERO, GEN7_BLENDFACTOR_ZERO)
  217.  
  218. #define SAMPLER_OFFSET(sf, se, mf, me) \
  219.         ((((((sf) * EXTEND_COUNT + (se)) * FILTER_COUNT + (mf)) * EXTEND_COUNT + (me)) + 2) * 2 * sizeof(struct gen7_sampler_state))
  220.  
  221. #define VERTEX_2s2s 0
  222.  
  223. #define COPY_SAMPLER 0
  224. #define COPY_VERTEX VERTEX_2s2s
  225. #define COPY_FLAGS(a) GEN7_SET_FLAGS(COPY_SAMPLER, (a) == GXcopy ? NO_BLEND : CLEAR, GEN7_WM_KERNEL_NOMASK, COPY_VERTEX)
  226.  
  227. #define FILL_SAMPLER (2 * sizeof(struct gen7_sampler_state))
  228. #define FILL_VERTEX VERTEX_2s2s
  229. #define FILL_FLAGS(op, format) GEN7_SET_FLAGS(FILL_SAMPLER, gen7_get_blend((op), false, (format)), GEN7_WM_KERNEL_NOMASK, FILL_VERTEX)
  230. #define FILL_FLAGS_NOBLEND GEN7_SET_FLAGS(FILL_SAMPLER, NO_BLEND, GEN7_WM_KERNEL_NOMASK, FILL_VERTEX)
  231.  
  232. #define GEN7_SAMPLER(f) (((f) >> 16) & 0xfff0)
  233. #define GEN7_BLEND(f) (((f) >> 0) & 0x7ff0)
  234. #define GEN7_READS_DST(f) (((f) >> 15) & 1)
  235. #define GEN7_KERNEL(f) (((f) >> 16) & 0xf)
  236. #define GEN7_VERTEX(f) (((f) >> 0) & 0xf)
  237. #define GEN7_SET_FLAGS(S, B, K, V)  (((S) | (K)) << 16 | ((B) | (V)))
  238.  
  239. #define OUT_BATCH(v) batch_emit(sna, v)
  240. #define OUT_VERTEX(x,y) vertex_emit_2s(sna, x,y)
  241. #define OUT_VERTEX_F(v) vertex_emit(sna, v)
  242.  
  243. static inline bool too_large(int width, int height)
  244. {
  245.         return width > GEN7_MAX_SIZE || height > GEN7_MAX_SIZE;
  246. }
  247.  
  248. static uint32_t gen7_get_blend(int op,
  249.                                bool has_component_alpha,
  250.                                uint32_t dst_format)
  251. {
  252.         uint32_t src, dst;
  253.  
  254.  
  255.     src = GEN7_BLENDFACTOR_ONE; //gen6_blend_op[op].src_blend;
  256.     dst = GEN7_BLENDFACTOR_INV_SRC_ALPHA; //gen6_blend_op[op].dst_blend;
  257.  
  258. #if 0
  259.         /* If there's no dst alpha channel, adjust the blend op so that
  260.          * we'll treat it always as 1.
  261.          */
  262.         if (PICT_FORMAT_A(dst_format) == 0) {
  263.                 if (src == GEN7_BLENDFACTOR_DST_ALPHA)
  264.                         src = GEN7_BLENDFACTOR_ONE;
  265.                 else if (src == GEN7_BLENDFACTOR_INV_DST_ALPHA)
  266.                         src = GEN7_BLENDFACTOR_ZERO;
  267.         }
  268.  
  269.         /* If the source alpha is being used, then we should only be in a
  270.          * case where the source blend factor is 0, and the source blend
  271.          * value is the mask channels multiplied by the source picture's alpha.
  272.          */
  273.         if (has_component_alpha && gen7_blend_op[op].src_alpha) {
  274.                 if (dst == GEN7_BLENDFACTOR_SRC_ALPHA)
  275.                         dst = GEN7_BLENDFACTOR_SRC_COLOR;
  276.                 else if (dst == GEN7_BLENDFACTOR_INV_SRC_ALPHA)
  277.                         dst = GEN7_BLENDFACTOR_INV_SRC_COLOR;
  278.         }
  279. #endif
  280.  
  281.         DBG(("blend op=%d, dst=%x [A=%d] => src=%d, dst=%d => offset=%x\n",
  282.              op, dst_format, PICT_FORMAT_A(dst_format),
  283.              src, dst, (int)BLEND_OFFSET(src, dst)));
  284.         return BLEND_OFFSET(src, dst);
  285. }
  286.  
  287. static uint32_t gen7_get_card_format(PictFormat format)
  288. {
  289.         switch (format) {
  290.         default:
  291.                 return -1;
  292.         case PICT_a8r8g8b8:
  293.                 return GEN7_SURFACEFORMAT_B8G8R8A8_UNORM;
  294.         case PICT_x8r8g8b8:
  295.                 return GEN7_SURFACEFORMAT_B8G8R8X8_UNORM;
  296.         case PICT_a8:
  297.                 return GEN7_SURFACEFORMAT_A8_UNORM;
  298.         }
  299. }
  300.  
  301. static uint32_t gen7_get_dest_format(PictFormat format)
  302. {
  303.         switch (format) {
  304.         default:
  305.                 return -1;
  306.         case PICT_a8r8g8b8:
  307.         case PICT_x8r8g8b8:
  308.                 return GEN7_SURFACEFORMAT_B8G8R8A8_UNORM;
  309.         case PICT_a8:
  310.                 return GEN7_SURFACEFORMAT_A8_UNORM;
  311.         }
  312. }
  313.  
  314. static int
  315. gen7_choose_composite_kernel(int op, bool has_mask, bool is_ca, bool is_affine)
  316. {
  317.         int base;
  318.  
  319.         if (has_mask) {
  320.                 if (is_ca) {
  321.                         if (gen7_blend_op[op].src_alpha)
  322.                                 base = GEN7_WM_KERNEL_MASKSA;
  323.                         else
  324.                                 base = GEN7_WM_KERNEL_MASKCA;
  325.                 } else
  326.                         base = GEN7_WM_KERNEL_MASK;
  327.         } else
  328.                 base = GEN7_WM_KERNEL_NOMASK;
  329.  
  330.         return base + !is_affine;
  331. }
  332.  
  333. static void
  334. gen7_emit_urb(struct sna *sna)
  335. {
  336.         OUT_BATCH(GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_PS | (2 - 2));
  337.         OUT_BATCH(8); /* in 1KBs */
  338.  
  339.         /* num of VS entries must be divisible by 8 if size < 9 */
  340.         OUT_BATCH(GEN7_3DSTATE_URB_VS | (2 - 2));
  341.         OUT_BATCH((sna->render_state.gen7.info->urb.max_vs_entries << GEN7_URB_ENTRY_NUMBER_SHIFT) |
  342.                   (2 - 1) << GEN7_URB_ENTRY_SIZE_SHIFT |
  343.                   (1 << GEN7_URB_STARTING_ADDRESS_SHIFT));
  344.  
  345.         OUT_BATCH(GEN7_3DSTATE_URB_HS | (2 - 2));
  346.         OUT_BATCH((0 << GEN7_URB_ENTRY_SIZE_SHIFT) |
  347.                   (2 << GEN7_URB_STARTING_ADDRESS_SHIFT));
  348.  
  349.         OUT_BATCH(GEN7_3DSTATE_URB_DS | (2 - 2));
  350.         OUT_BATCH((0 << GEN7_URB_ENTRY_SIZE_SHIFT) |
  351.                   (2 << GEN7_URB_STARTING_ADDRESS_SHIFT));
  352.  
  353.         OUT_BATCH(GEN7_3DSTATE_URB_GS | (2 - 2));
  354.         OUT_BATCH((0 << GEN7_URB_ENTRY_SIZE_SHIFT) |
  355.                   (1 << GEN7_URB_STARTING_ADDRESS_SHIFT));
  356. }
  357.  
  358. static void
  359. gen7_emit_state_base_address(struct sna *sna)
  360. {
  361.         OUT_BATCH(GEN7_STATE_BASE_ADDRESS | (10 - 2));
  362.         OUT_BATCH(0); /* general */
  363.         OUT_BATCH(kgem_add_reloc(&sna->kgem, /* surface */
  364.                                  sna->kgem.nbatch,
  365.                                  NULL,
  366.                                  I915_GEM_DOMAIN_INSTRUCTION << 16,
  367.                                  BASE_ADDRESS_MODIFY));
  368.         OUT_BATCH(kgem_add_reloc(&sna->kgem, /* instruction */
  369.                                  sna->kgem.nbatch,
  370.                                  sna->render_state.gen7.general_bo,
  371.                                  I915_GEM_DOMAIN_INSTRUCTION << 16,
  372.                                  BASE_ADDRESS_MODIFY));
  373.         OUT_BATCH(0); /* indirect */
  374.         OUT_BATCH(kgem_add_reloc(&sna->kgem,
  375.                                  sna->kgem.nbatch,
  376.                                  sna->render_state.gen7.general_bo,
  377.                                  I915_GEM_DOMAIN_INSTRUCTION << 16,
  378.                                  BASE_ADDRESS_MODIFY));
  379.  
  380.         /* upper bounds, disable */
  381.         OUT_BATCH(0);
  382.         OUT_BATCH(BASE_ADDRESS_MODIFY);
  383.         OUT_BATCH(0);
  384.         OUT_BATCH(BASE_ADDRESS_MODIFY);
  385. }
  386.  
  387. static void
  388. gen7_disable_vs(struct sna *sna)
  389. {
  390.         /* For future reference:
  391.          * A PIPE_CONTROL with post-sync op set to 1 and a depth stall needs
  392.          * to be emitted just prior to change VS state, i.e. 3DSTATE_VS,
  393.          * 3DSTATE_URB_VS, 3DSTATE_CONSTANT_VS,
  394.          * 3DSTATE_BINDING_TABLE_POINTER_VS, 3DSTATE_SAMPLER_STATE_POINTER_VS.
  395.          *
  396.          * Here we saved by the full-flush incurred when emitting
  397.          * the batchbuffer.
  398.          */
  399.         OUT_BATCH(GEN7_3DSTATE_VS | (6 - 2));
  400.         OUT_BATCH(0); /* no VS kernel */
  401.         OUT_BATCH(0);
  402.         OUT_BATCH(0);
  403.         OUT_BATCH(0);
  404.         OUT_BATCH(0); /* pass-through */
  405.  
  406. #if 0
  407.         OUT_BATCH(GEN7_3DSTATE_CONSTANT_VS | (7 - 2));
  408.         OUT_BATCH(0);
  409.         OUT_BATCH(0);
  410.         OUT_BATCH(0);
  411.         OUT_BATCH(0);
  412.         OUT_BATCH(0);
  413.         OUT_BATCH(0);
  414.  
  415.         OUT_BATCH(GEN7_3DSTATE_BINDING_TABLE_POINTERS_VS | (2 - 2));
  416.         OUT_BATCH(0);
  417.  
  418.         OUT_BATCH(GEN7_3DSTATE_SAMPLER_STATE_POINTERS_VS | (2 - 2));
  419.         OUT_BATCH(0);
  420. #endif
  421. }
  422.  
  423. static void
  424. gen7_disable_hs(struct sna *sna)
  425. {
  426.         OUT_BATCH(GEN7_3DSTATE_HS | (7 - 2));
  427.         OUT_BATCH(0); /* no HS kernel */
  428.         OUT_BATCH(0);
  429.         OUT_BATCH(0);
  430.         OUT_BATCH(0);
  431.         OUT_BATCH(0);
  432.         OUT_BATCH(0); /* pass-through */
  433.  
  434. #if 0
  435.         OUT_BATCH(GEN7_3DSTATE_CONSTANT_HS | (7 - 2));
  436.         OUT_BATCH(0);
  437.         OUT_BATCH(0);
  438.         OUT_BATCH(0);
  439.         OUT_BATCH(0);
  440.         OUT_BATCH(0);
  441.         OUT_BATCH(0);
  442.  
  443.         OUT_BATCH(GEN7_3DSTATE_BINDING_TABLE_POINTERS_HS | (2 - 2));
  444.         OUT_BATCH(0);
  445.  
  446.         OUT_BATCH(GEN7_3DSTATE_SAMPLER_STATE_POINTERS_HS | (2 - 2));
  447.         OUT_BATCH(0);
  448. #endif
  449. }
  450.  
  451. static void
  452. gen7_disable_te(struct sna *sna)
  453. {
  454.         OUT_BATCH(GEN7_3DSTATE_TE | (4 - 2));
  455.         OUT_BATCH(0);
  456.         OUT_BATCH(0);
  457.         OUT_BATCH(0);
  458. }
  459.  
  460. static void
  461. gen7_disable_ds(struct sna *sna)
  462. {
  463.         OUT_BATCH(GEN7_3DSTATE_DS | (6 - 2));
  464.         OUT_BATCH(0);
  465.         OUT_BATCH(0);
  466.         OUT_BATCH(0);
  467.         OUT_BATCH(0);
  468.         OUT_BATCH(0);
  469.  
  470. #if 0
  471.         OUT_BATCH(GEN7_3DSTATE_CONSTANT_DS | (7 - 2));
  472.         OUT_BATCH(0);
  473.         OUT_BATCH(0);
  474.         OUT_BATCH(0);
  475.         OUT_BATCH(0);
  476.         OUT_BATCH(0);
  477.         OUT_BATCH(0);
  478.  
  479.         OUT_BATCH(GEN7_3DSTATE_BINDING_TABLE_POINTERS_DS | (2 - 2));
  480.         OUT_BATCH(0);
  481.  
  482.         OUT_BATCH(GEN7_3DSTATE_SAMPLER_STATE_POINTERS_DS | (2 - 2));
  483.         OUT_BATCH(0);
  484. #endif
  485. }
  486.  
  487. static void
  488. gen7_disable_gs(struct sna *sna)
  489. {
  490.         OUT_BATCH(GEN7_3DSTATE_GS | (7 - 2));
  491.         OUT_BATCH(0); /* no GS kernel */
  492.         OUT_BATCH(0);
  493.         OUT_BATCH(0);
  494.         OUT_BATCH(0);
  495.         OUT_BATCH(0);
  496.         OUT_BATCH(0); /* pass-through */
  497.  
  498. #if 0
  499.         OUT_BATCH(GEN7_3DSTATE_CONSTANT_GS | (7 - 2));
  500.         OUT_BATCH(0);
  501.         OUT_BATCH(0);
  502.         OUT_BATCH(0);
  503.         OUT_BATCH(0);
  504.         OUT_BATCH(0);
  505.         OUT_BATCH(0);
  506.  
  507.         OUT_BATCH(GEN7_3DSTATE_BINDING_TABLE_POINTERS_GS | (2 - 2));
  508.         OUT_BATCH(0);
  509.  
  510.         OUT_BATCH(GEN7_3DSTATE_SAMPLER_STATE_POINTERS_GS | (2 - 2));
  511.         OUT_BATCH(0);
  512. #endif
  513. }
  514.  
  515. static void
  516. gen7_disable_streamout(struct sna *sna)
  517. {
  518.         OUT_BATCH(GEN7_3DSTATE_STREAMOUT | (3 - 2));
  519.         OUT_BATCH(0);
  520.         OUT_BATCH(0);
  521. }
  522.  
  523. static void
  524. gen7_emit_sf_invariant(struct sna *sna)
  525. {
  526.         OUT_BATCH(GEN7_3DSTATE_SF | (7 - 2));
  527.         OUT_BATCH(0);
  528.         OUT_BATCH(GEN7_3DSTATE_SF_CULL_NONE);
  529.         OUT_BATCH(2 << GEN7_3DSTATE_SF_TRIFAN_PROVOKE_SHIFT);
  530.         OUT_BATCH(0);
  531.         OUT_BATCH(0);
  532.         OUT_BATCH(0);
  533. }
  534.  
  535. static void
  536. gen7_emit_cc_invariant(struct sna *sna)
  537. {
  538. #if 0 /* unused, no change */
  539.         OUT_BATCH(GEN7_3DSTATE_CC_STATE_POINTERS | (2 - 2));
  540.         OUT_BATCH(0);
  541.  
  542.         OUT_BATCH(GEN7_3DSTATE_DEPTH_STENCIL_STATE_POINTERS | (2 - 2));
  543.         OUT_BATCH(0);
  544. #endif
  545.  
  546.         /* XXX clear to be safe */
  547.         OUT_BATCH(GEN7_3DSTATE_VIEWPORT_STATE_POINTERS_CC | (2 - 2));
  548.         OUT_BATCH(0);
  549. }
  550.  
  551. static void
  552. gen7_disable_clip(struct sna *sna)
  553. {
  554.         OUT_BATCH(GEN7_3DSTATE_CLIP | (4 - 2));
  555.         OUT_BATCH(0);
  556.         OUT_BATCH(0); /* pass-through */
  557.         OUT_BATCH(0);
  558.  
  559.         OUT_BATCH(GEN7_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CL | (2 - 2));
  560.         OUT_BATCH(0);
  561. }
  562.  
  563. static void
  564. gen7_emit_wm_invariant(struct sna *sna)
  565. {
  566.         OUT_BATCH(GEN7_3DSTATE_WM | (3 - 2));
  567.         OUT_BATCH(GEN7_WM_DISPATCH_ENABLE |
  568.                   GEN7_WM_PERSPECTIVE_PIXEL_BARYCENTRIC);
  569.         OUT_BATCH(0);
  570.  
  571. #if 0
  572.         /* XXX length bias of 7 in old spec? */
  573.         OUT_BATCH(GEN7_3DSTATE_CONSTANT_PS | (7 - 2));
  574.         OUT_BATCH(0);
  575.         OUT_BATCH(0);
  576.         OUT_BATCH(0);
  577.         OUT_BATCH(0);
  578.         OUT_BATCH(0);
  579.         OUT_BATCH(0);
  580. #endif
  581. }
  582.  
  583. static void
  584. gen7_emit_null_depth_buffer(struct sna *sna)
  585. {
  586.         OUT_BATCH(GEN7_3DSTATE_DEPTH_BUFFER | (7 - 2));
  587.         OUT_BATCH(GEN7_SURFACE_NULL << GEN7_3DSTATE_DEPTH_BUFFER_TYPE_SHIFT |
  588.                   GEN7_DEPTHFORMAT_D32_FLOAT << GEN7_3DSTATE_DEPTH_BUFFER_FORMAT_SHIFT);
  589.         OUT_BATCH(0); /* disable depth, stencil and hiz */
  590.         OUT_BATCH(0);
  591.         OUT_BATCH(0);
  592.         OUT_BATCH(0);
  593.         OUT_BATCH(0);
  594.  
  595. #if 0
  596.         OUT_BATCH(GEN7_3DSTATE_CLEAR_PARAMS | (3 - 2));
  597.         OUT_BATCH(0);
  598.         OUT_BATCH(0);
  599. #endif
  600. }
  601.  
  602. static void
  603. gen7_emit_invariant(struct sna *sna)
  604. {
  605.         OUT_BATCH(GEN7_PIPELINE_SELECT | PIPELINE_SELECT_3D);
  606.  
  607.         OUT_BATCH(GEN7_3DSTATE_MULTISAMPLE | (4 - 2));
  608.         OUT_BATCH(GEN7_3DSTATE_MULTISAMPLE_PIXEL_LOCATION_CENTER |
  609.                   GEN7_3DSTATE_MULTISAMPLE_NUMSAMPLES_1); /* 1 sample/pixel */
  610.         OUT_BATCH(0);
  611.         OUT_BATCH(0);
  612.  
  613.         OUT_BATCH(GEN7_3DSTATE_SAMPLE_MASK | (2 - 2));
  614.         OUT_BATCH(1);
  615.  
  616.         gen7_emit_urb(sna);
  617.  
  618.         gen7_emit_state_base_address(sna);
  619.  
  620.         gen7_disable_vs(sna);
  621.         gen7_disable_hs(sna);
  622.         gen7_disable_te(sna);
  623.         gen7_disable_ds(sna);
  624.         gen7_disable_gs(sna);
  625.         gen7_disable_clip(sna);
  626.         gen7_emit_sf_invariant(sna);
  627.         gen7_emit_wm_invariant(sna);
  628.         gen7_emit_cc_invariant(sna);
  629.         gen7_disable_streamout(sna);
  630.         gen7_emit_null_depth_buffer(sna);
  631.  
  632.         sna->render_state.gen7.needs_invariant = false;
  633. }
  634.  
  635. static void
  636. gen7_emit_cc(struct sna *sna, uint32_t blend_offset)
  637. {
  638.         struct gen7_render_state *render = &sna->render_state.gen7;
  639.  
  640.         if (render->blend == blend_offset)
  641.                 return;
  642.  
  643.         DBG(("%s: blend = %x\n", __FUNCTION__, blend_offset));
  644.  
  645.         /* XXX can have upto 8 blend states preload, selectable via
  646.          * Render Target Index. What other side-effects of Render Target Index?
  647.          */
  648.  
  649.         assert (is_aligned(render->cc_blend + blend_offset, 64));
  650.         OUT_BATCH(GEN7_3DSTATE_BLEND_STATE_POINTERS | (2 - 2));
  651.         OUT_BATCH((render->cc_blend + blend_offset) | 1);
  652.  
  653.         render->blend = blend_offset;
  654. }
  655.  
  656. static void
  657. gen7_emit_sampler(struct sna *sna, uint32_t state)
  658. {
  659.         if (sna->render_state.gen7.samplers == state)
  660.                 return;
  661.  
  662.         sna->render_state.gen7.samplers = state;
  663.  
  664.         DBG(("%s: sampler = %x\n", __FUNCTION__, state));
  665.  
  666.         assert (is_aligned(sna->render_state.gen7.wm_state + state, 32));
  667.         OUT_BATCH(GEN7_3DSTATE_SAMPLER_STATE_POINTERS_PS | (2 - 2));
  668.         OUT_BATCH(sna->render_state.gen7.wm_state + state);
  669. }
  670.  
  671. static void
  672. gen7_emit_sf(struct sna *sna, bool has_mask)
  673. {
  674.         int num_sf_outputs = has_mask ? 2 : 1;
  675.  
  676.         if (sna->render_state.gen7.num_sf_outputs == num_sf_outputs)
  677.                 return;
  678.  
  679.         DBG(("%s: num_sf_outputs=%d, read_length=%d, read_offset=%d\n",
  680.              __FUNCTION__, num_sf_outputs, 1, 0));
  681.  
  682.         sna->render_state.gen7.num_sf_outputs = num_sf_outputs;
  683.  
  684.         OUT_BATCH(GEN7_3DSTATE_SBE | (14 - 2));
  685.         OUT_BATCH(num_sf_outputs << GEN7_SBE_NUM_OUTPUTS_SHIFT |
  686.                   1 << GEN7_SBE_URB_ENTRY_READ_LENGTH_SHIFT |
  687.                   1 << GEN7_SBE_URB_ENTRY_READ_OFFSET_SHIFT);
  688.         OUT_BATCH(0);
  689.         OUT_BATCH(0); /* dw4 */
  690.         OUT_BATCH(0);
  691.         OUT_BATCH(0);
  692.         OUT_BATCH(0);
  693.         OUT_BATCH(0); /* dw8 */
  694.         OUT_BATCH(0);
  695.         OUT_BATCH(0);
  696.         OUT_BATCH(0);
  697.         OUT_BATCH(0); /* dw12 */
  698.         OUT_BATCH(0);
  699.         OUT_BATCH(0);
  700. }
  701.  
  702. static void
  703. gen7_emit_wm(struct sna *sna, int kernel)
  704. {
  705.         const uint32_t *kernels;
  706.  
  707.         if (sna->render_state.gen7.kernel == kernel)
  708.                 return;
  709.  
  710.         sna->render_state.gen7.kernel = kernel;
  711.         kernels = sna->render_state.gen7.wm_kernel[kernel];
  712.  
  713.         DBG(("%s: switching to %s, num_surfaces=%d (8-wide? %d, 16-wide? %d, 32-wide? %d)\n",
  714.              __FUNCTION__,
  715.              wm_kernels[kernel].name,
  716.              wm_kernels[kernel].num_surfaces,
  717.              kernels[0], kernels[1], kernels[2]));
  718.  
  719.         OUT_BATCH(GEN7_3DSTATE_PS | (8 - 2));
  720.         OUT_BATCH(kernels[0] ?: kernels[1] ?: kernels[2]);
  721.         OUT_BATCH(1 << GEN7_PS_SAMPLER_COUNT_SHIFT |
  722.                   wm_kernels[kernel].num_surfaces << GEN7_PS_BINDING_TABLE_ENTRY_COUNT_SHIFT);
  723.         OUT_BATCH(0); /* scratch address */
  724.         OUT_BATCH(sna->render_state.gen7.info->max_wm_threads |
  725.                   (kernels[0] ? GEN7_PS_8_DISPATCH_ENABLE : 0) |
  726.                   (kernels[1] ? GEN7_PS_16_DISPATCH_ENABLE : 0) |
  727.                   (kernels[2] ? GEN7_PS_32_DISPATCH_ENABLE : 0) |
  728.                   GEN7_PS_ATTRIBUTE_ENABLE);
  729.         OUT_BATCH((kernels[0] ? 4 : kernels[1] ? 6 : 8) << GEN7_PS_DISPATCH_START_GRF_SHIFT_0 |
  730.                   8 << GEN7_PS_DISPATCH_START_GRF_SHIFT_1 |
  731.                   6 << GEN7_PS_DISPATCH_START_GRF_SHIFT_2);
  732.         OUT_BATCH(kernels[2]);
  733.         OUT_BATCH(kernels[1]);
  734. }
  735.  
  736. static bool
  737. gen7_emit_binding_table(struct sna *sna, uint16_t offset)
  738. {
  739.         if (sna->render_state.gen7.surface_table == offset)
  740.                 return false;
  741.  
  742.         /* Binding table pointers */
  743.         assert(is_aligned(4*offset, 32));
  744.         OUT_BATCH(GEN7_3DSTATE_BINDING_TABLE_POINTERS_PS | (2 - 2));
  745.         OUT_BATCH(offset*4);
  746.  
  747.         sna->render_state.gen7.surface_table = offset;
  748.         return true;
  749. }
  750.  
  751. static bool
  752. gen7_emit_drawing_rectangle(struct sna *sna,
  753.                             const struct sna_composite_op *op)
  754. {
  755.         uint32_t limit = (op->dst.height - 1) << 16 | (op->dst.width - 1);
  756.         uint32_t offset = (uint16_t)op->dst.y << 16 | (uint16_t)op->dst.x;
  757.  
  758.         assert(!too_large(op->dst.x, op->dst.y));
  759.         assert(!too_large(op->dst.width, op->dst.height));
  760.  
  761.         if (sna->render_state.gen7.drawrect_limit == limit &&
  762.             sna->render_state.gen7.drawrect_offset == offset)
  763.                 return true;
  764.  
  765.         sna->render_state.gen7.drawrect_offset = offset;
  766.         sna->render_state.gen7.drawrect_limit = limit;
  767.  
  768.         OUT_BATCH(GEN7_3DSTATE_DRAWING_RECTANGLE | (4 - 2));
  769.         OUT_BATCH(0);
  770.         OUT_BATCH(limit);
  771.         OUT_BATCH(offset);
  772.         return false;
  773. }
  774.  
  775. static void
  776. gen7_emit_vertex_elements(struct sna *sna,
  777.                           const struct sna_composite_op *op)
  778. {
  779.         /*
  780.          * vertex data in vertex buffer
  781.          *    position: (x, y)
  782.          *    texture coordinate 0: (u0, v0) if (is_affine is true) else (u0, v0, w0)
  783.          *    texture coordinate 1 if (has_mask is true): same as above
  784.          */
  785.         struct gen7_render_state *render = &sna->render_state.gen7;
  786.         uint32_t src_format, dw;
  787.         int id = GEN7_VERTEX(op->u.gen7.flags);
  788.         bool has_mask;
  789.  
  790.         DBG(("%s: setup id=%d\n", __FUNCTION__, id));
  791.  
  792.         if (render->ve_id == id)
  793.                 return;
  794.         render->ve_id = id;
  795.  
  796.         /* The VUE layout
  797.          *    dword 0-3: pad (0.0, 0.0, 0.0. 0.0)
  798.          *    dword 4-7: position (x, y, 1.0, 1.0),
  799.          *    dword 8-11: texture coordinate 0 (u0, v0, w0, 1.0)
  800.          *    dword 12-15: texture coordinate 1 (u1, v1, w1, 1.0)
  801.          *
  802.          * dword 4-15 are fetched from vertex buffer
  803.          */
  804.         has_mask = (id >> 2) != 0;
  805.         OUT_BATCH(GEN7_3DSTATE_VERTEX_ELEMENTS |
  806.                 ((2 * (3 + has_mask)) + 1 - 2));
  807.  
  808.         OUT_BATCH(id << GEN7_VE0_VERTEX_BUFFER_INDEX_SHIFT | GEN7_VE0_VALID |
  809.                   GEN7_SURFACEFORMAT_R32G32B32A32_FLOAT << GEN7_VE0_FORMAT_SHIFT |
  810.                   0 << GEN7_VE0_OFFSET_SHIFT);
  811.         OUT_BATCH(GEN7_VFCOMPONENT_STORE_0 << GEN7_VE1_VFCOMPONENT_0_SHIFT |
  812.                   GEN7_VFCOMPONENT_STORE_0 << GEN7_VE1_VFCOMPONENT_1_SHIFT |
  813.                   GEN7_VFCOMPONENT_STORE_0 << GEN7_VE1_VFCOMPONENT_2_SHIFT |
  814.                   GEN7_VFCOMPONENT_STORE_0 << GEN7_VE1_VFCOMPONENT_3_SHIFT);
  815.  
  816.         /* x,y */
  817.         OUT_BATCH(id << GEN7_VE0_VERTEX_BUFFER_INDEX_SHIFT | GEN7_VE0_VALID |
  818.                   GEN7_SURFACEFORMAT_R16G16_SSCALED << GEN7_VE0_FORMAT_SHIFT |
  819.                   0 << GEN7_VE0_OFFSET_SHIFT);
  820.         OUT_BATCH(GEN7_VFCOMPONENT_STORE_SRC << GEN7_VE1_VFCOMPONENT_0_SHIFT |
  821.                   GEN7_VFCOMPONENT_STORE_SRC << GEN7_VE1_VFCOMPONENT_1_SHIFT |
  822.                   GEN7_VFCOMPONENT_STORE_0 << GEN7_VE1_VFCOMPONENT_2_SHIFT |
  823.                   GEN7_VFCOMPONENT_STORE_1_FLT << GEN7_VE1_VFCOMPONENT_3_SHIFT);
  824.  
  825.         /* u0, v0, w0 */
  826.         DBG(("%s: first channel %d floats, offset=4b\n", __FUNCTION__, id & 3));
  827.         dw = GEN7_VFCOMPONENT_STORE_1_FLT << GEN7_VE1_VFCOMPONENT_3_SHIFT;
  828.         switch (id & 3) {
  829.         default:
  830.                 assert(0);
  831.         case 0:
  832.                 src_format = GEN7_SURFACEFORMAT_R16G16_SSCALED;
  833.                 dw |= GEN7_VFCOMPONENT_STORE_SRC << GEN7_VE1_VFCOMPONENT_0_SHIFT;
  834.                 dw |= GEN7_VFCOMPONENT_STORE_SRC << GEN7_VE1_VFCOMPONENT_1_SHIFT;
  835.                 dw |= GEN7_VFCOMPONENT_STORE_0 << GEN7_VE1_VFCOMPONENT_2_SHIFT;
  836.                 break;
  837.         case 1:
  838.                 src_format = GEN7_SURFACEFORMAT_R32_FLOAT;
  839.                 dw |= GEN7_VFCOMPONENT_STORE_SRC << GEN7_VE1_VFCOMPONENT_0_SHIFT;
  840.                 dw |= GEN7_VFCOMPONENT_STORE_0 << GEN7_VE1_VFCOMPONENT_1_SHIFT;
  841.                 dw |= GEN7_VFCOMPONENT_STORE_0 << GEN7_VE1_VFCOMPONENT_2_SHIFT;
  842.                 break;
  843.         case 2:
  844.                 src_format = GEN7_SURFACEFORMAT_R32G32_FLOAT;
  845.                 dw |= GEN7_VFCOMPONENT_STORE_SRC << GEN7_VE1_VFCOMPONENT_0_SHIFT;
  846.                 dw |= GEN7_VFCOMPONENT_STORE_SRC << GEN7_VE1_VFCOMPONENT_1_SHIFT;
  847.                 dw |= GEN7_VFCOMPONENT_STORE_0 << GEN7_VE1_VFCOMPONENT_2_SHIFT;
  848.                 break;
  849.         case 3:
  850.                 src_format = GEN7_SURFACEFORMAT_R32G32B32_FLOAT;
  851.                 dw |= GEN7_VFCOMPONENT_STORE_SRC << GEN7_VE1_VFCOMPONENT_0_SHIFT;
  852.                 dw |= GEN7_VFCOMPONENT_STORE_SRC << GEN7_VE1_VFCOMPONENT_1_SHIFT;
  853.                 dw |= GEN7_VFCOMPONENT_STORE_SRC << GEN7_VE1_VFCOMPONENT_2_SHIFT;
  854.                 break;
  855.         }
  856.         OUT_BATCH(id << GEN7_VE0_VERTEX_BUFFER_INDEX_SHIFT | GEN7_VE0_VALID |
  857.                   src_format << GEN7_VE0_FORMAT_SHIFT |
  858.                   4 << GEN7_VE0_OFFSET_SHIFT);
  859.         OUT_BATCH(dw);
  860.  
  861.         /* u1, v1, w1 */
  862.         if (has_mask) {
  863.                 unsigned offset = 4 + ((id & 3) ?: 1) * sizeof(float);
  864.                 DBG(("%s: second channel %d floats, offset=%db\n", __FUNCTION__, id >> 2, offset));
  865.                 dw = GEN7_VFCOMPONENT_STORE_1_FLT << GEN7_VE1_VFCOMPONENT_3_SHIFT;
  866.                 switch (id >> 2) {
  867.                 case 1:
  868.                         src_format = GEN7_SURFACEFORMAT_R32_FLOAT;
  869.                         dw |= GEN7_VFCOMPONENT_STORE_SRC << GEN7_VE1_VFCOMPONENT_0_SHIFT;
  870.                         dw |= GEN7_VFCOMPONENT_STORE_0 << GEN7_VE1_VFCOMPONENT_1_SHIFT;
  871.                         dw |= GEN7_VFCOMPONENT_STORE_0 << GEN7_VE1_VFCOMPONENT_2_SHIFT;
  872.                         break;
  873.                 default:
  874.                         assert(0);
  875.                 case 2:
  876.                         src_format = GEN7_SURFACEFORMAT_R32G32_FLOAT;
  877.                         dw |= GEN7_VFCOMPONENT_STORE_SRC << GEN7_VE1_VFCOMPONENT_0_SHIFT;
  878.                         dw |= GEN7_VFCOMPONENT_STORE_SRC << GEN7_VE1_VFCOMPONENT_1_SHIFT;
  879.                         dw |= GEN7_VFCOMPONENT_STORE_0 << GEN7_VE1_VFCOMPONENT_2_SHIFT;
  880.                         break;
  881.                 case 3:
  882.                         src_format = GEN7_SURFACEFORMAT_R32G32B32_FLOAT;
  883.                         dw |= GEN7_VFCOMPONENT_STORE_SRC << GEN7_VE1_VFCOMPONENT_0_SHIFT;
  884.                         dw |= GEN7_VFCOMPONENT_STORE_SRC << GEN7_VE1_VFCOMPONENT_1_SHIFT;
  885.                         dw |= GEN7_VFCOMPONENT_STORE_SRC << GEN7_VE1_VFCOMPONENT_2_SHIFT;
  886.                         break;
  887.                 }
  888.                 OUT_BATCH(id << GEN7_VE0_VERTEX_BUFFER_INDEX_SHIFT | GEN7_VE0_VALID |
  889.                           src_format << GEN7_VE0_FORMAT_SHIFT |
  890.                           offset << GEN7_VE0_OFFSET_SHIFT);
  891.                 OUT_BATCH(dw);
  892.         }
  893. }
  894.  
  895. inline static void
  896. gen7_emit_pipe_invalidate(struct sna *sna)
  897. {
  898.         OUT_BATCH(GEN7_PIPE_CONTROL | (4 - 2));
  899.         OUT_BATCH(GEN7_PIPE_CONTROL_WC_FLUSH |
  900.                   GEN7_PIPE_CONTROL_TC_FLUSH |
  901.                   GEN7_PIPE_CONTROL_CS_STALL);
  902.         OUT_BATCH(0);
  903.         OUT_BATCH(0);
  904. }
  905.  
  906. inline static void
  907. gen7_emit_pipe_flush(struct sna *sna)
  908. {
  909.         OUT_BATCH(GEN7_PIPE_CONTROL | (4 - 2));
  910.         OUT_BATCH(GEN7_PIPE_CONTROL_WC_FLUSH);
  911.         OUT_BATCH(0);
  912.         OUT_BATCH(0);
  913. }
  914.  
  915. inline static void
  916. gen7_emit_pipe_stall(struct sna *sna)
  917. {
  918.         OUT_BATCH(GEN7_PIPE_CONTROL | (4 - 2));
  919.         OUT_BATCH(GEN7_PIPE_CONTROL_CS_STALL |
  920.                   GEN7_PIPE_CONTROL_STALL_AT_SCOREBOARD);
  921.         OUT_BATCH(0);
  922.         OUT_BATCH(0);
  923. }
  924.  
  925. static void
  926. gen7_emit_state(struct sna *sna,
  927.                 const struct sna_composite_op *op,
  928.                 uint16_t wm_binding_table)
  929. {
  930.         bool need_stall;
  931.  
  932.         if (sna->render_state.gen7.emit_flush)
  933.                 gen7_emit_pipe_flush(sna);
  934.  
  935.         gen7_emit_cc(sna, GEN7_BLEND(op->u.gen7.flags));
  936.         gen7_emit_sampler(sna, GEN7_SAMPLER(op->u.gen7.flags));
  937.         gen7_emit_sf(sna, GEN7_VERTEX(op->u.gen7.flags) >> 2);
  938.         gen7_emit_wm(sna, GEN7_KERNEL(op->u.gen7.flags));
  939.         gen7_emit_vertex_elements(sna, op);
  940.  
  941.         need_stall = gen7_emit_binding_table(sna, wm_binding_table);
  942.         need_stall &= gen7_emit_drawing_rectangle(sna, op);
  943.  
  944.         if (kgem_bo_is_dirty(op->src.bo) || kgem_bo_is_dirty(op->mask.bo)) {
  945.                 gen7_emit_pipe_invalidate(sna);
  946.                 kgem_clear_dirty(&sna->kgem);
  947.                 if (op->dst.bo->exec)
  948.                         kgem_bo_mark_dirty(op->dst.bo);
  949.                 need_stall = false;
  950.         }
  951.         if (need_stall)
  952.                 gen7_emit_pipe_stall(sna);
  953.  
  954.         sna->render_state.gen7.emit_flush = GEN7_READS_DST(op->u.gen7.flags);
  955. }
  956.  
  957. static bool gen7_magic_ca_pass(struct sna *sna,
  958.                                const struct sna_composite_op *op)
  959. {
  960.         struct gen7_render_state *state = &sna->render_state.gen7;
  961.  
  962.         if (!op->need_magic_ca_pass)
  963.                 return false;
  964.  
  965.         DBG(("%s: CA fixup (%d -> %d)\n", __FUNCTION__,
  966.              sna->render.vertex_start, sna->render.vertex_index));
  967.  
  968.         gen7_emit_pipe_stall(sna);
  969.  
  970.         gen7_emit_cc(sna,
  971.                      GEN7_BLEND(gen7_get_blend(PictOpAdd, true,
  972.                                                op->dst.format)));
  973.         gen7_emit_wm(sna,
  974.                      gen7_choose_composite_kernel(PictOpAdd,
  975.                                                   true, true,
  976.                                                   op->is_affine));
  977.  
  978.         OUT_BATCH(GEN7_3DPRIMITIVE | (7- 2));
  979.         OUT_BATCH(GEN7_3DPRIMITIVE_VERTEX_SEQUENTIAL | _3DPRIM_RECTLIST);
  980.         OUT_BATCH(sna->render.vertex_index - sna->render.vertex_start);
  981.         OUT_BATCH(sna->render.vertex_start);
  982.         OUT_BATCH(1);   /* single instance */
  983.         OUT_BATCH(0);   /* start instance location */
  984.         OUT_BATCH(0);   /* index buffer offset, ignored */
  985.  
  986.         state->last_primitive = sna->kgem.nbatch;
  987.         return true;
  988. }
  989.  
  990. static void null_create(struct sna_static_stream *stream)
  991. {
  992.         /* A bunch of zeros useful for legacy border color and depth-stencil */
  993.         sna_static_stream_map(stream, 64, 64);
  994. }
  995.  
  996. static void
  997. sampler_state_init(struct gen7_sampler_state *sampler_state,
  998.                    sampler_filter_t filter,
  999.                    sampler_extend_t extend)
  1000. {
  1001.         sampler_state->ss0.lod_preclamp = 1;    /* GL mode */
  1002.  
  1003.         /* We use the legacy mode to get the semantics specified by
  1004.          * the Render extension. */
  1005.         sampler_state->ss0.default_color_mode = GEN7_BORDER_COLOR_MODE_LEGACY;
  1006.  
  1007.         switch (filter) {
  1008.         default:
  1009.         case SAMPLER_FILTER_NEAREST:
  1010.                 sampler_state->ss0.min_filter = GEN7_MAPFILTER_NEAREST;
  1011.                 sampler_state->ss0.mag_filter = GEN7_MAPFILTER_NEAREST;
  1012.                 break;
  1013.         case SAMPLER_FILTER_BILINEAR:
  1014.                 sampler_state->ss0.min_filter = GEN7_MAPFILTER_LINEAR;
  1015.                 sampler_state->ss0.mag_filter = GEN7_MAPFILTER_LINEAR;
  1016.                 break;
  1017.         }
  1018.  
  1019.         switch (extend) {
  1020.         default:
  1021.         case SAMPLER_EXTEND_NONE:
  1022.                 sampler_state->ss3.r_wrap_mode = GEN7_TEXCOORDMODE_CLAMP_BORDER;
  1023.                 sampler_state->ss3.s_wrap_mode = GEN7_TEXCOORDMODE_CLAMP_BORDER;
  1024.                 sampler_state->ss3.t_wrap_mode = GEN7_TEXCOORDMODE_CLAMP_BORDER;
  1025.                 break;
  1026.         case SAMPLER_EXTEND_REPEAT:
  1027.                 sampler_state->ss3.r_wrap_mode = GEN7_TEXCOORDMODE_WRAP;
  1028.                 sampler_state->ss3.s_wrap_mode = GEN7_TEXCOORDMODE_WRAP;
  1029.                 sampler_state->ss3.t_wrap_mode = GEN7_TEXCOORDMODE_WRAP;
  1030.                 break;
  1031.         case SAMPLER_EXTEND_PAD:
  1032.                 sampler_state->ss3.r_wrap_mode = GEN7_TEXCOORDMODE_CLAMP;
  1033.                 sampler_state->ss3.s_wrap_mode = GEN7_TEXCOORDMODE_CLAMP;
  1034.                 sampler_state->ss3.t_wrap_mode = GEN7_TEXCOORDMODE_CLAMP;
  1035.                 break;
  1036.         case SAMPLER_EXTEND_REFLECT:
  1037.                 sampler_state->ss3.r_wrap_mode = GEN7_TEXCOORDMODE_MIRROR;
  1038.                 sampler_state->ss3.s_wrap_mode = GEN7_TEXCOORDMODE_MIRROR;
  1039.                 sampler_state->ss3.t_wrap_mode = GEN7_TEXCOORDMODE_MIRROR;
  1040.                 break;
  1041.         }
  1042. }
  1043.  
  1044. static void
  1045. sampler_copy_init(struct gen7_sampler_state *ss)
  1046. {
  1047.         sampler_state_init(ss, SAMPLER_FILTER_NEAREST, SAMPLER_EXTEND_NONE);
  1048.         ss->ss3.non_normalized_coord = 1;
  1049.  
  1050.         sampler_state_init(ss+1, SAMPLER_FILTER_NEAREST, SAMPLER_EXTEND_NONE);
  1051. }
  1052.  
  1053. static void
  1054. sampler_fill_init(struct gen7_sampler_state *ss)
  1055. {
  1056.         sampler_state_init(ss, SAMPLER_FILTER_NEAREST, SAMPLER_EXTEND_REPEAT);
  1057.         ss->ss3.non_normalized_coord = 1;
  1058.  
  1059.         sampler_state_init(ss+1, SAMPLER_FILTER_NEAREST, SAMPLER_EXTEND_NONE);
  1060. }
  1061.  
  1062. static uint32_t
  1063. gen7_tiling_bits(uint32_t tiling)
  1064. {
  1065.         switch (tiling) {
  1066.         default: assert(0);
  1067.         case I915_TILING_NONE: return 0;
  1068.         case I915_TILING_X: return GEN7_SURFACE_TILED;
  1069.         case I915_TILING_Y: return GEN7_SURFACE_TILED | GEN7_SURFACE_TILED_Y;
  1070.         }
  1071. }
  1072.  
  1073. /**
  1074.  * Sets up the common fields for a surface state buffer for the given
  1075.  * picture in the given surface state buffer.
  1076.  */
  1077. static uint32_t
  1078. gen7_bind_bo(struct sna *sna,
  1079.              struct kgem_bo *bo,
  1080.              uint32_t width,
  1081.              uint32_t height,
  1082.              uint32_t format,
  1083.              bool is_dst)
  1084. {
  1085.         uint32_t *ss;
  1086.         uint32_t domains;
  1087.         int offset;
  1088.         uint32_t is_scanout = is_dst && bo->scanout;
  1089.  
  1090.         COMPILE_TIME_ASSERT(sizeof(struct gen7_surface_state) == 32);
  1091.  
  1092.         /* After the first bind, we manage the cache domains within the batch */
  1093.         offset = kgem_bo_get_binding(bo, format | is_scanout << 31);
  1094.         if (offset) {
  1095.                 if (is_dst)
  1096.                         kgem_bo_mark_dirty(bo);
  1097.                 return offset * sizeof(uint32_t);
  1098.         }
  1099.  
  1100.         offset = sna->kgem.surface -=
  1101.                 sizeof(struct gen7_surface_state) / sizeof(uint32_t);
  1102.         ss = sna->kgem.batch + offset;
  1103.         ss[0] = (GEN7_SURFACE_2D << GEN7_SURFACE_TYPE_SHIFT |
  1104.                  gen7_tiling_bits(bo->tiling) |
  1105.                  format << GEN7_SURFACE_FORMAT_SHIFT);
  1106.         if (is_dst)
  1107.                 domains = I915_GEM_DOMAIN_RENDER << 16 |I915_GEM_DOMAIN_RENDER;
  1108.         else
  1109.                 domains = I915_GEM_DOMAIN_SAMPLER << 16;
  1110.         ss[1] = kgem_add_reloc(&sna->kgem, offset + 1, bo, domains, 0);
  1111.         ss[2] = ((width - 1)  << GEN7_SURFACE_WIDTH_SHIFT |
  1112.                  (height - 1) << GEN7_SURFACE_HEIGHT_SHIFT);
  1113.         ss[3] = (bo->pitch - 1) << GEN7_SURFACE_PITCH_SHIFT;
  1114.         ss[4] = 0;
  1115.         ss[5] = is_scanout ? 0 : 3 << 16;
  1116.         ss[6] = 0;
  1117.         ss[7] = 0;
  1118.         if (sna->kgem.gen == 075)
  1119.                 ss[7] |= HSW_SURFACE_SWIZZLE(RED, GREEN, BLUE, ALPHA);
  1120.  
  1121.         kgem_bo_set_binding(bo, format | is_scanout << 31, offset);
  1122.  
  1123.         DBG(("[%x] bind bo(handle=%d, addr=%d), format=%d, width=%d, height=%d, pitch=%d, tiling=%d -> %s\n",
  1124.              offset, bo->handle, ss[1],
  1125.              format, width, height, bo->pitch, bo->tiling,
  1126.              domains & 0xffff ? "render" : "sampler"));
  1127.  
  1128.         return offset * sizeof(uint32_t);
  1129. }
  1130.  
  1131. static void gen7_emit_vertex_buffer(struct sna *sna,
  1132.                                     const struct sna_composite_op *op)
  1133. {
  1134.         int id = GEN7_VERTEX(op->u.gen7.flags);
  1135.  
  1136.         OUT_BATCH(GEN7_3DSTATE_VERTEX_BUFFERS | (5 - 2));
  1137.         OUT_BATCH(id << GEN7_VB0_BUFFER_INDEX_SHIFT |
  1138.                   GEN7_VB0_VERTEXDATA |
  1139.                   GEN7_VB0_ADDRESS_MODIFY_ENABLE |
  1140.                   4*op->floats_per_vertex << GEN7_VB0_BUFFER_PITCH_SHIFT);
  1141.         sna->render.vertex_reloc[sna->render.nvertex_reloc++] = sna->kgem.nbatch;
  1142.         OUT_BATCH(0);
  1143.         OUT_BATCH(~0); /* max address: disabled */
  1144.         OUT_BATCH(0);
  1145.  
  1146.         sna->render.vb_id |= 1 << id;
  1147. }
  1148.  
  1149. static void gen7_emit_primitive(struct sna *sna)
  1150. {
  1151.         if (sna->kgem.nbatch == sna->render_state.gen7.last_primitive) {
  1152.                 sna->render.vertex_offset = sna->kgem.nbatch - 5;
  1153.                 return;
  1154.         }
  1155.  
  1156.         OUT_BATCH(GEN7_3DPRIMITIVE | (7- 2));
  1157.         OUT_BATCH(GEN7_3DPRIMITIVE_VERTEX_SEQUENTIAL | _3DPRIM_RECTLIST);
  1158.         sna->render.vertex_offset = sna->kgem.nbatch;
  1159.         OUT_BATCH(0);   /* vertex count, to be filled in later */
  1160.         OUT_BATCH(sna->render.vertex_index);
  1161.         OUT_BATCH(1);   /* single instance */
  1162.         OUT_BATCH(0);   /* start instance location */
  1163.         OUT_BATCH(0);   /* index buffer offset, ignored */
  1164.         sna->render.vertex_start = sna->render.vertex_index;
  1165.  
  1166.         sna->render_state.gen7.last_primitive = sna->kgem.nbatch;
  1167. }
  1168.  
  1169. static bool gen7_rectangle_begin(struct sna *sna,
  1170.                                  const struct sna_composite_op *op)
  1171. {
  1172.         int id = 1 << GEN7_VERTEX(op->u.gen7.flags);
  1173.         int ndwords;
  1174.  
  1175.         if (sna_vertex_wait__locked(&sna->render) && sna->render.vertex_offset)
  1176.                 return true;
  1177.  
  1178.         ndwords = op->need_magic_ca_pass ? 60 : 6;
  1179.         if ((sna->render.vb_id & id) == 0)
  1180.                 ndwords += 5;
  1181.         if (!kgem_check_batch(&sna->kgem, ndwords))
  1182.                 return false;
  1183.  
  1184.         if ((sna->render.vb_id & id) == 0)
  1185.                 gen7_emit_vertex_buffer(sna, op);
  1186.  
  1187.         gen7_emit_primitive(sna);
  1188.         return true;
  1189. }
  1190.  
  1191. static int gen7_get_rectangles__flush(struct sna *sna,
  1192.                                       const struct sna_composite_op *op)
  1193. {
  1194.         /* Preventing discarding new vbo after lock contention */
  1195.         if (sna_vertex_wait__locked(&sna->render)) {
  1196.                 int rem = vertex_space(sna);
  1197.                 if (rem > op->floats_per_rect)
  1198.                         return rem;
  1199.         }
  1200.  
  1201.         if (!kgem_check_batch(&sna->kgem, op->need_magic_ca_pass ? 65 : 6))
  1202.                 return 0;
  1203.         if (!kgem_check_reloc_and_exec(&sna->kgem, 2))
  1204.                 return 0;
  1205.  
  1206.         if (sna->render.vertex_offset) {
  1207.                 gen4_vertex_flush(sna);
  1208.                 if (gen7_magic_ca_pass(sna, op)) {
  1209.                         gen7_emit_pipe_stall(sna);
  1210.                         gen7_emit_cc(sna, GEN7_BLEND(op->u.gen7.flags));
  1211.                         gen7_emit_wm(sna, GEN7_KERNEL(op->u.gen7.flags));
  1212.                 }
  1213.         }
  1214.  
  1215.         return gen4_vertex_finish(sna);
  1216. }
  1217.  
  1218. inline static int gen7_get_rectangles(struct sna *sna,
  1219.                                       const struct sna_composite_op *op,
  1220.                                       int want,
  1221.                                       void (*emit_state)(struct sna *sna, const struct sna_composite_op *op))
  1222. {
  1223.         int rem;
  1224.  
  1225.         assert(want);
  1226.  
  1227. start:
  1228.         rem = vertex_space(sna);
  1229.         if (unlikely(rem < op->floats_per_rect)) {
  1230.                 DBG(("flushing vbo for %s: %d < %d\n",
  1231.                      __FUNCTION__, rem, op->floats_per_rect));
  1232.                 rem = gen7_get_rectangles__flush(sna, op);
  1233.                 if (unlikely(rem == 0))
  1234.                         goto flush;
  1235.         }
  1236.  
  1237.         if (unlikely(sna->render.vertex_offset == 0)) {
  1238.                 if (!gen7_rectangle_begin(sna, op))
  1239.                         goto flush;
  1240.                 else
  1241.                         goto start;
  1242.         }
  1243.  
  1244.         assert(op->floats_per_rect >= vertex_space(sna));
  1245.         assert(rem <= vertex_space(sna));
  1246.         if (want > 1 && want * op->floats_per_rect > rem)
  1247.                 want = rem / op->floats_per_rect;
  1248.  
  1249.         assert(want > 0);
  1250.         sna->render.vertex_index += 3*want;
  1251.         return want;
  1252.  
  1253. flush:
  1254.         if (sna->render.vertex_offset) {
  1255.                 gen4_vertex_flush(sna);
  1256.                 gen7_magic_ca_pass(sna, op);
  1257.         }
  1258.         sna_vertex_wait__locked(&sna->render);
  1259.         _kgem_submit(&sna->kgem);
  1260.         emit_state(sna, op);
  1261.         goto start;
  1262. }
  1263.  
  1264. inline static uint32_t *gen7_composite_get_binding_table(struct sna *sna,
  1265.                                                          uint16_t *offset)
  1266. {
  1267.         uint32_t *table;
  1268.  
  1269.         sna->kgem.surface -=
  1270.                 sizeof(struct gen7_surface_state) / sizeof(uint32_t);
  1271.         /* Clear all surplus entries to zero in case of prefetch */
  1272.         table = memset(sna->kgem.batch + sna->kgem.surface,
  1273.                        0, sizeof(struct gen7_surface_state));
  1274.  
  1275.         DBG(("%s(%x)\n", __FUNCTION__, 4*sna->kgem.surface));
  1276.  
  1277.         *offset = sna->kgem.surface;
  1278.         return table;
  1279. }
  1280.  
  1281. static void
  1282. gen7_get_batch(struct sna *sna, const struct sna_composite_op *op)
  1283. {
  1284.         kgem_set_mode(&sna->kgem, KGEM_RENDER, op->dst.bo);
  1285.  
  1286.         if (!kgem_check_batch_with_surfaces(&sna->kgem, 150, 4)) {
  1287.                 DBG(("%s: flushing batch: %d < %d+%d\n",
  1288.                      __FUNCTION__, sna->kgem.surface - sna->kgem.nbatch,
  1289.                      150, 4*8));
  1290.                 _kgem_submit(&sna->kgem);
  1291.                 _kgem_set_mode(&sna->kgem, KGEM_RENDER);
  1292.         }
  1293.  
  1294.         assert(sna->kgem.mode == KGEM_RENDER);
  1295.         assert(sna->kgem.ring == KGEM_RENDER);
  1296.  
  1297.         if (sna->render_state.gen7.needs_invariant)
  1298.                 gen7_emit_invariant(sna);
  1299. }
  1300.  
  1301. static void gen7_emit_composite_state(struct sna *sna,
  1302.                                       const struct sna_composite_op *op)
  1303. {
  1304.         uint32_t *binding_table;
  1305.         uint16_t offset;
  1306.  
  1307.         gen7_get_batch(sna, op);
  1308.  
  1309.         binding_table = gen7_composite_get_binding_table(sna, &offset);
  1310.  
  1311.         binding_table[0] =
  1312.                 gen7_bind_bo(sna,
  1313.                             op->dst.bo, op->dst.width, op->dst.height,
  1314.                             gen7_get_dest_format(op->dst.format),
  1315.                             true);
  1316.         binding_table[1] =
  1317.                 gen7_bind_bo(sna,
  1318.                              op->src.bo, op->src.width, op->src.height,
  1319.                              op->src.card_format,
  1320.                              false);
  1321.         if (op->mask.bo) {
  1322.                 binding_table[2] =
  1323.                         gen7_bind_bo(sna,
  1324.                                      op->mask.bo,
  1325.                                      op->mask.width,
  1326.                                      op->mask.height,
  1327.                                      op->mask.card_format,
  1328.                                      false);
  1329.         }
  1330.  
  1331.         if (sna->kgem.surface == offset &&
  1332.             *(uint64_t *)(sna->kgem.batch + sna->render_state.gen7.surface_table) == *(uint64_t*)binding_table &&
  1333.             (op->mask.bo == NULL ||
  1334.              sna->kgem.batch[sna->render_state.gen7.surface_table+2] == binding_table[2])) {
  1335.                 sna->kgem.surface += sizeof(struct gen7_surface_state) / sizeof(uint32_t);
  1336.                 offset = sna->render_state.gen7.surface_table;
  1337.         }
  1338.  
  1339.         gen7_emit_state(sna, op, offset);
  1340. }
  1341.  
  1342. static void
  1343. gen7_align_vertex(struct sna *sna, const struct sna_composite_op *op)
  1344. {
  1345.         if (op->floats_per_vertex != sna->render_state.gen7.floats_per_vertex) {
  1346.                 if (sna->render.vertex_size - sna->render.vertex_used < 2*op->floats_per_rect)
  1347.                         gen4_vertex_finish(sna);
  1348.  
  1349.                 DBG(("aligning vertex: was %d, now %d floats per vertex, %d->%d\n",
  1350.                      sna->render_state.gen7.floats_per_vertex,
  1351.                      op->floats_per_vertex,
  1352.                      sna->render.vertex_index,
  1353.                      (sna->render.vertex_used + op->floats_per_vertex - 1) / op->floats_per_vertex));
  1354.                 sna->render.vertex_index = (sna->render.vertex_used + op->floats_per_vertex - 1) / op->floats_per_vertex;
  1355.                 sna->render.vertex_used = sna->render.vertex_index * op->floats_per_vertex;
  1356.                 sna->render_state.gen7.floats_per_vertex = op->floats_per_vertex;
  1357.         }
  1358. }
  1359.  
  1360. static uint32_t
  1361. gen7_composite_create_blend_state(struct sna_static_stream *stream)
  1362. {
  1363.         char *base, *ptr;
  1364.         int src, dst;
  1365.  
  1366.         base = sna_static_stream_map(stream,
  1367.                                      GEN7_BLENDFACTOR_COUNT * GEN7_BLENDFACTOR_COUNT * GEN7_BLEND_STATE_PADDED_SIZE,
  1368.                                      64);
  1369.  
  1370.         ptr = base;
  1371.         for (src = 0; src < GEN7_BLENDFACTOR_COUNT; src++) {
  1372.                 for (dst= 0; dst < GEN7_BLENDFACTOR_COUNT; dst++) {
  1373.                         struct gen7_blend_state *blend =
  1374.                                 (struct gen7_blend_state *)ptr;
  1375.  
  1376.                         blend->blend0.dest_blend_factor = dst;
  1377.                         blend->blend0.source_blend_factor = src;
  1378.                         blend->blend0.blend_func = GEN7_BLENDFUNCTION_ADD;
  1379.                         blend->blend0.blend_enable =
  1380.                                 !(dst == GEN7_BLENDFACTOR_ZERO && src == GEN7_BLENDFACTOR_ONE);
  1381.  
  1382.                         blend->blend1.post_blend_clamp_enable = 1;
  1383.                         blend->blend1.pre_blend_clamp_enable = 1;
  1384.  
  1385.                         ptr += GEN7_BLEND_STATE_PADDED_SIZE;
  1386.                 }
  1387.         }
  1388.  
  1389.         return sna_static_stream_offsetof(stream, base);
  1390. }
  1391.  
  1392.  
  1393. fastcall static void
  1394. gen7_render_composite_blt(struct sna *sna,
  1395.                           const struct sna_composite_op *op,
  1396.                           const struct sna_composite_rectangles *r)
  1397. {
  1398.         gen7_get_rectangles(sna, op, 1, gen7_emit_composite_state);
  1399.         op->prim_emit(sna, op, r);
  1400. }
  1401.  
  1402. static void gen7_render_composite_done(struct sna *sna,
  1403.                                        const struct sna_composite_op *op)
  1404. {
  1405.         if (sna->render.vertex_offset) {
  1406.                 gen4_vertex_flush(sna);
  1407.                 gen7_magic_ca_pass(sna, op);
  1408.         }
  1409. }
  1410.  
  1411.  
  1412. static bool
  1413. gen7_blit_tex(struct sna *sna,
  1414.               uint8_t op,
  1415.                       PixmapPtr src, struct kgem_bo *src_bo,
  1416.                       PixmapPtr mask,struct kgem_bo *mask_bo,
  1417.                       PixmapPtr dst, struct kgem_bo *dst_bo,
  1418.               int32_t src_x, int32_t src_y,
  1419.               int32_t msk_x, int32_t msk_y,
  1420.               int32_t dst_x, int32_t dst_y,
  1421.               int32_t width, int32_t height,
  1422.               struct sna_composite_op *tmp)
  1423. {
  1424.  
  1425.  
  1426.     tmp->op = PictOpSrc;
  1427.  
  1428.     tmp->dst.pixmap = dst;
  1429.     tmp->dst.bo     = dst_bo;
  1430.     tmp->dst.width  = dst->drawable.width;
  1431.     tmp->dst.height = dst->drawable.height;
  1432.     tmp->dst.format = PICT_x8r8g8b8;
  1433.  
  1434.  
  1435.         tmp->src.repeat = RepeatNone;
  1436.         tmp->src.filter = PictFilterNearest;
  1437.     tmp->src.is_affine = true;
  1438.  
  1439.     tmp->src.bo = src_bo;
  1440.         tmp->src.pict_format = PICT_x8r8g8b8;
  1441.     tmp->src.card_format = gen7_get_card_format(tmp->src.pict_format);
  1442.     tmp->src.width  = src->drawable.width;
  1443.     tmp->src.height = src->drawable.height;
  1444.  
  1445.  
  1446.         tmp->is_affine = tmp->src.is_affine;
  1447.         tmp->has_component_alpha = false;
  1448.         tmp->need_magic_ca_pass = false;
  1449.  
  1450.         tmp->mask.repeat = SAMPLER_EXTEND_NONE;
  1451.         tmp->mask.filter = SAMPLER_FILTER_NEAREST;
  1452.     tmp->mask.is_affine = true;
  1453.  
  1454.     tmp->mask.bo = mask_bo;
  1455.     tmp->mask.pict_format = PIXMAN_a8;
  1456.     tmp->mask.card_format = gen7_get_card_format(tmp->mask.pict_format);
  1457.     tmp->mask.width  = mask->drawable.width;
  1458.     tmp->mask.height = mask->drawable.height;
  1459.  
  1460.  
  1461.     tmp->src.scale[0] = 1.f/width;            //src->width;
  1462.     tmp->src.scale[1] = 1.f/height;            //src->height;
  1463.  
  1464.     tmp->mask.scale[0] = 1.f/mask->drawable.width;
  1465.     tmp->mask.scale[1] = 1.f/mask->drawable.height;
  1466.  
  1467.  
  1468.  
  1469.         tmp->u.gen7.flags =
  1470.                 GEN7_SET_FLAGS(SAMPLER_OFFSET(tmp->src.filter,
  1471.                                               tmp->src.repeat,
  1472.                                               tmp->mask.filter,
  1473.                                               tmp->mask.repeat),
  1474.                                gen7_get_blend(tmp->op,
  1475.                                               tmp->has_component_alpha,
  1476.                                               tmp->dst.format),
  1477. /*                             gen7_choose_composite_kernel(tmp->op,
  1478.                                                             tmp->mask.bo != NULL,
  1479.                                                             tmp->has_component_alpha,
  1480.                                                             tmp->is_affine), */
  1481.                    GEN7_WM_KERNEL_MASK,
  1482.                                gen4_choose_composite_emitter(tmp));
  1483.  
  1484.         tmp->blt   = gen7_render_composite_blt;
  1485. //      tmp->box   = gen7_render_composite_box;
  1486.         tmp->done  = gen7_render_composite_done;
  1487.  
  1488.         kgem_set_mode(&sna->kgem, KGEM_RENDER, tmp->dst.bo);
  1489.         if (!kgem_check_bo(&sna->kgem,
  1490.                            tmp->dst.bo, tmp->src.bo, tmp->mask.bo,
  1491.                            NULL)) {
  1492.                 kgem_submit(&sna->kgem);
  1493.                 _kgem_set_mode(&sna->kgem, KGEM_RENDER);
  1494.         }
  1495.  
  1496.         gen7_emit_composite_state(sna, tmp);
  1497.         gen7_align_vertex(sna, tmp);
  1498.         return true;
  1499. }
  1500.  
  1501.  
  1502.  
  1503.  
  1504.  
  1505. static void gen7_render_flush(struct sna *sna)
  1506. {
  1507.         gen4_vertex_close(sna);
  1508.  
  1509.         assert(sna->render.vb_id == 0);
  1510.         assert(sna->render.vertex_offset == 0);
  1511. }
  1512.  
  1513.  
  1514.  
  1515. static void
  1516. gen7_render_context_switch(struct kgem *kgem,
  1517.                            int new_mode)
  1518. {
  1519.         if (kgem->nbatch) {
  1520.                 DBG(("%s: switch rings %d -> %d\n",
  1521.                      __FUNCTION__, kgem->mode, new_mode));
  1522.                 _kgem_submit(kgem);
  1523.         }
  1524.  
  1525.         kgem->ring = new_mode;
  1526. }
  1527.  
  1528. static void
  1529. gen7_render_retire(struct kgem *kgem)
  1530. {
  1531.         struct sna *sna;
  1532.  
  1533.         if (kgem->ring && (kgem->has_semaphores || !kgem->need_retire))
  1534.                 kgem->ring = kgem->mode;
  1535.  
  1536.         sna = container_of(kgem, struct sna, kgem);
  1537.         if (kgem->nbatch == 0 && sna->render.vbo && !kgem_bo_is_busy(sna->render.vbo)) {
  1538.                 DBG(("%s: resetting idle vbo\n", __FUNCTION__));
  1539.                 sna->render.vertex_used = 0;
  1540.                 sna->render.vertex_index = 0;
  1541.         }
  1542. }
  1543.  
  1544. static void
  1545. gen7_render_expire(struct kgem *kgem)
  1546. {
  1547.         struct sna *sna;
  1548.  
  1549.         sna = container_of(kgem, struct sna, kgem);
  1550.         if (sna->render.vbo && !sna->render.vertex_used) {
  1551.                 DBG(("%s: discarding vbo\n", __FUNCTION__));
  1552.                 kgem_bo_destroy(kgem, sna->render.vbo);
  1553.                 sna->render.vbo = NULL;
  1554.                 sna->render.vertices = sna->render.vertex_data;
  1555.                 sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data);
  1556.                 sna->render.vertex_used = 0;
  1557.                 sna->render.vertex_index = 0;
  1558.         }
  1559. }
  1560.  
  1561. static void gen7_render_reset(struct sna *sna)
  1562. {
  1563.         sna->render_state.gen7.emit_flush = false;
  1564.         sna->render_state.gen7.needs_invariant = true;
  1565.         sna->render_state.gen7.ve_id = 3 << 2;
  1566.         sna->render_state.gen7.last_primitive = -1;
  1567.  
  1568.         sna->render_state.gen7.num_sf_outputs = 0;
  1569.         sna->render_state.gen7.samplers = -1;
  1570.         sna->render_state.gen7.blend = -1;
  1571.         sna->render_state.gen7.kernel = -1;
  1572.         sna->render_state.gen7.drawrect_offset = -1;
  1573.         sna->render_state.gen7.drawrect_limit = -1;
  1574.         sna->render_state.gen7.surface_table = -1;
  1575.  
  1576.         sna->render.vertex_offset = 0;
  1577.         sna->render.nvertex_reloc = 0;
  1578.         sna->render.vb_id = 0;
  1579. }
  1580.  
  1581. static void gen7_render_fini(struct sna *sna)
  1582. {
  1583.         kgem_bo_destroy(&sna->kgem, sna->render_state.gen7.general_bo);
  1584. }
  1585.  
  1586. static bool is_gt2(struct sna *sna)
  1587. {
  1588.         return DEVICE_ID(sna->PciInfo) & 0x20;
  1589. }
  1590.  
  1591. static bool is_mobile(struct sna *sna)
  1592. {
  1593.         return (DEVICE_ID(sna->PciInfo) & 0xf) == 0x6;
  1594. }
  1595.  
  1596.  
  1597. static bool gen7_render_setup(struct sna *sna)
  1598. {
  1599.     struct gen7_render_state *state = &sna->render_state.gen7;
  1600.     struct sna_static_stream general;
  1601.     struct gen7_sampler_state *ss;
  1602.     int i, j, k, l, m;
  1603.  
  1604.     if (sna->kgem.gen == 070) {
  1605.         state->info = &ivb_gt_info;
  1606.         if (DEVICE_ID(sna->PciInfo) & 0xf) {
  1607.             state->info = &ivb_gt1_info;
  1608.             if (is_gt2(sna))
  1609.                 state->info = &ivb_gt2_info; /* XXX requires GT_MODE WiZ disabled */
  1610.         }
  1611.     } else if (sna->kgem.gen == 075) {
  1612.         state->info = &hsw_gt_info;
  1613.         if (DEVICE_ID(sna->PciInfo) & 0xf) {
  1614.             state->info = &hsw_gt1_info;
  1615.             if (is_gt2(sna))
  1616.                 state->info = &hsw_gt2_info;
  1617.         }
  1618.     } else
  1619.         return false;
  1620.  
  1621.     sna_static_stream_init(&general);
  1622.  
  1623.     /* Zero pad the start. If you see an offset of 0x0 in the batchbuffer
  1624.      * dumps, you know it points to zero.
  1625.      */
  1626.     null_create(&general);
  1627.  
  1628.     for (m = 0; m < GEN7_WM_KERNEL_COUNT; m++) {
  1629.         if (wm_kernels[m].size) {
  1630.             state->wm_kernel[m][1] =
  1631.                 sna_static_stream_add(&general,
  1632.                               wm_kernels[m].data,
  1633.                               wm_kernels[m].size,
  1634.                               64);
  1635.         } else {
  1636.             if (USE_8_PIXEL_DISPATCH) {
  1637.                 state->wm_kernel[m][0] =
  1638.                     sna_static_stream_compile_wm(sna, &general,
  1639.                                      wm_kernels[m].data, 8);
  1640.             }
  1641.  
  1642.             if (USE_16_PIXEL_DISPATCH) {
  1643.                 state->wm_kernel[m][1] =
  1644.                     sna_static_stream_compile_wm(sna, &general,
  1645.                                      wm_kernels[m].data, 16);
  1646.             }
  1647.  
  1648.             if (USE_32_PIXEL_DISPATCH) {
  1649.                 state->wm_kernel[m][2] =
  1650.                     sna_static_stream_compile_wm(sna, &general,
  1651.                                      wm_kernels[m].data, 32);
  1652.             }
  1653.         }
  1654.         assert(state->wm_kernel[m][0]|state->wm_kernel[m][1]|state->wm_kernel[m][2]);
  1655.     }
  1656.  
  1657.     ss = sna_static_stream_map(&general,
  1658.                    2 * sizeof(*ss) *
  1659.                    (2 +
  1660.                     FILTER_COUNT * EXTEND_COUNT *
  1661.                     FILTER_COUNT * EXTEND_COUNT),
  1662.                    32);
  1663.     state->wm_state = sna_static_stream_offsetof(&general, ss);
  1664.     sampler_copy_init(ss); ss += 2;
  1665.     sampler_fill_init(ss); ss += 2;
  1666.     for (i = 0; i < FILTER_COUNT; i++) {
  1667.         for (j = 0; j < EXTEND_COUNT; j++) {
  1668.             for (k = 0; k < FILTER_COUNT; k++) {
  1669.                 for (l = 0; l < EXTEND_COUNT; l++) {
  1670.                     sampler_state_init(ss++, i, j);
  1671.                     sampler_state_init(ss++, k, l);
  1672.                 }
  1673.             }
  1674.         }
  1675.     }
  1676.  
  1677.     state->cc_blend = gen7_composite_create_blend_state(&general);
  1678.  
  1679.     state->general_bo = sna_static_stream_fini(sna, &general);
  1680.     return state->general_bo != NULL;
  1681. }
  1682.  
  1683.  
  1684. bool gen7_render_init(struct sna *sna)
  1685. {
  1686.     if (!gen7_render_setup(sna))
  1687.         return false;
  1688.  
  1689.     sna->kgem.context_switch = gen7_render_context_switch;
  1690.     sna->kgem.retire = gen7_render_retire;
  1691.     sna->kgem.expire = gen7_render_expire;
  1692.  
  1693.     sna->render.blit_tex = gen7_blit_tex;
  1694.    
  1695.     sna->render.flush = gen7_render_flush;
  1696.     sna->render.reset = gen7_render_reset;
  1697.     sna->render.fini = gen7_render_fini;
  1698.  
  1699.     sna->render.max_3d_size = GEN7_MAX_SIZE;
  1700.     sna->render.max_3d_pitch = 1 << 18;
  1701.     return true;
  1702. }
  1703.  
  1704.  
  1705.