Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Mesa 3-D graphics library
  3.  *
  4.  * Copyright (C) 2013 LunarG, Inc.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the "Software"),
  8.  * to deal in the Software without restriction, including without limitation
  9.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10.  * and/or sell copies of the Software, and to permit persons to whom the
  11.  * Software is furnished to do so, subject to the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice shall be included
  14.  * in all copies or substantial portions of the 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
  21.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  22.  * DEALINGS IN THE SOFTWARE.
  23.  *
  24.  * Authors:
  25.  *    Chia-I Wu <olv@lunarg.com>
  26.  */
  27.  
  28. #include "util/u_dual_blend.h"
  29. #include "intel_reg.h"
  30.  
  31. #include "ilo_common.h"
  32. #include "ilo_context.h"
  33. #include "ilo_cp.h"
  34. #include "ilo_gpe_gen7.h"
  35. #include "ilo_shader.h"
  36. #include "ilo_state.h"
  37. #include "ilo_3d_pipeline.h"
  38. #include "ilo_3d_pipeline_gen6.h"
  39. #include "ilo_3d_pipeline_gen7.h"
  40.  
  41. static void
  42. gen7_wa_pipe_control_cs_stall(struct ilo_3d_pipeline *p,
  43.                               bool change_multisample_state,
  44.                               bool change_depth_state)
  45. {
  46.    struct intel_bo *bo = NULL;
  47.    uint32_t dw1 = PIPE_CONTROL_CS_STALL;
  48.  
  49.    assert(p->dev->gen == ILO_GEN(7));
  50.  
  51.    /* emit once */
  52.    if (p->state.has_gen6_wa_pipe_control)
  53.       return;
  54.    p->state.has_gen6_wa_pipe_control = true;
  55.  
  56.    /*
  57.     * From the Ivy Bridge PRM, volume 2 part 1, page 258:
  58.     *
  59.     *     "Due to an HW issue driver needs to send a pipe control with stall
  60.     *      when ever there is state change in depth bias related state"
  61.     *
  62.     * From the Ivy Bridge PRM, volume 2 part 1, page 292:
  63.     *
  64.     *     "A PIPE_CONTOL command with the CS Stall bit set must be programmed
  65.     *      in the ring after this instruction
  66.     *      (3DSTATE_PUSH_CONSTANT_ALLOC_PS)."
  67.     *
  68.     * From the Ivy Bridge PRM, volume 2 part 1, page 304:
  69.     *
  70.     *     "Driver must ierarchi that all the caches in the depth pipe are
  71.     *      flushed before this command (3DSTATE_MULTISAMPLE) is parsed. This
  72.     *      requires driver to send a PIPE_CONTROL with a CS stall along with a
  73.     *      Depth Flush prior to this command.
  74.     *
  75.     * From the Ivy Bridge PRM, volume 2 part 1, page 315:
  76.     *
  77.     *     "Driver must send a least one PIPE_CONTROL command with CS Stall and
  78.     *      a post sync operation prior to the group of depth
  79.     *      commands(3DSTATE_DEPTH_BUFFER, 3DSTATE_CLEAR_PARAMS,
  80.     *      3DSTATE_STENCIL_BUFFER, and 3DSTATE_HIER_DEPTH_BUFFER)."
  81.     */
  82.  
  83.    if (change_multisample_state)
  84.       dw1 |= PIPE_CONTROL_DEPTH_CACHE_FLUSH;
  85.  
  86.    if (change_depth_state) {
  87.       dw1 |= PIPE_CONTROL_WRITE_IMMEDIATE;
  88.       bo = p->workaround_bo;
  89.    }
  90.  
  91.    p->gen6_PIPE_CONTROL(p->dev, dw1, bo, 0, false, p->cp);
  92. }
  93.  
  94. static void
  95. gen7_wa_pipe_control_vs_depth_stall(struct ilo_3d_pipeline *p)
  96. {
  97.    assert(p->dev->gen == ILO_GEN(7));
  98.  
  99.    /*
  100.     * From the Ivy Bridge PRM, volume 2 part 1, page 106:
  101.     *
  102.     *     "A PIPE_CONTROL with Post-Sync Operation set to 1h and a depth stall
  103.     *      needs to be sent just prior to any 3DSTATE_VS, 3DSTATE_URB_VS,
  104.     *      3DSTATE_CONSTANT_VS, 3DSTATE_BINDING_TABLE_POINTER_VS,
  105.     *      3DSTATE_SAMPLER_STATE_POINTER_VS command.  Only one PIPE_CONTROL
  106.     *      needs to be sent before any combination of VS associated 3DSTATE."
  107.     */
  108.    p->gen6_PIPE_CONTROL(p->dev,
  109.          PIPE_CONTROL_DEPTH_STALL |
  110.          PIPE_CONTROL_WRITE_IMMEDIATE,
  111.          p->workaround_bo, 0, false, p->cp);
  112. }
  113.  
  114. static void
  115. gen7_wa_pipe_control_wm_depth_stall(struct ilo_3d_pipeline *p,
  116.                                     bool change_depth_buffer)
  117. {
  118.    assert(p->dev->gen == ILO_GEN(7));
  119.  
  120.    /*
  121.     * From the Ivy Bridge PRM, volume 2 part 1, page 276:
  122.     *
  123.     *     "The driver must make sure a PIPE_CONTROL with the Depth Stall
  124.     *      Enable bit set after all the following states are programmed:
  125.     *
  126.     *       * 3DSTATE_PS
  127.     *       * 3DSTATE_VIEWPORT_STATE_POINTERS_CC
  128.     *       * 3DSTATE_CONSTANT_PS
  129.     *       * 3DSTATE_BINDING_TABLE_POINTERS_PS
  130.     *       * 3DSTATE_SAMPLER_STATE_POINTERS_PS
  131.     *       * 3DSTATE_CC_STATE_POINTERS
  132.     *       * 3DSTATE_BLEND_STATE_POINTERS
  133.     *       * 3DSTATE_DEPTH_STENCIL_STATE_POINTERS"
  134.     *
  135.     * From the Ivy Bridge PRM, volume 2 part 1, page 315:
  136.     *
  137.     *     "Restriction: Prior to changing Depth/Stencil Buffer state (i.e.,
  138.     *      any combination of 3DSTATE_DEPTH_BUFFER, 3DSTATE_CLEAR_PARAMS,
  139.     *      3DSTATE_STENCIL_BUFFER, 3DSTATE_HIER_DEPTH_BUFFER) SW must first
  140.     *      issue a pipelined depth stall (PIPE_CONTROL with Depth Stall bit
  141.     *      set), followed by a pipelined depth cache flush (PIPE_CONTROL with
  142.     *      Depth Flush Bit set, followed by another pipelined depth stall
  143.     *      (PIPE_CONTROL with Depth Stall Bit set), unless SW can otherwise
  144.     *      guarantee that the pipeline from WM onwards is already flushed
  145.     *      (e.g., via a preceding MI_FLUSH)."
  146.     */
  147.    p->gen6_PIPE_CONTROL(p->dev,
  148.          PIPE_CONTROL_DEPTH_STALL,
  149.          NULL, 0, false, p->cp);
  150.  
  151.    if (!change_depth_buffer)
  152.       return;
  153.  
  154.    p->gen6_PIPE_CONTROL(p->dev,
  155.          PIPE_CONTROL_DEPTH_CACHE_FLUSH,
  156.          NULL, 0, false, p->cp);
  157.  
  158.    p->gen6_PIPE_CONTROL(p->dev,
  159.          PIPE_CONTROL_DEPTH_STALL,
  160.          NULL, 0, false, p->cp);
  161. }
  162.  
  163. static void
  164. gen7_wa_pipe_control_wm_max_threads_stall(struct ilo_3d_pipeline *p)
  165. {
  166.    assert(p->dev->gen == ILO_GEN(7));
  167.  
  168.    /*
  169.     * From the Ivy Bridge PRM, volume 2 part 1, page 286:
  170.     *
  171.     *     "If this field (Maximum Number of Threads in 3DSTATE_WM) is changed
  172.     *      between 3DPRIMITIVE commands, a PIPE_CONTROL command with Stall at
  173.     *      Pixel Scoreboard set is required to be issued."
  174.     */
  175.    p->gen6_PIPE_CONTROL(p->dev,
  176.          PIPE_CONTROL_STALL_AT_SCOREBOARD,
  177.          NULL, 0, false, p->cp);
  178.  
  179. }
  180.  
  181. #define DIRTY(state) (session->pipe_dirty & ILO_DIRTY_ ## state)
  182.  
  183. static void
  184. gen7_pipeline_common_urb(struct ilo_3d_pipeline *p,
  185.                          const struct ilo_context *ilo,
  186.                          struct gen6_pipeline_session *session)
  187. {
  188.    /* 3DSTATE_URB_{VS,GS,HS,DS} */
  189.    if (DIRTY(VE) || DIRTY(VS)) {
  190.       /* the first 16KB are reserved for VS and PS PCBs */
  191.       const int offset = 16 * 1024;
  192.       int vs_entry_size, vs_total_size;
  193.  
  194.       vs_entry_size = (ilo->vs) ?
  195.          ilo_shader_get_kernel_param(ilo->vs, ILO_KERNEL_OUTPUT_COUNT) : 0;
  196.  
  197.       /*
  198.        * From the Ivy Bridge PRM, volume 2 part 1, page 35:
  199.        *
  200.        *     "Programming Restriction: As the VS URB entry serves as both the
  201.        *      per-vertex input and output of the VS shader, the VS URB
  202.        *      Allocation Size must be sized to the maximum of the vertex input
  203.        *      and output structures."
  204.        */
  205.       if (vs_entry_size < ilo->ve->count)
  206.          vs_entry_size = ilo->ve->count;
  207.  
  208.       vs_entry_size *= sizeof(float) * 4;
  209.       vs_total_size = ilo->dev->urb_size - offset;
  210.  
  211.       gen7_wa_pipe_control_vs_depth_stall(p);
  212.  
  213.       p->gen7_3DSTATE_URB_VS(p->dev,
  214.             offset, vs_total_size, vs_entry_size, p->cp);
  215.  
  216.       p->gen7_3DSTATE_URB_GS(p->dev, offset, 0, 0, p->cp);
  217.       p->gen7_3DSTATE_URB_HS(p->dev, offset, 0, 0, p->cp);
  218.       p->gen7_3DSTATE_URB_DS(p->dev, offset, 0, 0, p->cp);
  219.    }
  220. }
  221.  
  222. static void
  223. gen7_pipeline_common_pcb_alloc(struct ilo_3d_pipeline *p,
  224.                                const struct ilo_context *ilo,
  225.                                struct gen6_pipeline_session *session)
  226. {
  227.    /* 3DSTATE_PUSH_CONSTANT_ALLOC_{VS,PS} */
  228.    if (session->hw_ctx_changed) {
  229.       /*
  230.        * push constant buffers are only allowed to take up at most the first
  231.        * 16KB of the URB
  232.        */
  233.       p->gen7_3DSTATE_PUSH_CONSTANT_ALLOC_VS(p->dev,
  234.             0, 8192, p->cp);
  235.  
  236.       p->gen7_3DSTATE_PUSH_CONSTANT_ALLOC_PS(p->dev,
  237.             8192, 8192, p->cp);
  238.  
  239.       gen7_wa_pipe_control_cs_stall(p, true, true);
  240.    }
  241. }
  242.  
  243. static void
  244. gen7_pipeline_common_pointers_1(struct ilo_3d_pipeline *p,
  245.                                 const struct ilo_context *ilo,
  246.                                 struct gen6_pipeline_session *session)
  247. {
  248.    /* 3DSTATE_VIEWPORT_STATE_POINTERS_{CC,SF_CLIP} */
  249.    if (session->viewport_state_changed) {
  250.       p->gen7_3DSTATE_VIEWPORT_STATE_POINTERS_CC(p->dev,
  251.             p->state.CC_VIEWPORT, p->cp);
  252.  
  253.       p->gen7_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP(p->dev,
  254.             p->state.SF_CLIP_VIEWPORT, p->cp);
  255.    }
  256. }
  257.  
  258. static void
  259. gen7_pipeline_common_pointers_2(struct ilo_3d_pipeline *p,
  260.                                 const struct ilo_context *ilo,
  261.                                 struct gen6_pipeline_session *session)
  262. {
  263.    /* 3DSTATE_BLEND_STATE_POINTERS */
  264.    if (session->cc_state_blend_changed) {
  265.       p->gen7_3DSTATE_BLEND_STATE_POINTERS(p->dev,
  266.             p->state.BLEND_STATE, p->cp);
  267.    }
  268.  
  269.    /* 3DSTATE_CC_STATE_POINTERS */
  270.    if (session->cc_state_cc_changed) {
  271.       p->gen7_3DSTATE_CC_STATE_POINTERS(p->dev,
  272.             p->state.COLOR_CALC_STATE, p->cp);
  273.    }
  274.  
  275.    /* 3DSTATE_DEPTH_STENCIL_STATE_POINTERS */
  276.    if (session->cc_state_dsa_changed) {
  277.       p->gen7_3DSTATE_DEPTH_STENCIL_STATE_POINTERS(p->dev,
  278.             p->state.DEPTH_STENCIL_STATE, p->cp);
  279.    }
  280. }
  281.  
  282. static void
  283. gen7_pipeline_vs(struct ilo_3d_pipeline *p,
  284.                  const struct ilo_context *ilo,
  285.                  struct gen6_pipeline_session *session)
  286. {
  287.    const bool emit_3dstate_binding_table = session->binding_table_vs_changed;
  288.    const bool emit_3dstate_sampler_state = session->sampler_state_vs_changed;
  289.    /* see gen6_pipeline_vs() */
  290.    const bool emit_3dstate_constant_vs = session->pcb_state_vs_changed;
  291.    const bool emit_3dstate_vs = (DIRTY(VS) || DIRTY(SAMPLER_VS));
  292.  
  293.    /* emit depth stall before any of the VS commands */
  294.    if (emit_3dstate_binding_table || emit_3dstate_sampler_state ||
  295.        emit_3dstate_constant_vs || emit_3dstate_vs)
  296.        gen7_wa_pipe_control_vs_depth_stall(p);
  297.  
  298.    /* 3DSTATE_BINDING_TABLE_POINTERS_VS */
  299.    if (emit_3dstate_binding_table) {
  300.       p->gen7_3DSTATE_BINDING_TABLE_POINTERS_VS(p->dev,
  301.             p->state.vs.BINDING_TABLE_STATE, p->cp);
  302.    }
  303.  
  304.    /* 3DSTATE_SAMPLER_STATE_POINTERS_VS */
  305.    if (emit_3dstate_sampler_state) {
  306.       p->gen7_3DSTATE_SAMPLER_STATE_POINTERS_VS(p->dev,
  307.             p->state.vs.SAMPLER_STATE, p->cp);
  308.    }
  309.  
  310.    gen6_pipeline_vs(p, ilo, session);
  311. }
  312.  
  313. static void
  314. gen7_pipeline_hs(struct ilo_3d_pipeline *p,
  315.                  const struct ilo_context *ilo,
  316.                  struct gen6_pipeline_session *session)
  317. {
  318.    /* 3DSTATE_CONSTANT_HS and 3DSTATE_HS */
  319.    if (session->hw_ctx_changed) {
  320.       p->gen7_3DSTATE_CONSTANT_HS(p->dev, 0, 0, 0, p->cp);
  321.       p->gen7_3DSTATE_HS(p->dev, NULL, 0, p->cp);
  322.    }
  323.  
  324.    /* 3DSTATE_BINDING_TABLE_POINTERS_HS */
  325.    if (session->hw_ctx_changed)
  326.       p->gen7_3DSTATE_BINDING_TABLE_POINTERS_HS(p->dev, 0, p->cp);
  327. }
  328.  
  329. static void
  330. gen7_pipeline_te(struct ilo_3d_pipeline *p,
  331.                  const struct ilo_context *ilo,
  332.                  struct gen6_pipeline_session *session)
  333. {
  334.    /* 3DSTATE_TE */
  335.    if (session->hw_ctx_changed)
  336.       p->gen7_3DSTATE_TE(p->dev, p->cp);
  337. }
  338.  
  339. static void
  340. gen7_pipeline_ds(struct ilo_3d_pipeline *p,
  341.                  const struct ilo_context *ilo,
  342.                  struct gen6_pipeline_session *session)
  343. {
  344.    /* 3DSTATE_CONSTANT_DS and 3DSTATE_DS */
  345.    if (session->hw_ctx_changed) {
  346.       p->gen7_3DSTATE_CONSTANT_DS(p->dev, 0, 0, 0, p->cp);
  347.       p->gen7_3DSTATE_DS(p->dev, NULL, 0, p->cp);
  348.    }
  349.  
  350.    /* 3DSTATE_BINDING_TABLE_POINTERS_DS */
  351.    if (session->hw_ctx_changed)
  352.       p->gen7_3DSTATE_BINDING_TABLE_POINTERS_DS(p->dev, 0, p->cp);
  353.  
  354. }
  355.  
  356. static void
  357. gen7_pipeline_gs(struct ilo_3d_pipeline *p,
  358.                  const struct ilo_context *ilo,
  359.                  struct gen6_pipeline_session *session)
  360. {
  361.    /* 3DSTATE_CONSTANT_GS and 3DSTATE_GS */
  362.    if (session->hw_ctx_changed) {
  363.       p->gen6_3DSTATE_CONSTANT_GS(p->dev, 0, 0, 0, p->cp);
  364.       p->gen7_3DSTATE_GS(p->dev, NULL, 0, p->cp);
  365.    }
  366.  
  367.    /* 3DSTATE_BINDING_TABLE_POINTERS_GS */
  368.    if (session->binding_table_gs_changed) {
  369.       p->gen7_3DSTATE_BINDING_TABLE_POINTERS_GS(p->dev,
  370.             p->state.gs.BINDING_TABLE_STATE, p->cp);
  371.    }
  372. }
  373.  
  374. static void
  375. gen7_pipeline_sol(struct ilo_3d_pipeline *p,
  376.                   const struct ilo_context *ilo,
  377.                   struct gen6_pipeline_session *session)
  378. {
  379.    const struct pipe_stream_output_info *so_info;
  380.    const struct ilo_shader_state *shader;
  381.    bool dirty_sh = false;
  382.  
  383.    if (ilo->gs) {
  384.       shader = ilo->gs;
  385.       dirty_sh = DIRTY(GS);
  386.    }
  387.    else {
  388.       shader = ilo->vs;
  389.       dirty_sh = DIRTY(VS);
  390.    }
  391.  
  392.    so_info = ilo_shader_get_kernel_so_info(shader);
  393.  
  394.    gen6_pipeline_update_max_svbi(p, ilo, session);
  395.  
  396.    /* 3DSTATE_SO_BUFFER */
  397.    if ((DIRTY(SO) || dirty_sh || session->batch_bo_changed) &&
  398.        ilo->so.enabled) {
  399.       int i;
  400.  
  401.       for (i = 0; i < ilo->so.count; i++) {
  402.          const int stride = so_info->stride[i] * 4; /* in bytes */
  403.          int base = 0;
  404.  
  405.          /* reset HW write offsets and offset buffer base */
  406.          if (!p->cp->render_ctx) {
  407.             ilo_cp_set_one_off_flags(p->cp, INTEL_EXEC_GEN7_SOL_RESET);
  408.             base += p->state.so_num_vertices * stride;
  409.          }
  410.  
  411.          p->gen7_3DSTATE_SO_BUFFER(p->dev, i, base, stride,
  412.                ilo->so.states[i], p->cp);
  413.       }
  414.  
  415.       for (; i < 4; i++)
  416.          p->gen7_3DSTATE_SO_BUFFER(p->dev, i, 0, 0, NULL, p->cp);
  417.    }
  418.  
  419.    /* 3DSTATE_SO_DECL_LIST */
  420.    if (dirty_sh && ilo->so.enabled)
  421.       p->gen7_3DSTATE_SO_DECL_LIST(p->dev, so_info, p->cp);
  422.  
  423.    /* 3DSTATE_STREAMOUT */
  424.    if (DIRTY(SO) || DIRTY(RASTERIZER) || dirty_sh) {
  425.       const unsigned buffer_mask = (1 << ilo->so.count) - 1;
  426.       const int output_count = ilo_shader_get_kernel_param(shader,
  427.             ILO_KERNEL_OUTPUT_COUNT);
  428.  
  429.       p->gen7_3DSTATE_STREAMOUT(p->dev, buffer_mask, output_count,
  430.             ilo->rasterizer->state.rasterizer_discard, p->cp);
  431.    }
  432. }
  433.  
  434. static void
  435. gen7_pipeline_sf(struct ilo_3d_pipeline *p,
  436.                  const struct ilo_context *ilo,
  437.                  struct gen6_pipeline_session *session)
  438. {
  439.    /* 3DSTATE_SBE */
  440.    if (DIRTY(RASTERIZER) || DIRTY(VS) || DIRTY(GS) || DIRTY(FS)) {
  441.       p->gen7_3DSTATE_SBE(p->dev, ilo->rasterizer, ilo->fs,
  442.             (ilo->gs) ? ilo->gs : ilo->vs, ilo->cp);
  443.    }
  444.  
  445.    /* 3DSTATE_SF */
  446.    if (DIRTY(RASTERIZER) || DIRTY(FB)) {
  447.       gen7_wa_pipe_control_cs_stall(p, true, true);
  448.       p->gen7_3DSTATE_SF(p->dev, ilo->rasterizer, ilo->fb.state.zsbuf, p->cp);
  449.    }
  450. }
  451.  
  452. static void
  453. gen7_pipeline_wm(struct ilo_3d_pipeline *p,
  454.                  const struct ilo_context *ilo,
  455.                  struct gen6_pipeline_session *session)
  456. {
  457.    /* 3DSTATE_WM */
  458.    if (DIRTY(FS) || DIRTY(BLEND) || DIRTY(DSA) || DIRTY(RASTERIZER)) {
  459.       const bool cc_may_kill = (ilo->dsa->alpha.enabled ||
  460.                                 ilo->blend->alpha_to_coverage);
  461.  
  462.       if (p->dev->gen == ILO_GEN(7) && session->hw_ctx_changed)
  463.          gen7_wa_pipe_control_wm_max_threads_stall(p);
  464.  
  465.       p->gen7_3DSTATE_WM(p->dev, ilo->fs,
  466.             ilo->rasterizer, cc_may_kill, p->cp);
  467.    }
  468.  
  469.    /* 3DSTATE_BINDING_TABLE_POINTERS_PS */
  470.    if (session->binding_table_fs_changed) {
  471.       p->gen7_3DSTATE_BINDING_TABLE_POINTERS_PS(p->dev,
  472.             p->state.wm.BINDING_TABLE_STATE, p->cp);
  473.    }
  474.  
  475.    /* 3DSTATE_SAMPLER_STATE_POINTERS_PS */
  476.    if (session->sampler_state_fs_changed) {
  477.       p->gen7_3DSTATE_SAMPLER_STATE_POINTERS_PS(p->dev,
  478.             p->state.wm.SAMPLER_STATE, p->cp);
  479.    }
  480.  
  481.    /* 3DSTATE_CONSTANT_PS */
  482.    if (session->pcb_state_fs_changed)
  483.       p->gen6_3DSTATE_CONSTANT_PS(p->dev, NULL, NULL, 0, p->cp);
  484.  
  485.    /* 3DSTATE_PS */
  486.    if (DIRTY(FS) || DIRTY(SAMPLER_FS) || DIRTY(BLEND) ||
  487.        session->kernel_bo_changed) {
  488.       const int num_samplers = ilo->sampler[PIPE_SHADER_FRAGMENT].count;
  489.       const bool dual_blend = ilo->blend->dual_blend;
  490.  
  491.       p->gen7_3DSTATE_PS(p->dev, ilo->fs, num_samplers, dual_blend, p->cp);
  492.    }
  493.  
  494.    /* 3DSTATE_SCISSOR_STATE_POINTERS */
  495.    if (session->scissor_state_changed) {
  496.       p->gen6_3DSTATE_SCISSOR_STATE_POINTERS(p->dev,
  497.             p->state.SCISSOR_RECT, p->cp);
  498.    }
  499.  
  500.    /* XXX what is the best way to know if this workaround is needed? */
  501.    {
  502.       const bool emit_3dstate_ps =
  503.          (DIRTY(FS) || DIRTY(SAMPLER_FS) || DIRTY(BLEND));
  504.       const bool emit_3dstate_depth_buffer =
  505.          (DIRTY(FB) || DIRTY(DSA) || session->state_bo_changed);
  506.  
  507.       if (emit_3dstate_ps ||
  508.           emit_3dstate_depth_buffer ||
  509.           session->pcb_state_fs_changed ||
  510.           session->viewport_state_changed ||
  511.           session->binding_table_fs_changed ||
  512.           session->sampler_state_fs_changed ||
  513.           session->cc_state_cc_changed ||
  514.           session->cc_state_blend_changed ||
  515.           session->cc_state_dsa_changed)
  516.          gen7_wa_pipe_control_wm_depth_stall(p, emit_3dstate_depth_buffer);
  517.    }
  518.  
  519.    /* 3DSTATE_DEPTH_BUFFER and 3DSTATE_CLEAR_PARAMS */
  520.    if (DIRTY(FB) || session->batch_bo_changed) {
  521.       const struct ilo_zs_surface *zs;
  522.  
  523.       if (ilo->fb.state.zsbuf) {
  524.          const struct ilo_surface_cso *surface =
  525.             (const struct ilo_surface_cso *) ilo->fb.state.zsbuf;
  526.  
  527.          assert(!surface->is_rt);
  528.          zs = &surface->u.zs;
  529.       }
  530.       else {
  531.          zs = &ilo->fb.null_zs;
  532.       }
  533.  
  534.       p->gen7_3DSTATE_DEPTH_BUFFER(p->dev, zs, p->cp);
  535.       p->gen6_3DSTATE_HIER_DEPTH_BUFFER(p->dev, zs, p->cp);
  536.       p->gen6_3DSTATE_STENCIL_BUFFER(p->dev, zs, p->cp);
  537.  
  538.       /* TODO */
  539.       p->gen6_3DSTATE_CLEAR_PARAMS(p->dev, 0, p->cp);
  540.    }
  541. }
  542.  
  543. static void
  544. gen7_pipeline_wm_multisample(struct ilo_3d_pipeline *p,
  545.                              const struct ilo_context *ilo,
  546.                              struct gen6_pipeline_session *session)
  547. {
  548.    /* 3DSTATE_MULTISAMPLE and 3DSTATE_SAMPLE_MASK */
  549.    if (DIRTY(SAMPLE_MASK) || DIRTY(FB)) {
  550.       const uint32_t *packed_sample_pos;
  551.  
  552.       gen7_wa_pipe_control_cs_stall(p, true, true);
  553.  
  554.       packed_sample_pos =
  555.          (ilo->fb.num_samples > 4) ? p->packed_sample_position_8x :
  556.          (ilo->fb.num_samples > 1) ? &p->packed_sample_position_4x :
  557.          &p->packed_sample_position_1x;
  558.  
  559.       p->gen6_3DSTATE_MULTISAMPLE(p->dev,
  560.             ilo->fb.num_samples, packed_sample_pos,
  561.             ilo->rasterizer->state.half_pixel_center, p->cp);
  562.  
  563.       p->gen7_3DSTATE_SAMPLE_MASK(p->dev,
  564.             (ilo->fb.num_samples > 1) ? ilo->sample_mask : 0x1,
  565.             ilo->fb.num_samples, p->cp);
  566.    }
  567. }
  568.  
  569. static void
  570. gen7_pipeline_commands(struct ilo_3d_pipeline *p,
  571.                        const struct ilo_context *ilo,
  572.                        struct gen6_pipeline_session *session)
  573. {
  574.    /*
  575.     * We try to keep the order of the commands match, as closely as possible,
  576.     * that of the classic i965 driver.  It allows us to compare the command
  577.     * streams easily.
  578.     */
  579.    gen6_pipeline_common_select(p, ilo, session);
  580.    gen6_pipeline_common_sip(p, ilo, session);
  581.    gen6_pipeline_vf_statistics(p, ilo, session);
  582.    gen7_pipeline_common_pcb_alloc(p, ilo, session);
  583.    gen6_pipeline_common_base_address(p, ilo, session);
  584.    gen7_pipeline_common_pointers_1(p, ilo, session);
  585.    gen7_pipeline_common_urb(p, ilo, session);
  586.    gen7_pipeline_common_pointers_2(p, ilo, session);
  587.    gen7_pipeline_wm_multisample(p, ilo, session);
  588.    gen7_pipeline_gs(p, ilo, session);
  589.    gen7_pipeline_hs(p, ilo, session);
  590.    gen7_pipeline_te(p, ilo, session);
  591.    gen7_pipeline_ds(p, ilo, session);
  592.    gen7_pipeline_vs(p, ilo, session);
  593.    gen7_pipeline_sol(p, ilo, session);
  594.    gen6_pipeline_clip(p, ilo, session);
  595.    gen7_pipeline_sf(p, ilo, session);
  596.    gen7_pipeline_wm(p, ilo, session);
  597.    gen6_pipeline_wm_raster(p, ilo, session);
  598.    gen6_pipeline_sf_rect(p, ilo, session);
  599.    gen6_pipeline_vf(p, ilo, session);
  600.    gen6_pipeline_vf_draw(p, ilo, session);
  601. }
  602.  
  603. static void
  604. ilo_3d_pipeline_emit_draw_gen7(struct ilo_3d_pipeline *p,
  605.                                const struct ilo_context *ilo)
  606. {
  607.    struct gen6_pipeline_session session;
  608.  
  609.    gen6_pipeline_prepare(p, ilo, &session);
  610.  
  611.    session.emit_draw_states = gen6_pipeline_states;
  612.    session.emit_draw_commands = gen7_pipeline_commands;
  613.  
  614.    gen6_pipeline_draw(p, ilo, &session);
  615.    gen6_pipeline_end(p, ilo, &session);
  616. }
  617.  
  618. static int
  619. gen7_pipeline_estimate_commands(const struct ilo_3d_pipeline *p,
  620.                                 const struct ilo_gpe_gen7 *gen7,
  621.                                 const struct ilo_context *ilo)
  622. {
  623.    static int size;
  624.    enum ilo_gpe_gen7_command cmd;
  625.  
  626.    if (size)
  627.       return size;
  628.  
  629.    for (cmd = 0; cmd < ILO_GPE_GEN7_COMMAND_COUNT; cmd++) {
  630.       int count;
  631.  
  632.       switch (cmd) {
  633.       case ILO_GPE_GEN7_PIPE_CONTROL:
  634.          /* for the workaround */
  635.          count = 2;
  636.          /* another one after 3DSTATE_URB */
  637.          count += 1;
  638.          /* and another one after 3DSTATE_CONSTANT_VS */
  639.          count += 1;
  640.          break;
  641.       case ILO_GPE_GEN7_3DSTATE_VERTEX_BUFFERS:
  642.          count = 33;
  643.          break;
  644.       case ILO_GPE_GEN7_3DSTATE_VERTEX_ELEMENTS:
  645.          count = 34;
  646.          break;
  647.       case ILO_GPE_GEN7_MEDIA_VFE_STATE:
  648.       case ILO_GPE_GEN7_MEDIA_CURBE_LOAD:
  649.       case ILO_GPE_GEN7_MEDIA_INTERFACE_DESCRIPTOR_LOAD:
  650.       case ILO_GPE_GEN7_MEDIA_STATE_FLUSH:
  651.       case ILO_GPE_GEN7_GPGPU_WALKER:
  652.          /* media commands */
  653.          count = 0;
  654.          break;
  655.       default:
  656.          count = 1;
  657.          break;
  658.       }
  659.  
  660.       if (count) {
  661.          size += gen7->estimate_command_size(p->dev,
  662.                cmd, count);
  663.       }
  664.    }
  665.  
  666.    return size;
  667. }
  668.  
  669. static int
  670. gen7_pipeline_estimate_states(const struct ilo_3d_pipeline *p,
  671.                               const struct ilo_gpe_gen7 *gen7,
  672.                               const struct ilo_context *ilo)
  673. {
  674.    static int static_size;
  675.    int shader_type, count, size;
  676.  
  677.    if (!static_size) {
  678.       struct {
  679.          enum ilo_gpe_gen7_state state;
  680.          int count;
  681.       } static_states[] = {
  682.          /* viewports */
  683.          { ILO_GPE_GEN7_SF_CLIP_VIEWPORT,            1 },
  684.          { ILO_GPE_GEN7_CC_VIEWPORT,                 1 },
  685.          /* cc */
  686.          { ILO_GPE_GEN7_COLOR_CALC_STATE,            1 },
  687.          { ILO_GPE_GEN7_BLEND_STATE,                 ILO_MAX_DRAW_BUFFERS },
  688.          { ILO_GPE_GEN7_DEPTH_STENCIL_STATE,         1 },
  689.          /* scissors */
  690.          { ILO_GPE_GEN7_SCISSOR_RECT,                1 },
  691.          /* binding table (vs, gs, fs) */
  692.          { ILO_GPE_GEN7_BINDING_TABLE_STATE,         ILO_MAX_VS_SURFACES },
  693.          { ILO_GPE_GEN7_BINDING_TABLE_STATE,         ILO_MAX_GS_SURFACES },
  694.          { ILO_GPE_GEN7_BINDING_TABLE_STATE,         ILO_MAX_WM_SURFACES },
  695.       };
  696.       int i;
  697.  
  698.       for (i = 0; i < Elements(static_states); i++) {
  699.          static_size += gen7->estimate_state_size(p->dev,
  700.                static_states[i].state,
  701.                static_states[i].count);
  702.       }
  703.    }
  704.  
  705.    size = static_size;
  706.  
  707.    /*
  708.     * render targets (fs)
  709.     * sampler views (vs, fs)
  710.     * constant buffers (vs, fs)
  711.     */
  712.    count = ilo->fb.state.nr_cbufs;
  713.    for (shader_type = 0; shader_type < PIPE_SHADER_TYPES; shader_type++) {
  714.       count += ilo->view[shader_type].count;
  715.       count += util_bitcount(ilo->cbuf[shader_type].enabled_mask);
  716.    }
  717.  
  718.    if (count) {
  719.       size += gen7->estimate_state_size(p->dev,
  720.             ILO_GPE_GEN7_SURFACE_STATE, count);
  721.    }
  722.  
  723.    /* samplers (vs, fs) */
  724.    for (shader_type = 0; shader_type < PIPE_SHADER_TYPES; shader_type++) {
  725.       count = ilo->sampler[shader_type].count;
  726.       if (count) {
  727.          size += gen7->estimate_state_size(p->dev,
  728.                ILO_GPE_GEN7_SAMPLER_BORDER_COLOR_STATE, count);
  729.          size += gen7->estimate_state_size(p->dev,
  730.                ILO_GPE_GEN7_SAMPLER_STATE, count);
  731.       }
  732.    }
  733.  
  734.    /* pcb (vs) */
  735.    if (ilo->vs &&
  736.        ilo_shader_get_kernel_param(ilo->vs, ILO_KERNEL_VS_PCB_UCP_SIZE)) {
  737.       const int pcb_size =
  738.          ilo_shader_get_kernel_param(ilo->vs, ILO_KERNEL_VS_PCB_UCP_SIZE);
  739.  
  740.       size += gen7->estimate_state_size(p->dev,
  741.             ILO_GPE_GEN7_PUSH_CONSTANT_BUFFER, pcb_size);
  742.    }
  743.  
  744.    return size;
  745. }
  746.  
  747. static int
  748. ilo_3d_pipeline_estimate_size_gen7(struct ilo_3d_pipeline *p,
  749.                                    enum ilo_3d_pipeline_action action,
  750.                                    const void *arg)
  751. {
  752.    const struct ilo_gpe_gen7 *gen7 = ilo_gpe_gen7_get();
  753.    int size;
  754.  
  755.    switch (action) {
  756.    case ILO_3D_PIPELINE_DRAW:
  757.       {
  758.          const struct ilo_context *ilo = arg;
  759.  
  760.          size = gen7_pipeline_estimate_commands(p, gen7, ilo) +
  761.             gen7_pipeline_estimate_states(p, gen7, ilo);
  762.       }
  763.       break;
  764.    case ILO_3D_PIPELINE_FLUSH:
  765.    case ILO_3D_PIPELINE_WRITE_TIMESTAMP:
  766.    case ILO_3D_PIPELINE_WRITE_DEPTH_COUNT:
  767.       size = gen7->estimate_command_size(p->dev,
  768.             ILO_GPE_GEN7_PIPE_CONTROL, 1);
  769.       break;
  770.    default:
  771.       assert(!"unknown 3D pipeline action");
  772.       size = 0;
  773.       break;
  774.    }
  775.  
  776.    return size;
  777. }
  778.  
  779. void
  780. ilo_3d_pipeline_init_gen7(struct ilo_3d_pipeline *p)
  781. {
  782.    const struct ilo_gpe_gen7 *gen7 = ilo_gpe_gen7_get();
  783.  
  784.    p->estimate_size = ilo_3d_pipeline_estimate_size_gen7;
  785.    p->emit_draw = ilo_3d_pipeline_emit_draw_gen7;
  786.    p->emit_flush = ilo_3d_pipeline_emit_flush_gen6;
  787.    p->emit_write_timestamp = ilo_3d_pipeline_emit_write_timestamp_gen6;
  788.    p->emit_write_depth_count = ilo_3d_pipeline_emit_write_depth_count_gen6;
  789.  
  790. #define GEN6_USE(p, name, from) \
  791.    p->gen6_ ## name = from->emit_ ## name
  792.    GEN6_USE(p, STATE_BASE_ADDRESS, gen7);
  793.    GEN6_USE(p, STATE_SIP, gen7);
  794.    GEN6_USE(p, PIPELINE_SELECT, gen7);
  795.    GEN6_USE(p, 3DSTATE_VERTEX_BUFFERS, gen7);
  796.    GEN6_USE(p, 3DSTATE_VERTEX_ELEMENTS, gen7);
  797.    GEN6_USE(p, 3DSTATE_INDEX_BUFFER, gen7);
  798.    GEN6_USE(p, 3DSTATE_VF_STATISTICS, gen7);
  799.    GEN6_USE(p, 3DSTATE_SCISSOR_STATE_POINTERS, gen7);
  800.    GEN6_USE(p, 3DSTATE_VS, gen7);
  801.    GEN6_USE(p, 3DSTATE_CLIP, gen7);
  802.    GEN6_USE(p, 3DSTATE_CONSTANT_VS, gen7);
  803.    GEN6_USE(p, 3DSTATE_CONSTANT_GS, gen7);
  804.    GEN6_USE(p, 3DSTATE_CONSTANT_PS, gen7);
  805.    GEN6_USE(p, 3DSTATE_DRAWING_RECTANGLE, gen7);
  806.    GEN6_USE(p, 3DSTATE_POLY_STIPPLE_OFFSET, gen7);
  807.    GEN6_USE(p, 3DSTATE_POLY_STIPPLE_PATTERN, gen7);
  808.    GEN6_USE(p, 3DSTATE_LINE_STIPPLE, gen7);
  809.    GEN6_USE(p, 3DSTATE_AA_LINE_PARAMETERS, gen7);
  810.    GEN6_USE(p, 3DSTATE_MULTISAMPLE, gen7);
  811.    GEN6_USE(p, 3DSTATE_STENCIL_BUFFER, gen7);
  812.    GEN6_USE(p, 3DSTATE_HIER_DEPTH_BUFFER, gen7);
  813.    GEN6_USE(p, 3DSTATE_CLEAR_PARAMS, gen7);
  814.    GEN6_USE(p, PIPE_CONTROL, gen7);
  815.    GEN6_USE(p, 3DPRIMITIVE, gen7);
  816.    GEN6_USE(p, INTERFACE_DESCRIPTOR_DATA, gen7);
  817.    GEN6_USE(p, CC_VIEWPORT, gen7);
  818.    GEN6_USE(p, COLOR_CALC_STATE, gen7);
  819.    GEN6_USE(p, BLEND_STATE, gen7);
  820.    GEN6_USE(p, DEPTH_STENCIL_STATE, gen7);
  821.    GEN6_USE(p, SCISSOR_RECT, gen7);
  822.    GEN6_USE(p, BINDING_TABLE_STATE, gen7);
  823.    GEN6_USE(p, SURFACE_STATE, gen7);
  824.    GEN6_USE(p, SAMPLER_STATE, gen7);
  825.    GEN6_USE(p, SAMPLER_BORDER_COLOR_STATE, gen7);
  826.    GEN6_USE(p, push_constant_buffer, gen7);
  827. #undef GEN6_USE
  828.  
  829. #define GEN7_USE(p, name, from) \
  830.    p->gen7_ ## name = from->emit_ ## name
  831.    GEN7_USE(p, 3DSTATE_DEPTH_BUFFER, gen7);
  832.    GEN7_USE(p, 3DSTATE_CC_STATE_POINTERS, gen7);
  833.    GEN7_USE(p, 3DSTATE_GS, gen7);
  834.    GEN7_USE(p, 3DSTATE_SF, gen7);
  835.    GEN7_USE(p, 3DSTATE_WM, gen7);
  836.    GEN7_USE(p, 3DSTATE_SAMPLE_MASK, gen7);
  837.    GEN7_USE(p, 3DSTATE_CONSTANT_HS, gen7);
  838.    GEN7_USE(p, 3DSTATE_CONSTANT_DS, gen7);
  839.    GEN7_USE(p, 3DSTATE_HS, gen7);
  840.    GEN7_USE(p, 3DSTATE_TE, gen7);
  841.    GEN7_USE(p, 3DSTATE_DS, gen7);
  842.    GEN7_USE(p, 3DSTATE_STREAMOUT, gen7);
  843.    GEN7_USE(p, 3DSTATE_SBE, gen7);
  844.    GEN7_USE(p, 3DSTATE_PS, gen7);
  845.    GEN7_USE(p, 3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP, gen7);
  846.    GEN7_USE(p, 3DSTATE_VIEWPORT_STATE_POINTERS_CC, gen7);
  847.    GEN7_USE(p, 3DSTATE_BLEND_STATE_POINTERS, gen7);
  848.    GEN7_USE(p, 3DSTATE_DEPTH_STENCIL_STATE_POINTERS, gen7);
  849.    GEN7_USE(p, 3DSTATE_BINDING_TABLE_POINTERS_VS, gen7);
  850.    GEN7_USE(p, 3DSTATE_BINDING_TABLE_POINTERS_HS, gen7);
  851.    GEN7_USE(p, 3DSTATE_BINDING_TABLE_POINTERS_DS, gen7);
  852.    GEN7_USE(p, 3DSTATE_BINDING_TABLE_POINTERS_GS, gen7);
  853.    GEN7_USE(p, 3DSTATE_BINDING_TABLE_POINTERS_PS, gen7);
  854.    GEN7_USE(p, 3DSTATE_SAMPLER_STATE_POINTERS_VS, gen7);
  855.    GEN7_USE(p, 3DSTATE_SAMPLER_STATE_POINTERS_HS, gen7);
  856.    GEN7_USE(p, 3DSTATE_SAMPLER_STATE_POINTERS_DS, gen7);
  857.    GEN7_USE(p, 3DSTATE_SAMPLER_STATE_POINTERS_GS, gen7);
  858.    GEN7_USE(p, 3DSTATE_SAMPLER_STATE_POINTERS_PS, gen7);
  859.    GEN7_USE(p, 3DSTATE_URB_VS, gen7);
  860.    GEN7_USE(p, 3DSTATE_URB_HS, gen7);
  861.    GEN7_USE(p, 3DSTATE_URB_DS, gen7);
  862.    GEN7_USE(p, 3DSTATE_URB_GS, gen7);
  863.    GEN7_USE(p, 3DSTATE_PUSH_CONSTANT_ALLOC_VS, gen7);
  864.    GEN7_USE(p, 3DSTATE_PUSH_CONSTANT_ALLOC_HS, gen7);
  865.    GEN7_USE(p, 3DSTATE_PUSH_CONSTANT_ALLOC_DS, gen7);
  866.    GEN7_USE(p, 3DSTATE_PUSH_CONSTANT_ALLOC_GS, gen7);
  867.    GEN7_USE(p, 3DSTATE_PUSH_CONSTANT_ALLOC_PS, gen7);
  868.    GEN7_USE(p, 3DSTATE_SO_DECL_LIST, gen7);
  869.    GEN7_USE(p, 3DSTATE_SO_BUFFER, gen7);
  870.    GEN7_USE(p, SF_CLIP_VIEWPORT, gen7);
  871. #undef GEN7_USE
  872. }
  873.