ilo: embed ilo_state_cc in ilo_blend_state
authorChia-I Wu <olvaffe@gmail.com>
Mon, 11 May 2015 11:48:52 +0000 (19:48 +0800)
committerChia-I Wu <olvaffe@gmail.com>
Sun, 14 Jun 2015 17:07:09 +0000 (01:07 +0800)
13 files changed:
src/gallium/drivers/ilo/core/ilo_builder_3d_bottom.h
src/gallium/drivers/ilo/core/ilo_state_3d.h
src/gallium/drivers/ilo/core/ilo_state_3d_bottom.c
src/gallium/drivers/ilo/ilo_blitter.h
src/gallium/drivers/ilo/ilo_blitter_rectlist.c
src/gallium/drivers/ilo/ilo_render.c
src/gallium/drivers/ilo/ilo_render_dynamic.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
src/gallium/drivers/ilo/ilo_state.c
src/gallium/drivers/ilo/ilo_state.h

index 2d7b9e0..cd1a682 100644 (file)
@@ -35,6 +35,7 @@
 #include "ilo_core.h"
 #include "ilo_dev.h"
 #include "ilo_format.h"
+#include "ilo_state_cc.h"
 #include "ilo_state_raster.h"
 #include "ilo_state_viewport.h"
 #include "ilo_builder.h"
@@ -406,21 +407,19 @@ gen8_3DSTATE_WM(struct ilo_builder *builder,
 
 static inline void
 gen8_3DSTATE_WM_DEPTH_STENCIL(struct ilo_builder *builder,
-                              const struct ilo_dsa_state *dsa)
+                              const struct ilo_state_cc *cc)
 {
    const uint8_t cmd_len = 3;
-   uint32_t dw1, dw2, *dw;
+   uint32_t *dw;
 
    ILO_DEV_ASSERT(builder->dev, 8, 8);
 
-   dw1 = dsa->payload[0];
-   dw2 = dsa->payload[1];
-
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_WM_DEPTH_STENCIL) | (cmd_len - 2);
-   dw[1] = dw1;
-   dw[2] = dw2;
+   /* see cc_set_gen8_3DSTATE_WM_DEPTH_STENCIL() */
+   dw[1] = cc->ds[0];
+   dw[2] = cc->ds[1];
 }
 
 static inline void
@@ -605,40 +604,18 @@ gen8_3DSTATE_PS_EXTRA(struct ilo_builder *builder,
 
 static inline void
 gen8_3DSTATE_PS_BLEND(struct ilo_builder *builder,
-                      const struct ilo_blend_state *blend,
-                      const struct ilo_fb_state *fb,
-                      const struct ilo_dsa_state *dsa)
+                      const struct ilo_state_cc *cc)
 {
    const uint8_t cmd_len = 2;
-   uint32_t dw1, *dw;
+   uint32_t *dw;
 
    ILO_DEV_ASSERT(builder->dev, 8, 8);
 
-   dw1 = 0;
-   if (blend->alpha_to_coverage && fb->num_samples > 1)
-      dw1 |= GEN8_PS_BLEND_DW1_ALPHA_TO_COVERAGE;
-
-   if (fb->state.nr_cbufs && fb->state.cbufs[0]) {
-      const struct ilo_fb_blend_caps *caps = &fb->blend_caps[0];
-
-      dw1 |= GEN8_PS_BLEND_DW1_WRITABLE_RT;
-      if (caps->can_blend) {
-         if (caps->dst_alpha_forced_one)
-            dw1 |= blend->dw_ps_blend_dst_alpha_forced_one;
-         else
-            dw1 |= blend->dw_ps_blend;
-      }
-
-      if (caps->can_alpha_test)
-         dw1 |= dsa->dw_ps_blend_alpha;
-   } else {
-      dw1 |= dsa->dw_ps_blend_alpha;
-   }
-
    ilo_builder_batch_pointer(builder, cmd_len, &dw);
 
    dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_PS_BLEND) | (cmd_len - 2);
-   dw[1] = dw1;
+   /* see cc_set_gen8_3DSTATE_PS_BLEND() */
+   dw[1] = cc->blend[0];
 }
 
 static inline void
@@ -1282,179 +1259,61 @@ gen6_SCISSOR_RECT(struct ilo_builder *builder,
 
 static inline uint32_t
 gen6_COLOR_CALC_STATE(struct ilo_builder *builder,
-                      const struct pipe_stencil_ref *stencil_ref,
-                      ubyte alpha_ref,
-                      const struct pipe_blend_color *blend_color)
+                      const struct ilo_state_cc *cc)
 {
    const int state_align = 64;
    const int state_len = 6;
-   uint32_t state_offset, *dw;
 
    ILO_DEV_ASSERT(builder->dev, 6, 8);
 
-   state_offset = ilo_builder_dynamic_pointer(builder,
-         ILO_BUILDER_ITEM_COLOR_CALC, state_align, state_len, &dw);
-
-   dw[0] = stencil_ref->ref_value[0] << 24 |
-           stencil_ref->ref_value[1] << 16 |
-           GEN6_CC_DW0_ALPHATEST_UNORM8;
-   dw[1] = alpha_ref;
-   dw[2] = fui(blend_color->color[0]);
-   dw[3] = fui(blend_color->color[1]);
-   dw[4] = fui(blend_color->color[2]);
-   dw[5] = fui(blend_color->color[3]);
-
-   return state_offset;
+   /* see cc_params_set_gen6_COLOR_CALC_STATE() */
+   return ilo_builder_dynamic_write(builder, ILO_BUILDER_ITEM_COLOR_CALC,
+         state_align, state_len, cc->cc);
 }
 
 static inline uint32_t
 gen6_DEPTH_STENCIL_STATE(struct ilo_builder *builder,
-                         const struct ilo_dsa_state *dsa)
+                         const struct ilo_state_cc *cc)
 {
    const int state_align = 64;
    const int state_len = 3;
 
    ILO_DEV_ASSERT(builder->dev, 6, 7.5);
 
-   STATIC_ASSERT(Elements(dsa->payload) >= state_len);
-
+   /* see cc_set_gen6_DEPTH_STENCIL_STATE() */
    return ilo_builder_dynamic_write(builder, ILO_BUILDER_ITEM_DEPTH_STENCIL,
-         state_align, state_len, dsa->payload);
+         state_align, state_len, cc->ds);
 }
 
 static inline uint32_t
 gen6_BLEND_STATE(struct ilo_builder *builder,
-                 const struct ilo_blend_state *blend,
-                 const struct ilo_fb_state *fb,
-                 const struct ilo_dsa_state *dsa)
+                 const struct ilo_state_cc *cc)
 {
    const int state_align = 64;
-   int state_len;
-   uint32_t state_offset, *dw;
-   unsigned num_targets, i;
+   const int state_len = 2 * cc->blend_state_count;
 
    ILO_DEV_ASSERT(builder->dev, 6, 7.5);
 
-   /*
-    * From the Sandy Bridge PRM, volume 2 part 1, page 376:
-    *
-    *     "The blend state is stored as an array of up to 8 elements..."
-    */
-   num_targets = fb->state.nr_cbufs;
-   assert(num_targets <= 8);
-
-   if (!num_targets) {
-      if (!dsa->dw_blend_alpha)
-         return 0;
-      /* to be able to reference alpha func */
-      num_targets = 1;
-   }
-
-   state_len = 2 * num_targets;
-
-   state_offset = ilo_builder_dynamic_pointer(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[i];
-
-      dw[0] = cso->payload[0];
-      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];
-
-         if (caps->can_blend) {
-            if (caps->dst_alpha_forced_one)
-               dw[0] |= cso->dw_blend_dst_alpha_forced_one;
-            else
-               dw[0] |= cso->dw_blend;
-         }
-
-         if (caps->can_logicop)
-            dw[1] |= blend->dw_logicop;
-
-         if (caps->can_alpha_test)
-            dw[1] |= dsa->dw_blend_alpha;
-      } else {
-         dw[1] |= GEN6_RT_DW1_WRITE_DISABLES_A |
-                  GEN6_RT_DW1_WRITE_DISABLES_R |
-                  GEN6_RT_DW1_WRITE_DISABLES_G |
-                  GEN6_RT_DW1_WRITE_DISABLES_B |
-                  dsa->dw_blend_alpha;
-      }
-
-      /*
-       * From the Sandy Bridge PRM, volume 2 part 1, page 356:
-       *
-       *     "When NumSamples = 1, AlphaToCoverage and AlphaToCoverage
-       *      Dither both must be disabled."
-       *
-       * There is no such limitation on GEN7, or for AlphaToOne.  But GL
-       * requires that anyway.
-       */
-      if (fb->num_samples > 1)
-         dw[1] |= blend->dw_alpha_mod;
-
-      dw += 2;
-   }
+   if (!state_len)
+      return 0;
 
-   return state_offset;
+   /* see cc_set_gen6_BLEND_STATE() */
+   return ilo_builder_dynamic_write(builder, ILO_BUILDER_ITEM_BLEND,
+         state_align, state_len, cc->blend);
 }
 
 static inline uint32_t
 gen8_BLEND_STATE(struct ilo_builder *builder,
-                 const struct ilo_blend_state *blend,
-                 const struct ilo_fb_state *fb,
-                 const struct ilo_dsa_state *dsa)
+                 const struct ilo_state_cc *cc)
 {
    const int state_align = 64;
-   const int state_len = 1 + 2 * fb->state.nr_cbufs;
-   uint32_t state_offset, *dw;
-   unsigned i;
+   const int state_len = 1 + 2 * cc->blend_state_count;
 
    ILO_DEV_ASSERT(builder->dev, 8, 8);
 
-   assert(fb->state.nr_cbufs <= 8);
-
-   state_offset = ilo_builder_dynamic_pointer(builder,
-         ILO_BUILDER_ITEM_BLEND, state_align, state_len, &dw);
-
-   dw[0] = blend->dw_shared;
-   if (fb->num_samples > 1)
-      dw[0] |= blend->dw_alpha_mod;
-   if (!fb->state.nr_cbufs || fb->blend_caps[0].can_alpha_test)
-      dw[0] |= dsa->dw_blend_alpha;
-   dw++;
-
-   for (i = 0; i < fb->state.nr_cbufs; i++) {
-      const struct ilo_fb_blend_caps *caps = &fb->blend_caps[i];
-      const struct ilo_blend_cso *cso = &blend->cso[i];
-
-      dw[0] = cso->payload[0];
-      dw[1] = cso->payload[1];
-
-      if (fb->state.cbufs[i]) {
-         if (caps->can_blend) {
-            if (caps->dst_alpha_forced_one)
-               dw[0] |= cso->dw_blend_dst_alpha_forced_one;
-            else
-               dw[0] |= cso->dw_blend;
-         }
-
-         if (caps->can_logicop)
-            dw[1] |= blend->dw_logicop;
-      } else {
-         dw[0] |= GEN8_RT_DW0_WRITE_DISABLES_A |
-                  GEN8_RT_DW0_WRITE_DISABLES_R |
-                  GEN8_RT_DW0_WRITE_DISABLES_G |
-                  GEN8_RT_DW0_WRITE_DISABLES_B;
-      }
-
-      dw += 2;
-   }
-
-   return state_offset;
+   /* see cc_set_gen8_BLEND_STATE() */
+   return ilo_builder_dynamic_write(builder, ILO_BUILDER_ITEM_BLEND,
+         state_align, state_len, &cc->blend[1]);
 }
 
 #endif /* ILO_BUILDER_3D_BOTTOM_H */
