ilo: update WM and PS related functions for Gen8
authorChia-I Wu <olvaffe@gmail.com>
Mon, 26 Jan 2015 10:06:00 +0000 (18:06 +0800)
committerChia-I Wu <olvaffe@gmail.com>
Wed, 11 Feb 2015 23:56:11 +0000 (07:56 +0800)
src/gallium/drivers/ilo/ilo_builder_3d_bottom.h
src/gallium/drivers/ilo/ilo_state_3d_bottom.c

index 958240a5288218f4161a50f06bffa4f22292f478..9a85f2339faad562d947d73da731b6f8e0a42afb 100644 (file)
@@ -517,6 +517,33 @@ gen7_3DSTATE_WM(struct ilo_builder *builder,
    dw[2] = dw2;
 }
 
+static inline void
+gen8_3DSTATE_WM(struct ilo_builder *builder,
+                const struct ilo_shader_state *fs,
+                const struct ilo_rasterizer_state *rasterizer)
+{
+   const uint8_t cmd_len = 2;
+   const struct ilo_shader_cso *cso;
+   uint32_t dw1, interps, *dw;
+
+   ILO_DEV_ASSERT(builder->dev, 8, 8);
+
+   /* see rasterizer_get_wm_gen8() */
+   dw1 = rasterizer->wm.payload[0];
+   dw1 |= GEN7_WM_DW1_STATISTICS;
+
+   /* see fs_init_cso_gen8() */
+   cso = ilo_shader_get_kernel_cso(fs);
+   interps = cso->payload[4];
+
+   assert(!(dw1 & interps));
+
+   ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+   dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_WM) | (cmd_len - 2);
+   dw[1] = dw1 | interps;
+}
+
 static inline void
 gen7_hiz_3DSTATE_WM(struct ilo_builder *builder, uint32_t hiz_op)
 {
@@ -542,6 +569,7 @@ gen7_3DSTATE_PS(struct ilo_builder *builder,
 
    ILO_DEV_ASSERT(builder->dev, 7, 7.5);
 
+   /* see fs_init_cso_gen7() */
    cso = ilo_shader_get_kernel_cso(fs);
    dw2 = cso->payload[0];
    dw4 = cso->payload[1];
@@ -600,6 +628,64 @@ gen7_disable_3DSTATE_PS(struct ilo_builder *builder)
    dw[7] = 0;
 }
 
+static inline void
+gen8_3DSTATE_PS(struct ilo_builder *builder,
+                const struct ilo_shader_state *fs)
+{
+   const uint8_t cmd_len = 12;
+   const struct ilo_shader_cso *cso;
+   uint32_t dw3, dw6, dw7, *dw;
+
+   ILO_DEV_ASSERT(builder->dev, 8, 8);
+
+   /* see fs_init_cso_gen8() */
+   cso = ilo_shader_get_kernel_cso(fs);
+   dw3 = cso->payload[0];
+   dw6 = cso->payload[1];
+   dw7 = cso->payload[2];
+
+   ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+   dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PS) | (cmd_len - 2);
+   dw[1] = ilo_shader_get_kernel_offset(fs);
+   dw[2] = 0;
+   dw[3] = dw3;
+   dw[4] = 0; /* scratch */
+   dw[5] = 0;
+   dw[6] = dw6;
+   dw[7] = dw7;
+   dw[8] = 0; /* kernel 1 */
+   dw[9] = 0;
+   dw[10] = 0; /* kernel 2 */
+   dw[11] = 0;
+}
+
+static inline void
+gen8_3DSTATE_PS_EXTRA(struct ilo_builder *builder,
+                      const struct ilo_shader_state *fs,
+                      bool cc_may_kill, bool per_sample)
+{
+   const uint8_t cmd_len = 2;
+   const struct ilo_shader_cso *cso;
+   uint32_t dw1, *dw;
+
+   ILO_DEV_ASSERT(builder->dev, 8, 8);
+
+   /* see fs_init_cso_gen8() */
+   cso = ilo_shader_get_kernel_cso(fs);
+   dw1 = cso->payload[3];
+
+   if (cc_may_kill)
+      dw1 |= GEN8_PSX_DW1_DISPATCH_ENABLE | GEN8_PSX_DW1_KILL_PIXEL;
+   if (per_sample)
+      dw1 |= GEN8_PSX_DW1_PER_SAMPLE;
+
+   ilo_builder_batch_pointer(builder, cmd_len, &dw);
+
+   dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_PS_EXTRA) | (cmd_len - 2);
+   dw[1] = dw1;
+}
+
 static inline void
 gen6_3DSTATE_CONSTANT_PS(struct ilo_builder *builder,
                          const uint32_t *bufs, const int *sizes,
index a78c6900951e23894f5013858e26a9fa8ceec6a7..bd4e1149fc6ff29f8f530bdf78e63ad52509bd9f 100644 (file)
@@ -492,13 +492,6 @@ rasterizer_init_wm_gen6(const struct ilo_dev_info *dev,
    if (state->line_stipple_enable)
       dw5 |= GEN6_WM_DW5_LINE_STIPPLE_ENABLE;
 
-   dw6 = GEN6_WM_DW6_ZW_INTERP_PIXEL |
-         GEN6_WM_DW6_MSRASTMODE_OFF_PIXEL |
-         GEN6_WM_DW6_MSDISPMODE_PERSAMPLE;
-
-   if (state->bottom_edge_rule)
-      dw6 |= GEN6_WM_DW6_POINT_RASTRULE_UPPER_RIGHT;
-
    /*
     * assertion that makes sure
     *
@@ -508,6 +501,10 @@ rasterizer_init_wm_gen6(const struct ilo_dev_info *dev,
     */
    STATIC_ASSERT(GEN6_WM_DW6_MSRASTMODE_OFF_PIXEL == 0 &&
                  GEN6_WM_DW6_MSDISPMODE_PERSAMPLE == 0);
+   dw6 = GEN6_WM_DW6_ZW_INTERP_PIXEL;
+
+   if (state->bottom_edge_rule)
+      dw6 |= GEN6_WM_DW6_POINT_RASTRULE_UPPER_RIGHT;
 
    wm->dw_msaa_rast =
       (state->multisample) ? GEN6_WM_DW6_MSRASTMODE_ON_PATTERN : 0;
@@ -527,9 +524,19 @@ rasterizer_init_wm_gen7(const struct ilo_dev_info *dev,
 
    ILO_DEV_ASSERT(dev, 7, 7.5);
 
+   /*
+    * assertion that makes sure
+    *
+    *   dw1 |= wm->dw_msaa_rast;
+    *   dw2 |= wm->dw_msaa_disp;
+    *
+    * is valid
+    */
+   STATIC_ASSERT(GEN7_WM_DW1_MSRASTMODE_OFF_PIXEL == 0 &&
+                 GEN7_WM_DW2_MSDISPMODE_PERSAMPLE == 0);
    dw1 = GEN7_WM_DW1_ZW_INTERP_PIXEL |
-         GEN7_WM_DW1_AA_LINE_WIDTH_2_0 |
-         GEN7_WM_DW1_MSRASTMODE_OFF_PIXEL;
+         GEN7_WM_DW1_AA_LINE_WIDTH_2_0;
+   dw2 = 0;
 
    /* same value as in 3DSTATE_SF */
    if (state->line_smooth)
@@ -543,19 +550,6 @@ rasterizer_init_wm_gen7(const struct ilo_dev_info *dev,
    if (state->bottom_edge_rule)
       dw1 |= GEN7_WM_DW1_POINT_RASTRULE_UPPER_RIGHT;
 
-   dw2 = GEN7_WM_DW2_MSDISPMODE_PERSAMPLE;
-
-   /*
-    * assertion that makes sure
-    *
-    *   dw1 |= wm->dw_msaa_rast;
-    *   dw2 |= wm->dw_msaa_disp;
-    *
-    * is valid
-    */
-   STATIC_ASSERT(GEN7_WM_DW1_MSRASTMODE_OFF_PIXEL == 0 &&
-                 GEN7_WM_DW2_MSDISPMODE_PERSAMPLE == 0);
-
    wm->dw_msaa_rast =
       (state->multisample) ? GEN7_WM_DW1_MSRASTMODE_ON_PATTERN : 0;
    wm->dw_msaa_disp = GEN7_WM_DW2_MSDISPMODE_PERPIXEL;
@@ -565,6 +559,32 @@ rasterizer_init_wm_gen7(const struct ilo_dev_info *dev,
    wm->payload[1] = dw2;
 }
 
+static uint32_t
+rasterizer_get_wm_gen8(const struct ilo_dev_info *dev,
+                       const struct pipe_rasterizer_state *state)
+{
+   uint32_t dw;
+
+   ILO_DEV_ASSERT(dev, 8, 8);
+
+   dw = GEN7_WM_DW1_ZW_INTERP_PIXEL |
+        GEN7_WM_DW1_AA_LINE_WIDTH_2_0;
+
+   /* same value as in 3DSTATE_SF */
+   if (state->line_smooth)
+      dw |= GEN7_WM_DW1_AA_LINE_CAP_1_0;
+
+   if (state->poly_stipple_enable)
+      dw |= GEN7_WM_DW1_POLY_STIPPLE_ENABLE;
+   if (state->line_stipple_enable)
+      dw |= GEN7_WM_DW1_LINE_STIPPLE_ENABLE;
+
+   if (state->bottom_edge_rule)
+      dw |= GEN7_WM_DW1_POINT_RASTRULE_UPPER_RIGHT;
+
+   return dw;
+}
+
 void
 ilo_gpe_init_rasterizer(const struct ilo_dev_info *dev,
                         const struct pipe_rasterizer_state *state,
@@ -573,7 +593,9 @@ ilo_gpe_init_rasterizer(const struct ilo_dev_info *dev,
    rasterizer_init_clip(dev, state, &rasterizer->clip);
 
    if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
-      rasterizer_init_wm_gen7(dev, state, &rasterizer->wm);
+      memset(&rasterizer->wm, 0, sizeof(rasterizer->wm));
+      rasterizer->wm.payload[0] = rasterizer_get_wm_gen8(dev, state);
+
       rasterizer_init_sf_gen8(dev, state, &rasterizer->sf);
    } else if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
       rasterizer_init_wm_gen7(dev, state, &rasterizer->wm);
@@ -681,6 +703,68 @@ fs_init_cso_gen6(const struct ilo_dev_info *dev,
    cso->payload[3] = dw6;
 }
 
+static uint32_t
+fs_get_wm_gen7(const struct ilo_dev_info *dev,
+               const struct ilo_shader_state *fs)
+{
+   uint32_t dw;
+
+   ILO_DEV_ASSERT(dev, 7, 7.5);
+
+   dw = ilo_shader_get_kernel_param(fs,
+         ILO_KERNEL_FS_BARYCENTRIC_INTERPOLATIONS) <<
+      GEN7_WM_DW1_BARYCENTRIC_INTERP__SHIFT;
+
+   /*
+    * TODO set this bit only when
+    *
+    *  a) fs writes colors and color is not masked, or
+    *  b) fs writes depth, or
+    *  c) fs or cc kills
+    */
+   dw |= GEN7_WM_DW1_PS_DISPATCH_ENABLE;
+
+   /*
+    * From the Ivy Bridge PRM, volume 2 part 1, page 278:
+    *
+    *     "This bit (Pixel Shader Kill Pixel), if ENABLED, indicates that
+    *      the PS kernel or color calculator has the ability to kill
+    *      (discard) pixels or samples, other than due to depth or stencil
+    *      testing. This bit is required to be ENABLED in the following
+    *      situations:
+    *
+    *      - The API pixel shader program contains "killpix" or "discard"
+    *        instructions, or other code in the pixel shader kernel that
+    *        can cause the final pixel mask to differ from the pixel mask
+    *        received on dispatch.
+    *
+    *      - A sampler with chroma key enabled with kill pixel mode is used
+    *        by the pixel shader.
+    *
+    *      - Any render target has Alpha Test Enable or AlphaToCoverage
+    *        Enable enabled.
+    *
+    *      - The pixel shader kernel generates and outputs oMask.
+    *
+    *      Note: As ClipDistance clipping is fully supported in hardware
+    *      and therefore not via PS instructions, there should be no need
+    *      to ENABLE this bit due to ClipDistance clipping."
+    */
+   if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_USE_KILL))
+      dw |= GEN7_WM_DW1_PS_KILL_PIXEL;
+
+   if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_OUTPUT_Z))
+      dw |= GEN7_WM_DW1_PSCDEPTH_ON;
+
+   if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_INPUT_Z))
+      dw |= GEN7_WM_DW1_PS_USE_DEPTH;
+
+   if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_INPUT_W))
+      dw |= GEN7_WM_DW1_PS_USE_W;
+
+   return dw;
+}
+
 static void
 fs_init_cso_gen7(const struct ilo_dev_info *dev,
                  const struct ilo_shader_state *fs,
@@ -688,7 +772,6 @@ fs_init_cso_gen7(const struct ilo_dev_info *dev,
 {
    int start_grf, sampler_count, max_threads;
    uint32_t dw2, dw4, dw5;
-   uint32_t wm_interps, wm_dw1;
 
    ILO_DEV_ASSERT(dev, 7, 7.5);
 
@@ -727,66 +810,83 @@ fs_init_cso_gen7(const struct ilo_dev_info *dev,
          0 << GEN7_PS_DW5_URB_GRF_START1__SHIFT |
          0 << GEN7_PS_DW5_URB_GRF_START2__SHIFT;
 
-   /* FS affects 3DSTATE_WM too */
-   wm_dw1 = 0;
+   STATIC_ASSERT(Elements(cso->payload) >= 4);
+   cso->payload[0] = dw2;
+   cso->payload[1] = dw4;
+   cso->payload[2] = dw5;
+   cso->payload[3] = fs_get_wm_gen7(dev, fs);
+}
 
-   /*
-    * TODO set this bit only when
-    *
-    *  a) fs writes colors and color is not masked, or
-    *  b) fs writes depth, or
-    *  c) fs or cc kills
-    */
-   wm_dw1 |= GEN7_WM_DW1_PS_DISPATCH_ENABLE;
+static uint32_t
+fs_get_psx_gen8(const struct ilo_dev_info *dev,
+                const struct ilo_shader_state *fs)
+{
+   uint32_t dw;
 
-   /*
-    * From the Ivy Bridge PRM, volume 2 part 1, page 278:
-    *
-    *     "This bit (Pixel Shader Kill Pixel), if ENABLED, indicates that
-    *      the PS kernel or color calculator has the ability to kill
-    *      (discard) pixels or samples, other than due to depth or stencil
-    *      testing. This bit is required to be ENABLED in the following
-    *      situations:
-    *
-    *      - The API pixel shader program contains "killpix" or "discard"
-    *        instructions, or other code in the pixel shader kernel that
-    *        can cause the final pixel mask to differ from the pixel mask
-    *        received on dispatch.
-    *
-    *      - A sampler with chroma key enabled with kill pixel mode is used
-    *        by the pixel shader.
-    *
-    *      - Any render target has Alpha Test Enable or AlphaToCoverage
-    *        Enable enabled.
-    *
-    *      - The pixel shader kernel generates and outputs oMask.
-    *
-    *      Note: As ClipDistance clipping is fully supported in hardware
-    *      and therefore not via PS instructions, there should be no need
-    *      to ENABLE this bit due to ClipDistance clipping."
-    */
-   if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_USE_KILL))
-      wm_dw1 |= GEN7_WM_DW1_PS_KILL_PIXEL;
+   ILO_DEV_ASSERT(dev, 8, 8);
 
-   if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_OUTPUT_Z))
-      wm_dw1 |= GEN7_WM_DW1_PSCDEPTH_ON;
+   dw = GEN8_PSX_DW1_DISPATCH_ENABLE;
 
