i915: Only flag context changes if the actual state is changed
[mesa.git] / src / mesa / drivers / dri / i915 / i915_state.c
index 9d7a9e1dfeaa72822d19f727a6db401019b8a393..0cddf82a40a19c0b9bc120dbc540703aad98e423 100644 (file)
@@ -49,7 +49,7 @@
 #define FILE_DEBUG_FLAG DEBUG_STATE
 
 void
-i915_update_stencil(GLcontext * ctx)
+i915_update_stencil(struct gl_context * ctx)
 {
    struct i915_context *i915 = I915_CONTEXT(ctx);
    GLuint front_ref, front_writemask, front_mask;
@@ -147,37 +147,40 @@ i915_update_stencil(GLcontext * ctx)
 }
 
 static void
-i915StencilFuncSeparate(GLcontext * ctx, GLenum face, GLenum func, GLint ref,
+i915StencilFuncSeparate(struct gl_context * ctx, GLenum face, GLenum func, GLint ref,
                         GLuint mask)
 {
 }
 
 static void
-i915StencilMaskSeparate(GLcontext * ctx, GLenum face, GLuint mask)
+i915StencilMaskSeparate(struct gl_context * ctx, GLenum face, GLuint mask)
 {
 }
 
 static void
-i915StencilOpSeparate(GLcontext * ctx, GLenum face, GLenum fail, GLenum zfail,
+i915StencilOpSeparate(struct gl_context * ctx, GLenum face, GLenum fail, GLenum zfail,
                       GLenum zpass)
 {
 }
 
 static void
-i915AlphaFunc(GLcontext * ctx, GLenum func, GLfloat ref)
+i915AlphaFunc(struct gl_context * ctx, GLenum func, GLfloat ref)
 {
    struct i915_context *i915 = I915_CONTEXT(ctx);
    int test = intel_translate_compare_func(func);
    GLubyte refByte;
+   GLuint dw;
 
    UNCLAMPED_FLOAT_TO_UBYTE(refByte, ref);
 
-   I915_STATECHANGE(i915, I915_UPLOAD_CTX);
-   i915->state.Ctx[I915_CTXREG_LIS6] &= ~(S6_ALPHA_TEST_FUNC_MASK |
-                                          S6_ALPHA_REF_MASK);
-   i915->state.Ctx[I915_CTXREG_LIS6] |= ((test << S6_ALPHA_TEST_FUNC_SHIFT) |
-                                         (((GLuint) refByte) <<
-                                          S6_ALPHA_REF_SHIFT));
+   dw = i915->state.Ctx[I915_CTXREG_LIS6];
+   dw &= ~(S6_ALPHA_TEST_FUNC_MASK | S6_ALPHA_REF_MASK);
+   dw |= ((test << S6_ALPHA_TEST_FUNC_SHIFT) |
+         (((GLuint) refByte) << S6_ALPHA_REF_SHIFT));
+   if (dw != i915->state.Ctx[I915_CTXREG_LIS6]) {
+      i915->state.Ctx[I915_CTXREG_LIS6] = dw;
+      I915_STATECHANGE(i915, I915_UPLOAD_CTX);
+   }
 }
 
 /* This function makes sure that the proper enables are
@@ -187,33 +190,43 @@ i915AlphaFunc(GLcontext * ctx, GLenum func, GLfloat ref)
  * calls to glEnable.
  */
 static void
-i915EvalLogicOpBlendState(GLcontext * ctx)
+i915EvalLogicOpBlendState(struct gl_context * ctx)
 {
    struct i915_context *i915 = I915_CONTEXT(ctx);
+   GLuint dw0, dw1;
 
-   I915_STATECHANGE(i915, I915_UPLOAD_CTX);
+   dw0 = i915->state.Ctx[I915_CTXREG_LIS5];
+   dw1 = i915->state.Ctx[I915_CTXREG_LIS6];
 
    if (RGBA_LOGICOP_ENABLED(ctx)) {
-      i915->state.Ctx[I915_CTXREG_LIS5] |= S5_LOGICOP_ENABLE;
-      i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_CBUF_BLEND_ENABLE;
+      dw0 |= S5_LOGICOP_ENABLE;
+      dw1 &= ~S6_CBUF_BLEND_ENABLE;
    }
    else {
-      i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_LOGICOP_ENABLE;
+      dw0 &= ~S5_LOGICOP_ENABLE;
 
       if (ctx->Color.BlendEnabled) {
-         i915->state.Ctx[I915_CTXREG_LIS6] |= S6_CBUF_BLEND_ENABLE;
+         dw1 |= S6_CBUF_BLEND_ENABLE;
       }
       else {
-         i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_CBUF_BLEND_ENABLE;
+         dw1 &= ~S6_CBUF_BLEND_ENABLE;
       }
    }
+   if (dw0 != i915->state.Ctx[I915_CTXREG_LIS5] ||
+       dw1 != i915->state.Ctx[I915_CTXREG_LIS6]) {
+      i915->state.Ctx[I915_CTXREG_LIS5] = dw0;
+      i915->state.Ctx[I915_CTXREG_LIS6] = dw1;
+
+      I915_STATECHANGE(i915, I915_UPLOAD_CTX);
+   }
 }
 
 static void
-i915BlendColor(GLcontext * ctx, const GLfloat color[4])
+i915BlendColor(struct gl_context * ctx, const GLfloat color[4])
 {
    struct i915_context *i915 = I915_CONTEXT(ctx);
    GLubyte r, g, b, a;
+   GLuint dw;
 
    DBG("%s\n", __FUNCTION__);
    
@@ -222,9 +235,11 @@ i915BlendColor(GLcontext * ctx, const GLfloat color[4])
    UNCLAMPED_FLOAT_TO_UBYTE(b, color[BCOMP]);
    UNCLAMPED_FLOAT_TO_UBYTE(a, color[ACOMP]);
 
-   I915_STATECHANGE(i915, I915_UPLOAD_CTX);
-   i915->state.Ctx[I915_CTXREG_BLENDCOLOR1] =
-      (a << 24) | (r << 16) | (g << 8) | b;
+   dw = (a << 24) | (r << 16) | (g << 8) | b;
+   if (dw != i915->state.Ctx[I915_CTXREG_BLENDCOLOR1]) {
+      I915_STATECHANGE(i915, I915_UPLOAD_CTX);
+      i915->state.Ctx[I915_CTXREG_BLENDCOLOR1] = dw
+   }
 }
 
 
@@ -255,7 +270,7 @@ translate_blend_equation(GLenum mode)
 }
 
 static void
-i915UpdateBlendState(GLcontext * ctx)
+i915UpdateBlendState(struct gl_context * ctx)
 {
    struct i915_context *i915 = I915_CONTEXT(ctx);
    GLuint iab = (i915->state.Ctx[I915_CTXREG_IAB] &
@@ -267,12 +282,12 @@ i915UpdateBlendState(GLcontext * ctx)
                   ~(S6_CBUF_SRC_BLEND_FACT_MASK |
                     S6_CBUF_DST_BLEND_FACT_MASK | S6_CBUF_BLEND_FUNC_MASK));
 
-   GLuint eqRGB = ctx->Color.BlendEquationRGB;
-   GLuint eqA = ctx->Color.BlendEquationA;
-   GLuint srcRGB = ctx->Color.BlendSrcRGB;
-   GLuint dstRGB = ctx->Color.BlendDstRGB;
-   GLuint srcA = ctx->Color.BlendSrcA;
-   GLuint dstA = ctx->Color.BlendDstA;
+   GLuint eqRGB = ctx->Color.Blend[0].EquationRGB;
+   GLuint eqA = ctx->Color.Blend[0].EquationA;
+   GLuint srcRGB = ctx->Color.Blend[0].SrcRGB;
+   GLuint dstRGB = ctx->Color.Blend[0].DstRGB;
+   GLuint srcA = ctx->Color.Blend[0].SrcA;
+   GLuint dstA = ctx->Color.Blend[0].DstA;
 
    if (eqRGB == GL_MIN || eqRGB == GL_MAX) {
       srcRGB = dstRGB = GL_ONE;
@@ -306,7 +321,7 @@ i915UpdateBlendState(GLcontext * ctx)
 
 
 static void
-i915BlendFuncSeparate(GLcontext * ctx, GLenum srcRGB,
+i915BlendFuncSeparate(struct gl_context * ctx, GLenum srcRGB,
                       GLenum dstRGB, GLenum srcA, GLenum dstA)
 {
    i915UpdateBlendState(ctx);
@@ -314,38 +329,47 @@ i915BlendFuncSeparate(GLcontext * ctx, GLenum srcRGB,
 
 
 static void
-i915BlendEquationSeparate(GLcontext * ctx, GLenum eqRGB, GLenum eqA)
+i915BlendEquationSeparate(struct gl_context * ctx, GLenum eqRGB, GLenum eqA)
 {
    i915UpdateBlendState(ctx);
 }
 
 
 static void
-i915DepthFunc(GLcontext * ctx, GLenum func)
+i915DepthFunc(struct gl_context * ctx, GLenum func)
 {
    struct i915_context *i915 = I915_CONTEXT(ctx);
    int test = intel_translate_compare_func(func);
+   GLuint dw;
 
    DBG("%s\n", __FUNCTION__);
    
-   I915_STATECHANGE(i915, I915_UPLOAD_CTX);
-   i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_TEST_FUNC_MASK;
-   i915->state.Ctx[I915_CTXREG_LIS6] |= test << S6_DEPTH_TEST_FUNC_SHIFT;
+   dw = i915->state.Ctx[I915_CTXREG_LIS6];
+   dw &= ~S6_DEPTH_TEST_FUNC_MASK;
+   dw |= test << S6_DEPTH_TEST_FUNC_SHIFT;
+   if (dw != i915->state.Ctx[I915_CTXREG_LIS6]) {
+      I915_STATECHANGE(i915, I915_UPLOAD_CTX);
+      i915->state.Ctx[I915_CTXREG_LIS6] = dw;
+   }
 }
 
 static void
-i915DepthMask(GLcontext * ctx, GLboolean flag)
+i915DepthMask(struct gl_context * ctx, GLboolean flag)
 {
    struct i915_context *i915 = I915_CONTEXT(ctx);
+   GLuint dw;
 
    DBG("%s flag (%d)\n", __FUNCTION__, flag);
-   
-   I915_STATECHANGE(i915, I915_UPLOAD_CTX);
 
+   dw = i915->state.Ctx[I915_CTXREG_LIS6];
    if (flag && ctx->Depth.Test)
-      i915->state.Ctx[I915_CTXREG_LIS6] |= S6_DEPTH_WRITE_ENABLE;
+      dw |= S6_DEPTH_WRITE_ENABLE;
    else
-      i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_WRITE_ENABLE;
+      dw &= ~S6_DEPTH_WRITE_ENABLE;
+   if (dw != i915->state.Ctx[I915_CTXREG_LIS6]) {
+      I915_STATECHANGE(i915, I915_UPLOAD_CTX);
+      i915->state.Ctx[I915_CTXREG_LIS6] = dw;
+   }
 }
 
 
@@ -357,7 +381,7 @@ i915DepthMask(GLcontext * ctx, GLboolean flag)
  *  - window pos/size or FBO size
  */
 void
-intelCalcViewport(GLcontext * ctx)
+intelCalcViewport(struct gl_context * ctx)
 {
    struct intel_context *intel = intel_context(ctx);
    const GLfloat *v = ctx->Viewport._WindowMap.m;
@@ -374,7 +398,7 @@ intelCalcViewport(GLcontext * ctx)
    else {
       /* window buffer, y=0=top */
       yScale = -1.0;
-      yBias = (intel->driDrawable) ? intel->driDrawable->h : 0.0F;
+      yBias = ctx->DrawBuffer->Height;
    }
 
    m[MAT_SX] = v[MAT_SX];
@@ -390,18 +414,16 @@ intelCalcViewport(GLcontext * ctx)
 
 /** Called from ctx->Driver.Viewport() */
 static void
-i915Viewport(GLcontext * ctx,
+i915Viewport(struct gl_context * ctx,
               GLint x, GLint y, GLsizei width, GLsizei height)
 {
    intelCalcViewport(ctx);
-
-   intel_viewport(ctx, x, y, width, height);
 }
 
 
 /** Called from ctx->Driver.DepthRange() */
 static void
-i915DepthRange(GLcontext * ctx, GLclampd nearval, GLclampd farval)
+i915DepthRange(struct gl_context * ctx, GLclampd nearval, GLclampd farval)
 {
    intelCalcViewport(ctx);
 }
@@ -414,7 +436,7 @@ i915DepthRange(GLcontext * ctx, GLclampd nearval, GLclampd farval)
  * Fortunately stipple is usually a repeating pattern.
  */
 static void
-i915PolygonStipple(GLcontext * ctx, const GLubyte * mask)
+i915PolygonStipple(struct gl_context * ctx, const GLubyte * mask)
 {
    struct i915_context *i915 = I915_CONTEXT(ctx);
    const GLubyte *m;
@@ -476,7 +498,7 @@ i915PolygonStipple(GLcontext * ctx, const GLubyte * mask)
  * Hardware clipping
  */
 static void
-i915Scissor(GLcontext * ctx, GLint x, GLint y, GLsizei w, GLsizei h)
+i915Scissor(struct gl_context * ctx, GLint x, GLint y, GLsizei w, GLsizei h)
 {
    struct i915_context *i915 = I915_CONTEXT(ctx);
    int x1, y1, x2, y2;
@@ -516,7 +538,7 @@ i915Scissor(GLcontext * ctx, GLint x, GLint y, GLsizei w, GLsizei h)
 }
 
 static void
-i915LogicOp(GLcontext * ctx, GLenum opcode)
+i915LogicOp(struct gl_context * ctx, GLenum opcode)
 {
    struct i915_context *i915 = I915_CONTEXT(ctx);
    int tmp = intel_translate_logic_op(opcode);
@@ -531,10 +553,10 @@ i915LogicOp(GLcontext * ctx, GLenum opcode)
 
 
 static void
-i915CullFaceFrontFace(GLcontext * ctx, GLenum unused)
+i915CullFaceFrontFace(struct gl_context * ctx, GLenum unused)
 {
    struct i915_context *i915 = I915_CONTEXT(ctx);
-   GLuint mode;
+   GLuint mode, dw;
 
    DBG("%s %d\n", __FUNCTION__,
        ctx->DrawBuffer ? ctx->DrawBuffer->Name : 0);
@@ -556,13 +578,17 @@ i915CullFaceFrontFace(GLcontext * ctx, GLenum unused)
       mode = S4_CULLMODE_BOTH;
    }
 
-   I915_STATECHANGE(i915, I915_UPLOAD_CTX);
-   i915->state.Ctx[I915_CTXREG_LIS4] &= ~S4_CULLMODE_MASK;
-   i915->state.Ctx[I915_CTXREG_LIS4] |= mode;
+   dw = i915->state.Ctx[I915_CTXREG_LIS4];
+   dw &= ~S4_CULLMODE_MASK;
+   dw |= mode;
+   if (dw != i915->state.Ctx[I915_CTXREG_LIS4]) {
+      i915->state.Ctx[I915_CTXREG_LIS4] = dw;
+      I915_STATECHANGE(i915, I915_UPLOAD_CTX);
+   }
 }
 
 static void
-i915LineWidth(GLcontext * ctx, GLfloat widthf)
+i915LineWidth(struct gl_context * ctx, GLfloat widthf)
 {
    struct i915_context *i915 = I915_CONTEXT(ctx);
    int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_LINE_WIDTH_MASK;
@@ -581,7 +607,7 @@ i915LineWidth(GLcontext * ctx, GLfloat widthf)
 }
 
 static void
-i915PointSize(GLcontext * ctx, GLfloat size)
+i915PointSize(struct gl_context * ctx, GLfloat size)
 {
    struct i915_context *i915 = I915_CONTEXT(ctx);
    int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_POINT_WIDTH_MASK;
@@ -600,7 +626,7 @@ i915PointSize(GLcontext * ctx, GLfloat size)
 
 
 static void
-i915PointParameterfv(GLcontext * ctx, GLenum pname, const GLfloat *params)
+i915PointParameterfv(struct gl_context * ctx, GLenum pname, const GLfloat *params)
 {
    struct i915_context *i915 = I915_CONTEXT(ctx);
 
@@ -622,7 +648,7 @@ i915PointParameterfv(GLcontext * ctx, GLenum pname, const GLfloat *params)
  */
 
 static void
-i915ColorMask(GLcontext * ctx,
+i915ColorMask(struct gl_context * ctx,
               GLboolean r, GLboolean g, GLboolean b, GLboolean a)
 {
    struct i915_context *i915 = I915_CONTEXT(ctx);
@@ -647,7 +673,7 @@ i915ColorMask(GLcontext * ctx,
 }
 
 static void
-update_specular(GLcontext * ctx)
+update_specular(struct gl_context * ctx)
 {
    /* A hack to trigger the rebuild of the fragment program.
     */
@@ -655,7 +681,7 @@ update_specular(GLcontext * ctx)
 }
 
 static void
-i915LightModelfv(GLcontext * ctx, GLenum pname, const GLfloat * param)
+i915LightModelfv(struct gl_context * ctx, GLenum pname, const GLfloat * param)
 {
    DBG("%s\n", __FUNCTION__);
    
@@ -665,7 +691,7 @@ i915LightModelfv(GLcontext * ctx, GLenum pname, const GLfloat * param)
 }
 
 static void
-i915ShadeModel(GLcontext * ctx, GLenum mode)
+i915ShadeModel(struct gl_context * ctx, GLenum mode)
 {
    struct i915_context *i915 = I915_CONTEXT(ctx);
    I915_STATECHANGE(i915, I915_UPLOAD_CTX);
@@ -686,12 +712,13 @@ i915ShadeModel(GLcontext * ctx, GLenum mode)
  * Fog
  */
 void
-i915_update_fog(GLcontext * ctx)
+i915_update_fog(struct gl_context * ctx)
 {
    struct i915_context *i915 = I915_CONTEXT(ctx);
    GLenum mode;
    GLboolean enabled;
    GLboolean try_pixel_fog;
+   GLuint dw;
 
    if (ctx->FragmentProgram._Current) {
       /* Pull in static fog state from program */
@@ -767,12 +794,16 @@ i915_update_fog(GLcontext * ctx)
       i915->vertex_fog = I915_FOG_VERTEX;
    }
 
-   I915_STATECHANGE(i915, I915_UPLOAD_CTX);
    I915_ACTIVESTATE(i915, I915_UPLOAD_FOG, enabled);
+   dw = i915->state.Ctx[I915_CTXREG_LIS5];
    if (enabled)
-      i915->state.Ctx[I915_CTXREG_LIS5] |= S5_FOG_ENABLE;
+      dw |= S5_FOG_ENABLE;
    else
-      i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_FOG_ENABLE;
+      dw &= ~S5_FOG_ENABLE;
+   if (dw != i915->state.Ctx[I915_CTXREG_LIS5]) {
+      i915->state.Ctx[I915_CTXREG_LIS5] = dw;
+      I915_STATECHANGE(i915, I915_UPLOAD_CTX);
+   }
 
    /* Always enable pixel fog.  Vertex fog using fog coord will conflict
     * with fog code appended onto fragment program.
@@ -782,7 +813,7 @@ i915_update_fog(GLcontext * ctx)
 }
 
 static void
-i915Fogfv(GLcontext * ctx, GLenum pname, const GLfloat * param)
+i915Fogfv(struct gl_context * ctx, GLenum pname, const GLfloat * param)
 {
    struct i915_context *i915 = I915_CONTEXT(ctx);
 
@@ -822,7 +853,7 @@ i915Fogfv(GLcontext * ctx, GLenum pname, const GLfloat * param)
 }
 
 static void
-i915Hint(GLcontext * ctx, GLenum target, GLenum state)
+i915Hint(struct gl_context * ctx, GLenum target, GLenum state)
 {
    switch (target) {
    case GL_FOG_HINT:
@@ -836,9 +867,10 @@ i915Hint(GLcontext * ctx, GLenum target, GLenum state)
  */
 
 static void
-i915Enable(GLcontext * ctx, GLenum cap, GLboolean state)
+i915Enable(struct gl_context * ctx, GLenum cap, GLboolean state)
 {
    struct i915_context *i915 = I915_CONTEXT(ctx);
+   GLuint dw;
 
    switch (cap) {
    case GL_TEXTURE_2D:
@@ -850,11 +882,15 @@ i915Enable(GLcontext * ctx, GLenum cap, GLboolean state)
       break;
 
    case GL_ALPHA_TEST:
-      I915_STATECHANGE(i915, I915_UPLOAD_CTX);
+      dw = i915->state.Ctx[I915_CTXREG_LIS6];
       if (state)
-         i915->state.Ctx[I915_CTXREG_LIS6] |= S6_ALPHA_TEST_ENABLE;
+         dw |= S6_ALPHA_TEST_ENABLE;
       else
-         i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_ALPHA_TEST_ENABLE;
+         dw &= ~S6_ALPHA_TEST_ENABLE;
+      if (dw != i915->state.Ctx[I915_CTXREG_LIS6]) {
+        i915->state.Ctx[I915_CTXREG_LIS6] = dw;
+        I915_STATECHANGE(i915, I915_UPLOAD_CTX);
+      }
       break;
 
    case GL_BLEND:
@@ -874,19 +910,27 @@ i915Enable(GLcontext * ctx, GLenum cap, GLboolean state)
       break;
 
    case GL_DITHER:
-      I915_STATECHANGE(i915, I915_UPLOAD_CTX);
+      dw = i915->state.Ctx[I915_CTXREG_LIS5];
       if (state)
-         i915->state.Ctx[I915_CTXREG_LIS5] |= S5_COLOR_DITHER_ENABLE;
+         dw |= S5_COLOR_DITHER_ENABLE;
       else
-         i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_COLOR_DITHER_ENABLE;
+         dw &= ~S5_COLOR_DITHER_ENABLE;
+      if (dw != i915->state.Ctx[I915_CTXREG_LIS5]) {
+        i915->state.Ctx[I915_CTXREG_LIS5] = dw;
+        I915_STATECHANGE(i915, I915_UPLOAD_CTX);
+      }
       break;
 
    case GL_DEPTH_TEST:
-      I915_STATECHANGE(i915, I915_UPLOAD_CTX);
+      dw = i915->state.Ctx[I915_CTXREG_LIS6];
       if (state)
-         i915->state.Ctx[I915_CTXREG_LIS6] |= S6_DEPTH_TEST_ENABLE;
+         dw |= S6_DEPTH_TEST_ENABLE;
       else
-         i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_TEST_ENABLE;
+         dw &= ~S6_DEPTH_TEST_ENABLE;
+      if (dw != i915->state.Ctx[I915_CTXREG_LIS6]) {
+        i915->state.Ctx[I915_CTXREG_LIS6] = dw;
+        I915_STATECHANGE(i915, I915_UPLOAD_CTX);
+      }
 
       i915DepthMask(ctx, ctx->Depth.Mask);
       break;
@@ -902,11 +946,15 @@ i915Enable(GLcontext * ctx, GLenum cap, GLboolean state)
       break;
 
    case GL_LINE_SMOOTH:
-      I915_STATECHANGE(i915, I915_UPLOAD_CTX);
+      dw = i915->state.Ctx[I915_CTXREG_LIS4];
       if (state)
-         i915->state.Ctx[I915_CTXREG_LIS4] |= S4_LINE_ANTIALIAS_ENABLE;
+         dw |= S4_LINE_ANTIALIAS_ENABLE;
       else
-         i915->state.Ctx[I915_CTXREG_LIS4] &= ~S4_LINE_ANTIALIAS_ENABLE;
+         dw &= ~S4_LINE_ANTIALIAS_ENABLE;
+      if (dw != i915->state.Ctx[I915_CTXREG_LIS4]) {
+        i915->state.Ctx[I915_CTXREG_LIS4] = dw;
+        I915_STATECHANGE(i915, I915_UPLOAD_CTX);
+      }
       break;
 
    case GL_FOG:
@@ -925,13 +973,15 @@ i915Enable(GLcontext * ctx, GLenum cap, GLboolean state)
             hw_stencil = (irbStencil && irbStencil->region);
          }
          if (hw_stencil) {
-            I915_STATECHANGE(i915, I915_UPLOAD_CTX);
+           dw = i915->state.Ctx[I915_CTXREG_LIS5];
             if (state)
-               i915->state.Ctx[I915_CTXREG_LIS5] |= (S5_STENCIL_TEST_ENABLE |
-                                                     S5_STENCIL_WRITE_ENABLE);
+               dw |= (S5_STENCIL_TEST_ENABLE | S5_STENCIL_WRITE_ENABLE);
             else
-               i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_TEST_ENABLE |
-                                                      S5_STENCIL_WRITE_ENABLE);
+               dw &= ~(S5_STENCIL_TEST_ENABLE | S5_STENCIL_WRITE_ENABLE);
+           if (dw != i915->state.Ctx[I915_CTXREG_LIS5]) {
+              i915->state.Ctx[I915_CTXREG_LIS5] = dw;
+              I915_STATECHANGE(i915, I915_UPLOAD_CTX);
+           }
          }
          else {
             FALLBACK(&i915->intel, I915_FALLBACK_STENCIL, state);
@@ -961,11 +1011,15 @@ i915Enable(GLcontext * ctx, GLenum cap, GLboolean state)
       /* This state change is handled in i915_reduced_primitive_state because
        * the hardware bit should only be set when rendering points.
        */
-      I915_STATECHANGE(i915, I915_UPLOAD_CTX);
+        dw = i915->state.Ctx[I915_CTXREG_LIS4];
       if (state)
-        i915->state.Ctx[I915_CTXREG_LIS4] |= S4_SPRITE_POINT_ENABLE;
+        dw |= S4_SPRITE_POINT_ENABLE;
       else
-        i915->state.Ctx[I915_CTXREG_LIS4] &= ~S4_SPRITE_POINT_ENABLE;
+        dw &= ~S4_SPRITE_POINT_ENABLE;
+      if (dw != i915->state.Ctx[I915_CTXREG_LIS4]) {
+        i915->state.Ctx[I915_CTXREG_LIS4] = dw;
+        I915_STATECHANGE(i915, I915_UPLOAD_CTX);
+      }
       break;
 
    case GL_POINT_SMOOTH:
@@ -1095,7 +1149,7 @@ i915_init_packets(struct i915_context *i915)
 }
 
 void
-i915_update_provoking_vertex(GLcontext * ctx)
+i915_update_provoking_vertex(struct gl_context * ctx)
 {
    struct i915_context *i915 = I915_CONTEXT(ctx);
 
@@ -1152,12 +1206,9 @@ i915InitStateFunctions(struct dd_function_table *functions)
 void
 i915InitState(struct i915_context *i915)
 {
-   GLcontext *ctx = &i915->intel.ctx;
+   struct gl_context *ctx = &i915->intel.ctx;
 
    i915_init_packets(i915);
 
    _mesa_init_driver_state(ctx);
-
-   memcpy(&i915->initial, &i915->state, sizeof(i915->state));
-   i915->current = &i915->state;
 }