i965: Use immediate float operands for some VS instructions.
[mesa.git] / src / mesa / drivers / dri / i965 / brw_cc.c
index fa8121e02d3c44de83cf0d86f0f30e50abdaa2fb..fa2d394b2222012a58c329358901572f99078c4d 100644 (file)
 #include "brw_defines.h"
 #include "brw_util.h"
 #include "main/macros.h"
-#include "main/enums.h"
 
 static void prepare_cc_vp( struct brw_context *brw )
 {
+   GLcontext *ctx = &brw->intel.ctx;
    struct brw_cc_viewport ccv;
 
    memset(&ccv, 0, sizeof(ccv));
 
-   ccv.min_depth = 0.0;
-   ccv.max_depth = 1.0;
+   /* _NEW_TRANSOFORM */
+   if (ctx->Transform.DepthClamp) {
+      /* _NEW_VIEWPORT */
+      ccv.min_depth = MIN2(ctx->Viewport.Near, ctx->Viewport.Far);
+      ccv.max_depth = MAX2(ctx->Viewport.Near, ctx->Viewport.Far);
+   } else {
+      ccv.min_depth = 0.0;
+      ccv.max_depth = 1.0;
+   }
 
    dri_bo_unreference(brw->cc.vp_bo);
-   brw->cc.vp_bo = brw_cache_data( &brw->cache, BRW_CC_VP, &ccv, NULL, 0 );
+   brw->cc.vp_bo = brw_cache_data(&brw->cache, BRW_CC_VP, &ccv, sizeof(ccv),
+                                 NULL, 0);
 }
 
 const struct brw_tracked_state brw_cc_vp = {
    .dirty = {
-      .mesa = 0,
+      .mesa = _NEW_VIEWPORT | _NEW_TRANSFORM,
       .brw = BRW_NEW_CONTEXT,
       .cache = 0
    },
@@ -80,62 +88,96 @@ struct brw_cc_unit_key {
    GLenum depth_func;
 };
 
+/**
+ * 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
+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;
+}
+
 static void
 cc_unit_populate_key(struct brw_context *brw, struct brw_cc_unit_key *key)
 {
-   struct gl_stencil_attrib *stencil = brw->attribs.Stencil;
+   GLcontext *ctx = &brw->intel.ctx;
+   const unsigned back = ctx->Stencil._BackFace;
 
    memset(key, 0, sizeof(*key));
 
-   key->stencil = stencil->Enabled;
-   key->stencil_two_side = stencil->_TestTwoSide;
+   key->stencil = ctx->Stencil._Enabled;
+   key->stencil_two_side = ctx->Stencil._TestTwoSide;
 
    if (key->stencil) {
-      key->stencil_func[0] = stencil->Function[0];
-      key->stencil_fail_op[0] = stencil->FailFunc[0];
-      key->stencil_pass_depth_fail_op[0] = stencil->ZFailFunc[0];
-      key->stencil_pass_depth_pass_op[0] = stencil->ZPassFunc[0];
-      key->stencil_ref[0] = stencil->Ref[0];
-      key->stencil_write_mask[0] = stencil->WriteMask[0];
-      key->stencil_test_mask[0] = stencil->ValueMask[0];
+      key->stencil_func[0] = ctx->Stencil.Function[0];
+      key->stencil_fail_op[0] = ctx->Stencil.FailFunc[0];
+      key->stencil_pass_depth_fail_op[0] = ctx->Stencil.ZFailFunc[0];
+      key->stencil_pass_depth_pass_op[0] = ctx->Stencil.ZPassFunc[0];
+      key->stencil_ref[0] = ctx->Stencil.Ref[0];
+      key->stencil_write_mask[0] = ctx->Stencil.WriteMask[0];
+      key->stencil_test_mask[0] = ctx->Stencil.ValueMask[0];
    }
    if (key->stencil_two_side) {
-      key->stencil_func[1] = stencil->Function[1];
-      key->stencil_fail_op[1] = stencil->FailFunc[1];
-      key->stencil_pass_depth_fail_op[1] = stencil->ZFailFunc[1];
-      key->stencil_pass_depth_pass_op[1] = stencil->ZPassFunc[1];
-      key->stencil_ref[1] = stencil->Ref[1];
-      key->stencil_write_mask[1] = stencil->WriteMask[1];
-      key->stencil_test_mask[1] = stencil->ValueMask[1];
+      key->stencil_func[1] = ctx->Stencil.Function[back];
+      key->stencil_fail_op[1] = ctx->Stencil.FailFunc[back];
+      key->stencil_pass_depth_fail_op[1] = ctx->Stencil.ZFailFunc[back];
+      key->stencil_pass_depth_pass_op[1] = ctx->Stencil.ZPassFunc[back];
+      key->stencil_ref[1] = ctx->Stencil.Ref[back];
+      key->stencil_write_mask[1] = ctx->Stencil.WriteMask[back];
+      key->stencil_test_mask[1] = ctx->Stencil.ValueMask[back];
    }
 
-   if (brw->attribs.Color->_LogicOpEnabled)
-      key->logic_op = brw->attribs.Color->LogicOp;
+   if (ctx->Color._LogicOpEnabled)
+      key->logic_op = ctx->Color.LogicOp;
    else
       key->logic_op = GL_COPY;
 
-   key->color_blend = brw->attribs.Color->BlendEnabled;
+   key->color_blend = ctx->Color.BlendEnabled;
    if (key->color_blend) {
-      key->blend_eq_rgb = brw->attribs.Color->BlendEquationRGB;
-      key->blend_eq_a = brw->attribs.Color->BlendEquationA;
-      key->blend_src_rgb = brw->attribs.Color->BlendSrcRGB;
-      key->blend_dst_rgb = brw->attribs.Color->BlendDstRGB;
-      key->blend_src_a = brw->attribs.Color->BlendSrcA;
-      key->blend_dst_a = brw->attribs.Color->BlendDstA;
+      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;
+
+      /* 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.
+       */
+      if (ctx->DrawBuffer->Visual.alphaBits == 0) {
+        key->blend_src_rgb = fix_xRGB_alpha(key->blend_src_rgb);
+        key->blend_src_a   = fix_xRGB_alpha(key->blend_src_a);
+        key->blend_dst_rgb = fix_xRGB_alpha(key->blend_dst_rgb);
+        key->blend_dst_a   = fix_xRGB_alpha(key->blend_dst_a);
+      }
    }
 