+   if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_USE_KILL))
+      dw |= GEN8_PSX_DW1_KILL_PIXEL;
+   if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_OUTPUT_Z))
+      dw |= GEN8_PSX_DW1_PSCDEPTH_ON;
    if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_INPUT_Z))
-      wm_dw1 |= GEN7_WM_DW1_PS_USE_DEPTH;
-
+      dw |= GEN8_PSX_DW1_USE_DEPTH;
    if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_INPUT_W))
-      wm_dw1 |= GEN7_WM_DW1_PS_USE_W;
+      dw |= GEN8_PSX_DW1_USE_W;
+   if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_INPUT_COUNT))
+      dw |= GEN8_PSX_DW1_ATTR_ENABLE;
 
-   wm_interps = ilo_shader_get_kernel_param(fs,
-         ILO_KERNEL_FS_BARYCENTRIC_INTERPOLATIONS);
+   return dw;
+}
+
+static uint32_t
+fs_get_wm_gen8(const struct ilo_dev_info *dev,
+               const struct ilo_shader_state *fs)
+{
+   ILO_DEV_ASSERT(dev, 8, 8);
 
-   wm_dw1 |= wm_interps << GEN7_WM_DW1_BARYCENTRIC_INTERP__SHIFT;
+   return ilo_shader_get_kernel_param(fs,
+         ILO_KERNEL_FS_BARYCENTRIC_INTERPOLATIONS) <<
+      GEN7_WM_DW1_BARYCENTRIC_INTERP__SHIFT;
+}
 
