[Mesa-dev] [PATCH 09/10] i965: Convert CC state on gen4-5 to genxml.

Rafael Antognolli rafael.antognolli at intel.com
Tue Jun 6 16:23:35 UTC 2017


Use set_blend_entry_bits and set_depth_stencil_bits to fill most of the
color calc struct, and then manually update the rest.

Signed-off-by: Rafael Antognolli <rafael.antognolli at intel.com>
---
 src/mesa/drivers/dri/i965/brw_cc.c            | 174 --------------------------
 src/mesa/drivers/dri/i965/brw_state.h         |   1 -
 src/mesa/drivers/dri/i965/brw_structs.h       |  92 --------------
 src/mesa/drivers/dri/i965/brw_util.h          |   1 -
 src/mesa/drivers/dri/i965/genX_state_upload.c |  99 ++++++++++++---
 5 files changed, 81 insertions(+), 286 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_cc.c b/src/mesa/drivers/dri/i965/brw_cc.c
index cdaa696..503ec83 100644
--- a/src/mesa/drivers/dri/i965/brw_cc.c
+++ b/src/mesa/drivers/dri/i965/brw_cc.c
@@ -39,180 +39,6 @@
 #include "main/stencil.h"
 #include "intel_batchbuffer.h"
 
-/**
- * Modify blend function to force destination alpha to 1.0
- *
- * If \c function specifies a blend function that uses destination alpha,
- * replace it with a function that hard-wires destination alpha to 1.0.  This
- * is used when rendering to xRGB targets.
- */
-GLenum
-brw_fix_xRGB_alpha(GLenum function)
-{
-   switch (function) {
-   case GL_DST_ALPHA:
-      return GL_ONE;
-
-   case GL_ONE_MINUS_DST_ALPHA:
-   case GL_SRC_ALPHA_SATURATE:
-      return GL_ZERO;
-   }
-
-   return function;
-}
-
-/**
- * Creates a CC unit packet from the current blend state.
- */
-static void upload_cc_unit(struct brw_context *brw)
-{
-   struct gl_context *ctx = &brw->ctx;
-   struct brw_cc_unit_state *cc;
-
-   cc = brw_state_batch(brw, sizeof(*cc), 64, &brw->cc.state_offset);
-   memset(cc, 0, sizeof(*cc));
-
-   /* _NEW_STENCIL | _NEW_BUFFERS */
-   if (ctx->Stencil._Enabled) {
-      const unsigned back = ctx->Stencil._BackFace;
-
-      cc->cc0.stencil_enable = 1;
-      cc->cc0.stencil_func =
-	 intel_translate_compare_func(ctx->Stencil.Function[0]);
-      cc->cc0.stencil_fail_op =
-	 intel_translate_stencil_op(ctx->Stencil.FailFunc[0]);
-      cc->cc0.stencil_pass_depth_fail_op =
-	 intel_translate_stencil_op(ctx->Stencil.ZFailFunc[0]);
-      cc->cc0.stencil_pass_depth_pass_op =
-	 intel_translate_stencil_op(ctx->Stencil.ZPassFunc[0]);
-      cc->cc1.stencil_ref = _mesa_get_stencil_ref(ctx, 0);
-      cc->cc1.stencil_write_mask = ctx->Stencil.WriteMask[0];
-      cc->cc1.stencil_test_mask = ctx->Stencil.ValueMask[0];
-
-      if (ctx->Stencil._TestTwoSide) {
-	 cc->cc0.bf_stencil_enable = 1;
-	 cc->cc0.bf_stencil_func =
-	    intel_translate_compare_func(ctx->Stencil.Function[back]);
-	 cc->cc0.bf_stencil_fail_op =
-	    intel_translate_stencil_op(ctx->Stencil.FailFunc[back]);
-	 cc->cc0.bf_stencil_pass_depth_fail_op =
-	    intel_translate_stencil_op(ctx->Stencil.ZFailFunc[back]);
-	 cc->cc0.bf_stencil_pass_depth_pass_op =
-	    intel_translate_stencil_op(ctx->Stencil.ZPassFunc[back]);
-	 cc->cc1.bf_stencil_ref = _mesa_get_stencil_ref(ctx, back);
-	 cc->cc2.bf_stencil_write_mask = ctx->Stencil.WriteMask[back];
-	 cc->cc2.bf_stencil_test_mask = ctx->Stencil.ValueMask[back];
-      }
-
-      /* Not really sure about this:
-       */
-      if (ctx->Stencil.WriteMask[0] ||
-	  (ctx->Stencil._TestTwoSide && ctx->Stencil.WriteMask[back]))
-	 cc->cc0.stencil_write_enable = 1;
-   }
-
-   /* _NEW_COLOR */
-   if (ctx->Color.ColorLogicOpEnabled && ctx->Color.LogicOp != GL_COPY) {
-      cc->cc2.logicop_enable = 1;
-      cc->cc5.logicop_func = intel_translate_logic_op(ctx->Color.LogicOp);
-   } else if (ctx->Color.BlendEnabled && !ctx->Color._AdvancedBlendMode) {
-      GLenum eqRGB = ctx->Color.Blend[0].EquationRGB;
-      GLenum eqA = ctx->Color.Blend[0].EquationA;
-      GLenum srcRGB = ctx->Color.Blend[0].SrcRGB;
-      GLenum dstRGB = ctx->Color.Blend[0].DstRGB;
-      GLenum srcA = ctx->Color.Blend[0].SrcA;
-      GLenum dstA = ctx->Color.Blend[0].DstA;
-
-      if (eqRGB == GL_MIN || eqRGB == GL_MAX) {
-	 srcRGB = dstRGB = GL_ONE;
-      }
-
-      if (eqA == GL_MIN || eqA == GL_MAX) {
-	 srcA = dstA = GL_ONE;
-      }
-
-      /* If the renderbuffer is XRGB, we have to frob the blend function to
-       * force the destination alpha to 1.0.  This means replacing GL_DST_ALPHA
-       * with GL_ONE and GL_ONE_MINUS_DST_ALPHA with GL_ZERO.
-       */
-      const struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];
-      if (rb && !_mesa_base_format_has_channel(rb->_BaseFormat,
-                                               GL_TEXTURE_ALPHA_TYPE)) {
-	 srcRGB = brw_fix_xRGB_alpha(srcRGB);
-	 srcA   = brw_fix_xRGB_alpha(srcA);
-	 dstRGB = brw_fix_xRGB_alpha(dstRGB);
-	 dstA   = brw_fix_xRGB_alpha(dstA);
-      }
-
-      cc->cc6.dest_blend_factor = brw_translate_blend_factor(dstRGB);
-      cc->cc6.src_blend_factor = brw_translate_blend_factor(srcRGB);
-      cc->cc6.blend_function = brw_translate_blend_equation(eqRGB);
-
-      cc->cc5.ia_dest_blend_factor = brw_translate_blend_factor(dstA);
-      cc->cc5.ia_src_blend_factor = brw_translate_blend_factor(srcA);
-      cc->cc5.ia_blend_function = brw_translate_blend_equation(eqA);
-
-      cc->cc3.blend_enable = 1;
-      cc->cc3.ia_blend_enable = (srcA != srcRGB ||
-				dstA != dstRGB ||
-				eqA != eqRGB);
-   }
-
-   /* _NEW_BUFFERS */
-   if (ctx->Color.AlphaEnabled && ctx->DrawBuffer->_NumColorDrawBuffers <= 1) {
-      cc->cc3.alpha_test = 1;
-      cc->cc3.alpha_test_func =
-	 intel_translate_compare_func(ctx->Color.AlphaFunc);
-      cc->cc3.alpha_test_format = BRW_ALPHATEST_FORMAT_UNORM8;
-
-      UNCLAMPED_FLOAT_TO_UBYTE(cc->cc7.alpha_ref.ub[0], ctx->Color.AlphaRef);
-   }
-
-   if (ctx->Color.DitherFlag) {
-      cc->cc5.dither_enable = 1;
-      cc->cc6.y_dither_offset = 0;
-      cc->cc6.x_dither_offset = 0;
-   }
-
-   /* _NEW_DEPTH */
-   if (ctx->Depth.Test) {
-      cc->cc2.depth_test = 1;
-      cc->cc2.depth_test_function =
-	 intel_translate_compare_func(ctx->Depth.Func);
-      cc->cc2.depth_write_enable = brw_depth_writes_enabled(brw);
-   }
-
-   if (brw->stats_wm)
-      cc->cc5.statistics_enable = 1;
-
-   /* BRW_NEW_CC_VP */
-   cc->cc4.cc_viewport_state_offset = (brw->batch.bo->offset64 +
-				       brw->cc.vp_offset) >> 5; /* reloc */
-
-   brw->ctx.NewDriverState |= BRW_NEW_GEN4_UNIT_STATE;
-
-   /* Emit CC viewport relocation */
-   brw_emit_reloc(&brw->batch,
-                  (brw->cc.state_offset +
-                   offsetof(struct brw_cc_unit_state, cc4)),
-                  brw->batch.bo, brw->cc.vp_offset,
-                  I915_GEM_DOMAIN_INSTRUCTION, 0);
-}
-
-const struct brw_tracked_state brw_cc_unit = {
-   .dirty = {
-      .mesa = _NEW_BUFFERS |
-              _NEW_COLOR |
-              _NEW_DEPTH |
-              _NEW_STENCIL,
-      .brw = BRW_NEW_BATCH |
-             BRW_NEW_BLORP |
-             BRW_NEW_CC_VP |
-             BRW_NEW_STATS_WM,
-   },
-   .emit = upload_cc_unit,
-};
-
 static void upload_blend_constant_color(struct brw_context *brw)
 {
    struct gl_context *ctx = &brw->ctx;
diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h
index 68e2ef9..a01511f 100644
--- a/src/mesa/drivers/dri/i965/brw_state.h
+++ b/src/mesa/drivers/dri/i965/brw_state.h
@@ -42,7 +42,6 @@ extern "C" {
 enum intel_msaa_layout;
 
 extern const struct brw_tracked_state brw_blend_constant_color;
-extern const struct brw_tracked_state brw_cc_unit;
 extern const struct brw_tracked_state brw_clip_unit;
 extern const struct brw_tracked_state brw_vs_pull_constants;
 extern const struct brw_tracked_state brw_tcs_pull_constants;
diff --git a/src/mesa/drivers/dri/i965/brw_structs.h b/src/mesa/drivers/dri/i965/brw_structs.h
index 6d3f80d..12f3024 100644
--- a/src/mesa/drivers/dri/i965/brw_structs.h
+++ b/src/mesa/drivers/dri/i965/brw_structs.h
@@ -180,98 +180,6 @@ struct brw_clip_unit_state
    float viewport_ymax;
 };
 
-struct brw_cc_unit_state
-{
-   struct
-   {
-      unsigned pad0:3;
-      unsigned bf_stencil_pass_depth_pass_op:3;
-      unsigned bf_stencil_pass_depth_fail_op:3;
-      unsigned bf_stencil_fail_op:3;
-      unsigned bf_stencil_func:3;
-      unsigned bf_stencil_enable:1;
-      unsigned pad1:2;
-      unsigned stencil_write_enable:1;
-      unsigned stencil_pass_depth_pass_op:3;
-      unsigned stencil_pass_depth_fail_op:3;
-      unsigned stencil_fail_op:3;
-      unsigned stencil_func:3;
-      unsigned stencil_enable:1;
-   } cc0;
-
-
-   struct
-   {
-      unsigned bf_stencil_ref:8;
-      unsigned stencil_write_mask:8;
-      unsigned stencil_test_mask:8;
-      unsigned stencil_ref:8;
-   } cc1;
-
-
-   struct
-   {
-      unsigned logicop_enable:1;
-      unsigned pad0:10;
-      unsigned depth_write_enable:1;
-      unsigned depth_test_function:3;
-      unsigned depth_test:1;
-      unsigned bf_stencil_write_mask:8;
-      unsigned bf_stencil_test_mask:8;
-   } cc2;
-
-
-   struct
-   {
-      unsigned pad0:8;
-      unsigned alpha_test_func:3;
-      unsigned alpha_test:1;
-      unsigned blend_enable:1;
-      unsigned ia_blend_enable:1;
-      unsigned pad1:1;
-      unsigned alpha_test_format:1;
-      unsigned pad2:16;
-   } cc3;
-
-   struct
-   {
-      unsigned pad0:5;
-      unsigned cc_viewport_state_offset:27; /* Offset from GENERAL_STATE_BASE */
-   } cc4;
-
-   struct
-   {
-      unsigned pad0:2;
-      unsigned ia_dest_blend_factor:5;
-      unsigned ia_src_blend_factor:5;
-      unsigned ia_blend_function:3;
-      unsigned statistics_enable:1;
-      unsigned logicop_func:4;
-      unsigned pad1:11;
-      unsigned dither_enable:1;
-   } cc5;
-
-   struct
-   {
-      unsigned clamp_post_alpha_blend:1;
-      unsigned clamp_pre_alpha_blend:1;
-      unsigned clamp_range:2;
-      unsigned pad0:11;
-      unsigned y_dither_offset:2;
-      unsigned x_dither_offset:2;
-      unsigned dest_blend_factor:5;
-      unsigned src_blend_factor:5;
-      unsigned blend_function:3;
-   } cc6;
-
-   struct {
-      union {
-	 float f;
-	 uint8_t ub[4];
-      } alpha_ref;
-   } cc7;
-};
-
 struct brw_gs_unit_state
 {
    struct thread0 thread0;
diff --git a/src/mesa/drivers/dri/i965/brw_util.h b/src/mesa/drivers/dri/i965/brw_util.h
index 8142860..095c43a 100644
--- a/src/mesa/drivers/dri/i965/brw_util.h
+++ b/src/mesa/drivers/dri/i965/brw_util.h
@@ -38,7 +38,6 @@
 
 extern GLuint brw_translate_blend_factor( GLenum factor );
 extern GLuint brw_translate_blend_equation( GLenum mode );
-extern GLenum brw_fix_xRGB_alpha(GLenum function);
 
 static inline float
 brw_get_line_width(struct brw_context *brw)
diff --git a/src/mesa/drivers/dri/i965/genX_state_upload.c b/src/mesa/drivers/dri/i965/genX_state_upload.c
index 089596e..af85af2 100644
--- a/src/mesa/drivers/dri/i965/genX_state_upload.c
+++ b/src/mesa/drivers/dri/i965/genX_state_upload.c
@@ -1175,7 +1175,7 @@ set_depth_stencil_bits(struct brw_context *brw, DEPTH_STENCIL_GENXML *ds)
    struct gl_stencil_attrib *stencil = &ctx->Stencil;
    const int b = stencil->_BackFace;
 
-   if (depth->Test && depth_irb) {
+   if (depth->Test && (GEN_GEN <= 5 || depth_irb)) {
       ds->DepthTestEnable = true;
       ds->DepthBufferWriteEnable = brw_depth_writes_enabled(brw);
       ds->DepthTestFunction = intel_translate_compare_func(depth->Func);
@@ -1212,9 +1212,11 @@ set_depth_stencil_bits(struct brw_context *brw, DEPTH_STENCIL_GENXML *ds)
             intel_translate_stencil_op(stencil->ZFailFunc[b]);
       }
 
-#if GEN_GEN >= 9
+#if GEN_GEN <= 5 || GEN_GEN >= 9
       ds->StencilReferenceValue = _mesa_get_stencil_ref(ctx, 0);
-      ds->BackfaceStencilReferenceValue = _mesa_get_stencil_ref(ctx, b);
+      ds->BackfaceStencilReferenceValue =
+         GEN_GEN >= 9 || stencil->_TestTwoSide ?
+         _mesa_get_stencil_ref(ctx, b) : 0;
 #endif
    }
 }
@@ -2511,6 +2513,28 @@ static const struct brw_tracked_state genX(gs_state) = {
 #define blend_factor(x) brw_translate_blend_factor(x)
 #define blend_eqn(x) brw_translate_blend_equation(x)
 
+/**
+ * Modify blend function to force destination alpha to 1.0
+ *
+ * If \c function specifies a blend function that uses destination alpha,
+ * replace it with a function that hard-wires destination alpha to 1.0.  This
+ * is used when rendering to xRGB targets.
+ */
+static GLenum
+brw_fix_xRGB_alpha(GLenum function)
+{
+   switch (function) {
+   case GL_DST_ALPHA:
+      return GL_ONE;
+
+   case GL_ONE_MINUS_DST_ALPHA:
+   case GL_SRC_ALPHA_SATURATE:
+      return GL_ZERO;
+   }
+
+   return function;
+}
+
 #if GEN_GEN >= 6
 typedef struct GENX(BLEND_STATE_ENTRY) BLEND_ENTRY_GENXML;
 #else
@@ -2535,6 +2559,9 @@ set_blend_entry_bits(struct brw_context *brw, BLEND_ENTRY_GENXML *entry, int i)
     */
    const bool integer = ctx->DrawBuffer->_IntegerBuffers & (0x1 << i);
 
+   const unsigned blend_enabled = GEN_GEN >= 6 ?
+      ctx->Color.BlendEnabled & (1 << i) : ctx->Color.BlendEnabled;
+
    /* _NEW_COLOR */
    if (ctx->Color.ColorLogicOpEnabled) {
       GLenum rb_type = rb ? _mesa_get_format_datatype(rb->Format)
@@ -2550,8 +2577,8 @@ set_blend_entry_bits(struct brw_context *brw, BLEND_ENTRY_GENXML *entry, int i)
          entry->LogicOpFunction =
             intel_translate_logic_op(ctx->Color.LogicOp);
       }
-   } else if (ctx->Color.BlendEnabled & (1 << i) && !integer &&
-              !ctx->Color._AdvancedBlendMode) {
+   } else if (blend_enabled && !ctx->Color._AdvancedBlendMode
+              && (GEN_GEN <= 5 || !integer)) {
       GLenum eqRGB = ctx->Color.Blend[i].EquationRGB;
       GLenum eqA = ctx->Color.Blend[i].EquationA;
       GLenum srcRGB = ctx->Color.Blend[i].SrcRGB;
@@ -2974,17 +3001,40 @@ static const struct brw_tracked_state genX(multisample_state) = {
 
 /* ---------------------------------------------------------------------- */
 
-#if GEN_GEN >= 6
 static void
 genX(upload_color_calc_state)(struct brw_context *brw)
 {
    struct gl_context *ctx = &brw->ctx;
 
    brw_state_emit(brw, GENX(COLOR_CALC_STATE), 64, &brw->cc.state_offset, cc) {
+#if GEN_GEN <= 5
+      cc.IndependentAlphaBlendEnable =
+         set_blend_entry_bits(brw, &cc, 0);
+      set_depth_stencil_bits(brw, &cc);
+
+      if (ctx->Color.AlphaEnabled &&
+          ctx->DrawBuffer->_NumColorDrawBuffers <= 1) {
+         cc.AlphaTestEnable = true;
+         cc.AlphaTestFunction =
+            intel_translate_compare_func(ctx->Color.AlphaFunc);
+      }
+
+      if (ctx->Color.DitherFlag) {
+         cc.ColorDitherEnable = true;
+         cc.XDitherOffset = 0;
+         cc.YDitherOffset = 0;
+      }
+
+      cc.StatisticsEnable = brw->stats_wm;
+
+      cc.CCViewportStatePointer =
+         instruction_ro_bo(brw->batch.bo, brw->cc.vp_offset);
+#else
       /* _NEW_COLOR */
-      cc.AlphaTestFormat = ALPHATEST_UNORM8;
-      UNCLAMPED_FLOAT_TO_UBYTE(cc.AlphaReferenceValueAsUNORM8,
-                               ctx->Color.AlphaRef);
+      cc.BlendConstantColorRed = ctx->Color.BlendColorUnclamped[0];
+      cc.BlendConstantColorGreen = ctx->Color.BlendColorUnclamped[1];
+      cc.BlendConstantColorBlue = ctx->Color.BlendColorUnclamped[2];
+      cc.BlendConstantColorAlpha = ctx->Color.BlendColorUnclamped[3];
 
 #if GEN_GEN < 9
       /* _NEW_STENCIL */
@@ -2993,34 +3043,47 @@ genX(upload_color_calc_state)(struct brw_context *brw)
          _mesa_get_stencil_ref(ctx, ctx->Stencil._BackFace);
 #endif
 
+#endif
+
       /* _NEW_COLOR */
-      cc.BlendConstantColorRed = ctx->Color.BlendColorUnclamped[0];
-      cc.BlendConstantColorGreen = ctx->Color.BlendColorUnclamped[1];
-      cc.BlendConstantColorBlue = ctx->Color.BlendColorUnclamped[2];
-      cc.BlendConstantColorAlpha = ctx->Color.BlendColorUnclamped[3];
+      if (GEN_GEN >= 6 ||
+          (ctx->Color.AlphaEnabled &&
+           ctx->DrawBuffer->_NumColorDrawBuffers <= 1)) {
+         cc.AlphaTestFormat = ALPHATEST_UNORM8;
+         UNCLAMPED_FLOAT_TO_UBYTE(cc.AlphaReferenceValueAsUNORM8,
+                                  ctx->Color.AlphaRef);
+      }
    }
 
+#if GEN_GEN >= 6
    brw_batch_emit(brw, GENX(3DSTATE_CC_STATE_POINTERS), ptr) {
       ptr.ColorCalcStatePointer = brw->cc.state_offset;
 #if GEN_GEN != 7
       ptr.ColorCalcStatePointerValid = true;
 #endif
    }
+#endif
+
+   brw->ctx.NewDriverState |= GEN_GEN <= 5 ? BRW_NEW_GEN4_UNIT_STATE : 0;
 }
 
 static const struct brw_tracked_state genX(color_calc_state) = {
    .dirty = {
       .mesa = _NEW_COLOR |
-              _NEW_STENCIL,
+              _NEW_STENCIL |
+              (GEN_GEN <= 5 ? _NEW_BUFFERS |
+                              _NEW_DEPTH
+                            : 0),
       .brw = BRW_NEW_BATCH |
              BRW_NEW_BLORP |
-             BRW_NEW_CC_STATE |
-             BRW_NEW_STATE_BASE_ADDRESS,
+             (GEN_GEN <= 5 ? BRW_NEW_CC_VP |
+                             BRW_NEW_STATS_WM
+                           : BRW_NEW_CC_STATE |
+                             BRW_NEW_STATE_BASE_ADDRESS),
    },
    .emit = genX(upload_color_calc_state),
 };
 
-#endif
 
 /* ---------------------------------------------------------------------- */
 
@@ -4218,7 +4281,7 @@ genX(init_atoms)(struct brw_context *brw)
       &brw_recalculate_urb_fence,
 
       &genX(cc_vp),
-      &brw_cc_unit,
+      &genX(color_calc_state),
 
       /* Surface state setup.  Must come before the VS/WM unit.  The binding
        * table upload must be last.
-- 
2.9.3



More information about the mesa-dev mailing list