Home | History | Annotate | Download | only in ilo
      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 (at) lunarg.com>
     26  */
     27 
     28 #include "genhw/genhw.h"
     29 #include "core/ilo_builder_3d.h"
     30 #include "core/ilo_builder_render.h"
     31 
     32 #include "ilo_blitter.h"
     33 #include "ilo_resource.h"
     34 #include "ilo_shader.h"
     35 #include "ilo_state.h"
     36 #include "ilo_render_gen.h"
     37 
     38 static void
     39 gen7_wa_post_3dstate_push_constant_alloc_ps(struct ilo_render *r)
     40 {
     41    /*
     42     * From the Ivy Bridge PRM, volume 2 part 1, page 292:
     43     *
     44     *     "A PIPE_CONTOL command with the CS Stall bit set must be programmed
     45     *      in the ring after this instruction
     46     *      (3DSTATE_PUSH_CONSTANT_ALLOC_PS)."
     47     */
     48    const uint32_t dw1 = GEN6_PIPE_CONTROL_CS_STALL;
     49 
     50    ILO_DEV_ASSERT(r->dev, 7, 7);
     51 
     52    r->state.deferred_pipe_control_dw1 |= dw1;
     53 }
     54 
     55 static void
     56 gen7_wa_pre_vs(struct ilo_render *r)
     57 {
     58    /*
     59     * From the Ivy Bridge PRM, volume 2 part 1, page 106:
     60     *
     61     *     "A PIPE_CONTROL with Post-Sync Operation set to 1h and a depth stall
     62     *      needs to be sent just prior to any 3DSTATE_VS, 3DSTATE_URB_VS,
     63     *      3DSTATE_CONSTANT_VS, 3DSTATE_BINDING_TABLE_POINTER_VS,
     64     *      3DSTATE_SAMPLER_STATE_POINTER_VS command.  Only one PIPE_CONTROL
     65     *      needs to be sent before any combination of VS associated 3DSTATE."
     66     */
     67    const uint32_t dw1 = GEN6_PIPE_CONTROL_DEPTH_STALL |
     68                         GEN6_PIPE_CONTROL_WRITE_IMM;
     69 
     70    ILO_DEV_ASSERT(r->dev, 7, 7);
     71 
     72    if ((r->state.current_pipe_control_dw1 & dw1) != dw1)
     73       ilo_render_pipe_control(r, dw1);
     74 }
     75 
     76 static void
     77 gen7_wa_pre_3dstate_sf_depth_bias(struct ilo_render *r)
     78 {
     79    /*
     80     * From the Ivy Bridge PRM, volume 2 part 1, page 258:
     81     *
     82     *     "Due to an HW issue driver needs to send a pipe control with stall
     83     *      when ever there is state change in depth bias related state (in
     84     *      3DSTATE_SF)"
     85     */
     86    const uint32_t dw1 = GEN6_PIPE_CONTROL_CS_STALL;
     87 
     88    ILO_DEV_ASSERT(r->dev, 7, 7);
     89 
     90    if ((r->state.current_pipe_control_dw1 & dw1) != dw1)
     91       ilo_render_pipe_control(r, dw1);
     92 }
     93 
     94 static void
     95 gen7_wa_pre_3dstate_multisample(struct ilo_render *r)
     96 {
     97    /*
     98     * From the Ivy Bridge PRM, volume 2 part 1, page 304:
     99     *
    100     *     "Driver must ierarchi that all the caches in the depth pipe are
    101     *      flushed before this command (3DSTATE_MULTISAMPLE) is parsed. This
    102     *      requires driver to send a PIPE_CONTROL with a CS stall along with a
    103     *      Depth Flush prior to this command.
    104     */
    105    const uint32_t dw1 = GEN6_PIPE_CONTROL_DEPTH_CACHE_FLUSH |
    106                         GEN6_PIPE_CONTROL_CS_STALL;
    107 
    108    ILO_DEV_ASSERT(r->dev, 7, 7.5);
    109 
    110    if ((r->state.current_pipe_control_dw1 & dw1) != dw1)
    111       ilo_render_pipe_control(r, dw1);
    112 }
    113 
    114 static void
    115 gen7_wa_pre_depth(struct ilo_render *r)
    116 {
    117    ILO_DEV_ASSERT(r->dev, 7, 7.5);
    118 
    119    if (ilo_dev_gen(r->dev) == ILO_GEN(7)) {
    120       /*
    121        * From the Ivy Bridge PRM, volume 2 part 1, page 315:
    122        *
    123        *     "Driver must send a least one PIPE_CONTROL command with CS Stall
    124        *      and a post sync operation prior to the group of depth
    125        *      commands(3DSTATE_DEPTH_BUFFER, 3DSTATE_CLEAR_PARAMS,
    126        *      3DSTATE_STENCIL_BUFFER, and 3DSTATE_HIER_DEPTH_BUFFER)."
    127        */
    128       const uint32_t dw1 = GEN6_PIPE_CONTROL_CS_STALL |
    129                            GEN6_PIPE_CONTROL_WRITE_IMM;
    130 
    131       if ((r->state.current_pipe_control_dw1 & dw1) != dw1)
    132          ilo_render_pipe_control(r, dw1);
    133    }
    134 
    135    /*
    136     * From the Ivy Bridge PRM, volume 2 part 1, page 315:
    137     *
    138     *     "Restriction: Prior to changing Depth/Stencil Buffer state (i.e.,
    139     *      any combination of 3DSTATE_DEPTH_BUFFER, 3DSTATE_CLEAR_PARAMS,
    140     *      3DSTATE_STENCIL_BUFFER, 3DSTATE_HIER_DEPTH_BUFFER) SW must first
    141     *      issue a pipelined depth stall (PIPE_CONTROL with Depth Stall bit
    142     *      set), followed by a pipelined depth cache flush (PIPE_CONTROL with
    143     *      Depth Flush Bit set, followed by another pipelined depth stall
    144     *      (PIPE_CONTROL with Depth Stall Bit set), unless SW can otherwise
    145     *      guarantee that the pipeline from WM onwards is already flushed
    146     *      (e.g., via a preceding MI_FLUSH)."
    147     */
    148    ilo_render_pipe_control(r, GEN6_PIPE_CONTROL_DEPTH_STALL);
    149    ilo_render_pipe_control(r, GEN6_PIPE_CONTROL_DEPTH_CACHE_FLUSH);
    150    ilo_render_pipe_control(r, GEN6_PIPE_CONTROL_DEPTH_STALL);
    151 }
    152 
    153 static void
    154 gen7_wa_pre_3dstate_ps_max_threads(struct ilo_render *r)
    155 {
    156    /*
    157     * From the Ivy Bridge PRM, volume 2 part 1, page 286:
    158     *
    159     *     "If this field (Maximum Number of Threads in 3DSTATE_PS) is changed
    160     *      between 3DPRIMITIVE commands, a PIPE_CONTROL command with Stall at
    161     *      Pixel Scoreboard set is required to be issued."
    162     */
    163    const uint32_t dw1 = GEN6_PIPE_CONTROL_PIXEL_SCOREBOARD_STALL;
    164 
    165    ILO_DEV_ASSERT(r->dev, 7, 7.5);
    166 
    167    if ((r->state.current_pipe_control_dw1 & dw1) != dw1)
    168       ilo_render_pipe_control(r, dw1);
    169 }
    170 
    171 static void
    172 gen7_wa_post_ps_and_later(struct ilo_render *r)
    173 {
    174    /*
    175     * From the Ivy Bridge PRM, volume 2 part 1, page 276:
    176     *
    177     *     "The driver must make sure a PIPE_CONTROL with the Depth Stall
    178     *      Enable bit set after all the following states are programmed:
    179     *
    180     *       - 3DSTATE_PS
    181     *       - 3DSTATE_VIEWPORT_STATE_POINTERS_CC
    182     *       - 3DSTATE_CONSTANT_PS
    183     *       - 3DSTATE_BINDING_TABLE_POINTERS_PS
    184     *       - 3DSTATE_SAMPLER_STATE_POINTERS_PS
    185     *       - 3DSTATE_CC_STATE_POINTERS
    186     *       - 3DSTATE_BLEND_STATE_POINTERS
    187     *       - 3DSTATE_DEPTH_STENCIL_STATE_POINTERS"
    188     */
    189    const uint32_t dw1 = GEN6_PIPE_CONTROL_DEPTH_STALL;
    190 
    191    ILO_DEV_ASSERT(r->dev, 7, 7);
    192 
    193    r->state.deferred_pipe_control_dw1 |= dw1;
    194 }
    195 
    196 #define DIRTY(state) (session->pipe_dirty & ILO_DIRTY_ ## state)
    197 
    198 void
    199 gen7_draw_common_urb(struct ilo_render *r,
    200                      const struct ilo_state_vector *vec,
    201                      struct ilo_render_draw_session *session)
    202 {
    203    /* 3DSTATE_URB_{VS,GS,HS,DS} */
    204    if (session->urb_delta.dirty & (ILO_STATE_URB_3DSTATE_URB_VS |
    205                                    ILO_STATE_URB_3DSTATE_URB_HS |
    206                                    ILO_STATE_URB_3DSTATE_URB_DS |
    207                                    ILO_STATE_URB_3DSTATE_URB_GS)) {
    208       if (ilo_dev_gen(r->dev) == ILO_GEN(7))
    209          gen7_wa_pre_vs(r);
    210 
    211       gen7_3DSTATE_URB_VS(r->builder, &vec->urb);
    212       gen7_3DSTATE_URB_GS(r->builder, &vec->urb);
    213       gen7_3DSTATE_URB_HS(r->builder, &vec->urb);
    214       gen7_3DSTATE_URB_DS(r->builder, &vec->urb);
    215    }
    216 }
    217 
    218 void
    219 gen7_draw_common_pcb_alloc(struct ilo_render *r,
    220                            const struct ilo_state_vector *vec,
    221                            struct ilo_render_draw_session *session)
    222 {
    223    /* 3DSTATE_PUSH_CONSTANT_ALLOC_{VS,PS} */
    224    if (session->urb_delta.dirty &
    225          (ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_VS |
    226           ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_HS |
    227           ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_DS |
    228           ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_GS |
    229           ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_PS)) {
    230       gen7_3DSTATE_PUSH_CONSTANT_ALLOC_VS(r->builder, &vec->urb);
    231       gen7_3DSTATE_PUSH_CONSTANT_ALLOC_GS(r->builder, &vec->urb);
    232       gen7_3DSTATE_PUSH_CONSTANT_ALLOC_PS(r->builder, &vec->urb);
    233 
    234       if (ilo_dev_gen(r->dev) == ILO_GEN(7))
    235          gen7_wa_post_3dstate_push_constant_alloc_ps(r);
    236    }
    237 }
    238 
    239 void
    240 gen7_draw_common_pointers_1(struct ilo_render *r,
    241                             const struct ilo_state_vector *vec,
    242                             struct ilo_render_draw_session *session)
    243 {
    244    /* 3DSTATE_VIEWPORT_STATE_POINTERS_{CC,SF_CLIP} */
    245    if (session->viewport_changed) {
    246       gen7_3DSTATE_VIEWPORT_STATE_POINTERS_CC(r->builder,
    247             r->state.CC_VIEWPORT);
    248 
    249       gen7_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP(r->builder,
    250             r->state.SF_CLIP_VIEWPORT);
    251    }
    252 }
    253 
    254 void
    255 gen7_draw_common_pointers_2(struct ilo_render *r,
    256                             const struct ilo_state_vector *vec,
    257                             struct ilo_render_draw_session *session)
    258 {
    259    /* 3DSTATE_BLEND_STATE_POINTERS */
    260    if (session->blend_changed) {
    261       gen7_3DSTATE_BLEND_STATE_POINTERS(r->builder,
    262             r->state.BLEND_STATE);
    263    }
    264 
    265    /* 3DSTATE_CC_STATE_POINTERS */
    266    if (session->cc_changed) {
    267       gen7_3DSTATE_CC_STATE_POINTERS(r->builder,
    268             r->state.COLOR_CALC_STATE);
    269    }
    270 
    271    /* 3DSTATE_DEPTH_STENCIL_STATE_POINTERS */
    272    if (ilo_dev_gen(r->dev) < ILO_GEN(8) && session->dsa_changed) {
    273       gen7_3DSTATE_DEPTH_STENCIL_STATE_POINTERS(r->builder,
    274             r->state.DEPTH_STENCIL_STATE);
    275    }
    276 }
    277 
    278 void
    279 gen7_draw_vs(struct ilo_render *r,
    280              const struct ilo_state_vector *vec,
    281              struct ilo_render_draw_session *session)
    282 {
    283    const bool emit_3dstate_binding_table = session->binding_table_vs_changed;
    284    const bool emit_3dstate_sampler_state = session->sampler_vs_changed;
    285    /* see gen6_draw_vs() */
    286    const bool emit_3dstate_constant_vs = session->pcb_vs_changed;
    287    const bool emit_3dstate_vs = (DIRTY(VS) || r->instruction_bo_changed);
    288 
    289    /* emit depth stall before any of the VS commands */
    290    if (ilo_dev_gen(r->dev) == ILO_GEN(7)) {
    291       if (emit_3dstate_binding_table || emit_3dstate_sampler_state ||
    292           emit_3dstate_constant_vs || emit_3dstate_vs)
    293          gen7_wa_pre_vs(r);
    294    }
    295 
    296    /* 3DSTATE_BINDING_TABLE_POINTERS_VS */
    297    if (emit_3dstate_binding_table) {
    298       gen7_3DSTATE_BINDING_TABLE_POINTERS_VS(r->builder,
    299               r->state.vs.BINDING_TABLE_STATE);
    300    }
    301 
    302    /* 3DSTATE_SAMPLER_STATE_POINTERS_VS */
    303    if (emit_3dstate_sampler_state) {
    304       gen7_3DSTATE_SAMPLER_STATE_POINTERS_VS(r->builder,
    305               r->state.vs.SAMPLER_STATE);
    306    }
    307 
    308    /* 3DSTATE_CONSTANT_VS */
    309    if (emit_3dstate_constant_vs) {
    310       gen7_3DSTATE_CONSTANT_VS(r->builder,
    311               &r->state.vs.PUSH_CONSTANT_BUFFER,
    312               &r->state.vs.PUSH_CONSTANT_BUFFER_size,
    313               1);
    314    }
    315 
    316    /* 3DSTATE_VS */
    317    if (emit_3dstate_vs) {
    318       const union ilo_shader_cso *cso = ilo_shader_get_kernel_cso(vec->vs);
    319       const uint32_t kernel_offset = ilo_shader_get_kernel_offset(vec->vs);
    320 
    321       if (ilo_dev_gen(r->dev) >= ILO_GEN(8)) {
    322          gen8_3DSTATE_VS(r->builder, &cso->vs,
    323                kernel_offset, r->vs_scratch.bo);
    324       } else {
    325          gen6_3DSTATE_VS(r->builder, &cso->vs,
    326                kernel_offset, r->vs_scratch.bo);
    327       }
    328    }
    329 }
    330 
    331 void
    332 gen7_draw_hs(struct ilo_render *r,
    333              const struct ilo_state_vector *vec,
    334              struct ilo_render_draw_session *session)
    335 {
    336    /* 3DSTATE_CONSTANT_HS and 3DSTATE_HS */
    337    if (r->hw_ctx_changed) {
    338       const struct ilo_state_hs *hs = &vec->disabled_hs;
    339       const uint32_t kernel_offset = 0;
    340 
    341       gen7_3DSTATE_CONSTANT_HS(r->builder, 0, 0, 0);
    342 
    343       if (ilo_dev_gen(r->dev) >= ILO_GEN(8))
    344          gen8_3DSTATE_HS(r->builder, hs, kernel_offset, NULL);
    345       else
    346          gen7_3DSTATE_HS(r->builder, hs, kernel_offset, NULL);
    347    }
    348 
    349    /* 3DSTATE_BINDING_TABLE_POINTERS_HS */
    350    if (r->hw_ctx_changed)
    351       gen7_3DSTATE_BINDING_TABLE_POINTERS_HS(r->builder, 0);
    352 }
    353 
    354 void
    355 gen7_draw_te(struct ilo_render *r,
    356              const struct ilo_state_vector *vec,
    357              struct ilo_render_draw_session *session)
    358 {
    359    /* 3DSTATE_TE */
    360    if (r->hw_ctx_changed) {
    361       const struct ilo_state_ds *ds = &vec->disabled_ds;
    362       gen7_3DSTATE_TE(r->builder, ds);
    363    }
    364 }
    365 
    366 void
    367 gen7_draw_ds(struct ilo_render *r,
    368              const struct ilo_state_vector *vec,
    369              struct ilo_render_draw_session *session)
    370 {
    371    /* 3DSTATE_CONSTANT_DS and 3DSTATE_DS */
    372    if (r->hw_ctx_changed) {
    373       const struct ilo_state_ds *ds = &vec->disabled_ds;
    374       const uint32_t kernel_offset = 0;
    375 
    376       gen7_3DSTATE_CONSTANT_DS(r->builder, 0, 0, 0);
    377 
    378       if (ilo_dev_gen(r->dev) >= ILO_GEN(8))
    379          gen8_3DSTATE_DS(r->builder, ds, kernel_offset, NULL);
    380       else
    381          gen7_3DSTATE_DS(r->builder, ds, kernel_offset, NULL);
    382    }
    383 
    384    /* 3DSTATE_BINDING_TABLE_POINTERS_DS */
    385    if (r->hw_ctx_changed)
    386       gen7_3DSTATE_BINDING_TABLE_POINTERS_DS(r->builder, 0);
    387 
    388 }
    389 
    390 void
    391 gen7_draw_gs(struct ilo_render *r,
    392              const struct ilo_state_vector *vec,
    393              struct ilo_render_draw_session *session)
    394 {
    395    /* 3DSTATE_CONSTANT_GS and 3DSTATE_GS */
    396    if (r->hw_ctx_changed) {
    397       const struct ilo_state_gs *gs = &vec->disabled_gs;
    398       const uint32_t kernel_offset = 0;
    399 
    400       gen7_3DSTATE_CONSTANT_GS(r->builder, 0, 0, 0);
    401 
    402       if (ilo_dev_gen(r->dev) >= ILO_GEN(8))
    403          gen8_3DSTATE_GS(r->builder, gs, kernel_offset, NULL);
    404       else
    405          gen7_3DSTATE_GS(r->builder, gs, kernel_offset, NULL);
    406    }
    407 
    408    /* 3DSTATE_BINDING_TABLE_POINTERS_GS */
    409    if (session->binding_table_gs_changed) {
    410       gen7_3DSTATE_BINDING_TABLE_POINTERS_GS(r->builder,
    411             r->state.gs.BINDING_TABLE_STATE);
    412    }
    413 }
    414 
    415 void
    416 gen7_draw_sol(struct ilo_render *r,
    417               const struct ilo_state_vector *vec,
    418               struct ilo_render_draw_session *session)
    419 {
    420    const struct ilo_state_sol *sol;
    421    const struct ilo_shader_state *shader;
    422    bool dirty_sh = false;
    423 
    424    if (vec->gs) {
    425       shader = vec->gs;
    426       dirty_sh = DIRTY(GS);
    427    }
    428    else {
    429       shader = vec->vs;
    430       dirty_sh = DIRTY(VS);
    431    }
    432 
    433    sol = ilo_shader_get_kernel_sol(shader);
    434 
    435    /* 3DSTATE_SO_BUFFER */
    436    if ((DIRTY(SO) || dirty_sh || r->batch_bo_changed) &&
    437        vec->so.enabled) {
    438       int i;
    439 
    440       for (i = 0; i < ILO_STATE_SOL_MAX_BUFFER_COUNT; i++) {
    441          const struct pipe_stream_output_target *target =
    442             (i < vec->so.count && vec->so.states[i]) ?
    443             vec->so.states[i] : NULL;
    444          const struct ilo_state_sol_buffer *sb = (target) ?
    445             &((const struct ilo_stream_output_target *) target)->sb :
    446             &vec->so.dummy_sb;
    447 
    448          if (ilo_dev_gen(r->dev) >= ILO_GEN(8))
    449             gen8_3DSTATE_SO_BUFFER(r->builder, sol, sb, i);
    450          else
    451             gen7_3DSTATE_SO_BUFFER(r->builder, sol, sb, i);
    452       }
    453    }
    454 
    455    /* 3DSTATE_SO_DECL_LIST */
    456    if (dirty_sh && vec->so.enabled)
    457       gen7_3DSTATE_SO_DECL_LIST(r->builder, sol);
    458 
    459    /*
    460     * From the Ivy Bridge PRM, volume 2 part 1, page 196-197:
    461     *
    462     *     "Anytime the SOL unit MMIO registers or non-pipeline state are
    463     *      written, the SOL unit needs to receive a pipeline state update with
    464     *      SOL unit dirty state for information programmed in MMIO/NP to get
    465     *      loaded into the SOL unit.
    466     *
    467     *      The SOL unit incorrectly double buffers MMIO/NP registers and only
    468     *      moves them into the design for usage when control topology is
    469     *      received with the SOL unit dirty state.
    470     *
    471     *      If the state does not change, need to resend the same state.
    472     *
    473     *      Because of corruption, software must flush the whole fixed function
    474     *      pipeline when 3DSTATE_STREAMOUT changes state."
    475     *
    476     * The first and fourth paragraphs are gone on Gen7.5+.
    477     */
    478 
    479    /* 3DSTATE_STREAMOUT */
    480    gen7_3DSTATE_STREAMOUT(r->builder, sol);
    481 }
    482 
    483 static void
    484 gen7_draw_sf(struct ilo_render *r,
    485              const struct ilo_state_vector *vec,
    486              struct ilo_render_draw_session *session)
    487 {
    488    /* 3DSTATE_SBE */
    489    if (DIRTY(FS)) {
    490       const struct ilo_state_sbe *sbe = ilo_shader_get_kernel_sbe(vec->fs);
    491       gen7_3DSTATE_SBE(r->builder, sbe);
    492    }
    493 
    494    /* 3DSTATE_SF */
    495    if (session->rs_delta.dirty & ILO_STATE_RASTER_3DSTATE_SF) {
    496       if (ilo_dev_gen(r->dev) == ILO_GEN(7))
    497          gen7_wa_pre_3dstate_sf_depth_bias(r);
    498 
    499       gen7_3DSTATE_SF(r->builder, &vec->rasterizer->rs);
    500    }
    501 }
    502 
    503 static void
    504 gen7_draw_wm(struct ilo_render *r,
    505              const struct ilo_state_vector *vec,
    506              struct ilo_render_draw_session *session)
    507 {
    508    const union ilo_shader_cso *cso = ilo_shader_get_kernel_cso(vec->fs);
    509    const uint32_t kernel_offset = ilo_shader_get_kernel_offset(vec->fs);
    510 
    511    /* 3DSTATE_WM */
    512    if (DIRTY(FS) || (session->rs_delta.dirty & ILO_STATE_RASTER_3DSTATE_WM))
    513       gen7_3DSTATE_WM(r->builder, &vec->rasterizer->rs, &cso->ps);
    514 
    515    /* 3DSTATE_BINDING_TABLE_POINTERS_PS */
    516    if (session->binding_table_fs_changed) {
    517       gen7_3DSTATE_BINDING_TABLE_POINTERS_PS(r->builder,
    518             r->state.wm.BINDING_TABLE_STATE);
    519    }
    520 
    521    /* 3DSTATE_SAMPLER_STATE_POINTERS_PS */
    522    if (session->sampler_fs_changed) {
    523       gen7_3DSTATE_SAMPLER_STATE_POINTERS_PS(r->builder,
    524             r->state.wm.SAMPLER_STATE);
    525    }
    526 
    527    /* 3DSTATE_CONSTANT_PS */
    528    if (session->pcb_fs_changed) {
    529       gen7_3DSTATE_CONSTANT_PS(r->builder,
    530             &r->state.wm.PUSH_CONSTANT_BUFFER,
    531             &r->state.wm.PUSH_CONSTANT_BUFFER_size,
    532             1);
    533    }
    534 
    535    /* 3DSTATE_PS */
    536    if (DIRTY(FS) || r->instruction_bo_changed) {
    537       if (r->hw_ctx_changed)
    538          gen7_wa_pre_3dstate_ps_max_threads(r);
    539 
    540       gen7_3DSTATE_PS(r->builder, &cso->ps, kernel_offset, r->fs_scratch.bo);
    541    }
    542 
    543    /* 3DSTATE_SCISSOR_STATE_POINTERS */
    544    if (session->scissor_changed) {
    545       gen6_3DSTATE_SCISSOR_STATE_POINTERS(r->builder,
    546             r->state.SCISSOR_RECT);
    547    }
    548 
    549    {
    550       const bool emit_3dstate_ps = (DIRTY(FS) || DIRTY(BLEND));
    551       const bool emit_3dstate_depth_buffer =
    552          (DIRTY(FB) || DIRTY(DSA) || r->state_bo_changed);
    553 
    554       if (ilo_dev_gen(r->dev) == ILO_GEN(7)) {
    555          /* XXX what is the best way to know if this workaround is needed? */
    556          if (emit_3dstate_ps ||
    557              session->pcb_fs_changed ||
    558              session->viewport_changed ||
    559              session->binding_table_fs_changed ||
    560              session->sampler_fs_changed ||
    561              session->cc_changed ||
    562              session->blend_changed ||
    563              session->dsa_changed)
    564             gen7_wa_post_ps_and_later(r);
    565       }
    566 
    567       if (emit_3dstate_depth_buffer)
    568          gen7_wa_pre_depth(r);
    569    }
    570 
    571    /* 3DSTATE_DEPTH_BUFFER and 3DSTATE_CLEAR_PARAMS */
    572    if (DIRTY(FB) || r->batch_bo_changed) {
    573       const struct ilo_state_zs *zs;
    574       uint32_t clear_params;
    575 
    576       if (vec->fb.state.zsbuf) {
    577          const struct ilo_surface_cso *surface =
    578             (const struct ilo_surface_cso *) vec->fb.state.zsbuf;
    579          const struct ilo_texture_slice *slice =
    580             ilo_texture_get_slice(ilo_texture(surface->base.texture),
    581                   surface->base.u.tex.level, surface->base.u.tex.first_layer);
    582 
    583          assert(!surface->is_rt);
    584          zs = &surface->u.zs;
    585          clear_params = slice->clear_value;
    586       }
    587       else {
    588          zs = &vec->fb.null_zs;
    589          clear_params = 0;
    590       }
    591 
    592       gen6_3DSTATE_DEPTH_BUFFER(r->builder, zs);
    593       gen6_3DSTATE_HIER_DEPTH_BUFFER(r->builder, zs);
    594       gen6_3DSTATE_STENCIL_BUFFER(r->builder, zs);
    595       gen7_3DSTATE_CLEAR_PARAMS(r->builder, clear_params);
    596    }
    597 }
    598 
    599 static void
    600 gen7_draw_wm_multisample(struct ilo_render *r,
    601                          const struct ilo_state_vector *vec,
    602                          struct ilo_render_draw_session *session)
    603 {
    604    /* 3DSTATE_MULTISAMPLE */
    605    if (DIRTY(FB) || (session->rs_delta.dirty &
    606             ILO_STATE_RASTER_3DSTATE_MULTISAMPLE)) {
    607       const uint8_t sample_count = (vec->fb.num_samples > 4) ? 8 :
    608                                    (vec->fb.num_samples > 1) ? 4 : 1;
    609 
    610       gen7_wa_pre_3dstate_multisample(r);
    611 
    612       gen6_3DSTATE_MULTISAMPLE(r->builder, &vec->rasterizer->rs,
    613             &r->sample_pattern, sample_count);
    614    }
    615 
    616    /* 3DSTATE_SAMPLE_MASK */
    617    if (session->rs_delta.dirty & ILO_STATE_RASTER_3DSTATE_SAMPLE_MASK)
    618       gen6_3DSTATE_SAMPLE_MASK(r->builder, &vec->rasterizer->rs);
    619 }
    620 
    621 void
    622 ilo_render_emit_draw_commands_gen7(struct ilo_render *render,
    623                                    const struct ilo_state_vector *vec,
    624                                    struct ilo_render_draw_session *session)
    625 {
    626    ILO_DEV_ASSERT(render->dev, 7, 7.5);
    627 
    628    /*
    629     * We try to keep the order of the commands match, as closely as possible,
    630     * that of the classic i965 driver.  It allows us to compare the command
    631     * streams easily.
    632     */
    633    gen6_draw_common_select(render, vec, session);
    634    gen6_draw_common_sip(render, vec, session);
    635    gen6_draw_vf_statistics(render, vec, session);
    636    gen7_draw_common_pcb_alloc(render, vec, session);
    637    gen6_draw_common_base_address(render, vec, session);
    638    gen7_draw_common_pointers_1(render, vec, session);
    639    gen7_draw_common_urb(render, vec, session);
    640    gen7_draw_common_pointers_2(render, vec, session);
    641    gen7_draw_wm_multisample(render, vec, session);
    642    gen7_draw_gs(render, vec, session);
    643    gen7_draw_hs(render, vec, session);
    644    gen7_draw_te(render, vec, session);
    645    gen7_draw_ds(render, vec, session);
    646    gen7_draw_vs(render, vec, session);
    647    gen7_draw_sol(render, vec, session);
    648    gen6_draw_clip(render, vec, session);
    649    gen7_draw_sf(render, vec, session);
    650    gen7_draw_wm(render, vec, session);
    651    gen6_draw_wm_raster(render, vec, session);
    652    gen6_draw_sf_rect(render, vec, session);
    653    gen6_draw_vf(render, vec, session);
    654 
    655    ilo_render_3dprimitive(render, &vec->draw_info);
    656 }
    657 
    658 static void
    659 gen7_rectlist_pcb_alloc(struct ilo_render *r,
    660                         const struct ilo_blitter *blitter)
    661 {
    662    gen7_3DSTATE_PUSH_CONSTANT_ALLOC_VS(r->builder, &blitter->urb);
    663    gen7_3DSTATE_PUSH_CONSTANT_ALLOC_PS(r->builder, &blitter->urb);
    664 
    665    if (ilo_dev_gen(r->dev) == ILO_GEN(7))
    666       gen7_wa_post_3dstate_push_constant_alloc_ps(r);
    667 }
    668 
    669 static void
    670 gen7_rectlist_urb(struct ilo_render *r,
    671                   const struct ilo_blitter *blitter)
    672 {
    673    gen7_3DSTATE_URB_VS(r->builder, &blitter->urb);
    674    gen7_3DSTATE_URB_GS(r->builder, &blitter->urb);
    675    gen7_3DSTATE_URB_HS(r->builder, &blitter->urb);
    676    gen7_3DSTATE_URB_DS(r->builder, &blitter->urb);
    677 }
    678 
    679 static void
    680 gen7_rectlist_vs_to_sf(struct ilo_render *r,
    681                        const struct ilo_blitter *blitter)
    682 {
    683    gen7_3DSTATE_CONSTANT_VS(r->builder, NULL, NULL, 0);
    684    gen6_3DSTATE_VS(r->builder, &blitter->vs, 0, NULL);
    685 
    686    gen7_3DSTATE_CONSTANT_HS(r->builder, NULL, NULL, 0);
    687    gen7_3DSTATE_HS(r->builder, &blitter->hs, 0, NULL);
    688 
    689    gen7_3DSTATE_TE(r->builder, &blitter->ds);
    690 
    691    gen7_3DSTATE_CONSTANT_DS(r->builder, NULL, NULL, 0);
    692    gen7_3DSTATE_DS(r->builder, &blitter->ds, 0, NULL);
    693 
    694    gen7_3DSTATE_CONSTANT_GS(r->builder, NULL, NULL, 0);
    695    gen7_3DSTATE_GS(r->builder, &blitter->gs, 0, NULL);
    696 
    697    gen7_3DSTATE_STREAMOUT(r->builder, &blitter->sol);
    698 
    699    gen6_3DSTATE_CLIP(r->builder, &blitter->fb.rs);
    700 
    701    if (ilo_dev_gen(r->dev) == ILO_GEN(7))
    702       gen7_wa_pre_3dstate_sf_depth_bias(r);
    703 
    704    gen7_3DSTATE_SF(r->builder, &blitter->fb.rs);
    705    gen7_3DSTATE_SBE(r->builder, &blitter->sbe);
    706 }
    707 
    708 static void
    709 gen7_rectlist_wm(struct ilo_render *r,
    710                  const struct ilo_blitter *blitter)
    711 {
    712    gen7_3DSTATE_WM(r->builder, &blitter->fb.rs, &blitter->ps);
    713 
    714    gen7_3DSTATE_CONSTANT_PS(r->builder, NULL, NULL, 0);
    715 
    716    gen7_wa_pre_3dstate_ps_max_threads(r);
    717    gen7_3DSTATE_PS(r->builder, &blitter->ps, 0, NULL);
    718 }
    719 
    720 static void
    721 gen7_rectlist_wm_depth(struct ilo_render *r,
    722                        const struct ilo_blitter *blitter)
    723 {
    724    gen7_wa_pre_depth(r);
    725 
    726    if (blitter->uses & (ILO_BLITTER_USE_FB_DEPTH |
    727                         ILO_BLITTER_USE_FB_STENCIL))
    728       gen6_3DSTATE_DEPTH_BUFFER(r->builder, &blitter->fb.dst.u.zs);
    729 
    730    if (blitter->uses & ILO_BLITTER_USE_FB_DEPTH) {
    731       gen6_3DSTATE_HIER_DEPTH_BUFFER(r->builder,
    732             &blitter->fb.dst.u.zs);
    733    }
    734 
    735    if (blitter->uses & ILO_BLITTER_USE_FB_STENCIL) {
    736       gen6_3DSTATE_STENCIL_BUFFER(r->builder,
    737             &blitter->fb.dst.u.zs);
    738    }
    739 
    740    gen7_3DSTATE_CLEAR_PARAMS(r->builder,
    741          blitter->depth_clear_value);
    742 }
    743 
    744 static void
    745 gen7_rectlist_wm_multisample(struct ilo_render *r,
    746                              const struct ilo_blitter *blitter)
    747 {
    748    const uint8_t sample_count = (blitter->fb.num_samples > 4) ? 8 :
    749                                 (blitter->fb.num_samples > 1) ? 4 : 1;
    750 
    751    gen7_wa_pre_3dstate_multisample(r);
    752 
    753    gen6_3DSTATE_MULTISAMPLE(r->builder, &blitter->fb.rs,
    754          &r->sample_pattern, sample_count);
    755 
    756    gen6_3DSTATE_SAMPLE_MASK(r->builder, &blitter->fb.rs);
    757 }
    758 
    759 void
    760 ilo_render_emit_rectlist_commands_gen7(struct ilo_render *r,
    761                                        const struct ilo_blitter *blitter,
    762                                        const struct ilo_render_rectlist_session *session)
    763 {
    764    ILO_DEV_ASSERT(r->dev, 7, 7.5);
    765 
    766    gen7_rectlist_wm_multisample(r, blitter);
    767 
    768    gen6_state_base_address(r->builder, true);
    769 
    770    gen6_user_3DSTATE_VERTEX_BUFFERS(r->builder,
    771          session->vb_start, session->vb_end,
    772          sizeof(blitter->vertices[0]));
    773 
    774    gen6_3DSTATE_VERTEX_ELEMENTS(r->builder, &blitter->vf);
    775 
    776    gen7_rectlist_pcb_alloc(r, blitter);
    777 
    778    /* needed for any VS-related commands */
    779    if (ilo_dev_gen(r->dev) == ILO_GEN(7))
    780       gen7_wa_pre_vs(r);
    781 
    782    gen7_rectlist_urb(r, blitter);
    783 
    784    if (blitter->uses & ILO_BLITTER_USE_DSA) {
    785       gen7_3DSTATE_DEPTH_STENCIL_STATE_POINTERS(r->builder,
    786             r->state.DEPTH_STENCIL_STATE);
    787    }
    788 
    789    if (blitter->uses & ILO_BLITTER_USE_CC) {
    790       gen7_3DSTATE_CC_STATE_POINTERS(r->builder,
    791             r->state.COLOR_CALC_STATE);
    792    }
    793 
    794    gen7_rectlist_vs_to_sf(r, blitter);
    795    gen7_rectlist_wm(r, blitter);
    796 
    797    if (blitter->uses & ILO_BLITTER_USE_VIEWPORT) {
    798       gen7_3DSTATE_VIEWPORT_STATE_POINTERS_CC(r->builder,
    799             r->state.CC_VIEWPORT);
    800    }
    801 
    802    gen7_rectlist_wm_depth(r, blitter);
    803 
    804    gen6_3DSTATE_DRAWING_RECTANGLE(r->builder, 0, 0,
    805          blitter->fb.width, blitter->fb.height);
    806 
    807    if (ilo_dev_gen(r->dev) == ILO_GEN(7))
    808       gen7_wa_post_ps_and_later(r);
    809 
    810    ilo_render_3dprimitive(r, &blitter->draw_info);
    811 }
    812 
    813 int
    814 ilo_render_get_draw_commands_len_gen7(const struct ilo_render *render,
    815                                       const struct ilo_state_vector *vec)
    816 {
    817    static int len;
    818 
    819    ILO_DEV_ASSERT(render->dev, 7, 7.5);
    820 
    821    if (!len) {
    822       len += GEN7_3DSTATE_URB_ANY__SIZE * 4;
    823       len += GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_ANY__SIZE * 5;
    824       len += GEN6_3DSTATE_CONSTANT_ANY__SIZE * 5;
    825       len += GEN7_3DSTATE_POINTERS_ANY__SIZE * (5 + 5 + 4);
    826       len += GEN7_3DSTATE_SO_BUFFER__SIZE * 4;
    827       len += GEN6_PIPE_CONTROL__SIZE * 5;
    828 
    829       len +=
    830          GEN6_STATE_BASE_ADDRESS__SIZE +
    831          GEN6_STATE_SIP__SIZE +
    832          GEN6_3DSTATE_VF_STATISTICS__SIZE +
    833          GEN6_PIPELINE_SELECT__SIZE +
    834          GEN6_3DSTATE_CLEAR_PARAMS__SIZE +
    835          GEN6_3DSTATE_DEPTH_BUFFER__SIZE +
    836          GEN6_3DSTATE_STENCIL_BUFFER__SIZE +
    837          GEN6_3DSTATE_HIER_DEPTH_BUFFER__SIZE +
    838          GEN6_3DSTATE_VERTEX_BUFFERS__SIZE +
    839          GEN6_3DSTATE_VERTEX_ELEMENTS__SIZE +
    840          GEN6_3DSTATE_INDEX_BUFFER__SIZE +
    841          GEN75_3DSTATE_VF__SIZE +
    842          GEN6_3DSTATE_VS__SIZE +
    843          GEN6_3DSTATE_GS__SIZE +
    844          GEN6_3DSTATE_CLIP__SIZE +
    845          GEN6_3DSTATE_SF__SIZE +
    846          GEN6_3DSTATE_WM__SIZE +
    847          GEN6_3DSTATE_SAMPLE_MASK__SIZE +
    848          GEN7_3DSTATE_HS__SIZE +
    849          GEN7_3DSTATE_TE__SIZE +
    850          GEN7_3DSTATE_DS__SIZE +
    851          GEN7_3DSTATE_STREAMOUT__SIZE +
    852          GEN7_3DSTATE_SBE__SIZE +
    853          GEN7_3DSTATE_PS__SIZE +
    854          GEN6_3DSTATE_DRAWING_RECTANGLE__SIZE +
    855          GEN6_3DSTATE_POLY_STIPPLE_OFFSET__SIZE +
    856          GEN6_3DSTATE_POLY_STIPPLE_PATTERN__SIZE +
    857          GEN6_3DSTATE_LINE_STIPPLE__SIZE +
    858          GEN6_3DSTATE_AA_LINE_PARAMETERS__SIZE +
    859          GEN6_3DSTATE_MULTISAMPLE__SIZE +
    860          GEN7_3DSTATE_SO_DECL_LIST__SIZE +
    861          GEN6_3DPRIMITIVE__SIZE;
    862    }
    863 
    864    return len;
    865 }
    866