ilo: clean up ilo_gpe_init_blend()
authorChia-I Wu <olvaffe@gmail.com>
Sun, 25 Jan 2015 17:08:31 +0000 (01:08 +0800)
committerChia-I Wu <olvaffe@gmail.com>
Wed, 11 Feb 2015 23:56:10 +0000 (07:56 +0800)
Make ilo_blend_state more space efficient and forward-looking.

src/gallium/drivers/ilo/ilo_builder_3d_bottom.h
src/gallium/drivers/ilo/ilo_state.h
src/gallium/drivers/ilo/ilo_state_3d_bottom.c

index f137232bcaa2e64a23c0a7d289dc76a4355240e1..2c3efb6ca2f10439c19bedc3fc2143a0a1e9bc47 100644 (file)
@@ -1232,11 +1232,10 @@ gen6_BLEND_STATE(struct ilo_builder *builder,
          ILO_BUILDER_ITEM_BLEND, state_align, state_len, &dw);
 
    for (i = 0; i < num_targets; i++) {
-      const struct ilo_blend_cso *cso =
-         &blend->cso[(blend->independent_blend_enable) ? i : 0];
+      const struct ilo_blend_cso *cso = &blend->cso[i];
 
       dw[0] = cso->payload[0];
-      dw[1] = cso->payload[1];
+      dw[1] = cso->payload[1] | blend->dw_shared;
 
       if (i < fb->state.nr_cbufs && fb->state.cbufs[i]) {
          const struct ilo_fb_blend_caps *caps = &fb->blend_caps[i];
@@ -1249,7 +1248,7 @@ gen6_BLEND_STATE(struct ilo_builder *builder,
          }
 
          if (caps->can_logicop)
-            dw[1] |= cso->dw_logicop;
+            dw[1] |= blend->dw_logicop;
 
          if (caps->can_alpha_test)
             dw[1] |= dsa->dw_alpha;
@@ -1271,7 +1270,7 @@ gen6_BLEND_STATE(struct ilo_builder *builder,
        * requires that anyway.
        */
       if (fb->num_samples > 1)
-         dw[1] |= cso->dw_alpha_mod;
+         dw[1] |= blend->dw_alpha_mod;
 
       dw += 2;
    }
index afe27847a9383a9f67e992d9eb8ddb93813238cc..cecca3e4abd762bb0bd6279d20b9150b27be3e90 100644 (file)
@@ -252,17 +252,17 @@ struct ilo_blend_cso {
 
    uint32_t dw_blend;
    uint32_t dw_blend_dst_alpha_forced_one;
-
-   uint32_t dw_logicop;
-   uint32_t dw_alpha_mod;
 };
 
 struct ilo_blend_state {
    struct ilo_blend_cso cso[ILO_MAX_DRAW_BUFFERS];
 
-   bool independent_blend_enable;
    bool dual_blend;
    bool alpha_to_coverage;
+
+   uint32_t dw_shared;
+   uint32_t dw_alpha_mod;
+   uint32_t dw_logicop;
 };
 
 struct ilo_sampler_cso {
index 822f8a46f68db1622025a7636c550f327bd8c4fd..d926ec5e7aee13474d23c12efa7282c95a042756 100644 (file)
@@ -1245,13 +1245,15 @@ gen6_blend_factor_dst_alpha_forced_one(int factor)
 }
 
 static uint32_t
-blend_get_rt_blend_enable(const struct ilo_dev_info *dev,
-                          const struct pipe_rt_blend_state *rt,
-                          bool dst_alpha_forced_one)
+blend_get_rt_blend_enable_gen6(const struct ilo_dev_info *dev,
+                               const struct pipe_rt_blend_state *rt,
+                               bool dst_alpha_forced_one)
 {
    int rgb_src, rgb_dst, a_src, a_dst;
    uint32_t dw;
 
+   ILO_DEV_ASSERT(dev, 6, 7.5);
+
    if (!rt->blend_enable)
       return 0;
 
@@ -1267,7 +1269,7 @@ blend_get_rt_blend_enable(const struct ilo_dev_info *dev,
       a_dst = gen6_blend_factor_dst_alpha_forced_one(a_dst);
    }
 
-   dw = 1 << 31 |
+   dw = GEN6_BLEND_DW0_BLEND_ENABLE |
         gen6_translate_pipe_blend(rt->alpha_func) << 26 |
         a_src << 20 |
         a_dst << 15 |
@@ -1277,102 +1279,120 @@ blend_get_rt_blend_enable(const struct ilo_dev_info *dev,
 
    if (rt->rgb_func != rt->alpha_func ||
        rgb_src != a_src || rgb_dst != a_dst)
-      dw |= 1 << 30;
+      dw |= GEN6_BLEND_DW0_INDEPENDENT_ALPHA_ENABLE;
 
    return dw;
 }
 
-void
-ilo_gpe_init_blend(const struct ilo_dev_info *dev,
-                   const struct pipe_blend_state *state,
-                   struct ilo_blend_state *blend)
+static void
+blend_init_cso_gen6(const struct ilo_dev_info *dev,
+                    const struct pipe_blend_state *state,
+                    struct ilo_blend_state *blend,
+                    unsigned index)
 {
-   unsigned num_cso, i;
+   const struct pipe_rt_blend_state *rt = &state->rt[index];
+   struct ilo_blend_cso *cso = &blend->cso[index];
 
    ILO_DEV_ASSERT(dev, 6, 7.5);
 
-   if (state->independent_blend_enable) {
-      num_cso = Elements(blend->cso);
-   }
-   else {
-      memset(blend->cso, 0, sizeof(blend->cso));
-      num_cso = 1;
-   }
+   cso->payload[0] = 0;
+   cso->payload[1] = GEN6_BLEND_DW1_COLORCLAMP_RTFORMAT |
+                     GEN6_BLEND_DW1_PRE_BLEND_CLAMP |
+                     GEN6_BLEND_DW1_POST_BLEND_CLAMP;
 
-   blend->independent_blend_enable = state->independent_blend_enable;
-   blend->alpha_to_coverage = state->alpha_to_coverage;
-   blend->dual_blend = false;
-
-   for (i = 0; i < num_cso; i++) {
-      const struct pipe_rt_blend_state *rt = &state->rt[i];
-      struct ilo_blend_cso *cso = &blend->cso[i];
-      bool dual_blend;
+   if (!(rt->colormask & PIPE_MASK_A))
+      cso->payload[1] |= GEN6_BLEND_DW1_WRITE_DISABLE_A;
+   if (!(rt->colormask & PIPE_MASK_R))
+      cso->payload[1] |= GEN6_BLEND_DW1_WRITE_DISABLE_R;
+   if (!(rt->colormask & PIPE_MASK_G))
+      cso->payload[1] |= GEN6_BLEND_DW1_WRITE_DISABLE_G;
+   if (!(rt->colormask & PIPE_MASK_B))
+      cso->payload[1] |= GEN6_BLEND_DW1_WRITE_DISABLE_B;
 
-      cso->payload[0] = 0;
-      cso->payload[1] = GEN6_BLEND_DW1_COLORCLAMP_RTFORMAT |
-                            0x3;
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 365:
+    *
+    *     "Color Buffer Blending and Logic Ops must not be enabled
+    *      simultaneously, or behavior is UNDEFINED."
+    *
+    * Since state->logicop_enable takes precedence over rt->blend_enable,
+    * no special care is needed.
+    */
+   if (state->logicop_enable) {
+      cso->dw_blend = 0;
+      cso->dw_blend_dst_alpha_forced_one = 0;
+   } else {
+      cso->dw_blend = blend_get_rt_blend_enable_gen6(dev, rt, false);
+      cso->dw_blend_dst_alpha_forced_one =
+         blend_get_rt_blend_enable_gen6(dev, rt, true);
+   }
+}
 
-      if (!(rt->colormask & PIPE_MASK_A))
-         cso->payload[1] |= 1 << 27;
-      if (!(rt->colormask & PIPE_MASK_R))
-         cso->payload[1] |= 1 << 26;
-      if (!(rt->colormask & PIPE_MASK_G))
-         cso->payload[1] |= 1 << 25;
-      if (!(rt->colormask & PIPE_MASK_B))
-         cso->payload[1] |= 1 << 24;
+static uint32_t
+blend_get_logicop_enable_gen6(const struct ilo_dev_info *dev,
+                              const struct pipe_blend_state *state)
+{
+   ILO_DEV_ASSERT(dev, 6, 7.5);
 
-      if (state->dither)
-         cso->payload[1] |= 1 << 12;
+   if (!state->logicop_enable)
+      return 0;
 
-      /*
-       * From the Sandy Bridge PRM, volume 2 part 1, page 365:
-       *
-       *     "Color Buffer Blending and Logic Ops must not be enabled
-       *      simultaneously, or behavior is UNDEFINED."
-       *
-       * Since state->logicop_enable takes precedence over rt->blend_enable,
-       * no special care is needed.
-       */
-      if (state->logicop_enable) {
-         cso->dw_logicop = 1 << 22 |
-            gen6_translate_pipe_logicop(state->logicop_func) << 18;
+   return GEN6_BLEND_DW1_LOGICOP_ENABLE |
+          gen6_translate_pipe_logicop(state->logicop_func) << 18;
+}
 
-         cso->dw_blend = 0;
-         cso->dw_blend_dst_alpha_forced_one = 0;
+static uint32_t
+blend_get_alpha_mod_gen6(const struct ilo_dev_info *dev,
+                         const struct pipe_blend_state *state,
+                         bool dual_blend)
+{
+   uint32_t dw = 0;
 
-         dual_blend = false;
-      }
-      else {
-         cso->dw_logicop = 0;
+   ILO_DEV_ASSERT(dev, 6, 7.5);
 
-         cso->dw_blend = blend_get_rt_blend_enable(dev, rt, false);
-         cso->dw_blend_dst_alpha_forced_one =
-            blend_get_rt_blend_enable(dev, rt, true);
+   if (state->alpha_to_coverage) {
+      dw |= GEN6_BLEND_DW1_ALPHA_TO_COVERAGE;
+      if (ilo_dev_gen(dev) >= ILO_GEN(7))
+         dw |= GEN6_BLEND_DW1_ALPHA_TO_COVERAGE_DITHER;
+   }
+   /*
+    * From the Sandy Bridge PRM, volume 2 part 1, page 378:
+    *
+    *     "If Dual Source Blending is enabled, this bit (AlphaToOne Enable)
+    *      must be disabled."
+    */
+   if (state->alpha_to_one && !dual_blend)
+      dw |= GEN6_BLEND_DW1_ALPHA_TO_ONE;
 
-         dual_blend = (rt->blend_enable &&
-               util_blend_state_is_dual(state, i));
-      }
+   return dw;
+}
 
-      cso->dw_alpha_mod = 0;
+void
+ilo_gpe_init_blend(const struct ilo_dev_info *dev,
+                   const struct pipe_blend_state *state,
+                   struct ilo_blend_state *blend)
+{
+   unsigned i;
 
-      if (state->alpha_to_coverage) {
-         cso->dw_alpha_mod |= 1 << 31;
+   ILO_DEV_ASSERT(dev, 6, 7.5);
 
-         if (ilo_dev_gen(dev) >= ILO_GEN(7))
-            cso->dw_alpha_mod |= 1 << 29;
-      }
+   blend->dual_blend = (util_blend_state_is_dual(state, 0) &&
+                        state->rt[0].blend_enable &&
+                        !state->logicop_enable);
+   blend->alpha_to_coverage = state->alpha_to_coverage;
 
-      /*
-       * From the Sandy Bridge PRM, volume 2 part 1, page 378:
-       *
-       *     "If Dual Source Blending is enabled, this bit (AlphaToOne Enable)
-       *      must be disabled."
-       */
-      if (state->alpha_to_one && !dual_blend)
-         cso->dw_alpha_mod |= 1 << 30;
+   blend->dw_alpha_mod =
+      blend_get_alpha_mod_gen6(dev, state, blend->dual_blend);
+   blend->dw_logicop = blend_get_logicop_enable_gen6(dev, state);
+   blend->dw_shared = (state->dither) ? GEN6_BLEND_DW1_DITHER_ENABLE : 0;
 
-      if (dual_blend)
-         blend->dual_blend = true;
+   blend_init_cso_gen6(dev, state, blend, 0);
+   if (state->independent_blend_enable) {
+      for (i = 1; i < Elements(blend->cso); i++)
+         blend_init_cso_gen6(dev, state, blend, i);
+   } else {
+      for (i = 1; i < Elements(blend->cso); i++)
+         blend->cso[i] = blend->cso[0];
    }
 }