-   STATIC_ASSERT(Elements(cso->payload) >= 4);
-   cso->payload[0] = dw2;
-   cso->payload[1] = dw4;
-   cso->payload[2] = dw5;
-   cso->payload[3] = wm_dw1;
+static void
+fs_init_cso_gen8(const struct ilo_dev_info *dev,
+                 const struct ilo_shader_state *fs,
+                 struct ilo_shader_cso *cso)
+{
+   int start_grf, sampler_count;
+   uint32_t dw3, dw6, dw7;
+
+   ILO_DEV_ASSERT(dev, 8, 8);
+
+   start_grf = ilo_shader_get_kernel_param(fs, ILO_KERNEL_URB_DATA_START_REG);
+   sampler_count = ilo_shader_get_kernel_param(fs, ILO_KERNEL_SAMPLER_COUNT);
+
+   dw3 = (true) ? 0 : GEN6_THREADDISP_FP_MODE_ALT;
+   dw3 |= ((sampler_count + 3) / 4) << GEN6_THREADDISP_SAMPLER_COUNT__SHIFT;
+
+   /* always 64? */
+   dw6 = (64 - 2) << GEN8_PS_DW6_MAX_THREADS__SHIFT |
+         GEN8_PS_DW6_POSOFFSET_NONE;
+   if (ilo_shader_get_kernel_param(fs, ILO_KERNEL_PCB_CBUF0_SIZE))
+      dw6 |= GEN8_PS_DW6_PUSH_CONSTANT_ENABLE;
+
+   assert(!ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_DISPATCH_16_OFFSET));
+   dw6 |= GEN6_PS_DISPATCH_8 << GEN8_PS_DW6_DISPATCH_MODE__SHIFT;
+
+   dw7 = start_grf << GEN8_PS_DW7_URB_GRF_START0__SHIFT |
+         0 << GEN8_PS_DW7_URB_GRF_START1__SHIFT |
+         0 << GEN8_PS_DW7_URB_GRF_START2__SHIFT;
+
+   STATIC_ASSERT(Elements(cso->payload) >= 5);
+   cso->payload[0] = dw3;
+   cso->payload[1] = dw6;
+   cso->payload[2] = dw7;
+   cso->payload[3] = fs_get_psx_gen8(dev, fs);
+   cso->payload[4] = fs_get_wm_gen8(dev, fs);
 }
 
 void
@@ -794,7 +894,9 @@ ilo_gpe_init_fs_cso(const struct ilo_dev_info *dev,
                     const struct ilo_shader_state *fs,
                     struct ilo_shader_cso *cso)
 {
-   if (ilo_dev_gen(dev) >= ILO_GEN(7))
+   if (ilo_dev_gen(dev) >= ILO_GEN(8))
+      fs_init_cso_gen8(dev, fs, cso);
+   else if (ilo_dev_gen(dev) >= ILO_GEN(7))
       fs_init_cso_gen7(dev, fs, cso);
    else
       fs_init_cso_gen6(dev, fs, cso);