ilo: update draw command emission for Gen8
authorChia-I Wu <olvaffe@gmail.com>
Tue, 27 Jan 2015 12:11:27 +0000 (20:11 +0800)
committerChia-I Wu <olvaffe@gmail.com>
Wed, 11 Feb 2015 23:56:13 +0000 (07:56 +0800)
src/gallium/drivers/ilo/Makefile.sources
src/gallium/drivers/ilo/ilo_render.c
src/gallium/drivers/ilo/ilo_render_gen.h
src/gallium/drivers/ilo/ilo_render_gen6.c
src/gallium/drivers/ilo/ilo_render_gen7.c
src/gallium/drivers/ilo/ilo_render_gen8.c [new file with mode: 0644]

index 8dd2f9b..b07362f 100644 (file)
@@ -40,6 +40,7 @@ C_SOURCES := \
        ilo_render_dynamic.c \
        ilo_render_gen6.c \
        ilo_render_gen7.c \
+       ilo_render_gen8.c \
        ilo_render_media.c \
        ilo_render_surface.c \
        ilo_screen.c \
index 4799a58..8fadf01 100644 (file)
@@ -428,7 +428,7 @@ int
 ilo_render_get_draw_len(const struct ilo_render *render,
                         const struct ilo_state_vector *vec)
 {
-   ILO_DEV_ASSERT(render->dev, 6, 7.5);
+   ILO_DEV_ASSERT(render->dev, 6, 8);
 
    return ilo_render_get_draw_dynamic_states_len(render, vec) +
           ilo_render_get_draw_surface_states_len(render, vec) +
@@ -481,7 +481,7 @@ ilo_render_emit_draw(struct ilo_render *render,
 {
    struct ilo_render_draw_session session;
 
-   ILO_DEV_ASSERT(render->dev, 6, 7.5);
+   ILO_DEV_ASSERT(render->dev, 6, 8);
 
    draw_session_prepare(render, vec, &session);
 
index 5f62875..a0952f9 100644 (file)
@@ -187,11 +187,17 @@ int
 ilo_render_get_draw_commands_len_gen7(const struct ilo_render *render,
                                       const struct ilo_state_vector *vec);
 
+int
+ilo_render_get_draw_commands_len_gen8(const struct ilo_render *render,
+                                      const struct ilo_state_vector *vec);
+
 static inline int
 ilo_render_get_draw_commands_len(const struct ilo_render *render,
                                  const struct ilo_state_vector *vec)
 {
-   if (ilo_dev_gen(render->dev) >= ILO_GEN(7))
+   if (ilo_dev_gen(render->dev) >= ILO_GEN(8))
+      return ilo_render_get_draw_commands_len_gen8(render, vec);
+   else if (ilo_dev_gen(render->dev) >= ILO_GEN(7))
       return ilo_render_get_draw_commands_len_gen7(render, vec);
    else
       return ilo_render_get_draw_commands_len_gen6(render, vec);
@@ -207,6 +213,11 @@ ilo_render_emit_draw_commands_gen7(struct ilo_render *render,
                                    const struct ilo_state_vector *vec,
                                    struct ilo_render_draw_session *session);
 
+void
+ilo_render_emit_draw_commands_gen8(struct ilo_render *render,
+                                   const struct ilo_state_vector *vec,
+                                   struct ilo_render_draw_session *session);
+
 static inline void
 ilo_render_emit_draw_commands(struct ilo_render *render,
                               const struct ilo_state_vector *vec,
@@ -214,7 +225,9 @@ ilo_render_emit_draw_commands(struct ilo_render *render,
 {
    const unsigned batch_used = ilo_builder_batch_used(render->builder);
 
-   if (ilo_dev_gen(render->dev) >= ILO_GEN(7))
+   if (ilo_dev_gen(render->dev) >= ILO_GEN(8))
+      ilo_render_emit_draw_commands_gen8(render, vec, session);
+   else if (ilo_dev_gen(render->dev) >= ILO_GEN(7))
       ilo_render_emit_draw_commands_gen7(render, vec, session);
    else
       ilo_render_emit_draw_commands_gen6(render, vec, session);
@@ -362,4 +375,59 @@ gen6_draw_wm_raster(struct ilo_render *r,
                     const struct ilo_state_vector *ilo,
                     struct ilo_render_draw_session *session);
 
+void
+gen7_draw_common_pcb_alloc(struct ilo_render *r,
+                           const struct ilo_state_vector *vec,
+                           struct ilo_render_draw_session *session);
+
+void
+gen7_draw_common_pointers_1(struct ilo_render *r,
+                            const struct ilo_state_vector *vec,
+                            struct ilo_render_draw_session *session);
+
+void
+gen7_draw_common_urb(struct ilo_render *r,
+                     const struct ilo_state_vector *vec,
+                     struct ilo_render_draw_session *session);
+
+void
+gen7_draw_common_pointers_2(struct ilo_render *r,
+                            const struct ilo_state_vector *vec,
+                            struct ilo_render_draw_session *session);
+
+void
+gen7_draw_vs(struct ilo_render *r,
+             const struct ilo_state_vector *vec,
+             struct ilo_render_draw_session *session);
+
+void
+gen7_draw_ds(struct ilo_render *r,
+             const struct ilo_state_vector *vec,
+             struct ilo_render_draw_session *session);
+
+void
+gen7_draw_te(struct ilo_render *r,
+             const struct ilo_state_vector *vec,
+             struct ilo_render_draw_session *session);
+
+void
+gen7_draw_hs(struct ilo_render *r,
+             const struct ilo_state_vector *vec,
+             struct ilo_render_draw_session *session);
+
+void
+gen7_draw_gs(struct ilo_render *r,
+             const struct ilo_state_vector *vec,
+             struct ilo_render_draw_session *session);
+
+void
+gen7_draw_sol(struct ilo_render *r,
+              const struct ilo_state_vector *vec,
+              struct ilo_render_draw_session *session);
+
+void
+gen7_draw_vf_draw(struct ilo_render *r,
+                  const struct ilo_state_vector *vec,
+                  struct ilo_render_draw_session *session);
+
 #endif /* ILO_RENDER_GEN_H */
index 5e8cb33..0221acd 100644 (file)
@@ -258,7 +258,10 @@ gen6_draw_common_base_address(struct ilo_render *r,
       if (ilo_dev_gen(r->dev) == ILO_GEN(6))
          gen6_wa_pre_non_pipelined(r);
 
-      gen6_state_base_address(r->builder, r->hw_ctx_changed);
+      if (ilo_dev_gen(r->dev) >= ILO_GEN(8))
+         gen8_state_base_address(r->builder, r->hw_ctx_changed);
+      else
+         gen6_state_base_address(r->builder, r->hw_ctx_changed);
 
       /*
        * From the Sandy Bridge PRM, volume 1 part 1, page 28:
index 1de6e2b..e76db79 100644 (file)
@@ -38,7 +38,7 @@
 /**
  * A wrapper for gen6_PIPE_CONTROL().
  */
-static inline void
+static void
 gen7_pipe_control(struct ilo_render *r, uint32_t dw1)
 {
    struct intel_bo *bo = (dw1 & GEN6_PIPE_CONTROL_WRITE__MASK) ?
@@ -222,7 +222,7 @@ gen7_wa_post_ps_and_later(struct ilo_render *r)
 
 #define DIRTY(state) (session->pipe_dirty & ILO_DIRTY_ ## state)
 
-static void
+void
 gen7_draw_common_urb(struct ilo_render *r,
                      const struct ilo_state_vector *vec,
                      struct ilo_render_draw_session *session)
@@ -230,8 +230,10 @@ gen7_draw_common_urb(struct ilo_render *r,
    /* 3DSTATE_URB_{VS,GS,HS,DS} */
    if (DIRTY(VE) || DIRTY(VS)) {
       /* the first 16KB are reserved for VS and PS PCBs */
-      const int offset = (ilo_dev_gen(r->dev) == ILO_GEN(7.5) &&
-            r->dev->gt == 3) ? 32768 : 16384;
+      const int offset =
+         (ilo_dev_gen(r->dev) >= ILO_GEN(8)) ||
+          (ilo_dev_gen(r->dev) == ILO_GEN(7.5) && r->dev->gt == 3) ?
+          32768 : 16384;
       int vs_entry_size, vs_total_size;
 
       vs_entry_size = (vec->vs) ?
@@ -251,7 +253,8 @@ gen7_draw_common_urb(struct ilo_render *r,
       vs_entry_size *= sizeof(float) * 4;
       vs_total_size = r->dev->urb_size - offset;
 
-      gen7_wa_pre_vs(r);
+      if (ilo_dev_gen(r->dev) < ILO_GEN(8))
+         gen7_wa_pre_vs(r);
 
       gen7_3DSTATE_URB_VS(r->builder,
             offset, vs_total_size, vs_entry_size);
@@ -262,7 +265,7 @@ gen7_draw_common_urb(struct ilo_render *r,
    }
 }
 
-static void
+void
 gen7_draw_common_pcb_alloc(struct ilo_render *r,
                            const struct ilo_state_vector *vec,
                            struct ilo_render_draw_session *session)
@@ -273,8 +276,10 @@ gen7_draw_common_pcb_alloc(struct ilo_render *r,
        * Push constant buffers are only allowed to take up at most the first
        * 16KB of the URB.  Split the space evenly for VS and FS.
        */
-      const int max_size = (ilo_dev_gen(r->dev) == ILO_GEN(7.5) &&
-            r->dev->gt == 3) ? 32768 : 16384;
+      const int max_size =
+         (ilo_dev_gen(r->dev) >= ILO_GEN(8)) ||
+          (ilo_dev_gen(r->dev) == ILO_GEN(7.5) && r->dev->gt == 3) ?
+          32768 : 16384;
       const int size = max_size / 2;
       int offset = 0;
 
@@ -288,7 +293,7 @@ gen7_draw_common_pcb_alloc(struct ilo_render *r,
    }
 }
 
-static void
+void
 gen7_draw_common_pointers_1(struct ilo_render *r,
                             const struct ilo_state_vector *vec,
                             struct ilo_render_draw_session *session)
@@ -303,7 +308,7 @@ gen7_draw_common_pointers_1(struct ilo_render *r,
    }
 }
 
-static void
+void
 gen7_draw_common_pointers_2(struct ilo_render *r,
                             const struct ilo_state_vector *vec,
                             struct ilo_render_draw_session *session)
@@ -321,29 +326,29 @@ gen7_draw_common_pointers_2(struct ilo_render *r,
    }
 
    /* 3DSTATE_DEPTH_STENCIL_STATE_POINTERS */
-   if (session->dsa_changed) {
+   if (ilo_dev_gen(r->dev) < ILO_GEN(8) && session->dsa_changed) {
       gen7_3DSTATE_DEPTH_STENCIL_STATE_POINTERS(r->builder,
             r->state.DEPTH_STENCIL_STATE);
    }
 }
 
-static void
+void
 gen7_draw_vs(struct ilo_render *r,
              const struct ilo_state_vector *vec,
              struct ilo_render_draw_session *session)
 {
-   const bool emit_3dstate_binding_table =
-      session->binding_table_vs_changed;
-   const bool emit_3dstate_sampler_state =
-      session->sampler_vs_changed;
+   const bool emit_3dstate_binding_table = session->binding_table_vs_changed;
+   const bool emit_3dstate_sampler_state = session->sampler_vs_changed;
    /* see gen6_draw_vs() */
    const bool emit_3dstate_constant_vs = session->pcb_vs_changed;
    const bool emit_3dstate_vs = (DIRTY(VS) || r->instruction_bo_changed);
 
    /* emit depth stall before any of the VS commands */
-   if (emit_3dstate_binding_table || emit_3dstate_sampler_state ||
-           emit_3dstate_constant_vs || emit_3dstate_vs)
-      gen7_wa_pre_vs(r);
+   if (ilo_dev_gen(r->dev) < ILO_GEN(8)) {
+      if (emit_3dstate_binding_table || emit_3dstate_sampler_state ||
+          emit_3dstate_constant_vs || emit_3dstate_vs)
+         gen7_wa_pre_vs(r);
+   }
 
    /* 3DSTATE_BINDING_TABLE_POINTERS_VS */
    if (emit_3dstate_binding_table) {
@@ -366,11 +371,18 @@ gen7_draw_vs(struct ilo_render *r,
    }
 
    /* 3DSTATE_VS */
-   if (emit_3dstate_vs)
-      gen6_3DSTATE_VS(r->builder, vec->vs);
+   if (ilo_dev_gen(r->dev) >= ILO_GEN(8)) {
+      if (emit_3dstate_vs || DIRTY(RASTERIZER)) {
+         gen8_3DSTATE_VS(r->builder, vec->vs,
+               vec->rasterizer->state.clip_plane_enable);
+      }
+   } else {
+      if (emit_3dstate_vs)
+         gen6_3DSTATE_VS(r->builder, vec->vs);
+   }
 }
 
-static void
+void
 gen7_draw_hs(struct ilo_render *r,
              const struct ilo_state_vector *vec,
              struct ilo_render_draw_session *session)
@@ -386,7 +398,7 @@ gen7_draw_hs(struct ilo_render *r,
       gen7_3DSTATE_BINDING_TABLE_POINTERS_HS(r->builder, 0);
 }
 
-static void
+void
 gen7_draw_te(struct ilo_render *r,
              const struct ilo_state_vector *vec,
              struct ilo_render_draw_session *session)
@@ -396,7 +408,7 @@ gen7_draw_te(struct ilo_render *r,
       gen7_3DSTATE_TE(r->builder);
 }
 
-static void
+void
 gen7_draw_ds(struct ilo_render *r,
              const struct ilo_state_vector *vec,
              struct ilo_render_draw_session *session)
@@ -413,7 +425,7 @@ gen7_draw_ds(struct ilo_render *r,
 
 }
 
-static void
+void
 gen7_draw_gs(struct ilo_render *r,
              const struct ilo_state_vector *vec,
              struct ilo_render_draw_session *session)
@@ -431,7 +443,7 @@ gen7_draw_gs(struct ilo_render *r,
    }
 }
 
-static void
+void
 gen7_draw_sol(struct ilo_render *r,
               const struct ilo_state_vector *vec,
               struct ilo_render_draw_session *session)
@@ -633,7 +645,7 @@ gen7_draw_wm_multisample(struct ilo_render *r,
    }
 }
 
-static void
+void
 gen7_draw_vf_draw(struct ilo_render *r,
                   const struct ilo_state_vector *vec,
                   struct ilo_render_draw_session *session)
@@ -693,7 +705,9 @@ gen7_rectlist_pcb_alloc(struct ilo_render *r,
     * 16KB of the URB.  Split the space evenly for VS and FS.
     */
    const int max_size =
-      (ilo_dev_gen(r->dev) == ILO_GEN(7.5) && r->dev->gt == 3) ? 32768 : 16384;
+      (ilo_dev_gen(r->dev) >= ILO_GEN(8)) ||
+       (ilo_dev_gen(r->dev) == ILO_GEN(7.5) && r->dev->gt == 3) ?
+       32768 : 16384;
    const int size = max_size / 2;
    int offset = 0;
 
@@ -711,7 +725,9 @@ gen7_rectlist_urb(struct ilo_render *r,
 {
    /* the first 16KB are reserved for VS and PS PCBs */
    const int offset =
-      (ilo_dev_gen(r->dev) == ILO_GEN(7.5) && r->dev->gt == 3) ? 32768 : 16384;
+      (ilo_dev_gen(r->dev) >= ILO_GEN(8)) ||
+       (ilo_dev_gen(r->dev) == ILO_GEN(7.5) && r->dev->gt == 3) ?
+       32768 : 16384;
 
    gen7_3DSTATE_URB_VS(r->builder, offset, r->dev->urb_size - offset,
          (blitter->ve.count + blitter->ve.prepend_nosrc_cso) *
diff --git a/src/gallium/drivers/ilo/ilo_render_gen8.c b/src/gallium/drivers/ilo/ilo_render_gen8.c
new file mode 100644 (file)
index 0000000..a56eda9
--- /dev/null
@@ -0,0 +1,395 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2013 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#include "genhw/genhw.h"
+#include "util/u_dual_blend.h"
+
+#include "ilo_blitter.h"
+#include "ilo_builder_3d.h"
+#include "ilo_builder_render.h"
+#include "ilo_shader.h"
+#include "ilo_state.h"
+#include "ilo_render_gen.h"
+
+/**
+ * A wrapper for gen6_PIPE_CONTROL().
+ */
+static void
+gen8_pipe_control(struct ilo_render *r, uint32_t dw1)
+{
+   struct intel_bo *bo = (dw1 & GEN6_PIPE_CONTROL_WRITE__MASK) ?
+      r->workaround_bo : NULL;
+
+   ILO_DEV_ASSERT(r->dev, 8, 8);
+
+   if (dw1 & GEN6_PIPE_CONTROL_CS_STALL) {
+      /* CS stall cannot be set alone */
+      const uint32_t mask = GEN6_PIPE_CONTROL_RENDER_CACHE_FLUSH |
+                            GEN6_PIPE_CONTROL_DEPTH_CACHE_FLUSH |
+                            GEN6_PIPE_CONTROL_PIXEL_SCOREBOARD_STALL |
+                            GEN6_PIPE_CONTROL_DEPTH_STALL |
+                            GEN6_PIPE_CONTROL_WRITE__MASK;
+      if (!(dw1 & mask))
+         dw1 |= GEN6_PIPE_CONTROL_PIXEL_SCOREBOARD_STALL;
+   }
+
+   gen6_PIPE_CONTROL(r->builder, dw1, bo, 0, 0);
+
+
+   r->state.current_pipe_control_dw1 |= dw1;
+   r->state.deferred_pipe_control_dw1 &= ~dw1;
+}
+
+static void
+gen8_wa_pre_depth(struct ilo_render *r)
+{
+   /*
+    * From the Ivy Bridge PRM, volume 2 part 1, page 315:
+    *
+    *     "Driver must send a least one PIPE_CONTROL command with CS Stall and
+    *      a post sync operation prior to the group of depth
+    *      commands(3DSTATE_DEPTH_BUFFER, 3DSTATE_CLEAR_PARAMS,
+    *      3DSTATE_STENCIL_BUFFER, and 3DSTATE_HIER_DEPTH_BUFFER)."
+    */
+   const uint32_t dw1 = GEN6_PIPE_CONTROL_CS_STALL |
+                        GEN6_PIPE_CONTROL_WRITE_IMM;
+
+   ILO_DEV_ASSERT(r->dev, 8, 8);
+
+   if ((r->state.current_pipe_control_dw1 & dw1) != dw1)
+      gen8_pipe_control(r, dw1);
+
+   /*
+    * From the Ivy Bridge PRM, volume 2 part 1, page 315:
+    *
+    *     "Restriction: Prior to changing Depth/Stencil Buffer state (i.e.,
+    *      any combination of 3DSTATE_DEPTH_BUFFER, 3DSTATE_CLEAR_PARAMS,
+    *      3DSTATE_STENCIL_BUFFER, 3DSTATE_HIER_DEPTH_BUFFER) SW must first
+    *      issue a pipelined depth stall (PIPE_CONTROL with Depth Stall bit
+    *      set), followed by a pipelined depth cache flush (PIPE_CONTROL with
+    *      Depth Flush Bit set, followed by another pipelined depth stall
+    *      (PIPE_CONTROL with Depth Stall Bit set), unless SW can otherwise
+    *      guarantee that the pipeline from WM onwards is already flushed
+    *      (e.g., via a preceding MI_FLUSH)."
+    */
+   gen8_pipe_control(r, GEN6_PIPE_CONTROL_DEPTH_STALL);
+   gen8_pipe_control(r, GEN6_PIPE_CONTROL_DEPTH_CACHE_FLUSH);
+   gen8_pipe_control(r, GEN6_PIPE_CONTROL_DEPTH_STALL);
+}
+
+#define DIRTY(state) (session->pipe_dirty & ILO_DIRTY_ ## state)
+
+static void
+gen8_draw_sf(struct ilo_render *r,
+             const struct ilo_state_vector *vec,
+             struct ilo_render_draw_session *session)
+{
+   /* 3DSTATE_RASTER */
+   if (DIRTY(RASTERIZER)) {
+      gen8_3DSTATE_RASTER(r->builder, (vec->rasterizer) ?
+            &vec->rasterizer->sf : NULL);
+   }
+
+   /* 3DSTATE_SBE */
+   if (DIRTY(RASTERIZER) || DIRTY(FS)) {
+      gen8_3DSTATE_SBE(r->builder, vec->fs, (vec->rasterizer) ?
+            vec->rasterizer->state.sprite_coord_mode : 0);
+   }
+
+   /* 3DSTATE_SBE_SWIZ */
+   if (DIRTY(FS))
+      gen8_3DSTATE_SBE_SWIZ(r->builder, vec->fs);
+
+   /* 3DSTATE_SF */
+   if (DIRTY(RASTERIZER)) {
+      gen8_3DSTATE_SF(r->builder, (vec->rasterizer) ?
+            &vec->rasterizer->sf : NULL);
+   }
+}
+
+static void
+gen8_draw_wm(struct ilo_render *r,
+             const struct ilo_state_vector *vec,
+             struct ilo_render_draw_session *session)
+{
+   /* 3DSTATE_WM */
+   if (DIRTY(FS) || DIRTY(RASTERIZER))
+      gen8_3DSTATE_WM(r->builder, vec->fs, vec->rasterizer);
+
+   if (DIRTY(DSA))
+      gen8_3DSTATE_WM_DEPTH_STENCIL(r->builder, vec->dsa);
+
+   /* 3DSTATE_WM_HZ_OP and 3DSTATE_WM_CHROMAKEY */
+   if (r->hw_ctx_changed) {
+      gen8_disable_3DSTATE_WM_HZ_OP(r->builder);
+      gen8_3DSTATE_WM_CHROMAKEY(r->builder);
+   }
+
+   /* 3DSTATE_BINDING_TABLE_POINTERS_PS */
+   if (session->binding_table_fs_changed) {
+      gen7_3DSTATE_BINDING_TABLE_POINTERS_PS(r->builder,
+            r->state.wm.BINDING_TABLE_STATE);
+   }
+
+   /* 3DSTATE_SAMPLER_STATE_POINTERS_PS */
+   if (session->sampler_fs_changed) {
+      gen7_3DSTATE_SAMPLER_STATE_POINTERS_PS(r->builder,
+            r->state.wm.SAMPLER_STATE);
+   }
+
+   /* 3DSTATE_CONSTANT_PS */
+   if (session->pcb_fs_changed) {
+      gen7_3DSTATE_CONSTANT_PS(r->builder,
+            &r->state.wm.PUSH_CONSTANT_BUFFER,
+            &r->state.wm.PUSH_CONSTANT_BUFFER_size,
+            1);
+   }
+
+   /* 3DSTATE_PS */
+   if (DIRTY(FS) || r->instruction_bo_changed)
+      gen8_3DSTATE_PS(r->builder, vec->fs);
+
+   /* 3DSTATE_PS_EXTRA */
+   if (DIRTY(FS) || DIRTY(DSA) || DIRTY(BLEND)) {
+      const bool cc_may_kill = (vec->dsa->dw_blend_alpha ||
+                                vec->blend->alpha_to_coverage);
+      gen8_3DSTATE_PS_EXTRA(r->builder, vec->fs, cc_may_kill, false);
+   }
+
+   /* 3DSTATE_PS_BLEND */
+   if (DIRTY(BLEND) || DIRTY(FB) || DIRTY(DSA))
+      gen8_3DSTATE_PS_BLEND(r->builder, vec->blend, &vec->fb, vec->dsa);
+
+   /* 3DSTATE_SCISSOR_STATE_POINTERS */
+   if (session->scissor_changed) {
+      gen6_3DSTATE_SCISSOR_STATE_POINTERS(r->builder,
+            r->state.SCISSOR_RECT);
+   }
+
+   /* 3DSTATE_DEPTH_BUFFER and 3DSTATE_CLEAR_PARAMS */
+   if (DIRTY(FB) || r->batch_bo_changed) {
+      const struct ilo_zs_surface *zs;
+      uint32_t clear_params;
+
+      if (vec->fb.state.zsbuf) {
+         const struct ilo_surface_cso *surface =
+            (const struct ilo_surface_cso *) vec->fb.state.zsbuf;
+         const struct ilo_texture_slice *slice =
+            ilo_texture_get_slice(ilo_texture(surface->base.texture),
+                  surface->base.u.tex.level, surface->base.u.tex.first_layer);
+
+         assert(!surface->is_rt);
+         zs = &surface->u.zs;
+         clear_params = slice->clear_value;
+      }
+      else {
+         zs = &vec->fb.null_zs;
+         clear_params = 0;
+      }
+
+      gen8_wa_pre_depth(r);
+
+      gen6_3DSTATE_DEPTH_BUFFER(r->builder, zs, false);
+      gen6_3DSTATE_HIER_DEPTH_BUFFER(r->builder, zs);
+      gen6_3DSTATE_STENCIL_BUFFER(r->builder, zs);
+      gen7_3DSTATE_CLEAR_PARAMS(r->builder, clear_params);
+   }
+}
+
+static void
+gen8_draw_wm_sample_pattern(struct ilo_render *r,
+                            const struct ilo_state_vector *vec,
+                            struct ilo_render_draw_session *session)
+{
+   /* 3DSTATE_SAMPLE_PATTERN */
+   if (r->hw_ctx_changed) {
+      gen8_3DSTATE_SAMPLE_PATTERN(r->builder,
+            &r->sample_pattern_1x,
+            &r->sample_pattern_2x,
+            &r->sample_pattern_4x,
+            r->sample_pattern_8x,
+            r->sample_pattern_16x);
+   }
+}
+
+static void
+gen8_draw_wm_multisample(struct ilo_render *r,
+                         const struct ilo_state_vector *vec,
+                         struct ilo_render_draw_session *session)
+{
+   /* 3DSTATE_MULTISAMPLE and 3DSTATE_SAMPLE_MASK */
+   if (DIRTY(SAMPLE_MASK) || DIRTY(FB) || DIRTY(RASTERIZER)) {
+      gen8_3DSTATE_MULTISAMPLE(r->builder, vec->fb.num_samples,
+            vec->rasterizer->state.half_pixel_center);
+
+      gen7_3DSTATE_SAMPLE_MASK(r->builder,
+            (vec->fb.num_samples > 1) ? vec->sample_mask : 0x1,
+            vec->fb.num_samples);
+   }
+}
+
+static void
+gen8_draw_vf(struct ilo_render *r,
+             const struct ilo_state_vector *vec,
+             struct ilo_render_draw_session *session)
+{
+   const int prim = gen6_3d_translate_pipe_prim(vec->draw->mode);
+   int i;
+
+   /* 3DSTATE_INDEX_BUFFER */
+   if (DIRTY(IB) || r->batch_bo_changed)
+      gen8_3DSTATE_INDEX_BUFFER(r->builder, &vec->ib);
+
+   /* 3DSTATE_VF */
+   if (session->primitive_restart_changed) {
+      gen75_3DSTATE_VF(r->builder, vec->draw->primitive_restart,
+            vec->draw->restart_index);
+   }
+
+   /* 3DSTATE_VERTEX_BUFFERS */
+   if (DIRTY(VB) || DIRTY(VE) || r->batch_bo_changed)
+      gen6_3DSTATE_VERTEX_BUFFERS(r->builder, vec->ve, &vec->vb);
+
+   /* 3DSTATE_VERTEX_ELEMENTS */
+   if (DIRTY(VE))
+      gen6_3DSTATE_VERTEX_ELEMENTS(r->builder, vec->ve);
+
+   gen8_3DSTATE_VF_TOPOLOGY(r->builder, prim);
+
+   for (i = 0; i < vec->ve->vb_count; i++) {
+      gen8_3DSTATE_VF_INSTANCING(r->builder, i,
+            vec->ve->instance_divisors[i]);
+   }
+
+   gen8_3DSTATE_VF_SGVS(r->builder,
+         false, 0, 0,
+         false, 0, 0);
+}
+
+void
+ilo_render_emit_draw_commands_gen8(struct ilo_render *render,
+                                   const struct ilo_state_vector *vec,
+                                   struct ilo_render_draw_session *session)
+{
+   ILO_DEV_ASSERT(render->dev, 8, 8);
+
+   /*
+    * We try to keep the order of the commands match, as closely as possible,
+    * that of the classic i965 driver.  It allows us to compare the command
+    * streams easily.
+    */
+   gen6_draw_common_select(render, vec, session);
+   gen6_draw_common_sip(render, vec, session);
+   gen6_draw_vf_statistics(render, vec, session);
+   gen8_draw_wm_sample_pattern(render, vec, session);
+   gen6_draw_common_base_address(render, vec, session);
+   gen7_draw_common_pointers_1(render, vec, session);
+   gen7_draw_common_pcb_alloc(render, vec, session);
+   gen7_draw_common_urb(render, vec, session);
+   gen7_draw_common_pointers_2(render, vec, session);
+   gen8_draw_wm_multisample(render, vec, session);
+   gen7_draw_gs(render, vec, session);
+   gen7_draw_hs(render, vec, session);
+   gen7_draw_te(render, vec, session);
+   gen7_draw_ds(render, vec, session);
+   gen7_draw_vs(render, vec, session);
+   gen7_draw_sol(render, vec, session);
+   gen6_draw_clip(render, vec, session);
+   gen8_draw_sf(render, vec, session);
+   gen8_draw_wm(render, vec, session);
+   gen6_draw_wm_raster(render, vec, session);
+   gen6_draw_sf_rect(render, vec, session);
+   gen8_draw_vf(render, vec, session);
+   gen7_draw_vf_draw(render, vec, session);
+}
+
+int
+ilo_render_get_draw_commands_len_gen8(const struct ilo_render *render,
+                                      const struct ilo_state_vector *vec)
+{
+   static int len;
+
+   ILO_DEV_ASSERT(render->dev, 8, 8);
+
+   if (!len) {
+      len += GEN7_3DSTATE_URB_ANY__SIZE * 4;
+      len += GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_ANY__SIZE * 5;
+      len += GEN6_3DSTATE_CONSTANT_ANY__SIZE * 5;
+      len += GEN7_3DSTATE_POINTERS_ANY__SIZE * (5 + 5 + 4);
+      len += GEN7_3DSTATE_SO_BUFFER__SIZE * 4;
+      len += GEN6_PIPE_CONTROL__SIZE * 5;
+
+      len +=
+         GEN6_STATE_BASE_ADDRESS__SIZE +
+         GEN6_STATE_SIP__SIZE +
+         GEN6_3DSTATE_VF_STATISTICS__SIZE +
+         GEN6_PIPELINE_SELECT__SIZE +
+         GEN6_3DSTATE_CLEAR_PARAMS__SIZE +
+         GEN6_3DSTATE_DEPTH_BUFFER__SIZE +
+         GEN6_3DSTATE_STENCIL_BUFFER__SIZE +
+         GEN6_3DSTATE_HIER_DEPTH_BUFFER__SIZE +
+         GEN6_3DSTATE_VERTEX_BUFFERS__SIZE +
+         GEN6_3DSTATE_VERTEX_ELEMENTS__SIZE +
+         GEN6_3DSTATE_INDEX_BUFFER__SIZE +
+         GEN75_3DSTATE_VF__SIZE +
+         GEN6_3DSTATE_VS__SIZE +
+         GEN6_3DSTATE_GS__SIZE +
+         GEN6_3DSTATE_CLIP__SIZE +
+         GEN6_3DSTATE_SF__SIZE +
+         GEN6_3DSTATE_WM__SIZE +
+         GEN6_3DSTATE_SAMPLE_MASK__SIZE +
+         GEN7_3DSTATE_HS__SIZE +
+         GEN7_3DSTATE_TE__SIZE +
+         GEN7_3DSTATE_DS__SIZE +
+         GEN7_3DSTATE_STREAMOUT__SIZE +
+         GEN7_3DSTATE_SBE__SIZE +
+         GEN7_3DSTATE_PS__SIZE +
+         GEN6_3DSTATE_DRAWING_RECTANGLE__SIZE +
+         GEN6_3DSTATE_POLY_STIPPLE_OFFSET__SIZE +
+         GEN6_3DSTATE_POLY_STIPPLE_PATTERN__SIZE +
+         GEN6_3DSTATE_LINE_STIPPLE__SIZE +
+         GEN6_3DSTATE_AA_LINE_PARAMETERS__SIZE +
+         GEN6_3DSTATE_MULTISAMPLE__SIZE +
+         GEN7_3DSTATE_SO_DECL_LIST__SIZE +
+         GEN6_3DPRIMITIVE__SIZE;
+
+      len +=
+         GEN8_3DSTATE_VF_INSTANCING__SIZE * 33 +
+         GEN8_3DSTATE_VF_SGVS__SIZE +
+         GEN8_3DSTATE_VF_TOPOLOGY__SIZE +
+         GEN8_3DSTATE_SBE_SWIZ__SIZE +
+         GEN8_3DSTATE_RASTER__SIZE +
+         GEN8_3DSTATE_WM_CHROMAKEY__SIZE +
+         GEN8_3DSTATE_WM_DEPTH_STENCIL__SIZE +
+         GEN8_3DSTATE_WM_HZ_OP__SIZE +
+         GEN8_3DSTATE_PS_EXTRA__SIZE +
+         GEN8_3DSTATE_PS_BLEND__SIZE +
+         GEN8_3DSTATE_SAMPLE_PATTERN__SIZE;
+   }
+
+   return len;
+}