index 78cd671..45929b2 100644 (file)
@@ -101,38 +101,6 @@ struct ilo_so_state {
    bool enabled;
 };
 
-struct ilo_dsa_state {
-   /* DEPTH_STENCIL_STATE or Gen8+ 3DSTATE_WM_DEPTH_STENCIL */
-   uint32_t payload[3];
-
-   uint32_t dw_blend_alpha;
-   uint32_t dw_ps_blend_alpha;
-   ubyte alpha_ref;
-};
-
-struct ilo_blend_cso {
-   /* BLEND_STATE */
-   uint32_t payload[2];
-
-   uint32_t dw_blend;
-   uint32_t dw_blend_dst_alpha_forced_one;
-};
-
-struct ilo_blend_state {
-   struct ilo_blend_cso cso[ILO_MAX_DRAW_BUFFERS];
-
-   bool dual_blend;
-   bool alpha_to_coverage;
-
-   uint32_t dw_shared;
-   uint32_t dw_alpha_mod;
-   uint32_t dw_logicop;
-
-   /* a part of 3DSTATE_PS_BLEND */
-   uint32_t dw_ps_blend;
-   uint32_t dw_ps_blend_dst_alpha_forced_one;
-};
-
 struct ilo_surface_cso {
    struct pipe_surface base;
 
@@ -152,11 +120,11 @@ struct ilo_fb_state {
    struct ilo_fb_blend_caps {
       bool is_unorm;
       bool is_integer;
+      bool force_dst_alpha_one;
 
       bool can_logicop;
       bool can_blend;
       bool can_alpha_test;
-      bool dst_alpha_forced_one;
    } blend_caps[PIPE_MAX_COLOR_BUFS];
 
    unsigned num_samples;
@@ -186,16 +154,6 @@ ilo_gpe_init_ve_nosrc(const struct ilo_dev *dev,
                       struct ilo_ve_cso *cso);
 
 void
-ilo_gpe_init_dsa(const struct ilo_dev *dev,
-                 const struct pipe_depth_stencil_alpha_state *state,
-                 struct ilo_dsa_state *dsa);
-
-void
-ilo_gpe_init_blend(const struct ilo_dev *dev,
-                   const struct pipe_blend_state *state,
-                   struct ilo_blend_state *blend);
-
-void
 ilo_gpe_init_vs_cso(const struct ilo_dev *dev,
                     const struct ilo_shader_state *vs,
                     struct ilo_shader_cso *cso);
index 83da224..932b80d 100644 (file)
@@ -26,7 +26,6 @@
  */
 
 #include "genhw/genhw.h"
-#include "util/u_dual_blend.h"
 #include "util/u_framebuffer.h"
 #include "util/u_half.h"
 
@@ -314,681 +313,6 @@ ilo_gpe_init_fs_cso(const struct ilo_dev *dev,
       fs_init_cso_gen6(dev, fs, cso);
 }
 
-/**
- * Translate a pipe logicop to the matching hardware logicop.
- */
-static int
-gen6_translate_pipe_logicop(unsigned logicop)
-{
-   switch (logicop) {
-   case PIPE_LOGICOP_CLEAR:         return GEN6_LOGICOP_CLEAR;
-   case PIPE_LOGICOP_NOR:           return GEN6_LOGICOP_NOR;
-   case PIPE_LOGICOP_AND_INVERTED:  return GEN6_LOGICOP_AND_INVERTED;
-   case PIPE_LOGICOP_COPY_INVERTED: return GEN6_LOGICOP_COPY_INVERTED;
-   case PIPE_LOGICOP_AND_REVERSE:   return GEN6_LOGICOP_AND_REVERSE;
-   case PIPE_LOGICOP_INVERT:        return GEN6_LOGICOP_INVERT;
-   case PIPE_LOGICOP_XOR:           return GEN6_LOGICOP_XOR;
-   case PIPE_LOGICOP_NAND:          return GEN6_LOGICOP_NAND;
-   case PIPE_LOGICOP_AND:           return GEN6_LOGICOP_AND;
-   case PIPE_LOGICOP_EQUIV:         return GEN6_LOGICOP_EQUIV;
-   case PIPE_LOGICOP_NOOP:          return GEN6_LOGICOP_NOOP;
-   case PIPE_LOGICOP_OR_INVERTED:   return GEN6_LOGICOP_OR_INVERTED;
-   case PIPE_LOGICOP_COPY:          return GEN6_LOGICOP_COPY;
-   case PIPE_LOGICOP_OR_REVERSE:    return GEN6_LOGICOP_OR_REVERSE;
-   case PIPE_LOGICOP_OR:            return GEN6_LOGICOP_OR;
-   case PIPE_LOGICOP_SET:           return GEN6_LOGICOP_SET;
-   default:
-      assert(!"unknown logicop function");
-      return GEN6_LOGICOP_CLEAR;
-   }
-}
-
-/**
- * Translate a pipe blend function to the matching hardware blend function.
- */
-static int
-gen6_translate_pipe_blend(unsigned blend)
-{
-   switch (blend) {
-   case PIPE_BLEND_ADD:                return GEN6_BLENDFUNCTION_ADD;
-   case PIPE_BLEND_SUBTRACT:           return GEN6_BLENDFUNCTION_SUBTRACT;
-   case PIPE_BLEND_REVERSE_SUBTRACT:   return GEN6_BLENDFUNCTION_REVERSE_SUBTRACT;
-   case PIPE_BLEND_MIN:                return GEN6_BLENDFUNCTION_MIN;
-   case PIPE_BLEND_MAX:                return GEN6_BLENDFUNCTION_MAX;
-   default:
-      assert(!"unknown blend function");
-      return GEN6_BLENDFUNCTION_ADD;
-   };
-}
-
-/**
- * Translate a pipe blend factor to the matching hardware blend factor.
- */
-static int
-gen6_translate_pipe_blendfactor(unsigned blendfactor)
-{
-   switch (blendfactor) {
-   case PIPE_BLENDFACTOR_ONE:                return GEN6_BLENDFACTOR_ONE;
-   case PIPE_BLENDFACTOR_SRC_COLOR:          return GEN6_BLENDFACTOR_SRC_COLOR;
-   case PIPE_BLENDFACTOR_SRC_ALPHA:          return GEN6_BLENDFACTOR_SRC_ALPHA;
-   case PIPE_BLENDFACTOR_DST_ALPHA:          return GEN6_BLENDFACTOR_DST_ALPHA;
-   case PIPE_BLENDFACTOR_DST_COLOR:          return GEN6_BLENDFACTOR_DST_COLOR;
-   case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: return GEN6_BLENDFACTOR_SRC_ALPHA_SATURATE;
-   case PIPE_BLENDFACTOR_CONST_COLOR:        return GEN6_BLENDFACTOR_CONST_COLOR;
-   case PIPE_BLENDFACTOR_CONST_ALPHA:        return GEN6_BLENDFACTOR_CONST_ALPHA;
-   case PIPE_BLENDFACTOR_SRC1_COLOR:         return GEN6_BLENDFACTOR_SRC1_COLOR;
-   case PIPE_BLENDFACTOR_SRC1_ALPHA:         return GEN6_BLENDFACTOR_SRC1_ALPHA;
-   case PIPE_BLENDFACTOR_ZERO:               return GEN6_BLENDFACTOR_ZERO;
-   case PIPE_BLENDFACTOR_INV_SRC_COLOR:      return GEN6_BLENDFACTOR_INV_SRC_COLOR;
-   case PIPE_BLENDFACTOR_INV_SRC_ALPHA:      return GEN6_BLENDFACTOR_INV_SRC_ALPHA;
-   case PIPE_BLENDFACTOR_INV_DST_ALPHA:      return GEN6_BLENDFACTOR_INV_DST_ALPHA;
-   case PIPE_BLENDFACTOR_INV_DST_COLOR:      return GEN6_BLENDFACTOR_INV_DST_COLOR;
-   case PIPE_BLENDFACTOR_INV_CONST_COLOR:    return GEN6_BLENDFACTOR_INV_CONST_COLOR;
-   case PIPE_BLENDFACTOR_INV_CONST_ALPHA:    return GEN6_BLENDFACTOR_INV_CONST_ALPHA;
-   case PIPE_BLENDFACTOR_INV_SRC1_COLOR:     return GEN6_BLENDFACTOR_INV_SRC1_COLOR;
-   case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:     return GEN6_BLENDFACTOR_INV_SRC1_ALPHA;
-   default:
-      assert(!"unknown blend factor");
-      return GEN6_BLENDFACTOR_ONE;
-   };
-}
-
-/**
- * Translate a pipe stencil op to the matching hardware stencil op.
- */
-static int
-gen6_translate_pipe_stencil_op(unsigned stencil_op)
-{
-   switch (stencil_op) {
-   case PIPE_STENCIL_OP_KEEP:       return GEN6_STENCILOP_KEEP;
-   case PIPE_STENCIL_OP_ZERO:       return GEN6_STENCILOP_ZERO;
-   case PIPE_STENCIL_OP_REPLACE:    return GEN6_STENCILOP_REPLACE;
-   case PIPE_STENCIL_OP_INCR:       return GEN6_STENCILOP_INCRSAT;
-   case PIPE_STENCIL_OP_DECR:       return GEN6_STENCILOP_DECRSAT;
-   case PIPE_STENCIL_OP_INCR_WRAP:  return GEN6_STENCILOP_INCR;
-   case PIPE_STENCIL_OP_DECR_WRAP:  return GEN6_STENCILOP_DECR;
-   case PIPE_STENCIL_OP_INVERT:     return GEN6_STENCILOP_INVERT;
-   default:
-      assert(!"unknown stencil op");
-      return GEN6_STENCILOP_KEEP;
-   }
-}
-
-static int
-gen6_blend_factor_dst_alpha_forced_one(int factor)
-{
-   switch (factor) {
-   case GEN6_BLENDFACTOR_DST_ALPHA:
-      return GEN6_BLENDFACTOR_ONE;
-   case GEN6_BLENDFACTOR_INV_DST_ALPHA:
-   case GEN6_BLENDFACTOR_SRC_ALPHA_SATURATE:
-      return GEN6_BLENDFACTOR_ZERO;
-   default:
-      return factor;
-   }
-}
-
-static uint32_t
-blend_get_rt_blend_enable_gen6(const struct ilo_dev *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;
-
-   rgb_src = gen6_translate_pipe_blendfactor(rt->rgb_src_factor);
-   rgb_dst = gen6_translate_pipe_blendfactor(rt->rgb_dst_factor);
-   a_src = gen6_translate_pipe_blendfactor(rt->alpha_src_factor);
-   a_dst = gen6_translate_pipe_blendfactor(rt->alpha_dst_factor);
-
-   if (dst_alpha_forced_one) {
-      rgb_src = gen6_blend_factor_dst_alpha_forced_one(rgb_src);
-      rgb_dst = gen6_blend_factor_dst_alpha_forced_one(rgb_dst);
-      a_src = gen6_blend_factor_dst_alpha_forced_one(a_src);
-      a_dst = gen6_blend_factor_dst_alpha_forced_one(a_dst);
-   }
-
-   dw = GEN6_RT_DW0_BLEND_ENABLE |
-        gen6_translate_pipe_blend(rt->alpha_func) << 26 |
-        a_src << 20 |
-        a_dst << 15 |
-        gen6_translate_pipe_blend(rt->rgb_func) << 11 |
-        rgb_src << 5 |
-        rgb_dst;
-
-   if (rt->rgb_func != rt->alpha_func ||
-       rgb_src != a_src || rgb_dst != a_dst)
-      dw |= GEN6_RT_DW0_INDEPENDENT_ALPHA_ENABLE;
-
-   return dw;
-}
-
-static uint32_t
-blend_get_rt_blend_enable_gen8(const struct ilo_dev *dev,
-                               const struct pipe_rt_blend_state *rt,
-                               bool dst_alpha_forced_one,
-                               bool *independent_alpha)
-{
-   int rgb_src, rgb_dst, a_src, a_dst;
-   uint32_t dw;
-
-   ILO_DEV_ASSERT(dev, 8, 8);
-
-   if (!rt->blend_enable) {
-      *independent_alpha = false;
-      return 0;
-   }
-
-   rgb_src = gen6_translate_pipe_blendfactor(rt->rgb_src_factor);
-   rgb_dst = gen6_translate_pipe_blendfactor(rt->rgb_dst_factor);
-   a_src = gen6_translate_pipe_blendfactor(rt->alpha_src_factor);
-   a_dst = gen6_translate_pipe_blendfactor(rt->alpha_dst_factor);
-
-   if (dst_alpha_forced_one) {
-      rgb_src = gen6_blend_factor_dst_alpha_forced_one(rgb_src);
-      rgb_dst = gen6_blend_factor_dst_alpha_forced_one(rgb_dst);
-      a_src = gen6_blend_factor_dst_alpha_forced_one(a_src);
-      a_dst = gen6_blend_factor_dst_alpha_forced_one(a_dst);
-   }
-
-   dw = GEN8_RT_DW0_BLEND_ENABLE |
-        rgb_src << 26 |
-        rgb_dst << 21 |
-        gen6_translate_pipe_blend(rt->rgb_func) << 18 |
-        a_src << 13 |
-        a_dst << 8 |
-        gen6_translate_pipe_blend(rt->alpha_func) << 5;
-
-   *independent_alpha = (rt->rgb_func != rt->alpha_func ||
-                         rgb_src != a_src ||
-                         rgb_dst != a_dst);
-
-   return dw;
-}
-
-static void
-blend_init_cso_gen6(const struct ilo_dev *dev,
-                    const struct pipe_blend_state *state,
-                    struct ilo_blend_state *blend,
-                    unsigned index)
-{
-   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);
-
-   cso->payload[0] = 0;
-   cso->payload[1] = GEN6_RT_DW1_COLORCLAMP_RTFORMAT |
-                     GEN6_RT_DW1_PRE_BLEND_CLAMP |
-                     GEN6_RT_DW1_POST_BLEND_CLAMP;
-
-   if (!(rt->colormask & PIPE_MASK_A))
-      cso->payload[1] |= GEN6_RT_DW1_WRITE_DISABLES_A;
-   if (!(rt->colormask & PIPE_MASK_R))
-      cso->payload[1] |= GEN6_RT_DW1_WRITE_DISABLES_R;
-   if (!(rt->colormask & PIPE_MASK_G))
-      cso->payload[1] |= GEN6_RT_DW1_WRITE_DISABLES_G;
-   if (!(rt->colormask & PIPE_MASK_B))
-      cso->payload[1] |= GEN6_RT_DW1_WRITE_DISABLES_B;
-
-   /*
-    * 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);
-   }
-}
-
-static bool
-blend_init_cso_gen8(const struct ilo_dev *dev,
-                    const struct pipe_blend_state *state,
-                    struct ilo_blend_state *blend,
-                    unsigned index)
-{
-   const struct pipe_rt_blend_state *rt = &state->rt[index];
-   struct ilo_blend_cso *cso = &blend->cso[index];
-   bool independent_alpha = false;
-
-   ILO_DEV_ASSERT(dev, 8, 8);
-
-   cso->payload[0] = 0;
-   cso->payload[1] = GEN8_RT_DW1_COLORCLAMP_RTFORMAT |
-                     GEN8_RT_DW1_PRE_BLEND_CLAMP |
-                     GEN8_RT_DW1_POST_BLEND_CLAMP;
-
-   if (!(rt->colormask & PIPE_MASK_A))
-      cso->payload[0] |= GEN8_RT_DW0_WRITE_DISABLES_A;
-   if (!(rt->colormask & PIPE_MASK_R))
-      cso->payload[0] |= GEN8_RT_DW0_WRITE_DISABLES_R;
-   if (!(rt->colormask & PIPE_MASK_G))
-      cso->payload[0] |= GEN8_RT_DW0_WRITE_DISABLES_G;
-   if (!(rt->colormask & PIPE_MASK_B))
-      cso->payload[0] |= GEN8_RT_DW0_WRITE_DISABLES_B;
-
-   if (state->logicop_enable) {
-      cso->dw_blend = 0;
-      cso->dw_blend_dst_alpha_forced_one = 0;
-   } else {
-      bool tmp[2];
-
-      cso->dw_blend = blend_get_rt_blend_enable_gen8(dev, rt, false, &tmp[0]);
-      cso->dw_blend_dst_alpha_forced_one =
-         blend_get_rt_blend_enable_gen8(dev, rt, true, &tmp[1]);
-
-      if (tmp[0] || tmp[1])
-         independent_alpha = true;
-   }
-
-   return independent_alpha;
-}
-
-static uint32_t
-blend_get_logicop_enable_gen6(const struct ilo_dev *dev,
-                              const struct pipe_blend_state *state)
-{
-   ILO_DEV_ASSERT(dev, 6, 7.5);
-
-   if (!state->logicop_enable)
-      return 0;
-
-   return GEN6_RT_DW1_LOGICOP_ENABLE |
-          gen6_translate_pipe_logicop(state->logicop_func) << 18;
-}
-
-static uint32_t
-blend_get_logicop_enable_gen8(const struct ilo_dev *dev,
-                              const struct pipe_blend_state *state)
-{
-   ILO_DEV_ASSERT(dev, 8, 8);
-
-   if (!state->logicop_enable)
-      return 0;
-
-   return GEN8_RT_DW1_LOGICOP_ENABLE |
-          gen6_translate_pipe_logicop(state->logicop_func) << 27;
-}
-
-static uint32_t
-blend_get_alpha_mod_gen6(const struct ilo_dev *dev,
-                         const struct pipe_blend_state *state,
-                         bool dual_blend)
-{
-   uint32_t dw = 0;
-
-   ILO_DEV_ASSERT(dev, 6, 7.5);
-
-   if (state->alpha_to_coverage) {
-      dw |= GEN6_RT_DW1_ALPHA_TO_COVERAGE;
-      if (ilo_dev_gen(dev) >= ILO_GEN(7))
-         dw |= GEN6_RT_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_RT_DW1_ALPHA_TO_ONE;
-
-   return dw;
-}
-
-static uint32_t
-blend_get_alpha_mod_gen8(const struct ilo_dev *dev,
-                         const struct pipe_blend_state *state,
-                         bool dual_blend)
-{
-   uint32_t dw = 0;
-
-   ILO_DEV_ASSERT(dev, 8, 8);
-
-   if (state->alpha_to_coverage) {
-      dw |= GEN8_BLEND_DW0_ALPHA_TO_COVERAGE |
-            GEN8_BLEND_DW0_ALPHA_TO_COVERAGE_DITHER;
-   }
-
-   if (state->alpha_to_one && !dual_blend)
-      dw |= GEN8_BLEND_DW0_ALPHA_TO_ONE;
-
-   return dw;
-}
-
-static uint32_t
-blend_get_ps_blend_gen8(const struct ilo_dev *dev, uint32_t rt_dw0)
-{
-   int rgb_src, rgb_dst, a_src, a_dst;
-   uint32_t dw;
-
-   ILO_DEV_ASSERT(dev, 8, 8);
-
-   if (!(rt_dw0 & GEN8_RT_DW0_BLEND_ENABLE))
-      return 0;
-
-   a_src = GEN_EXTRACT(rt_dw0, GEN8_RT_DW0_SRC_ALPHA_FACTOR);
-   a_dst = GEN_EXTRACT(rt_dw0, GEN8_RT_DW0_DST_ALPHA_FACTOR);
-   rgb_src = GEN_EXTRACT(rt_dw0, GEN8_RT_DW0_SRC_COLOR_FACTOR);
-   rgb_dst = GEN_EXTRACT(rt_dw0, GEN8_RT_DW0_DST_COLOR_FACTOR);
-
-   dw = GEN8_PS_BLEND_DW1_BLEND_ENABLE;
-   dw |= GEN_SHIFT32(a_src, GEN8_PS_BLEND_DW1_SRC_ALPHA_FACTOR);
-   dw |= GEN_SHIFT32(a_dst, GEN8_PS_BLEND_DW1_DST_ALPHA_FACTOR);
-   dw |= GEN_SHIFT32(rgb_src, GEN8_PS_BLEND_DW1_SRC_COLOR_FACTOR);
-   dw |= GEN_SHIFT32(rgb_dst, GEN8_PS_BLEND_DW1_DST_COLOR_FACTOR);
-
-   if (a_src != rgb_src || a_dst != rgb_dst)
-      dw |= GEN8_PS_BLEND_DW1_INDEPENDENT_ALPHA_ENABLE;
-
-   return dw;
-}
-
-void
-ilo_gpe_init_blend(const struct ilo_dev *dev,
-                   const struct pipe_blend_state *state,
-                   struct ilo_blend_state *blend)
-{
-   unsigned i;
-
-   ILO_DEV_ASSERT(dev, 6, 8);
-
-   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;
-
-   if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
-      bool independent_alpha;
-
-      blend->dw_alpha_mod =
-         blend_get_alpha_mod_gen8(dev, state, blend->dual_blend);
-      blend->dw_logicop = blend_get_logicop_enable_gen8(dev, state);
-      blend->dw_shared = (state->dither) ? GEN8_BLEND_DW0_DITHER_ENABLE : 0;
-
-      independent_alpha = blend_init_cso_gen8(dev, state, blend, 0);
-      if (independent_alpha)
-         blend->dw_shared |= GEN8_BLEND_DW0_INDEPENDENT_ALPHA_ENABLE;
-
-      blend->dw_ps_blend = blend_get_ps_blend_gen8(dev,
-            blend->cso[0].dw_blend);
-      blend->dw_ps_blend_dst_alpha_forced_one = blend_get_ps_blend_gen8(dev,
-            blend->cso[0].dw_blend_dst_alpha_forced_one);
-
-      if (state->independent_blend_enable) {
-         for (i = 1; i < Elements(blend->cso); i++) {
-            independent_alpha = blend_init_cso_gen8(dev, state, blend, i);
-            if (independent_alpha)
-               blend->dw_shared |= GEN8_BLEND_DW0_INDEPENDENT_ALPHA_ENABLE;
-         }
-      } else {
-         for (i = 1; i < Elements(blend->cso); i++)
-            blend->cso[i] = blend->cso[0];
-      }
-   } else {
-      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_RT_DW1_DITHER_ENABLE : 0;
-
-      blend->dw_ps_blend = 0;
-      blend->dw_ps_blend_dst_alpha_forced_one = 0;
-
-      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];
-      }
-   }
-}
-
-/**
- * Translate a pipe DSA test function to the matching hardware compare
- * function.
- */
-static int
-gen6_translate_dsa_func(unsigned func)
-{
-   switch (func) {
-   case PIPE_FUNC_NEVER:      return GEN6_COMPAREFUNCTION_NEVER;
-   case PIPE_FUNC_LESS:       return GEN6_COMPAREFUNCTION_LESS;
-   case PIPE_FUNC_EQUAL:      return GEN6_COMPAREFUNCTION_EQUAL;
-   case PIPE_FUNC_LEQUAL:     return GEN6_COMPAREFUNCTION_LEQUAL;
-   case PIPE_FUNC_GREATER:    return GEN6_COMPAREFUNCTION_GREATER;
-   case PIPE_FUNC_NOTEQUAL:   return GEN6_COMPAREFUNCTION_NOTEQUAL;
-   case PIPE_FUNC_GEQUAL:     return GEN6_COMPAREFUNCTION_GEQUAL;
-   case PIPE_FUNC_ALWAYS:     return GEN6_COMPAREFUNCTION_ALWAYS;
-   default:
-      assert(!"unknown depth/stencil/alpha test function");
-      return GEN6_COMPAREFUNCTION_NEVER;
-   }
-}
-
-static uint32_t
-dsa_get_stencil_enable_gen6(const struct ilo_dev *dev,
-                            const struct pipe_stencil_state *stencil0,
-                            const struct pipe_stencil_state *stencil1)
-{
-   uint32_t dw;
-
-   ILO_DEV_ASSERT(dev, 6, 7.5);
-
-   if (!stencil0->enabled)
-      return 0;
-
-   /*
-    * From the Sandy Bridge PRM, volume 2 part 1, page 359:
-    *
-    *     "If the Depth Buffer is either undefined or does not have a surface
-    *      format of D32_FLOAT_S8X24_UINT or D24_UNORM_S8_UINT and separate
-    *      stencil buffer is disabled, Stencil Test Enable must be DISABLED"
-    *
-    * From the Sandy Bridge PRM, volume 2 part 1, page 370:
-    *
-    *     "This field (Stencil Test Enable) cannot be enabled if
-    *      Surface Format in 3DSTATE_DEPTH_BUFFER is set to D16_UNORM."
-    *
-    * TODO We do not check these yet.
-    */
-   dw = GEN6_ZS_DW0_STENCIL_TEST_ENABLE |
-        gen6_translate_dsa_func(stencil0->func) << 28 |
-        gen6_translate_pipe_stencil_op(stencil0->fail_op) << 25 |
-        gen6_translate_pipe_stencil_op(stencil0->zfail_op) << 22 |
-        gen6_translate_pipe_stencil_op(stencil0->zpass_op) << 19;
-   if (stencil0->writemask)
-      dw |= GEN6_ZS_DW0_STENCIL_WRITE_ENABLE;
-
-   if (stencil1->enabled) {
-      dw |= GEN6_ZS_DW0_STENCIL1_ENABLE |
-            gen6_translate_dsa_func(stencil1->func) << 12 |
-            gen6_translate_pipe_stencil_op(stencil1->fail_op) << 9 |
-            gen6_translate_pipe_stencil_op(stencil1->zfail_op) << 6 |
-            gen6_translate_pipe_stencil_op(stencil1->zpass_op) << 3;
-      if (stencil1->writemask)
-         dw |= GEN6_ZS_DW0_STENCIL_WRITE_ENABLE;
-   }
-
-   return dw;
-}
-
-static uint32_t
-dsa_get_stencil_enable_gen8(const struct ilo_dev *dev,
-                            const struct pipe_stencil_state *stencil0,
-                            const struct pipe_stencil_state *stencil1)
-{
-   uint32_t dw;
-
-   ILO_DEV_ASSERT(dev, 8, 8);
-
-   if (!stencil0->enabled)
-      return 0;
-
-   dw = gen6_translate_pipe_stencil_op(stencil0->fail_op) << 29 |
-        gen6_translate_pipe_stencil_op(stencil0->zfail_op) << 26 |
-        gen6_translate_pipe_stencil_op(stencil0->zpass_op) << 23 |
-        gen6_translate_dsa_func(stencil0->func) << 8 |
-        GEN8_ZS_DW1_STENCIL_TEST_ENABLE;
-   if (stencil0->writemask)
-      dw |= GEN8_ZS_DW1_STENCIL_WRITE_ENABLE;
-
-   if (stencil1->enabled) {
-      dw |= gen6_translate_dsa_func(stencil1->func) << 20 |
-            gen6_translate_pipe_stencil_op(stencil1->fail_op) << 17 |
-            gen6_translate_pipe_stencil_op(stencil1->zfail_op) << 14 |
-            gen6_translate_pipe_stencil_op(stencil1->zpass_op) << 11 |
-            GEN8_ZS_DW1_STENCIL1_ENABLE;
-      if (stencil1->writemask)
-         dw |= GEN8_ZS_DW1_STENCIL_WRITE_ENABLE;
-   }
-
-   return dw;
-}
-
-static uint32_t
-dsa_get_depth_enable_gen6(const struct ilo_dev *dev,
-                          const struct pipe_depth_state *state)
-{
-   uint32_t dw;
-
-   ILO_DEV_ASSERT(dev, 6, 7.5);
-
-   /*
-    * From the Sandy Bridge PRM, volume 2 part 1, page 360:
-    *
-    *     "Enabling the Depth Test function without defining a Depth Buffer is
-    *      UNDEFINED."
-    *
-    * From the Sandy Bridge PRM, volume 2 part 1, page 375:
-    *
-    *     "A Depth Buffer must be defined before enabling writes to it, or
-    *      operation is UNDEFINED."
-    *
-    * TODO We do not check these yet.
-    */
-   if (state->enabled) {
-      dw = GEN6_ZS_DW2_DEPTH_TEST_ENABLE |
-           gen6_translate_dsa_func(state->func) << 27;
-   } else {
-      dw = GEN6_COMPAREFUNCTION_ALWAYS << 27;
-   }
-
-   if (state->writemask)
-      dw |= GEN6_ZS_DW2_DEPTH_WRITE_ENABLE;
-
-   return dw;
-}
-
-static uint32_t
-dsa_get_depth_enable_gen8(const struct ilo_dev *dev,
-                          const struct pipe_depth_state *state)
-{
-   uint32_t dw;
-
-   ILO_DEV_ASSERT(dev, 8, 8);
-
-   if (state->enabled) {
-      dw = GEN8_ZS_DW1_DEPTH_TEST_ENABLE |
-           gen6_translate_dsa_func(state->func) << 5;
-   } else {
-      dw = GEN6_COMPAREFUNCTION_ALWAYS << 5;
-   }
-
-   if (state->writemask)
-      dw |= GEN8_ZS_DW1_DEPTH_WRITE_ENABLE;
-
-   return dw;
-}
-
-static uint32_t
-dsa_get_alpha_enable_gen6(const struct ilo_dev *dev,
-                          const struct pipe_alpha_state *state)
-{
-   uint32_t dw;
-
-   ILO_DEV_ASSERT(dev, 6, 7.5);
-
-   if (!state->enabled)
-      return 0;
-
-   /* this will be ORed to BLEND_STATE */
-   dw = GEN6_RT_DW1_ALPHA_TEST_ENABLE |
-        gen6_translate_dsa_func(state->func) << 13;
-
-   return dw;
-}
-
-static uint32_t
-dsa_get_alpha_enable_gen8(const struct ilo_dev *dev,
-                          const struct pipe_alpha_state *state)
-{
-   uint32_t dw;
-
-   ILO_DEV_ASSERT(dev, 8, 8);
-
-   if (!state->enabled)
-      return 0;
-
-   /* this will be ORed to BLEND_STATE */
-   dw = GEN8_BLEND_DW0_ALPHA_TEST_ENABLE |
-        gen6_translate_dsa_func(state->func) << 24;
-
-   return dw;
-}
-
-void
-ilo_gpe_init_dsa(const struct ilo_dev *dev,
-                 const struct pipe_depth_stencil_alpha_state *state,
-                 struct ilo_dsa_state *dsa)
-{
-   ILO_DEV_ASSERT(dev, 6, 8);
-
-   STATIC_ASSERT(Elements(dsa->payload) >= 3);
-
-   if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
-      const uint32_t dw_stencil = dsa_get_stencil_enable_gen8(dev,
-            &state->stencil[0], &state->stencil[1]);
-      const uint32_t dw_depth = dsa_get_depth_enable_gen8(dev, &state->depth);
-
-      assert(!(dw_stencil & dw_depth));
-      dsa->payload[0] = dw_stencil | dw_depth;
-
-      dsa->dw_blend_alpha = dsa_get_alpha_enable_gen8(dev, &state->alpha);
-      dsa->dw_ps_blend_alpha = (state->alpha.enabled) ?
-         GEN8_PS_BLEND_DW1_ALPHA_TEST_ENABLE : 0;
-   } else {
-      dsa->payload[0] = dsa_get_stencil_enable_gen6(dev,
-            &state->stencil[0], &state->stencil[1]);
-      dsa->payload[2] = dsa_get_depth_enable_gen6(dev, &state->depth);
-
-      dsa->dw_blend_alpha = dsa_get_alpha_enable_gen6(dev, &state->alpha);
-      dsa->dw_ps_blend_alpha = 0;
-   }
-
-   dsa->payload[1] = state->stencil[0].valuemask << 24 |
-                     state->stencil[0].writemask << 16 |
-                     state->stencil[1].valuemask << 8 |
-                     state->stencil[1].writemask;
-
-   dsa->alpha_ref = float_to_ubyte(state->alpha.ref_value);
-}
-
 static void
 fb_set_blend_caps(const struct ilo_dev *dev,
                   enum pipe_format format,
@@ -1029,12 +353,12 @@ fb_set_blend_caps(const struct ilo_dev *dev,
     */
    caps->can_alpha_test = !caps->is_integer;
 
-   caps->dst_alpha_forced_one =
+   caps->force_dst_alpha_one =
       (ilo_format_translate_render(dev, format) !=
        ilo_format_translate_color(dev, format));
 
    /* sanity check */
-   if (caps->dst_alpha_forced_one) {
+   if (caps->force_dst_alpha_one) {
       enum pipe_format render_format;
 
       switch (format) {
index a092aff..072f0f7 100644 (file)
@@ -64,13 +64,7 @@ struct ilo_blitter {
    struct ilo_state_viewport vp;
    uint32_t vp_data[20];
 
-   struct ilo_dsa_state dsa;
-
-   struct {
-      struct pipe_stencil_ref stencil_ref;
-      ubyte alpha_ref;
-      struct pipe_blend_color blend_color;
-   } cc;
+   struct ilo_state_cc cc;
 
    uint32_t depth_clear_value;
 
index 51e640d..9d43195 100644 (file)
@@ -115,18 +115,18 @@ ilo_blitter_set_rectlist(struct ilo_blitter *blitter,
 }
 
 static void
-ilo_blitter_set_clear_values(struct ilo_blitter *blitter,
-                             uint32_t depth, ubyte stencil)
+ilo_blitter_set_depth_clear_value(struct ilo_blitter *blitter,
+                                  uint32_t depth)
 {
    blitter->depth_clear_value = depth;
-   blitter->cc.stencil_ref.ref_value[0] = stencil;
 }
 
 static void
-ilo_blitter_set_dsa(struct ilo_blitter *blitter,
-                    const struct pipe_depth_stencil_alpha_state *state)
+ilo_blitter_set_cc(struct ilo_blitter *blitter,
+                   const struct ilo_state_cc_info *info)
 {
-   ilo_gpe_init_dsa(blitter->ilo->dev, state, &blitter->dsa);
+   memset(&blitter->cc, 0, sizeof(blitter->cc));
+   ilo_state_cc_init(&blitter->cc, blitter->ilo->dev, info);
 }
 
 static void
@@ -337,7 +337,7 @@ ilo_blitter_rectlist_clear_zs(struct ilo_blitter *blitter,
                               double depth, unsigned stencil)
 {
    struct ilo_texture *tex = ilo_texture(zs->texture);
-   struct pipe_depth_stencil_alpha_state dsa_state;
+   struct ilo_state_cc_info info;
    uint32_t uses, clear_value;
 
    if (!ilo_image_can_enable_aux(&tex->image, zs->u.tex.level))
@@ -377,17 +377,20 @@ ilo_blitter_rectlist_clear_zs(struct ilo_blitter *blitter,
     *      - [DevSNB] errata: For stencil buffer only clear, the previous
     *        depth clear value must be delivered during the clear."
     */
-   memset(&dsa_state, 0, sizeof(dsa_state));
+   memset(&info, 0, sizeof(info));
 
-   if (clear_flags & PIPE_CLEAR_DEPTH)
-      dsa_state.depth.writemask = true;
+   if (clear_flags & PIPE_CLEAR_DEPTH) {
+      info.depth.cv_has_buffer = true;
+      info.depth.write_enable = true;
+   }
 
    if (clear_flags & PIPE_CLEAR_STENCIL) {
-      dsa_state.stencil[0].enabled = true;
-      dsa_state.stencil[0].func = PIPE_FUNC_ALWAYS;
-      dsa_state.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP;
-      dsa_state.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
-      dsa_state.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP;
+      info.stencil.cv_has_buffer = true;
+      info.stencil.test_enable = true;
+      info.stencil.front.test_func = GEN6_COMPAREFUNCTION_ALWAYS;
+      info.stencil.front.fail_op = GEN6_STENCILOP_KEEP;
+      info.stencil.front.zfail_op = GEN6_STENCILOP_KEEP;
+      info.stencil.front.zpass_op = GEN6_STENCILOP_REPLACE;
 
       /*
        * From the Ivy Bridge PRM, volume 2 part 1, page 277:
@@ -398,11 +401,12 @@ ilo_blitter_rectlist_clear_zs(struct ilo_blitter *blitter,
        *      - DEPTH_STENCIL_STATE::Stencil Test Mask must be 0xFF
        *      - DEPTH_STENCIL_STATE::Back Face Stencil Write Mask must be 0xFF
        *      - DEPTH_STENCIL_STATE::Back Face Stencil Test Mask must be 0xFF"
+       *
+       * Back frace masks will be copied from front face masks.
        */
-      dsa_state.stencil[0].valuemask = 0xff;
-      dsa_state.stencil[0].writemask = 0xff;
-      dsa_state.stencil[1].valuemask = 0xff;
-      dsa_state.stencil[1].writemask = 0xff;
+      info.params.stencil_front.test_ref = (uint8_t) stencil;
+      info.params.stencil_front.test_mask = 0xff;
+      info.params.stencil_front.write_mask = 0xff;
    }
 
    ilo_blitter_set_invariants(blitter);
@@ -410,8 +414,8 @@ ilo_blitter_rectlist_clear_zs(struct ilo_blitter *blitter,
          ILO_STATE_RASTER_EARLYZ_DEPTH_CLEAR,
          clear_flags & PIPE_CLEAR_STENCIL);
 
-   ilo_blitter_set_dsa(blitter, &dsa_state);
-   ilo_blitter_set_clear_values(blitter, clear_value, (ubyte) stencil);
+   ilo_blitter_set_cc(blitter, &info);
+   ilo_blitter_set_depth_clear_value(blitter, clear_value);
    ilo_blitter_set_fb_from_surface(blitter, zs);
 
    uses = ILO_BLITTER_USE_DSA;
@@ -432,7 +436,7 @@ ilo_blitter_rectlist_resolve_z(struct ilo_blitter *blitter,
                                unsigned level, unsigned slice)
 {
    struct ilo_texture *tex = ilo_texture(res);
-   struct pipe_depth_stencil_alpha_state dsa_state;
+   struct ilo_state_cc_info info;
    const struct ilo_texture_slice *s =
       ilo_texture_get_slice(tex, level, slice);
 
@@ -446,17 +450,18 @@ ilo_blitter_rectlist_resolve_z(struct ilo_blitter *blitter,
     *      to NEVER. Depth Buffer Write Enable must be enabled. Stencil Test
     *      Enable and Stencil Buffer Write Enable must be disabled."
     */
-   memset(&dsa_state, 0, sizeof(dsa_state));
-   dsa_state.depth.writemask = true;
-   dsa_state.depth.enabled = true;
-   dsa_state.depth.func = PIPE_FUNC_NEVER;
+   memset(&info, 0, sizeof(info));
+   info.depth.cv_has_buffer = true;
+   info.depth.test_enable = true;
+   info.depth.write_enable = true;
+   info.depth.test_func = GEN6_COMPAREFUNCTION_NEVER;
 
    ilo_blitter_set_invariants(blitter);
    ilo_blitter_set_earlyz_op(blitter,
          ILO_STATE_RASTER_EARLYZ_DEPTH_RESOLVE, false);
 
-   ilo_blitter_set_dsa(blitter, &dsa_state);
-   ilo_blitter_set_clear_values(blitter, s->clear_value, 0);
+   ilo_blitter_set_cc(blitter, &info);
+   ilo_blitter_set_depth_clear_value(blitter, s->clear_value);
    ilo_blitter_set_fb_from_resource(blitter, res, res->format, level, slice);
    ilo_blitter_set_uses(blitter,
          ILO_BLITTER_USE_DSA | ILO_BLITTER_USE_FB_DEPTH);
@@ -470,7 +475,7 @@ ilo_blitter_rectlist_resolve_hiz(struct ilo_blitter *blitter,
                                  unsigned level, unsigned slice)
 {
    struct ilo_texture *tex = ilo_texture(res);
-   struct pipe_depth_stencil_alpha_state dsa_state;
+   struct ilo_state_cc_info info;
 
    if (!ilo_image_can_enable_aux(&tex->image, level))
       return;
@@ -482,14 +487,15 @@ ilo_blitter_rectlist_resolve_hiz(struct ilo_blitter *blitter,
     *      disabled. Depth Buffer Write Enable must be enabled. Stencil Test
     *      Enable and Stencil Buffer Write Enable must be disabled."
     */
-   memset(&dsa_state, 0, sizeof(dsa_state));
-   dsa_state.depth.writemask = true;
+   memset(&info, 0, sizeof(info));
+   info.depth.cv_has_buffer = true;
+   info.depth.write_enable = true;
 
    ilo_blitter_set_invariants(blitter);
    ilo_blitter_set_earlyz_op(blitter,
          ILO_STATE_RASTER_EARLYZ_HIZ_RESOLVE, false);
 
-   ilo_blitter_set_dsa(blitter, &dsa_state);
+   ilo_blitter_set_cc(blitter, &info);
    ilo_blitter_set_fb_from_resource(blitter, res, res->format, level, slice);
    ilo_blitter_set_uses(blitter,
          ILO_BLITTER_USE_DSA | ILO_BLITTER_USE_FB_DEPTH);
index f710598..6935138 100644 (file)
@@ -453,6 +453,9 @@ draw_session_prepare(struct ilo_render *render,
 
       ilo_state_viewport_full_delta(&vec->viewport.vp, render->dev,
             &session->vp_delta);
+
+      ilo_state_cc_full_delta(&vec->blend->cc, render->dev,
+            &session->cc_delta);
    } else {
       session->prim_changed =
          (render->state.reduced_prim != session->reduced_prim);
@@ -468,6 +471,11 @@ draw_session_prepare(struct ilo_render *render,
          ilo_state_viewport_full_delta(&vec->viewport.vp, render->dev,
                &session->vp_delta);
       }
+
+      if (vec->dirty & ILO_DIRTY_BLEND) {
+         ilo_state_cc_get_delta(&vec->blend->cc, render->dev,
+               &render->state.cc, &session->cc_delta);
+      }
    }
 }
 
@@ -486,6 +494,7 @@ draw_session_end(struct ilo_render *render,
    render->state.primitive_restart = vec->draw->primitive_restart;
 
    render->state.rs = vec->rasterizer->rs;
+   render->state.cc = vec->blend->cc;
 }
 
 void
index cc3791e..5618920 100644 (file)
@@ -99,32 +99,30 @@ gen6_emit_draw_dynamic_cc(struct ilo_render *r,
    ILO_DEV_ASSERT(r->dev, 6, 8);
 
    /* BLEND_STATE */
-   if (DIRTY(BLEND) || DIRTY(FB) || DIRTY(DSA)) {
-      if (ilo_dev_gen(r->dev) >= ILO_GEN(8)) {
-         r->state.BLEND_STATE = gen8_BLEND_STATE(r->builder,
-               vec->blend, &vec->fb, vec->dsa);
-      } else {
-         r->state.BLEND_STATE = gen6_BLEND_STATE(r->builder,
-               vec->blend, &vec->fb, vec->dsa);
-      }
+   if ((session->cc_delta.dirty & ILO_STATE_CC_BLEND_STATE) ||
+        r->state_bo_changed) {
+      if (ilo_dev_gen(r->dev) >= ILO_GEN(8))
+         r->state.BLEND_STATE = gen8_BLEND_STATE(r->builder, &vec->blend->cc);
+      else
+         r->state.BLEND_STATE = gen6_BLEND_STATE(r->builder, &vec->blend->cc);
 
       session->blend_changed = true;
    }
 
    /* COLOR_CALC_STATE */
-   if (DIRTY(DSA) || DIRTY(STENCIL_REF) || DIRTY(BLEND_COLOR)) {
+   if ((session->cc_delta.dirty & ILO_STATE_CC_COLOR_CALC_STATE) ||
+       r->state_bo_changed) {
       r->state.COLOR_CALC_STATE =
-         gen6_COLOR_CALC_STATE(r->builder, &vec->stencil_ref,
-               vec->dsa->alpha_ref, &vec->blend_color);
-
+         gen6_COLOR_CALC_STATE(r->builder, &vec->blend->cc);
       session->cc_changed = true;
    }
 
    /* DEPTH_STENCIL_STATE */
-   if (ilo_dev_gen(r->dev) < ILO_GEN(8) && DIRTY(DSA)) {
+   if (ilo_dev_gen(r->dev) < ILO_GEN(8) &&
+       ((session->cc_delta.dirty & ILO_STATE_CC_DEPTH_STENCIL_STATE) ||
+        r->state_bo_changed)) {
       r->state.DEPTH_STENCIL_STATE =
-         gen6_DEPTH_STENCIL_STATE(r->builder, vec->dsa);
-
+         gen6_DEPTH_STENCIL_STATE(r->builder, &vec->blend->cc);
       session->dsa_changed = true;
    }
 }
@@ -450,13 +448,12 @@ ilo_render_emit_rectlist_dynamic_states(struct ilo_render *render,
 
    if (blitter->uses & ILO_BLITTER_USE_DSA) {
       render->state.DEPTH_STENCIL_STATE =
-         gen6_DEPTH_STENCIL_STATE(render->builder, &blitter->dsa);
+         gen6_DEPTH_STENCIL_STATE(render->builder, &blitter->cc);
    }
 
    if (blitter->uses & ILO_BLITTER_USE_CC) {
       render->state.COLOR_CALC_STATE =
-         gen6_COLOR_CALC_STATE(render->builder, &blitter->cc.stencil_ref,
-               blitter->cc.alpha_ref, &blitter->cc.blend_color);
+         gen6_COLOR_CALC_STATE(render->builder, &blitter->cc);
    }
 
    if (blitter->uses & ILO_BLITTER_USE_VIEWPORT) {
index 2bf5172..cc6f77d 100644 (file)
@@ -91,6 +91,7 @@ struct ilo_render {
       int so_max_vertices;
 
       struct ilo_state_raster rs;
+      struct ilo_state_cc cc;
 
       uint32_t SF_VIEWPORT;
       uint32_t CLIP_VIEWPORT;
@@ -149,6 +150,7 @@ struct ilo_render_draw_session {
 
    struct ilo_state_raster_delta rs_delta;
    struct ilo_state_viewport_delta vp_delta;
+   struct ilo_state_cc_delta cc_delta;
 
    /* dynamic states */
    bool viewport_changed;
index e292ae8..ff0bf2f 100644 (file)
@@ -29,7 +29,6 @@
 #include "core/ilo_builder_3d.h"
 #include "core/ilo_builder_mi.h"
 #include "core/ilo_builder_render.h"
-#include "util/u_dual_blend.h"
 #include "util/u_prim.h"
 
 #include "ilo_blitter.h"
@@ -679,18 +678,14 @@ gen6_draw_wm(struct ilo_render *r,
    }
 
    /* 3DSTATE_WM */
-   if (DIRTY(FS) || DIRTY(BLEND) || DIRTY(DSA) ||
+   if (DIRTY(FS) || DIRTY(BLEND) ||
        (session->rs_delta.dirty & ILO_STATE_RASTER_3DSTATE_WM) ||
        r->instruction_bo_changed) {
-      const bool dual_blend = vec->blend->dual_blend;
-      const bool cc_may_kill = (vec->dsa->dw_blend_alpha ||
-                                vec->blend->alpha_to_coverage);
-
       if (ilo_dev_gen(r->dev) == ILO_GEN(6) && r->hw_ctx_changed)
          gen6_wa_pre_3dstate_wm_max_threads(r);
 
       gen6_3DSTATE_WM(r->builder, &vec->rasterizer->rs, vec->fs,
-            dual_blend, cc_may_kill);
+            vec->blend->dual_blend, vec->blend->alpha_may_kill);
    }
 }
 
index b427b29..0931a77 100644 (file)
@@ -28,7 +28,6 @@
 #include "genhw/genhw.h"
 #include "core/ilo_builder_3d.h"
 #include "core/ilo_builder_render.h"
-#include "util/u_dual_blend.h"
 
 #include "ilo_blitter.h"
 #include "ilo_shader.h"
@@ -497,12 +496,10 @@ gen7_draw_wm(struct ilo_render *r,
              struct ilo_render_draw_session *session)
 {
    /* 3DSTATE_WM */
-   if (DIRTY(FS) || DIRTY(BLEND) || DIRTY(DSA) ||
+   if (DIRTY(FS) || DIRTY(BLEND) ||
        (session->rs_delta.dirty & ILO_STATE_RASTER_3DSTATE_WM)) {
-      const bool cc_may_kill = (vec->dsa->dw_blend_alpha ||
-                                vec->blend->alpha_to_coverage);
-
-      gen7_3DSTATE_WM(r->builder, &vec->rasterizer->rs, vec->fs, cc_may_kill);
+      gen7_3DSTATE_WM(r->builder, &vec->rasterizer->rs, vec->fs,
+            vec->blend->alpha_may_kill);
    }
 
    /* 3DSTATE_BINDING_TABLE_POINTERS_PS */
index 7afb35e..e0e1a85 100644 (file)
@@ -28,7 +28,6 @@
 #include "genhw/genhw.h"
 #include "core/ilo_builder_3d.h"
 #include "core/ilo_builder_render.h"
-#include "util/u_dual_blend.h"
 
 #include "ilo_blitter.h"
 #include "ilo_shader.h"
@@ -93,8 +92,8 @@ gen8_draw_wm(struct ilo_render *r,
    if (session->rs_delta.dirty & ILO_STATE_RASTER_3DSTATE_WM)
       gen8_3DSTATE_WM(r->builder, &vec->rasterizer->rs);
 
-   if (DIRTY(DSA))
-      gen8_3DSTATE_WM_DEPTH_STENCIL(r->builder, vec->dsa);
+   if (session->cc_delta.dirty & ILO_STATE_CC_3DSTATE_WM_DEPTH_STENCIL)
+      gen8_3DSTATE_WM_DEPTH_STENCIL(r->builder, &vec->blend->cc);
 
    /* 3DSTATE_WM_HZ_OP and 3DSTATE_WM_CHROMAKEY */
    if (r->hw_ctx_changed) {
@@ -127,15 +126,14 @@ gen8_draw_wm(struct ilo_render *r,
       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);
+   if (DIRTY(FS) || DIRTY(BLEND)) {
+      gen8_3DSTATE_PS_EXTRA(r->builder, vec->fs,
+            vec->blend->alpha_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);
+   if (session->cc_delta.dirty & ILO_STATE_CC_3DSTATE_PS_BLEND)
+      gen8_3DSTATE_PS_BLEND(r->builder, &vec->blend->cc);
 
    /* 3DSTATE_SCISSOR_STATE_POINTERS */
    if (session->scissor_changed) {
index 0481521..0a568bf 100644 (file)
@@ -28,6 +28,7 @@
 #include "core/ilo_builder_3d.h" /* for gen6_3d_translate_pipe_prim() */
 #include "core/ilo_format.h"
 #include "core/ilo_state_3d.h"
+#include "util/u_dual_blend.h"
 #include "util/u_dynarray.h"
 #include "util/u_helpers.h"
 #include "util/u_resource.h"
@@ -160,6 +161,112 @@ ilo_translate_half_pixel_center(bool half_pixel_center)
    return (half_pixel_center) ? GEN6_PIXLOC_CENTER : GEN6_PIXLOC_UL_CORNER;
 }
 
+static enum gen_compare_function
+ilo_translate_compare_func(unsigned func)
+{
+   switch (func) {
+   case PIPE_FUNC_NEVER:               return GEN6_COMPAREFUNCTION_NEVER;
+   case PIPE_FUNC_LESS:                return GEN6_COMPAREFUNCTION_LESS;
+   case PIPE_FUNC_EQUAL:               return GEN6_COMPAREFUNCTION_EQUAL;
+   case PIPE_FUNC_LEQUAL:              return GEN6_COMPAREFUNCTION_LEQUAL;
+   case PIPE_FUNC_GREATER:             return GEN6_COMPAREFUNCTION_GREATER;
+   case PIPE_FUNC_NOTEQUAL:            return GEN6_COMPAREFUNCTION_NOTEQUAL;
+   case PIPE_FUNC_GEQUAL:              return GEN6_COMPAREFUNCTION_GEQUAL;
+   case PIPE_FUNC_ALWAYS:              return GEN6_COMPAREFUNCTION_ALWAYS;
+   default:
+      assert(!"unknown compare function");
+      return GEN6_COMPAREFUNCTION_NEVER;
+   }
+}
+
+static enum gen_stencil_op
+ilo_translate_stencil_op(unsigned stencil_op)
+{
+   switch (stencil_op) {
+   case PIPE_STENCIL_OP_KEEP:          return GEN6_STENCILOP_KEEP;
+   case PIPE_STENCIL_OP_ZERO:          return GEN6_STENCILOP_ZERO;
+   case PIPE_STENCIL_OP_REPLACE:       return GEN6_STENCILOP_REPLACE;
+   case PIPE_STENCIL_OP_INCR:          return GEN6_STENCILOP_INCRSAT;
+   case PIPE_STENCIL_OP_DECR:          return GEN6_STENCILOP_DECRSAT;
+   case PIPE_STENCIL_OP_INCR_WRAP:     return GEN6_STENCILOP_INCR;
+   case PIPE_STENCIL_OP_DECR_WRAP:     return GEN6_STENCILOP_DECR;
+   case PIPE_STENCIL_OP_INVERT:        return GEN6_STENCILOP_INVERT;
+   default:
+      assert(!"unknown stencil op");
+      return GEN6_STENCILOP_KEEP;
+   }
+}
+
+static enum gen_logic_op
+ilo_translate_logicop(unsigned logicop)
+{
+   switch (logicop) {
+   case PIPE_LOGICOP_CLEAR:            return GEN6_LOGICOP_CLEAR;
+   case PIPE_LOGICOP_NOR:              return GEN6_LOGICOP_NOR;
+   case PIPE_LOGICOP_AND_INVERTED:     return GEN6_LOGICOP_AND_INVERTED;
+   case PIPE_LOGICOP_COPY_INVERTED:    return GEN6_LOGICOP_COPY_INVERTED;
+   case PIPE_LOGICOP_AND_REVERSE:      return GEN6_LOGICOP_AND_REVERSE;
+   case PIPE_LOGICOP_INVERT:           return GEN6_LOGICOP_INVERT;
+   case PIPE_LOGICOP_XOR:              return GEN6_LOGICOP_XOR;
+   case PIPE_LOGICOP_NAND:             return GEN6_LOGICOP_NAND;
+   case PIPE_LOGICOP_AND:              return GEN6_LOGICOP_AND;
+   case PIPE_LOGICOP_EQUIV:            return GEN6_LOGICOP_EQUIV;
+   case PIPE_LOGICOP_NOOP:             return GEN6_LOGICOP_NOOP;
+   case PIPE_LOGICOP_OR_INVERTED:      return GEN6_LOGICOP_OR_INVERTED;
+   case PIPE_LOGICOP_COPY:             return GEN6_LOGICOP_COPY;
+   case PIPE_LOGICOP_OR_REVERSE:       return GEN6_LOGICOP_OR_REVERSE;
+   case PIPE_LOGICOP_OR:               return GEN6_LOGICOP_OR;
+   case PIPE_LOGICOP_SET:              return GEN6_LOGICOP_SET;
+   default:
+      assert(!"unknown logicop function");
+      return GEN6_LOGICOP_CLEAR;
+   }
+}
+
+static int
+ilo_translate_blend_func(unsigned blend)
+{
+   switch (blend) {
+   case PIPE_BLEND_ADD:                return GEN6_BLENDFUNCTION_ADD;
+   case PIPE_BLEND_SUBTRACT:           return GEN6_BLENDFUNCTION_SUBTRACT;
+   case PIPE_BLEND_REVERSE_SUBTRACT:   return GEN6_BLENDFUNCTION_REVERSE_SUBTRACT;
+   case PIPE_BLEND_MIN:                return GEN6_BLENDFUNCTION_MIN;
+   case PIPE_BLEND_MAX:                return GEN6_BLENDFUNCTION_MAX;
+   default:
+      assert(!"unknown blend function");
+      return GEN6_BLENDFUNCTION_ADD;
+   }
+}
+
+static int
+ilo_translate_blend_factor(unsigned factor)
+{
+   switch (factor) {
+   case PIPE_BLENDFACTOR_ONE:                return GEN6_BLENDFACTOR_ONE;
+   case PIPE_BLENDFACTOR_SRC_COLOR:          return GEN6_BLENDFACTOR_SRC_COLOR;
+   case PIPE_BLENDFACTOR_SRC_ALPHA:          return GEN6_BLENDFACTOR_SRC_ALPHA;
+   case PIPE_BLENDFACTOR_DST_ALPHA:          return GEN6_BLENDFACTOR_DST_ALPHA;
+   case PIPE_BLENDFACTOR_DST_COLOR:          return GEN6_BLENDFACTOR_DST_COLOR;
+   case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: return GEN6_BLENDFACTOR_SRC_ALPHA_SATURATE;
+   case PIPE_BLENDFACTOR_CONST_COLOR:        return GEN6_BLENDFACTOR_CONST_COLOR;
+   case PIPE_BLENDFACTOR_CONST_ALPHA:        return GEN6_BLENDFACTOR_CONST_ALPHA;
+   case PIPE_BLENDFACTOR_SRC1_COLOR:         return GEN6_BLENDFACTOR_SRC1_COLOR;
+   case PIPE_BLENDFACTOR_SRC1_ALPHA:         return GEN6_BLENDFACTOR_SRC1_ALPHA;
+   case PIPE_BLENDFACTOR_ZERO:               return GEN6_BLENDFACTOR_ZERO;
+   case PIPE_BLENDFACTOR_INV_SRC_COLOR:      return GEN6_BLENDFACTOR_INV_SRC_COLOR;
+   case PIPE_BLENDFACTOR_INV_SRC_ALPHA:      return GEN6_BLENDFACTOR_INV_SRC_ALPHA;
+   case PIPE_BLENDFACTOR_INV_DST_ALPHA:      return GEN6_BLENDFACTOR_INV_DST_ALPHA;
+   case PIPE_BLENDFACTOR_INV_DST_COLOR:      return GEN6_BLENDFACTOR_INV_DST_COLOR;
+   case PIPE_BLENDFACTOR_INV_CONST_COLOR:    return GEN6_BLENDFACTOR_INV_CONST_COLOR;
+   case PIPE_BLENDFACTOR_INV_CONST_ALPHA:    return GEN6_BLENDFACTOR_INV_CONST_ALPHA;
+   case PIPE_BLENDFACTOR_INV_SRC1_COLOR:     return GEN6_BLENDFACTOR_INV_SRC1_COLOR;
+   case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:     return GEN6_BLENDFACTOR_INV_SRC1_ALPHA;
+   default:
+      assert(!"unknown blend factor");
+      return GEN6_BLENDFACTOR_ONE;
+   }
+}
+
 static void
 finalize_shader_states(struct ilo_state_vector *vec)
 {
@@ -466,6 +573,98 @@ finalize_rasterizer(struct ilo_context *ilo)
    }
 }
 
+static bool
+finalize_blend_rt(struct ilo_context *ilo)
+{
+   struct ilo_state_vector *vec = &ilo->state_vector;
+   const struct ilo_fb_state *fb = &vec->fb;
+   struct ilo_blend_state *blend = vec->blend;
+   struct ilo_state_cc_blend_info *info = &vec->blend->info.blend;
+   bool changed = false;
+   unsigned i;
+
+   if (!(vec->dirty & (ILO_DIRTY_FB | ILO_DIRTY_BLEND)))
+      return false;
+
+   /* set up one for dummy RT writes */
+   if (!fb->state.nr_cbufs) {
+      if (info->rt != &blend->dummy_rt) {
+         info->rt = &blend->dummy_rt;
+         info->rt_count = 1;
+         changed = true;
+      }
+
+      return changed;
+   }
+
+   if (info->rt != blend->effective_rt ||
+       info->rt_count != fb->state.nr_cbufs) {
+      info->rt = blend->effective_rt;
+      info->rt_count = fb->state.nr_cbufs;
+      changed = true;
+   }
+
+   for (i = 0; i < fb->state.nr_cbufs; i++) {
+      const struct ilo_fb_blend_caps *caps = &fb->blend_caps[i];
+      struct ilo_state_cc_blend_rt_info *rt = &blend->effective_rt[i];
+      /* ignore logicop when not UNORM */
+      const bool logicop_enable =
+         (blend->rt[i].logicop_enable && caps->is_unorm);
+
+      if (rt->cv_is_unorm != caps->is_unorm ||
+          rt->cv_is_integer != caps->is_integer ||
+          rt->logicop_enable != logicop_enable ||
+          rt->force_dst_alpha_one != caps->force_dst_alpha_one) {
+         rt->cv_is_unorm = caps->is_unorm;
+         rt->cv_is_integer = caps->is_integer;
+         rt->logicop_enable = logicop_enable;
+         rt->force_dst_alpha_one = caps->force_dst_alpha_one;
+
+         changed = true;
+      }
+   }
+
+   return changed;
+}
+
+static void
+finalize_blend(struct ilo_context *ilo)
+{
+   const struct ilo_dev *dev = ilo->dev;
+   struct ilo_state_vector *vec = &ilo->state_vector;
+   struct ilo_blend_state *blend = vec->blend;
+   struct ilo_state_cc_info *info = &blend->info;
+   const bool sample_count_one = (vec->fb.num_samples <= 1);
+   const bool float_source0_alpha =
+      (!vec->fb.state.nr_cbufs || !vec->fb.state.cbufs[0] ||
+       !util_format_is_pure_integer(vec->fb.state.cbufs[0]->format));
+
+   /* check for non-orthogonal states */
+   if (finalize_blend_rt(ilo) ||
+       info->alpha.cv_sample_count_one != sample_count_one ||
+       info->alpha.cv_float_source0_alpha != float_source0_alpha ||
+       info->alpha.test_enable != vec->dsa->alpha_test ||
+       info->alpha.test_func != vec->dsa->alpha_func ||
+       memcmp(&info->stencil, &vec->dsa->stencil, sizeof(info->stencil)) ||
+       memcmp(&info->depth, &vec->dsa->depth, sizeof(info->depth)) ||
+       memcmp(&info->params, &vec->cc_params, sizeof(info->params))) {
+      info->alpha.cv_sample_count_one = sample_count_one;
+      info->alpha.cv_float_source0_alpha = float_source0_alpha;
+      info->alpha.test_enable = vec->dsa->alpha_test;
+      info->alpha.test_func = vec->dsa->alpha_func;
+      info->stencil = vec->dsa->stencil;
+      info->depth = vec->dsa->depth;
+      info->params = vec->cc_params;
+
+      ilo_state_cc_set_info(&blend->cc, dev, info);
+
+      blend->alpha_may_kill = (info->alpha.alpha_to_coverage ||
+                               info->alpha.test_enable);
+
+      vec->dirty |= ILO_DIRTY_BLEND;
+   }
+}
+
 /**
  * Finalize states.  Some states depend on other states and are
  * incomplete/invalid until finalized.
@@ -483,6 +682,7 @@ ilo_finalize_3d_states(struct ilo_context *ilo,
 
    finalize_rasterizer(ilo);
    finalize_viewport(ilo);
+   finalize_blend(ilo);
 
    u_upload_unmap(ilo->uploader);
 }
@@ -526,12 +726,79 @@ ilo_create_blend_state(struct pipe_context *pipe,
                        const struct pipe_blend_state *state)
 {
    const struct ilo_dev *dev = ilo_context(pipe)->dev;
+   struct ilo_state_cc_info *info;
    struct ilo_blend_state *blend;
+   int i;
 
-   blend = MALLOC_STRUCT(ilo_blend_state);
+   blend = CALLOC_STRUCT(ilo_blend_state);
    assert(blend);
 
-   ilo_gpe_init_blend(dev, state, blend);
+   info = &blend->info;
+
+   info->alpha.cv_float_source0_alpha = true;
+   info->alpha.cv_sample_count_one = true;
+   info->alpha.alpha_to_one = state->alpha_to_one;
+   info->alpha.alpha_to_coverage = state->alpha_to_coverage;
+   info->alpha.test_enable = false;
+   info->alpha.test_func = GEN6_COMPAREFUNCTION_ALWAYS;
+
+   info->stencil.cv_has_buffer = true;
+   info->depth.cv_has_buffer= true;
+
+   info->blend.rt = blend->effective_rt;
+   info->blend.rt_count = 1;
+   info->blend.dither_enable = state->dither;
+
+   for (i = 0; i < ARRAY_SIZE(blend->rt); i++) {
+      const struct pipe_rt_blend_state *rt = &state->rt[i];
+      struct ilo_state_cc_blend_rt_info *rt_info = &blend->rt[i];
+
+      rt_info->cv_has_buffer = true;
+      rt_info->cv_is_unorm = true;
+      rt_info->cv_is_integer = false;
+
+      /* logic op takes precedence over blending */
+      if (state->logicop_enable) {
+         rt_info->logicop_enable = true;
+         rt_info->logicop_func = ilo_translate_logicop(state->logicop_func);
+      } else if (rt->blend_enable) {
+         rt_info->blend_enable = true;
+
+         rt_info->rgb_src = ilo_translate_blend_factor(rt->rgb_src_factor);
+         rt_info->rgb_dst = ilo_translate_blend_factor(rt->rgb_dst_factor);
+         rt_info->rgb_func = ilo_translate_blend_func(rt->rgb_func);
+
+         rt_info->a_src = ilo_translate_blend_factor(rt->alpha_src_factor);
+         rt_info->a_dst = ilo_translate_blend_factor(rt->alpha_dst_factor);
+         rt_info->a_func = ilo_translate_blend_func(rt->alpha_func);
+      }
+
+      if (!(rt->colormask & PIPE_MASK_A))
+         rt_info->argb_write_disables |= (1 << 3);
+      if (!(rt->colormask & PIPE_MASK_R))
+         rt_info->argb_write_disables |= (1 << 2);
+      if (!(rt->colormask & PIPE_MASK_G))
+         rt_info->argb_write_disables |= (1 << 1);
+      if (!(rt->colormask & PIPE_MASK_B))
+         rt_info->argb_write_disables |= (1 << 0);
+
+      if (!state->independent_blend_enable) {
+         for (i = 1; i < ARRAY_SIZE(blend->rt); i++)
+            blend->rt[i] = *rt_info;
+         break;
+      }
+   }
+
+   memcpy(blend->effective_rt, blend->rt, sizeof(blend->rt));
+
+   blend->dummy_rt.argb_write_disables = 0xf;
+
+   if (!ilo_state_cc_init(&blend->cc, dev, &blend->info)) {
+      FREE(blend);
+      return NULL;
+   }
+
+   blend->dual_blend = util_blend_state_is_dual(state, 0);
 
    return blend;
 }
@@ -814,13 +1081,48 @@ static void *
 ilo_create_depth_stencil_alpha_state(struct pipe_context *pipe,
                                      const struct pipe_depth_stencil_alpha_state *state)
 {
-   const struct ilo_dev *dev = ilo_context(pipe)->dev;
    struct ilo_dsa_state *dsa;
+   int i;
 
-   dsa = MALLOC_STRUCT(ilo_dsa_state);
+   dsa = CALLOC_STRUCT(ilo_dsa_state);
    assert(dsa);
 
-   ilo_gpe_init_dsa(dev, state, dsa);
+   dsa->depth.cv_has_buffer = true;
+   dsa->depth.test_enable = state->depth.enabled;
+   dsa->depth.write_enable = state->depth.writemask;
+   dsa->depth.test_func = ilo_translate_compare_func(state->depth.func);
+
+   dsa->stencil.cv_has_buffer = true;
+   for (i = 0; i < ARRAY_SIZE(state->stencil); i++) {
+      const struct pipe_stencil_state *stencil = &state->stencil[i];
+      struct ilo_state_cc_stencil_op_info *op;
+
+      if (!stencil->enabled)
+         break;
+
+      if (i == 0) {
+         dsa->stencil.test_enable = true;
+         dsa->stencil_front.test_mask = stencil->valuemask;
+         dsa->stencil_front.write_mask = stencil->writemask;
+
+         op = &dsa->stencil.front;
+      } else {
+         dsa->stencil.twosided_enable = true;
+         dsa->stencil_back.test_mask = stencil->valuemask;
+         dsa->stencil_back.write_mask = stencil->writemask;
+
+         op = &dsa->stencil.back;
+      }
+
+      op->test_func = ilo_translate_compare_func(stencil->func);
+      op->fail_op = ilo_translate_stencil_op(stencil->fail_op);
+      op->zfail_op = ilo_translate_stencil_op(stencil->zfail_op);
+      op->zpass_op = ilo_translate_stencil_op(stencil->zpass_op);
+   }
+
+   dsa->alpha_test = state->alpha.enabled;
+   dsa->alpha_ref = state->alpha.ref_value;
+   dsa->alpha_func = ilo_translate_compare_func(state->alpha.func);
 
    return dsa;
 }
@@ -831,6 +1133,17 @@ ilo_bind_depth_stencil_alpha_state(struct pipe_context *pipe, void *state)
    struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
 
    vec->dsa = state;
+   if (vec->dsa) {
+      vec->cc_params.alpha_ref = vec->dsa->alpha_ref;
+      vec->cc_params.stencil_front.test_mask =
+         vec->dsa->stencil_front.test_mask;
+      vec->cc_params.stencil_front.write_mask =
+         vec->dsa->stencil_front.write_mask;
+      vec->cc_params.stencil_back.test_mask =
+         vec->dsa->stencil_back.test_mask;
+      vec->cc_params.stencil_back.write_mask =
+         vec->dsa->stencil_back.write_mask;
+   }
 
    vec->dirty |= ILO_DIRTY_DSA;
 }
@@ -990,7 +1303,7 @@ ilo_set_blend_color(struct pipe_context *pipe,
 {
    struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
 
-   vec->blend_color = *state;
+   memcpy(vec->cc_params.blend_rgba, state->color, sizeof(state->color));
 
    vec->dirty |= ILO_DIRTY_BLEND_COLOR;
 }
@@ -1007,6 +1320,9 @@ ilo_set_stencil_ref(struct pipe_context *pipe,
 
    vec->stencil_ref = *state;
 
+   vec->cc_params.stencil_front.test_ref = state->ref_value[0];
+   vec->cc_params.stencil_back.test_ref = state->ref_value[1];
+
    vec->dirty |= ILO_DIRTY_STENCIL_REF;
 }
 
index 8f6cce2..39d0d7e 100644 (file)
@@ -29,6 +29,7 @@
 #define ILO_STATE_H
 
 #include "core/ilo_state_3d.h"
+#include "core/ilo_state_cc.h"
 #include "core/ilo_state_raster.h"
 #include "core/ilo_state_sampler.h"
 #include "core/ilo_state_surface.h"
@@ -191,6 +192,32 @@ struct ilo_viewport_state {
    uint32_t vp_data[20 * ILO_MAX_VIEWPORTS];
 };
 
+struct ilo_dsa_state {
+   struct ilo_state_cc_depth_info depth;
+
+   struct ilo_state_cc_stencil_info stencil;
+   struct {
+      uint8_t test_mask;
+      uint8_t write_mask;
+   } stencil_front, stencil_back;
+
+   bool alpha_test;
+   float alpha_ref;
+   enum gen_compare_function alpha_func;
+};
+
+struct ilo_blend_state {
+   struct ilo_state_cc_blend_rt_info rt[PIPE_MAX_COLOR_BUFS];
+   struct ilo_state_cc_blend_rt_info dummy_rt;
+   bool dual_blend;
+
+   /* these are invalid until finalize_blend() */
+   struct ilo_state_cc_blend_rt_info effective_rt[PIPE_MAX_COLOR_BUFS];
+   struct ilo_state_cc_info info;
+   struct ilo_state_cc cc;
+   bool alpha_may_kill;
+};
+
 struct ilo_global_binding_cso {
    struct pipe_resource *resource;
    uint32_t *handle;
@@ -240,10 +267,11 @@ struct ilo_state_vector {
 
    struct ilo_shader_state *fs;
 
-   const struct ilo_dsa_state *dsa;
+   struct ilo_state_cc_params_info cc_params;
    struct pipe_stencil_ref stencil_ref;
-   const struct ilo_blend_state *blend;
-   struct pipe_blend_color blend_color;
+   const struct ilo_dsa_state *dsa;
+   struct ilo_blend_state *blend;
+
    struct ilo_fb_state fb;
 
    /* shader resources */