mesa: begin implementation of GL_ARB_draw_buffers_blend
[mesa.git] / src / mesa / drivers / dri / i965 / gen6_cc.c
index ba1e3abe83ec206c35958ee7d7dc2963973ad099..f51afa40716d4675038775fc4ad84d54070289d5 100644 (file)
 #include "brw_util.h"
 #include "intel_batchbuffer.h"
 #include "main/macros.h"
-#include "main/enums.h"
 
-struct brw_blend_state_key {
+struct gen6_blend_state_key {
    GLboolean color_blend, alpha_enabled;
+   GLboolean dither;
+   GLboolean color_mask[BRW_MAX_DRAW_BUFFERS][4];
 
    GLenum logic_op;
 
@@ -43,18 +44,19 @@ struct brw_blend_state_key {
    GLenum blend_dst_rgb, blend_dst_a;
 
    GLenum alpha_func;
-
-   GLboolean dither;
 };
 
 static void
 blend_state_populate_key(struct brw_context *brw,
-                        struct brw_blend_state_key *key)
+                        struct gen6_blend_state_key *key)
 {
-   GLcontext *ctx = &brw->intel.ctx;
+   struct gl_context *ctx = &brw->intel.ctx;
 
    memset(key, 0, sizeof(*key));
 
+   /* _NEW_COLOR */
+   memcpy(key->color_mask, ctx->Color.ColorMask, sizeof(key->color_mask));
+
    /* _NEW_COLOR */
    if (ctx->Color._LogicOpEnabled)
       key->logic_op = ctx->Color.LogicOp;
@@ -64,12 +66,12 @@ blend_state_populate_key(struct brw_context *brw,
    /* _NEW_COLOR */
    key->color_blend = ctx->Color.BlendEnabled;
    if (key->color_blend) {
-      key->blend_eq_rgb = ctx->Color.BlendEquationRGB;
-      key->blend_eq_a = ctx->Color.BlendEquationA;
-      key->blend_src_rgb = ctx->Color.BlendSrcRGB;
-      key->blend_dst_rgb = ctx->Color.BlendDstRGB;
-      key->blend_src_a = ctx->Color.BlendSrcA;
-      key->blend_dst_a = ctx->Color.BlendDstA;
+      key->blend_eq_rgb = ctx->Color.Blend[0].EquationRGB;
+      key->blend_eq_a = ctx->Color.Blend[0].EquationA;
+      key->blend_src_rgb = ctx->Color.Blend[0].SrcRGB;
+      key->blend_dst_rgb = ctx->Color.Blend[0].DstRGB;
+      key->blend_src_a = ctx->Color.Blend[0].SrcA;
+      key->blend_dst_a = ctx->Color.Blend[0].DstA;
    }
 
    /* _NEW_COLOR */
@@ -87,56 +89,64 @@ blend_state_populate_key(struct brw_context *brw,
  */
 static drm_intel_bo *
 blend_state_create_from_key(struct brw_context *brw,
-                           struct brw_blend_state_key *key)
+                           struct gen6_blend_state_key *key)
 {
-   struct gen6_blend_state blend;
+   struct gen6_blend_state blend[BRW_MAX_DRAW_BUFFERS];
    drm_intel_bo *bo;
+   int b;
 
    memset(&blend, 0, sizeof(blend));
 
-   if (key->logic_op != GL_COPY) {
-      blend.blend1.logic_op_enable = 1;
-      blend.blend1.logic_op_func = intel_translate_logic_op(key->logic_op);
-   } else if (key->color_blend) {
-      GLenum eqRGB = key->blend_eq_rgb;
-      GLenum eqA = key->blend_eq_a;
-      GLenum srcRGB = key->blend_src_rgb;
-      GLenum dstRGB = key->blend_dst_rgb;
-      GLenum srcA = key->blend_src_a;
-      GLenum dstA = key->blend_dst_a;
-
-      if (eqRGB == GL_MIN || eqRGB == GL_MAX) {
-        srcRGB = dstRGB = GL_ONE;
+   for (b = 0; b < BRW_MAX_DRAW_BUFFERS; b++) {
+      if (key->logic_op != GL_COPY) {
+        blend[b].blend1.logic_op_enable = 1;
+        blend[b].blend1.logic_op_func = intel_translate_logic_op(key->logic_op);
+      } else if (key->color_blend & (1 << b)) {
+        GLenum eqRGB = key->blend_eq_rgb;
+        GLenum eqA = key->blend_eq_a;
+        GLenum srcRGB = key->blend_src_rgb;
+        GLenum dstRGB = key->blend_dst_rgb;
+        GLenum srcA = key->blend_src_a;
+        GLenum dstA = key->blend_dst_a;
+
+        if (eqRGB == GL_MIN || eqRGB == GL_MAX) {
+           srcRGB = dstRGB = GL_ONE;
+        }
+
+        if (eqA == GL_MIN || eqA == GL_MAX) {
+           srcA = dstA = GL_ONE;
+        }
+
+        blend[b].blend0.dest_blend_factor = brw_translate_blend_factor(dstRGB);
+        blend[b].blend0.source_blend_factor = brw_translate_blend_factor(srcRGB);
+        blend[b].blend0.blend_func = brw_translate_blend_equation(eqRGB);
+
+        blend[b].blend0.ia_dest_blend_factor = brw_translate_blend_factor(dstA);
+        blend[b].blend0.ia_source_blend_factor = brw_translate_blend_factor(srcA);
+        blend[b].blend0.ia_blend_func = brw_translate_blend_equation(eqA);
+
+        blend[b].blend0.blend_enable = 1;
+        blend[b].blend0.ia_blend_enable = (srcA != srcRGB ||
+                                        dstA != dstRGB ||
+                                        eqA != eqRGB);
       }
 
-      if (eqA == GL_MIN || eqA == GL_MAX) {
-        srcA = dstA = GL_ONE;
-      }
-
-      blend.blend0.dest_blend_factor = brw_translate_blend_factor(dstRGB);
-      blend.blend0.source_blend_factor = brw_translate_blend_factor(srcRGB);
-      blend.blend0.blend_func = brw_translate_blend_equation(eqRGB);
-
-      blend.blend0.ia_dest_blend_factor = brw_translate_blend_factor(dstA);
-      blend.blend0.ia_source_blend_factor = brw_translate_blend_factor(srcA);
-      blend.blend0.ia_blend_func = brw_translate_blend_equation(eqA);
-
-      blend.blend0.blend_enable = 1;
-      blend.blend0.ia_blend_enable = (srcA != srcRGB ||
-                                     dstA != dstRGB ||
-                                     eqA != eqRGB);
-   }
+      if (key->alpha_enabled) {
+        blend[b].blend1.alpha_test_enable = 1;
+        blend[b].blend1.alpha_test_func = intel_translate_compare_func(key->alpha_func);
 
-   if (key->alpha_enabled) {
-      blend.blend1.alpha_test_enable = 1;
-      blend.blend1.alpha_test_func = intel_translate_compare_func(key->alpha_func);
+      }
 
-   }
+      if (key->dither) {
+        blend[b].blend1.dither_enable = 1;
+        blend[b].blend1.y_dither_offset = 0;
+        blend[b].blend1.x_dither_offset = 0;
+      }
 
-   if (key->dither) {
-      blend.blend1.dither_enable = 1;
-      blend.blend1.y_dither_offset = 0;
-      blend.blend1.x_dither_offset = 0;
+      blend[b].blend1.write_disable_r = !key->color_mask[b][0];
+      blend[b].blend1.write_disable_g = !key->color_mask[b][1];
+      blend[b].blend1.write_disable_b = !key->color_mask[b][2];
+      blend[b].blend1.write_disable_a = !key->color_mask[b][3];
    }
 
    bo = brw_upload_cache(&brw->cache, BRW_BLEND_STATE,
@@ -150,7 +160,7 @@ blend_state_create_from_key(struct brw_context *brw,
 static void
 prepare_blend_state(struct brw_context *brw)
 {
-   struct brw_blend_state_key key;
+   struct gen6_blend_state_key key;
 
    blend_state_populate_key(brw, &key);
 
@@ -173,17 +183,17 @@ const struct brw_tracked_state gen6_blend_state = {
    .prepare = prepare_blend_state,
 };
 
-struct brw_color_calc_state_key {
-   GLubyte blend_constant_color[4];
+struct gen6_color_calc_state_key {
+   float blend_constant_color[4];
    GLclampf alpha_ref;
    GLubyte stencil_ref[2];
 };
 
 static void
 color_calc_state_populate_key(struct brw_context *brw,
-                             struct brw_color_calc_state_key *key)
+                             struct gen6_color_calc_state_key *key)
 {
-   GLcontext *ctx = &brw->intel.ctx;
+   struct gl_context *ctx = &brw->intel.ctx;
 
    memset(key, 0, sizeof(*key));
 
@@ -211,7 +221,7 @@ color_calc_state_populate_key(struct brw_context *brw,
  */
 static drm_intel_bo *
 color_calc_state_create_from_key(struct brw_context *brw,
-                                struct brw_color_calc_state_key *key)
+                                struct gen6_color_calc_state_key *key)
 {
    struct gen6_color_calc_state cc;
    drm_intel_bo *bo;
@@ -240,7 +250,7 @@ color_calc_state_create_from_key(struct brw_context *brw,
 static void
 prepare_color_calc_state(struct brw_context *brw)
 {
-   struct brw_color_calc_state_key key;
+   struct gen6_color_calc_state_key key;
 
    color_calc_state_populate_key(brw, &key);
 
@@ -256,7 +266,7 @@ prepare_color_calc_state(struct brw_context *brw)
 
 const struct brw_tracked_state gen6_color_calc_state = {
    .dirty = {
-      .mesa = _NEW_COLOR,
+      .mesa = _NEW_COLOR | _NEW_STENCIL,
       .brw = 0,
       .cache = 0,
    },
@@ -268,13 +278,11 @@ static void upload_cc_state_pointers(struct brw_context *brw)
    struct intel_context *intel = &brw->intel;
 
    BEGIN_BATCH(4);
-   OUT_BATCH(CMD_3D_CC_STATE_POINTERS << 16 | (4 - 2));
-   OUT_RELOC(brw->cc.state_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 1);
+   OUT_BATCH(_3DSTATE_CC_STATE_POINTERS << 16 | (4 - 2));
    OUT_RELOC(brw->cc.blend_state_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 1);
    OUT_RELOC(brw->cc.depth_stencil_state_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 1);
+   OUT_RELOC(brw->cc.state_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 1);
    ADVANCE_BATCH();
-
-   intel_batchbuffer_emit_mi_flush(intel->batch);
 }