-   key->alpha_enabled = brw->attribs.Color->AlphaEnabled;
+   key->alpha_enabled = ctx->Color.AlphaEnabled;
    if (key->alpha_enabled) {
-      key->alpha_func = brw->attribs.Color->AlphaFunc;
-      key->alpha_ref = brw->attribs.Color->AlphaRef;
+      key->alpha_func = ctx->Color.AlphaFunc;
+      key->alpha_ref = ctx->Color.AlphaRef;
    }
 
-   key->dither = brw->attribs.Color->DitherFlag;
+   key->dither = ctx->Color.DitherFlag;
 
-   key->depth_test = brw->attribs.Depth->Test;
+   key->depth_test = ctx->Depth.Test;
    if (key->depth_test) {
-      key->depth_func = brw->attribs.Depth->Func;
-      key->depth_write = brw->attribs.Depth->Mask;
+      key->depth_func = ctx->Depth.Func;
+      key->depth_write = ctx->Depth.Mask;
    }
 }
 
@@ -251,8 +293,7 @@ cc_unit_create_from_key(struct brw_context *brw, struct brw_cc_unit_key *key)
    bo = brw_upload_cache(&brw->cache, BRW_CC_UNIT,
                         key, sizeof(*key),
                         &brw->cc.vp_bo, 1,
-                        &cc, sizeof(cc),
-                        NULL, NULL);
+                        &cc, sizeof(cc));
 
    /* Emit CC viewport relocation */
    dri_bo_emit_reloc(bo,