From 35707dbe57873adb5a8088cd47c13bd216e143e4 Mon Sep 17 00:00:00 2001
From: Zou Nan hai <nanhai.zou@intel.com>
Date: Thu, 12 Apr 2007 09:43:00 +0800
Subject:   Initial 965 GLSL support

---
 src/mesa/drivers/dri/i965/brw_clip.h      |   4 +-
 src/mesa/drivers/dri/i965/brw_context.c   |  47 ++++++++
 src/mesa/drivers/dri/i965/brw_eu.h        |   3 +-
 src/mesa/drivers/dri/i965/brw_eu_emit.c   |   2 +-
 src/mesa/drivers/dri/i965/brw_gs.h        |   4 +-
 src/mesa/drivers/dri/i965/brw_sf.h        |   4 +-
 src/mesa/drivers/dri/i965/brw_vs.h        |   1 +
 src/mesa/drivers/dri/i965/brw_vs_emit.c   | 184 ++++++++++++++++++++++--------
 src/mesa/drivers/dri/i965/brw_vs_tnl.c    |   2 +-
 src/mesa/drivers/dri/i965/brw_wm.c        |   4 +
 src/mesa/drivers/dri/i965/brw_wm_emit.c   |  82 ++++++++++---
 src/mesa/drivers/dri/i965/brw_wm_pass0.c  |   4 +
 src/mesa/drivers/dri/i965/brw_wm_pass1.c  |   5 +-
 src/mesa/drivers/dri/i965/intel_context.c |   4 +
 src/mesa/shader/slang/slang_codegen.c     |   1 +
 15 files changed, 276 insertions(+), 75 deletions(-)

(limited to 'src')

diff --git a/src/mesa/drivers/dri/i965/brw_clip.h b/src/mesa/drivers/dri/i965/brw_clip.h
index 49b2770a51..2a65697325 100644
--- a/src/mesa/drivers/dri/i965/brw_clip.h
+++ b/src/mesa/drivers/dri/i965/brw_clip.h
@@ -42,7 +42,7 @@
  * up polygon offset and flatshading at this point:
  */
 struct brw_clip_prog_key {
-   GLuint attrs:16;		
+   GLuint attrs:32;		
    GLuint primitive:4;
    GLuint nr_userclip:3;
    GLuint do_flat_shading:1;
@@ -51,7 +51,7 @@ struct brw_clip_prog_key {
    GLuint fill_ccw:2;		/* includes cull information */
    GLuint offset_cw:1;
    GLuint offset_ccw:1;
-   GLuint pad0:1;
+   GLuint pad0:17;
 
    GLuint copy_bfc_cw:1;
    GLuint copy_bfc_ccw:1;
diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c
index 397a9bd3f5..badf178b68 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -44,6 +44,8 @@
 #include "api_noop.h"
 #include "vtxfmt.h"
 
+#include "shader/shader_api.h"
+
 /***************************************
  * Mesa's Driver Functions
  ***************************************/
@@ -60,12 +62,57 @@ static const struct dri_extension brw_extensions[] =
     { NULL,                                NULL }
 };
 
+static void brwLinkProgram(GLcontext *ctx, GLuint program)
+{
+        struct brw_context *brw = brw_context(ctx);
+        struct brw_vertex_program *vert_prog;
+        struct brw_fragment_program *frag_prog;
+        struct gl_shader_program *sh_prog;
+        _mesa_link_program(ctx, program);
+
+        sh_prog = _mesa_lookup_shader_program(ctx, program);
+	if (sh_prog) {
+	    sh_prog->FragmentProgram = 
+		_mesa_realloc(sh_prog->FragmentProgram,
+			sizeof(struct gl_fragment_program),
+			sizeof(struct brw_fragment_program));
+	    frag_prog = (struct brw_fragment_program *)sh_prog->FragmentProgram;
+	    frag_prog->id = brw->program_id++;
+	    sh_prog->VertexProgram = _mesa_realloc(sh_prog->VertexProgram,
+		    sizeof(struct gl_vertex_program),
+		    sizeof(struct brw_vertex_program));
+	    vert_prog = (struct brw_vertex_program *)sh_prog->VertexProgram;
+	    vert_prog->id = brw->program_id++;
+	}
+}
+
+static void brwUseProgram(GLcontext *ctx, GLuint program)
+{
+        struct brw_context *brw = brw_context(ctx);
+        struct gl_shader_program *sh_prog;
+        _mesa_use_program(ctx, program);
+        sh_prog = ctx->Shader.CurrentProgram;
+        if (sh_prog) {
+            ctx->VertexProgram.Enabled = GL_TRUE;
+            ctx->FragmentProgram.Enabled = GL_TRUE;
+            brw->attribs.VertexProgram->Current = sh_prog->VertexProgram;
+            brw->attribs.FragmentProgram->Current = sh_prog->FragmentProgram;
+            brw->state.dirty.brw |= BRW_NEW_VERTEX_PROGRAM;
+            brw->state.dirty.brw |= BRW_NEW_FRAGMENT_PROGRAM;
+        }
+}
 
+static void brwInitProgFuncs( struct dd_function_table *functions )
+{
+   functions->UseProgram = brwUseProgram;
+   functions->LinkProgram = brwLinkProgram;
+}
 static void brwInitDriverFunctions( struct dd_function_table *functions )
 {
    intelInitDriverFunctions( functions );
    brwInitTextureFuncs( functions );
    brwInitFragProgFuncs( functions );
+   brwInitProgFuncs( functions );
 }
 
 
diff --git a/src/mesa/drivers/dri/i965/brw_eu.h b/src/mesa/drivers/dri/i965/brw_eu.h
index 52f89d577c..144f209eda 100644
--- a/src/mesa/drivers/dri/i965/brw_eu.h
+++ b/src/mesa/drivers/dri/i965/brw_eu.h
@@ -860,5 +860,6 @@ void brw_math_invert( struct brw_compile *p,
 		      struct brw_reg dst,
 		      struct brw_reg src);
 
-
+void brw_set_src1( struct brw_instruction *insn,
+                          struct brw_reg reg );
 #endif
diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c
index 9992b47d8a..0c04bf6c62 100644
--- a/src/mesa/drivers/dri/i965/brw_eu_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c
@@ -164,7 +164,7 @@ static void brw_set_src0( struct brw_instruction *insn,
 }
 
 
-static void brw_set_src1( struct brw_instruction *insn,
+void brw_set_src1( struct brw_instruction *insn,
 			  struct brw_reg reg )
 {
    assert(reg.file != BRW_MESSAGE_REGISTER_FILE);
diff --git a/src/mesa/drivers/dri/i965/brw_gs.h b/src/mesa/drivers/dri/i965/brw_gs.h
index 29a4e80ce1..18a4537c32 100644
--- a/src/mesa/drivers/dri/i965/brw_gs.h
+++ b/src/mesa/drivers/dri/i965/brw_gs.h
@@ -40,11 +40,11 @@
 #define MAX_GS_VERTS (4)	     
 
 struct brw_gs_prog_key {
+   GLuint attrs:32;
    GLuint primitive:4;
-   GLuint attrs:16;		
    GLuint hint_gs_always:1;
    GLuint need_gs_prog:1;
-   GLuint pad:10;
+   GLuint pad:26;
 };
 
 struct brw_gs_compile {
diff --git a/src/mesa/drivers/dri/i965/brw_sf.h b/src/mesa/drivers/dri/i965/brw_sf.h
index fb72b84ba8..23b89684b2 100644
--- a/src/mesa/drivers/dri/i965/brw_sf.h
+++ b/src/mesa/drivers/dri/i965/brw_sf.h
@@ -45,12 +45,12 @@
 #define SF_UNFILLED_TRIS   3
 
 struct brw_sf_prog_key {
+   GLuint attrs:32;
    GLuint primitive:2;
    GLuint do_twoside_color:1;
    GLuint do_flat_shading:1;
-   GLuint attrs:16;
    GLuint frontface_ccw:1;
-   GLuint pad:11;
+   GLuint pad:27;
 };
 
 
diff --git a/src/mesa/drivers/dri/i965/brw_vs.h b/src/mesa/drivers/dri/i965/brw_vs.h
index fdb5785d67..c31a1b6366 100644
--- a/src/mesa/drivers/dri/i965/brw_vs.h
+++ b/src/mesa/drivers/dri/i965/brw_vs.h
@@ -67,6 +67,7 @@ struct brw_vs_compile {
    struct brw_reg r1;
    struct brw_reg regs[PROGRAM_ADDRESS+1][128];
    struct brw_reg tmp;
+   struct brw_reg ret;
 
    struct brw_reg userplane[6];
 
diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c
index 6eb11b19ad..613ee03b2a 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c
@@ -134,6 +134,17 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
 					     WRITEMASK_X);
       reg++;
    }
+
+   c->ret =  brw_reg(BRW_GENERAL_REGISTER_FILE,
+           reg,
+           0,
+           BRW_REGISTER_TYPE_D,
+           BRW_VERTICAL_STRIDE_8,
+           BRW_WIDTH_8,
+           BRW_HORIZONTAL_STRIDE_1,
+           BRW_SWIZZLE_XXXX,
+           WRITEMASK_X);
+   reg++;
  
    
    /* Some opcodes need an internal temporary:
@@ -213,57 +224,68 @@ static void unalias2( struct brw_vs_compile *c,
    }
 }
 
+static void emit_sop( struct brw_compile *p,
+                      struct brw_reg dst,
+                      struct brw_reg arg0,
+                      struct brw_reg arg1, 
+		      GLuint cond)
+{
+   brw_push_insn_state(p);
+   brw_CMP(p, brw_null_reg(), cond, arg0, arg1);
+   brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+   brw_MOV(p, dst, brw_imm_f(1.0f));
+   brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
+   brw_MOV(p, dst, brw_imm_f(0.0f));
+   brw_pop_insn_state(p);
+}
 
+static void emit_seq( struct brw_compile *p,
+                      struct brw_reg dst,
+                      struct brw_reg arg0,
+                      struct brw_reg arg1 )
+{
+   emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_EQ);
+}
 
-
+static void emit_sne( struct brw_compile *p,
+                      struct brw_reg dst,
+                      struct brw_reg arg0,
+                      struct brw_reg arg1 )
+{
+   emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_NEQ);
+}
 static void emit_slt( struct brw_compile *p, 
 		      struct brw_reg dst,
 		      struct brw_reg arg0,
 		      struct brw_reg arg1 )
 {
-   /* Could be done with an if/else/endif, but this method uses half
-    * the instructions.  Note that we are careful to reference the
-    * arguments before writing the dest.  That means we emit the
-    * instructions in an odd order and have to play with the flag
-    * values.
-    */
-   brw_push_insn_state(p);
-   brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_GE, arg0, arg1);
-
-   /* Write all values to 1:
-    */
-   brw_set_predicate_control(p, BRW_PREDICATE_NONE);
-   brw_MOV(p, dst, brw_imm_f(1.0));
+   emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_L);
+}
 
-   /* Where the test succeeded, overwite with zero:
-    */
-   brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
-   brw_MOV(p, dst, brw_imm_f(0.0));
-   brw_pop_insn_state(p);
+static void emit_sle( struct brw_compile *p, 
+		      struct brw_reg dst,
+		      struct brw_reg arg0,
+		      struct brw_reg arg1 )
+{
+   emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_LE);
 }
 
+static void emit_sgt( struct brw_compile *p, 
+		      struct brw_reg dst,
+		      struct brw_reg arg0,
+		      struct brw_reg arg1 )
+{
+   emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_G);
+}
 
 static void emit_sge( struct brw_compile *p, 
 		      struct brw_reg dst,
 		      struct brw_reg arg0,
 		      struct brw_reg arg1 )
 {
-   brw_push_insn_state(p);
-   brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_GE, arg0, arg1);
-
-   /* Write all values to zero:
-    */
-   brw_set_predicate_control(p, BRW_PREDICATE_NONE);
-   brw_MOV(p, dst, brw_imm_f(0));
-
-   /* Where the test succeeded, overwite with 1:
-    */
-   brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
-   brw_MOV(p, dst, brw_imm_f(1.0));
-   brw_pop_insn_state(p);
+  emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_GE);
 }
 
-
 static void emit_max( struct brw_compile *p, 
 		      struct brw_reg dst,
 		      struct brw_reg arg0,
@@ -592,9 +614,13 @@ static struct brw_reg get_reg( struct brw_vs_compile *c,
    case PROGRAM_TEMPORARY:
    case PROGRAM_INPUT:
    case PROGRAM_OUTPUT:
-   case PROGRAM_STATE_VAR:
       assert(c->regs[file][index].nr != 0);
       return c->regs[file][index];
+   case PROGRAM_STATE_VAR:
+   case PROGRAM_CONSTANT:
+   case PROGRAM_UNIFORM:
+      assert(c->regs[PROGRAM_STATE_VAR][index].nr != 0);
+      return c->regs[PROGRAM_STATE_VAR][index];
    case PROGRAM_ADDRESS:
       assert(index == 0);
       return c->regs[file][index];
@@ -891,17 +917,46 @@ static void emit_vertex_write( struct brw_vs_compile *c)
 
 }
 
-
-
+static void 
+post_vs_emit( struct brw_vs_compile *c, struct brw_instruction *end_inst )
+{
+   GLuint nr_insns = c->vp->program.Base.NumInstructions;
+   GLuint insn, target_insn;
+   struct prog_instruction *inst1, *inst2;
+   struct brw_instruction *brw_inst1, *brw_inst2;
+   int offset;
+   for (insn = 0; insn < nr_insns; insn++) {
+       inst1 = &c->vp->program.Base.Instructions[insn];
+       brw_inst1 = inst1->Data;
+       switch (inst1->Opcode) {
+	   case OPCODE_CAL:
+	   case OPCODE_BRA:
+	       target_insn = inst1->BranchTarget;
+	       inst2 = &c->vp->program.Base.Instructions[target_insn];
+	       brw_inst2 = inst2->Data;
+	       offset = brw_inst2 - brw_inst1;
+	       brw_set_src1(brw_inst1, brw_imm_d(offset*16));
+	       break;
+	   case OPCODE_END:
+	       offset = end_inst - brw_inst1;
+	       brw_set_src1(brw_inst1, brw_imm_d(offset*16));
+	       break;
+	   default:
+	       break;
+       }
+   }
+}
 
 /* Emit the fragment program instructions here.
  */
-void brw_vs_emit( struct brw_vs_compile *c )
+void brw_vs_emit(struct brw_vs_compile *c )
 {
+#define MAX_IFSN 32
    struct brw_compile *p = &c->func;
    GLuint nr_insns = c->vp->program.Base.NumInstructions;
-   GLuint insn;
-
+   GLuint insn, if_insn = 0;
+   struct brw_instruction *end_inst;
+   struct brw_instruction *if_inst[32];
 
    if (INTEL_DEBUG & DEBUG_VS) {
       _mesa_printf("\n\n\nvs-emit:\n");
@@ -924,6 +979,7 @@ void brw_vs_emit( struct brw_vs_compile *c )
       
       /* Get argument regs.  SWZ is special and does this itself.
        */
+      inst->Data = &p->store[p->nr_insn];
       if (inst->Opcode != OPCODE_SWZ)
 	 for (i = 0; i < 3; i++) 
 	    args[i] = get_arg(c, inst->SrcReg[i]);
@@ -934,7 +990,6 @@ void brw_vs_emit( struct brw_vs_compile *c )
        */
       dst = get_dst(c, inst->DstReg);
 
-      
       switch (inst->Opcode) {
       case OPCODE_ABS:
 	 brw_MOV(p, dst, brw_abs(args[0]));
@@ -1003,12 +1058,25 @@ void brw_vs_emit( struct brw_vs_compile *c )
       case OPCODE_RSQ:
 	 emit_math1(c, BRW_MATH_FUNCTION_RSQ, dst, args[0], BRW_MATH_PRECISION_FULL);
 	 break;
+
+      case OPCODE_SEQ:
+         emit_seq(p, dst, args[0], args[1]);
+         break;
+      case OPCODE_SNE:
+         emit_sne(p, dst, args[0], args[1]);
+         break;
       case OPCODE_SGE:
 	 emit_sge(p, dst, args[0], args[1]);
 	 break;
+      case OPCODE_SGT:
+         emit_sgt(p, dst, args[0], args[1]);
+        break;
       case OPCODE_SLT:
 	 emit_slt(p, dst, args[0], args[1]);
 	 break;
+      case OPCODE_SLE:
+         emit_sle(p, dst, args[0], args[1]);
+         break;
       case OPCODE_SUB:
 	 brw_ADD(p, dst, args[0], negate(args[1]));
 	 break;
@@ -1021,21 +1089,45 @@ void brw_vs_emit( struct brw_vs_compile *c )
       case OPCODE_XPD:
 	 emit_xpd(p, dst, args[0], args[1]);
 	 break;
+      case OPCODE_IF:
+	 assert(if_insn < MAX_IFSN);
+         if_inst[if_insn++] = brw_IF(p, BRW_EXECUTE_8);
+	 break;
+      case OPCODE_ELSE:
+	 brw_ELSE(p, if_inst[if_insn]);
+	 break;
+      case OPCODE_ENDIF:
+         assert(if_insn > 0);
+	 brw_ENDIF(p, if_inst[--if_insn]);
+	 break;			
+      case OPCODE_BRA:
+         brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
+         brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
+         brw_set_predicate_control_flag_value(p, 0xFF);
+        break;
+      case OPCODE_CAL:
+         brw_ADD(p, c->ret, brw_ip_reg(), brw_imm_d(2*16));
+	 inst->Data = &p->store[p->nr_insn];
+	 brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
+        break;
+      case OPCODE_RET:
+         brw_MOV(p, brw_ip_reg(), c->ret);
       case OPCODE_END:	
+         brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
+        break;
       case OPCODE_PRINT:
+      case OPCODE_BGNSUB:
+      case OPCODE_ENDSUB:
 	 break;
       default:
+	 _mesa_printf("Unsupport opcode %d in vertex shader\n", inst->Opcode);
 	 break;
       }
 
       release_tmps(c);
    }
 
+   end_inst = &p->store[p->nr_insn];
    emit_vertex_write(c);
-
+   post_vs_emit(c, end_inst);
 }
-
-
-
-
-
diff --git a/src/mesa/drivers/dri/i965/brw_vs_tnl.c b/src/mesa/drivers/dri/i965/brw_vs_tnl.c
index 35adc4846a..bc0526fab6 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_tnl.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_tnl.c
@@ -855,7 +855,7 @@ static struct ureg calculate_light_attenuation( struct tnl_program *p,
       struct ureg slt = get_temp(p);
 
       emit_op2(p, OPCODE_DP3, spot, 0, ureg_negate(VPpli), spot_dir_norm);
-      emit_op2(p, OPCODE_SLT, slt, 0, swizzle1(spot_dir_norm,W), spot);
+      emit_op2(p, OPCODE_SLT, slt, 0, spot, swizzle1(spot_dir_norm,W));
       emit_op2(p, OPCODE_POW, spot, 0, spot, swizzle1(attenuation, W));
       emit_op2(p, OPCODE_MUL, att, 0, slt, spot);
 
diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c
index 1497dc7968..a02a0a23af 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.c
+++ b/src/mesa/drivers/dri/i965/brw_wm.c
@@ -66,7 +66,11 @@ GLuint brw_wm_nr_args( GLuint opcode )
    case OPCODE_POW:
    case OPCODE_SUB:
    case OPCODE_SGE:
+   case OPCODE_SGT:
+   case OPCODE_SLE:
    case OPCODE_SLT:
+   case OPCODE_SEQ:
+   case OPCODE_SNE:
    case OPCODE_ADD:
    case OPCODE_MAX:
    case OPCODE_MIN:
diff --git a/src/mesa/drivers/dri/i965/brw_wm_emit.c b/src/mesa/drivers/dri/i965/brw_wm_emit.c
index fd60515972..197a0ae13d 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_emit.c
@@ -343,11 +343,10 @@ static void emit_lrp( struct brw_compile *p,
       }
    }
 }
-
-
-static void emit_slt( struct brw_compile *p, 
+static void emit_sop( struct brw_compile *p, 
 		      const struct brw_reg *dst,
 		      GLuint mask,
+		      GLuint cond,
 		      const struct brw_reg *arg0,
 		      const struct brw_reg *arg1 )
 {
@@ -356,34 +355,66 @@ static void emit_slt( struct brw_compile *p,
    for (i = 0; i < 4; i++) {
       if (mask & (1<<i)) {	
 	 brw_MOV(p, dst[i], brw_imm_f(0));
-	 brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, arg0[i], arg1[i]);
+	 brw_CMP(p, brw_null_reg(), cond, arg0[i], arg1[i]);
 	 brw_MOV(p, dst[i], brw_imm_f(1.0));
 	 brw_set_predicate_control_flag_value(p, 0xff);
       }
    }
 }
 
-/* Isn't this just the same as the above with the args swapped?
- */
-static void emit_sge( struct brw_compile *p, 
+static void emit_slt( struct brw_compile *p, 
 		      const struct brw_reg *dst,
 		      GLuint mask,
 		      const struct brw_reg *arg0,
 		      const struct brw_reg *arg1 )
 {
-   GLuint i;
+	 emit_sop(p, dst, mask, BRW_CONDITIONAL_L, arg0, arg1);
+}
 
-   for (i = 0; i < 4; i++) {
-      if (mask & (1<<i)) {	
-	 brw_MOV(p, dst[i], brw_imm_f(0));
-	 brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_GE, arg0[i], arg1[i]);
-	 brw_MOV(p, dst[i], brw_imm_f(1.0));
-	 brw_set_predicate_control_flag_value(p, 0xff);
-      }
-   }
+static void emit_sle( struct brw_compile *p, 
+		      const struct brw_reg *dst,
+		      GLuint mask,
+		      const struct brw_reg *arg0,
+		      const struct brw_reg *arg1 )
+{
+	 emit_sop(p, dst, mask, BRW_CONDITIONAL_LE, arg0, arg1);
+}
+
+static void emit_sgt( struct brw_compile *p, 
+		      const struct brw_reg *dst,
+		      GLuint mask,
+		      const struct brw_reg *arg0,
+		      const struct brw_reg *arg1 )
+{
+	 emit_sop(p, dst, mask, BRW_CONDITIONAL_G, arg0, arg1);
+}
+
+static void emit_sge( struct brw_compile *p, 
+		      const struct brw_reg *dst,
+		      GLuint mask,
+		      const struct brw_reg *arg0,
+		      const struct brw_reg *arg1 )
+{
+	 emit_sop(p, dst, mask, BRW_CONDITIONAL_GE, arg0, arg1);
 }
 
+static void emit_seq( struct brw_compile *p, 
+		      const struct brw_reg *dst,
+		      GLuint mask,
+		      const struct brw_reg *arg0,
+		      const struct brw_reg *arg1 )
+{
+	 emit_sop(p, dst, mask, BRW_CONDITIONAL_EQ, arg0, arg1);
+}
 
+static void emit_sne( struct brw_compile *p, 
+		      const struct brw_reg *dst,
+		      GLuint mask,
+		      const struct brw_reg *arg0,
+		      const struct brw_reg *arg1 )
+{
+	 emit_sop(p, dst, mask, BRW_CONDITIONAL_NEQ, arg0, arg1);
+}
 
 static void emit_cmp( struct brw_compile *p, 
 		      const struct brw_reg *dst,
@@ -543,8 +574,8 @@ static void emit_math1( struct brw_compile *p,
 			GLuint mask,
 			const struct brw_reg *arg0 )
 {
-   assert((mask & WRITEMASK_XYZW) == WRITEMASK_X ||
-	  function == BRW_MATH_FUNCTION_SINCOS);
+   //assert((mask & WRITEMASK_XYZW) == WRITEMASK_X ||
+   //	  function == BRW_MATH_FUNCTION_SINCOS);
    
    brw_MOV(p, brw_message_reg(2), arg0[0]);
 
@@ -1208,9 +1239,21 @@ void brw_wm_emit( struct brw_wm_compile *c )
 	 emit_slt(p, dst, dst_flags, args[0], args[1]);
 	 break;
 
+      case OPCODE_SLE:
+	 emit_sle(p, dst, dst_flags, args[0], args[1]);
+	break;
+      case OPCODE_SGT:
+	 emit_sgt(p, dst, dst_flags, args[0], args[1]);
+	break;
       case OPCODE_SGE:
 	 emit_sge(p, dst, dst_flags, args[0], args[1]);
 	 break;
+      case OPCODE_SEQ:
+	 emit_seq(p, dst, dst_flags, args[0], args[1]);
+	break;
+      case OPCODE_SNE:
+	 emit_sne(p, dst, dst_flags, args[0], args[1]);
+	break;
 
       case OPCODE_LIT:
 	 emit_lit(p, dst, dst_flags, args[0]);
@@ -1231,7 +1274,8 @@ void brw_wm_emit( struct brw_wm_compile *c )
 	 break;
 
       default:
-	 assert(0);
+	_mesa_printf("unsupport opcode %d in fragment program\n", 
+		inst->opcode);
       }
       
       for (i = 0; i < 4; i++)
diff --git a/src/mesa/drivers/dri/i965/brw_wm_pass0.c b/src/mesa/drivers/dri/i965/brw_wm_pass0.c
index 00f6f6b9a4..1bfae5a069 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_pass0.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_pass0.c
@@ -168,6 +168,7 @@ static const struct brw_wm_ref *pass0_get_reg( struct brw_wm_compile *c,
       case PROGRAM_PAYLOAD:
       case PROGRAM_TEMPORARY:
       case PROGRAM_OUTPUT:
+      case PROGRAM_VARYING:
 	 break;
 
       case PROGRAM_LOCAL_PARAM:
@@ -179,6 +180,8 @@ static const struct brw_wm_ref *pass0_get_reg( struct brw_wm_compile *c,
 	 break;
 
       case PROGRAM_STATE_VAR:
+      case PROGRAM_UNIFORM:
+      case PROGRAM_CONSTANT:
       case PROGRAM_NAMED_PARAM: {
 	 struct gl_program_parameter_list *plist = c->fp->program.Base.Parameters;
 	 
@@ -197,6 +200,7 @@ static const struct brw_wm_ref *pass0_get_reg( struct brw_wm_compile *c,
 	    break;
 	    
 	 case PROGRAM_STATE_VAR:
+	 case PROGRAM_UNIFORM:
 	    /* These may change from run to run:
 	     */
 	    ref = get_param_ref(c, &plist->ParameterValues[idx][component] );
diff --git a/src/mesa/drivers/dri/i965/brw_wm_pass1.c b/src/mesa/drivers/dri/i965/brw_wm_pass1.c
index d668def700..26c044d400 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_pass1.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_pass1.c
@@ -155,7 +155,11 @@ void brw_wm_pass1( struct brw_wm_compile *c )
 
       case OPCODE_SUB:
       case OPCODE_SLT:
+      case OPCODE_SLE:
       case OPCODE_SGE:
+      case OPCODE_SGT:
+      case OPCODE_SEQ:
+      case OPCODE_SNE:
       case OPCODE_ADD:
       case OPCODE_MAX:
       case OPCODE_MIN:
@@ -257,7 +261,6 @@ void brw_wm_pass1( struct brw_wm_compile *c )
       case OPCODE_DST:
       case OPCODE_TXP:
       default:
-	 assert(0);
 	 break;
       }
 
diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c
index 10eb9a2e28..a94c1dc6d5 100644
--- a/src/mesa/drivers/dri/i965/intel_context.c
+++ b/src/mesa/drivers/dri/i965/intel_context.c
@@ -81,6 +81,7 @@ int INTEL_DEBUG = (0);
 #define need_GL_EXT_fog_coord
 #define need_GL_EXT_multi_draw_arrays
 #define need_GL_EXT_secondary_color
+#define need_GL_VERSION_2_0
 #include "extension_helper.h"
 
 #ifndef VERBOSE
@@ -180,6 +181,9 @@ const struct dri_extension card_extensions[] =
     { "GL_MESA_ycbcr_texture",             NULL },
     { "GL_NV_blend_square",                NULL },
     { "GL_SGIS_generate_mipmap",           NULL },
+    { "GL_ARB_shading_language_100",       GL_VERSION_2_0_functions},
+    /* XXX not implement yet, to compile builtin glsl lib */
+    { "GL_ARB_draw_buffers",               NULL },
     { NULL,                                NULL }
 };
 
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index fe6b615c5d..30f044e77c 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -1746,6 +1746,7 @@ _slang_gen_var_decl(slang_assemble_ctx *A, slang_variable *var)
 
       n->Store->File = PROGRAM_TEMPORARY;
       n->Store->Size = _slang_sizeof_type_specifier(&n->Var->type.specifier);
+      A->program->NumTemporaries++;
       assert(n->Store->Size > 0);
    }
    return n;
-- 
cgit v1.2.3


From a78b26fff04026a24189ecad7ec85bfe0df2cce1 Mon Sep 17 00:00:00 2001
From: Zou Nan hai <nanhai.zou@intel.com>
Date: Mon, 30 Apr 2007 15:24:38 +0800
Subject:   support nested function call   else instruction fix.

---
 src/mesa/drivers/dri/i965/brw_vs.h      |  2 +-
 src/mesa/drivers/dri/i965/brw_vs_emit.c | 30 ++++++++++++++++--------------
 2 files changed, 17 insertions(+), 15 deletions(-)

(limited to 'src')

diff --git a/src/mesa/drivers/dri/i965/brw_vs.h b/src/mesa/drivers/dri/i965/brw_vs.h
index c31a1b6366..912ab563f4 100644
--- a/src/mesa/drivers/dri/i965/brw_vs.h
+++ b/src/mesa/drivers/dri/i965/brw_vs.h
@@ -67,7 +67,7 @@ struct brw_vs_compile {
    struct brw_reg r1;
    struct brw_reg regs[PROGRAM_ADDRESS+1][128];
    struct brw_reg tmp;
-   struct brw_reg ret;
+   struct brw_reg stack;
 
    struct brw_reg userplane[6];
 
diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c
index 613ee03b2a..f8367c4826 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c
@@ -135,16 +135,8 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
       reg++;
    }
 
-   c->ret =  brw_reg(BRW_GENERAL_REGISTER_FILE,
-           reg,
-           0,
-           BRW_REGISTER_TYPE_D,
-           BRW_VERTICAL_STRIDE_8,
-           BRW_WIDTH_8,
-           BRW_HORIZONTAL_STRIDE_1,
-           BRW_SWIZZLE_XXXX,
-           WRITEMASK_X);
-   reg++;
+   c->stack =  brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, reg, 0);
+   reg += 2;
  
    
    /* Some opcodes need an internal temporary:
@@ -956,7 +948,8 @@ void brw_vs_emit(struct brw_vs_compile *c )
    GLuint nr_insns = c->vp->program.Base.NumInstructions;
    GLuint insn, if_insn = 0;
    struct brw_instruction *end_inst;
-   struct brw_instruction *if_inst[32];
+   struct brw_instruction *if_inst[MAX_IFSN];
+   struct brw_indirect stack_index = brw_indirect(0, 0);   
 
    if (INTEL_DEBUG & DEBUG_VS) {
       _mesa_printf("\n\n\nvs-emit:\n");
@@ -970,6 +963,7 @@ void brw_vs_emit(struct brw_vs_compile *c )
    /* Static register allocation
     */
    brw_vs_alloc_regs(c);
+   brw_MOV(p, get_addr_reg(stack_index), brw_address(c->stack));
 
    for (insn = 0; insn < nr_insns; insn++) {
 
@@ -1094,7 +1088,7 @@ void brw_vs_emit(struct brw_vs_compile *c )
          if_inst[if_insn++] = brw_IF(p, BRW_EXECUTE_8);
 	 break;
       case OPCODE_ELSE:
-	 brw_ELSE(p, if_inst[if_insn]);
+	 if_inst[if_insn-1] = brw_ELSE(p, if_inst[if_insn-1]);
 	 break;
       case OPCODE_ENDIF:
          assert(if_insn > 0);
@@ -1106,12 +1100,20 @@ void brw_vs_emit(struct brw_vs_compile *c )
          brw_set_predicate_control_flag_value(p, 0xFF);
         break;
       case OPCODE_CAL:
-         brw_ADD(p, c->ret, brw_ip_reg(), brw_imm_d(2*16));
+	 brw_set_access_mode(p, BRW_ALIGN_1);
+	 brw_ADD(p, deref_1uw(stack_index, 0), brw_ip_reg(), brw_imm_d(3*16));
+	 brw_set_access_mode(p, BRW_ALIGN_16);
+	 brw_ADD(p, get_addr_reg(stack_index),
+			 get_addr_reg(stack_index), brw_imm_d(4));
 	 inst->Data = &p->store[p->nr_insn];
 	 brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
         break;
       case OPCODE_RET:
-         brw_MOV(p, brw_ip_reg(), c->ret);
+	 brw_ADD(p, get_addr_reg(stack_index),
+			 get_addr_reg(stack_index), brw_imm_d(-4));
+	 brw_set_access_mode(p, BRW_ALIGN_1);
+         brw_MOV(p, brw_ip_reg(), deref_1uw(stack_index, 0));
+	 brw_set_access_mode(p, BRW_ALIGN_16);
       case OPCODE_END:	
          brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
         break;
-- 
cgit v1.2.3


From 58eac1bbf320b4104c3158aaeca4726f1a59daf9 Mon Sep 17 00:00:00 2001
From: Zou Nan hai <nanhai.zou@intel.com>
Date: Wed, 9 May 2007 10:08:10 +0800
Subject:   Support loop, conditional update fix

---
 src/mesa/drivers/dri/i965/brw_vs_emit.c | 27 +++++++++++++++++----------
 1 file changed, 17 insertions(+), 10 deletions(-)

(limited to 'src')

diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c
index f8367c4826..ffc1a0ea09 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c
@@ -921,8 +921,10 @@ post_vs_emit( struct brw_vs_compile *c, struct brw_instruction *end_inst )
        inst1 = &c->vp->program.Base.Instructions[insn];
        brw_inst1 = inst1->Data;
        switch (inst1->Opcode) {
-	   case OPCODE_CAL:
 	   case OPCODE_BRA:
+	   case OPCODE_BRK:
+	   case OPCODE_CAL:
+	   case OPCODE_ENDLOOP:
 	       target_insn = inst1->BranchTarget;
 	       inst2 = &c->vp->program.Base.Instructions[target_insn];
 	       brw_inst2 = inst2->Data;
@@ -943,12 +945,12 @@ post_vs_emit( struct brw_vs_compile *c, struct brw_instruction *end_inst )
  */
 void brw_vs_emit(struct brw_vs_compile *c )
 {
-#define MAX_IFSN 32
+#define MAX_IF_DEPTH 32
    struct brw_compile *p = &c->func;
    GLuint nr_insns = c->vp->program.Base.NumInstructions;
    GLuint insn, if_insn = 0;
    struct brw_instruction *end_inst;
-   struct brw_instruction *if_inst[MAX_IFSN];
+   struct brw_instruction *if_inst[MAX_IF_DEPTH];
    struct brw_indirect stack_index = brw_indirect(0, 0);   
 
    if (INTEL_DEBUG & DEBUG_VS) {
@@ -1083,8 +1085,13 @@ void brw_vs_emit(struct brw_vs_compile *c )
       case OPCODE_XPD:
 	 emit_xpd(p, dst, args[0], args[1]);
 	 break;
+
+      case OPCODE_INT:
+	 /* XXX TODO track type information in shader program */
+	 brw_MOV(p, dst, args[0]);
+	 break;
       case OPCODE_IF:
-	 assert(if_insn < MAX_IFSN);
+	 assert(if_insn < MAX_IF_DEPTH);
          if_inst[if_insn++] = brw_IF(p, BRW_EXECUTE_8);
 	 break;
       case OPCODE_ELSE:
@@ -1094,11 +1101,6 @@ void brw_vs_emit(struct brw_vs_compile *c )
          assert(if_insn > 0);
 	 brw_ENDIF(p, if_inst[--if_insn]);
 	 break;			
-      case OPCODE_BRA:
-         brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
-         brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
-         brw_set_predicate_control_flag_value(p, 0xFF);
-        break;
       case OPCODE_CAL:
 	 brw_set_access_mode(p, BRW_ALIGN_1);
 	 brw_ADD(p, deref_1uw(stack_index, 0), brw_ip_reg(), brw_imm_d(3*16));
@@ -1114,9 +1116,13 @@ void brw_vs_emit(struct brw_vs_compile *c )
 	 brw_set_access_mode(p, BRW_ALIGN_1);
          brw_MOV(p, brw_ip_reg(), deref_1uw(stack_index, 0));
 	 brw_set_access_mode(p, BRW_ALIGN_16);
+      case OPCODE_ENDLOOP:
+      case OPCODE_BRK:
+      case OPCODE_BRA:
       case OPCODE_END:	
          brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
         break;
+      case OPCODE_BGNLOOP:
       case OPCODE_PRINT:
       case OPCODE_BGNSUB:
       case OPCODE_ENDSUB:
@@ -1125,7 +1131,8 @@ void brw_vs_emit(struct brw_vs_compile *c )
 	 _mesa_printf("Unsupport opcode %d in vertex shader\n", inst->Opcode);
 	 break;
       }
-
+      brw_set_predicate_control(p,
+		 inst->CondUpdate?BRW_PREDICATE_NORMAL:BRW_PREDICATE_NONE);
       release_tmps(c);
    }
 
-- 
cgit v1.2.3


From d19d0596daf004b56d80f78fa1a329b43c2ebf94 Mon Sep 17 00:00:00 2001
From: Zou Nan hai <nanhai.zou@intel.com>
Date: Thu, 21 Jun 2007 10:22:28 +0800
Subject:   support branch and loop in pixel shader   most of the sample
 working with some small modification

---
 progs/glsl/CH06-brick.frag.txt           |    6 +-
 progs/glsl/CH11-bumpmap.frag.txt         |    2 +-
 progs/glsl/CH11-bumpmap.vert.txt         |    9 +-
 progs/glsl/CH11-toyball.frag.txt         |    7 +-
 progs/glsl/CH11-toyball.vert.txt         |    7 +-
 src/mesa/drivers/dri/i965/Makefile       |    1 +
 src/mesa/drivers/dri/i965/brw_eu.h       |    8 +-
 src/mesa/drivers/dri/i965/brw_eu_emit.c  |   28 +-
 src/mesa/drivers/dri/i965/brw_vs.h       |    5 +
 src/mesa/drivers/dri/i965/brw_vs_emit.c  |   84 ++-
 src/mesa/drivers/dri/i965/brw_wm.c       |   80 +-
 src/mesa/drivers/dri/i965/brw_wm.h       |   10 +
 src/mesa/drivers/dri/i965/brw_wm_emit.c  |   28 +-
 src/mesa/drivers/dri/i965/brw_wm_fp.c    |   16 +-
 src/mesa/drivers/dri/i965/brw_wm_glsl.c  | 1177 ++++++++++++++++++++++++++++++
 src/mesa/drivers/dri/i965/brw_wm_pass2.c |    2 +-
 src/mesa/drivers/dri/i965/brw_wm_state.c |    7 +-
 17 files changed, 1365 insertions(+), 112 deletions(-)
 create mode 100644 src/mesa/drivers/dri/i965/brw_wm_glsl.c

(limited to 'src')

diff --git a/progs/glsl/CH06-brick.frag.txt b/progs/glsl/CH06-brick.frag.txt
index 06ef04e3af..388c5f9e66 100644
--- a/progs/glsl/CH06-brick.frag.txt
+++ b/progs/glsl/CH06-brick.frag.txt
@@ -23,7 +23,11 @@ void main()
     
     position = MCposition / BrickSize;
 
-    if (fract(position.y * 0.5) > 0.5)
+//    if (fract(position.y * 0.5) > 0.5)
+//        position.x += 0.5;
+    float tmp;
+    tmp  = fract(position.y * 0.5);
+    if (tmp > 0.5)
         position.x += 0.5;
 
     position = fract(position);
diff --git a/progs/glsl/CH11-bumpmap.frag.txt b/progs/glsl/CH11-bumpmap.frag.txt
index 063576f5a3..1467f767ec 100644
--- a/progs/glsl/CH11-bumpmap.frag.txt
+++ b/progs/glsl/CH11-bumpmap.frag.txt
@@ -33,7 +33,7 @@ void main()
     litColor = SurfaceColor * max(dot(normDelta, LightDir), 0.0);
     vec3 reflectDir = reflect(LightDir, normDelta);
     
-    float spec = max(dot(EyeDir, reflectDir), 0.0);
+    float spec = max(dot(normalize(EyeDir), reflectDir), 0.0);
     spec *= SpecularFactor;
     litColor = min(litColor + spec, vec3(1.0));
 
diff --git a/progs/glsl/CH11-bumpmap.vert.txt b/progs/glsl/CH11-bumpmap.vert.txt
index d3d19f62ac..55cf43ba7d 100644
--- a/progs/glsl/CH11-bumpmap.vert.txt
+++ b/progs/glsl/CH11-bumpmap.vert.txt
@@ -31,8 +31,9 @@ void main()
     v.z = dot(LightPosition, n);
     LightDir = normalize(v);
 
-    v.x = dot(EyeDir, t);
-    v.y = dot(EyeDir, b);
-    v.z = dot(EyeDir, n);
-    EyeDir = normalize(v);
+/*  v.x = dot(EyeDir, t);
+  v.y = dot(EyeDir, b);
+  v.z = dot(EyeDir, n);
+    EyeDir = normalize(EyeDir);
+*/
 }
diff --git a/progs/glsl/CH11-toyball.frag.txt b/progs/glsl/CH11-toyball.frag.txt
index 90ec1c27fc..f3cac62fb3 100644
--- a/progs/glsl/CH11-toyball.frag.txt
+++ b/progs/glsl/CH11-toyball.frag.txt
@@ -49,14 +49,15 @@ void main()
     inorout += dot(distance, vec4(1.0));
 
     distance.x = dot(p, HalfSpace4);
-    distance.y = StripeWidth - abs(p.z);
+//    distance.y = StripeWidth - abs(p.z);
+    distance.y = StripeWidth - abs(p.y);
     distance = smoothstep(-FWidth, FWidth, distance);
     inorout += distance.x;
 
     inorout = clamp(inorout, 0.0, 1.0);
 
-    surfColor = mix(Yellow, Red, inorout);
-    surfColor = mix(surfColor, Blue, distance.y);
+    surfColor = mix(Yellow, Blue, distance.y);
+    surfColor = mix(surfColor, Red, inorout);
 
     // normal = point on surface for sphere at (0,0,0)
     normal = p;
diff --git a/progs/glsl/CH11-toyball.vert.txt b/progs/glsl/CH11-toyball.vert.txt
index b7da3ac839..a3ee1b0377 100644
--- a/progs/glsl/CH11-toyball.vert.txt
+++ b/progs/glsl/CH11-toyball.vert.txt
@@ -14,10 +14,11 @@ uniform vec4 BallCenter;   // ball center in modelling coordinates
 
 void main()
 { 
-//orig:    ECposition   = gl_ModelViewMatrix * gl_Vertex;
+    ECposition   = gl_ModelViewMatrix * gl_Vertex;
 
-    ECposition = gl_TextureMatrix[0] * gl_Vertex;
-    ECposition = gl_ModelViewMatrix * ECposition;
+//  ECposition = gl_TextureMatrix[0] * gl_Vertex;
+//  ECposition = gl_MultiTexCoord0 * gl_Vertex;
+//    ECposition = gl_ModelViewMatrix * ECposition;
 
     ECballCenter = gl_ModelViewMatrix * BallCenter;
     gl_Position  = ftransform();
diff --git a/src/mesa/drivers/dri/i965/Makefile b/src/mesa/drivers/dri/i965/Makefile
index 9e4ff112dc..66de6f583c 100644
--- a/src/mesa/drivers/dri/i965/Makefile
+++ b/src/mesa/drivers/dri/i965/Makefile
@@ -70,6 +70,7 @@ DRIVER_SOURCES = \
 	brw_wm_emit.c \
 	brw_wm_fp.c \
 	brw_wm_iz.c \
+	brw_wm_glsl.c \
 	brw_wm_pass0.c \
 	brw_wm_pass1.c \
 	brw_wm_pass2.c \
diff --git a/src/mesa/drivers/dri/i965/brw_eu.h b/src/mesa/drivers/dri/i965/brw_eu.h
index 144f209eda..9b6581fd93 100644
--- a/src/mesa/drivers/dri/i965/brw_eu.h
+++ b/src/mesa/drivers/dri/i965/brw_eu.h
@@ -668,7 +668,10 @@ static __inline struct brw_indirect brw_indirect( GLuint addr_subnr, GLint offse
    return ptr;
 }
 
-
+static __inline struct brw_instruction *current_insn( struct brw_compile *p)
+{
+	return &p->store[p->nr_insn];
+}
 
 void brw_pop_insn_state( struct brw_compile *p );
 void brw_push_insn_state( struct brw_compile *p );
@@ -808,9 +811,10 @@ void brw_ENDIF(struct brw_compile *p,
 struct brw_instruction *brw_DO(struct brw_compile *p,
 			       GLuint execute_size);
 
-void brw_WHILE(struct brw_compile *p, 
+struct brw_instruction *brw_WHILE(struct brw_compile *p, 
 	       struct brw_instruction *patch_insn);
 
+struct brw_instruction *brw_BREAK(struct brw_compile *p);
 /* Forward jumps:
  */
 void brw_land_fwd_jump(struct brw_compile *p, 
diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c
index 0c04bf6c62..7b95fbdac0 100644
--- a/src/mesa/drivers/dri/i965/brw_eu_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c
@@ -186,7 +186,7 @@ void brw_set_src1( struct brw_instruction *insn,
        * in the future:
        */
       assert (reg.address_mode == BRW_ADDRESS_DIRECT);
-      assert (reg.file == BRW_GENERAL_REGISTER_FILE);
+      //assert (reg.file == BRW_GENERAL_REGISTER_FILE);
 
       if (insn->header.access_mode == BRW_ALIGN_1) {
 	 insn->bits3.da1.src1_subreg_nr = reg.subnr;
@@ -597,6 +597,20 @@ void brw_ENDIF(struct brw_compile *p,
    }
 }
 
+struct brw_instruction *brw_BREAK(struct brw_compile *p)
+{
+   struct brw_instruction *insn;
+   insn = next_insn(p, BRW_OPCODE_BREAK);
+   brw_set_dest(insn, brw_ip_reg());
+   brw_set_src0(insn, brw_ip_reg());
+   brw_set_src1(insn, brw_imm_d(0x0));
+   insn->header.compression_control = BRW_COMPRESSION_NONE;
+   insn->header.execution_size = BRW_EXECUTE_8;
+   insn->header.mask_control = BRW_MASK_DISABLE;
+   insn->bits3.if_else.pad0 = 0;
+   return insn;
+}
+
 /* DO/WHILE loop:
  */
 struct brw_instruction *brw_DO(struct brw_compile *p, GLuint execute_size)
@@ -608,13 +622,15 @@ struct brw_instruction *brw_DO(struct brw_compile *p, GLuint execute_size)
 
       /* Override the defaults for this instruction:
        */
-      brw_set_dest(insn, retype(brw_vec1_grf(0,0), BRW_REGISTER_TYPE_UD));
-      brw_set_src0(insn, retype(brw_vec1_grf(0,0), BRW_REGISTER_TYPE_UD));
-      brw_set_src1(insn, retype(brw_vec1_grf(0,0), BRW_REGISTER_TYPE_UD));
+      brw_set_dest(insn, brw_null_reg());
+      brw_set_src0(insn, brw_null_reg());
+      brw_set_src1(insn, brw_null_reg());
 
       insn->header.compression_control = BRW_COMPRESSION_NONE;
       insn->header.execution_size = execute_size;
+      insn->header.predicate_control = BRW_PREDICATE_NONE;
       /* insn->header.mask_control = BRW_MASK_ENABLE; */
+      insn->header.mask_control = BRW_MASK_DISABLE;
 
       return insn;
    }
@@ -622,7 +638,7 @@ struct brw_instruction *brw_DO(struct brw_compile *p, GLuint execute_size)
 
 
 
-void brw_WHILE(struct brw_compile *p, 
+struct brw_instruction *brw_WHILE(struct brw_compile *p, 
 	       struct brw_instruction *do_insn)
 {
    struct brw_instruction *insn;
@@ -653,7 +669,9 @@ void brw_WHILE(struct brw_compile *p,
 
 /*    insn->header.mask_control = BRW_MASK_ENABLE; */
 
+   insn->header.mask_control = BRW_MASK_DISABLE;
    p->current->header.predicate_control = BRW_PREDICATE_NONE;   
+   return insn;
 }
 
 
diff --git a/src/mesa/drivers/dri/i965/brw_vs.h b/src/mesa/drivers/dri/i965/brw_vs.h
index 912ab563f4..36636b5ffd 100644
--- a/src/mesa/drivers/dri/i965/brw_vs.h
+++ b/src/mesa/drivers/dri/i965/brw_vs.h
@@ -69,6 +69,11 @@ struct brw_vs_compile {
    struct brw_reg tmp;
    struct brw_reg stack;
 
+   struct {	
+       GLboolean used_in_src;
+       struct brw_reg reg;
+   } output_regs[128];
+
    struct brw_reg userplane[6];
 
 };
diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c
index ffc1a0ea09..fa94d5b1a8 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c
@@ -135,6 +135,13 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
       reg++;
    }
 
+   for (i = 0; i < 128; i++) {
+       if (c->output_regs[i].used_in_src) {
+            c->regs[PROGRAM_OUTPUT][i] = brw_vec8_grf(reg, 0);
+            reg++;
+        }
+   }
+
    c->stack =  brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, reg, 0);
    reg += 2;
  
@@ -686,28 +693,28 @@ static void emit_arl( struct brw_vs_compile *c,
  * account.
  */
 static struct brw_reg get_arg( struct brw_vs_compile *c,
-			       struct prog_src_register src )
+			       struct prog_src_register *src )
 {
    struct brw_reg reg;
 
-   if (src.File == PROGRAM_UNDEFINED)
+   if (src->File == PROGRAM_UNDEFINED)
       return brw_null_reg();
 
-   if (src.RelAddr) 
-      reg = deref(c, c->regs[PROGRAM_STATE_VAR][0], src.Index);
+   if (src->RelAddr) 
+      reg = deref(c, c->regs[PROGRAM_STATE_VAR][0], src->Index);
    else
-      reg = get_reg(c, src.File, src.Index);
+      reg = get_reg(c, src->File, src->Index);
 
    /* Convert 3-bit swizzle to 2-bit.  
     */
-   reg.dw1.bits.swizzle = BRW_SWIZZLE4(GET_SWZ(src.Swizzle, 0),
-				       GET_SWZ(src.Swizzle, 1),
-				       GET_SWZ(src.Swizzle, 2),
-				       GET_SWZ(src.Swizzle, 3));
+   reg.dw1.bits.swizzle = BRW_SWIZZLE4(GET_SWZ(src->Swizzle, 0),
+				       GET_SWZ(src->Swizzle, 1),
+				       GET_SWZ(src->Swizzle, 2),
+				       GET_SWZ(src->Swizzle, 3));
 
    /* Note this is ok for non-swizzle instructions: 
     */
-   reg.negate = src.NegateBase ? 1 : 0;   
+   reg.negate = src->NegateBase ? 1 : 0;   
 
    return reg;
 }
@@ -921,10 +928,8 @@ post_vs_emit( struct brw_vs_compile *c, struct brw_instruction *end_inst )
        inst1 = &c->vp->program.Base.Instructions[insn];
        brw_inst1 = inst1->Data;
        switch (inst1->Opcode) {
-	   case OPCODE_BRA:
-	   case OPCODE_BRK:
 	   case OPCODE_CAL:
-	   case OPCODE_ENDLOOP:
+	   case OPCODE_BRA:
 	       target_insn = inst1->BranchTarget;
 	       inst2 = &c->vp->program.Base.Instructions[target_insn];
 	       brw_inst2 = inst2->Data;
@@ -945,12 +950,12 @@ post_vs_emit( struct brw_vs_compile *c, struct brw_instruction *end_inst )
  */
 void brw_vs_emit(struct brw_vs_compile *c )
 {
-#define MAX_IF_DEPTH 32
+#define MAX_IFSN 32
    struct brw_compile *p = &c->func;
    GLuint nr_insns = c->vp->program.Base.NumInstructions;
    GLuint insn, if_insn = 0;
    struct brw_instruction *end_inst;
-   struct brw_instruction *if_inst[MAX_IF_DEPTH];
+   struct brw_instruction *if_inst[MAX_IFSN];
    struct brw_indirect stack_index = brw_indirect(0, 0);   
 
    if (INTEL_DEBUG & DEBUG_VS) {
@@ -962,6 +967,20 @@ void brw_vs_emit(struct brw_vs_compile *c )
    brw_set_compression_control(p, BRW_COMPRESSION_NONE);
    brw_set_access_mode(p, BRW_ALIGN_16);
    
+   /* Message registers can't be read, so copy the output into GRF register
+      if they are used in source registers */
+   for (insn = 0; insn < nr_insns; insn++) {
+       GLuint i;
+       struct prog_instruction *inst = &c->vp->program.Base.Instructions[insn];
+       for (i = 0; i < 3; i++) {
+	   struct prog_src_register *src = &inst->SrcReg[i];
+	   GLuint index = src->Index;
+	   GLuint file = src->File;	
+	   if (file == PROGRAM_OUTPUT && index != VERT_RESULT_HPOS)
+	       c->output_regs[index].used_in_src = GL_TRUE;
+       }
+   }
+
    /* Static register allocation
     */
    brw_vs_alloc_regs(c);
@@ -977,8 +996,15 @@ void brw_vs_emit(struct brw_vs_compile *c )
        */
       inst->Data = &p->store[p->nr_insn];
       if (inst->Opcode != OPCODE_SWZ)
-	 for (i = 0; i < 3; i++) 
-	    args[i] = get_arg(c, inst->SrcReg[i]);
+	  for (i = 0; i < 3; i++) {
+	      struct prog_src_register *src = &inst->SrcReg[i];
+	      GLuint index = src->Index;
+	      GLuint file = src->File;	
+	      if (file == PROGRAM_OUTPUT&&c->output_regs[index].used_in_src)
+		  args[i] = c->output_regs[index].reg;
+	      else
+		  args[i] = get_arg(c, src);
+	  }
 
       /* Get dest regs.  Note that it is possible for a reg to be both
        * dst and arg, given the static allocation of registers.  So
@@ -1085,13 +1111,8 @@ void brw_vs_emit(struct brw_vs_compile *c )
       case OPCODE_XPD:
 	 emit_xpd(p, dst, args[0], args[1]);
 	 break;
-
-      case OPCODE_INT:
-	 /* XXX TODO track type information in shader program */
-	 brw_MOV(p, dst, args[0]);
-	 break;
       case OPCODE_IF:
-	 assert(if_insn < MAX_IF_DEPTH);
+	 assert(if_insn < MAX_IFSN);
          if_inst[if_insn++] = brw_IF(p, BRW_EXECUTE_8);
 	 break;
       case OPCODE_ELSE:
@@ -1101,6 +1122,11 @@ void brw_vs_emit(struct brw_vs_compile *c )
          assert(if_insn > 0);
 	 brw_ENDIF(p, if_inst[--if_insn]);
 	 break;			
+      case OPCODE_BRA:
+         brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
+         brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
+         brw_set_predicate_control_flag_value(p, 0xff);
+        break;
       case OPCODE_CAL:
 	 brw_set_access_mode(p, BRW_ALIGN_1);
 	 brw_ADD(p, deref_1uw(stack_index, 0), brw_ip_reg(), brw_imm_d(3*16));
@@ -1116,13 +1142,9 @@ void brw_vs_emit(struct brw_vs_compile *c )
 	 brw_set_access_mode(p, BRW_ALIGN_1);
          brw_MOV(p, brw_ip_reg(), deref_1uw(stack_index, 0));
 	 brw_set_access_mode(p, BRW_ALIGN_16);
-      case OPCODE_ENDLOOP:
-      case OPCODE_BRK:
-      case OPCODE_BRA:
       case OPCODE_END:	
          brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
         break;
-      case OPCODE_BGNLOOP:
       case OPCODE_PRINT:
       case OPCODE_BGNSUB:
       case OPCODE_ENDSUB:
@@ -1131,8 +1153,12 @@ void brw_vs_emit(struct brw_vs_compile *c )
 	 _mesa_printf("Unsupport opcode %d in vertex shader\n", inst->Opcode);
 	 break;
       }
-      brw_set_predicate_control(p,
-		 inst->CondUpdate?BRW_PREDICATE_NORMAL:BRW_PREDICATE_NONE);
+
+      if (inst->DstReg.File == PROGRAM_OUTPUT
+	      &&inst->DstReg.Index != VERT_RESULT_HPOS
+	      &&c->output_regs[inst->DstReg.Index].used_in_src)
+	  brw_MOV(p, get_dst(c, inst->DstReg), dst);
+
       release_tmps(c);
    }
 
diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c
index a02a0a23af..45ba4eaf32 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.c
+++ b/src/mesa/drivers/dri/i965/brw_wm.c
@@ -154,47 +154,49 @@ static void do_wm_prog( struct brw_context *brw,
    c->fp = fp;
    c->env_param = brw->intel.ctx.FragmentProgram.Parameters;
 
-
-   /* Augment fragment program.  Add instructions for pre- and
-    * post-fragment-program tasks such as interpolation and fogging.
-    */
-   brw_wm_pass_fp(c);
-   
-   /* Translate to intermediate representation.  Build register usage
-    * chains.
-    */
-   brw_wm_pass0(c);
-
-   /* Dead code removal.
-    */
-   brw_wm_pass1(c);
-
-   /* Hal optimization
-    */
-   brw_wm_pass_hal (c);
-   
-   /* Register allocation.
-    */
-   c->grf_limit = BRW_WM_MAX_GRF/2;
-
-   /* This is where we start emitting gen4 code:
-    */
-   brw_init_compile(&c->func);    
-
-   brw_wm_pass2(c);
-
-   c->prog_data.total_grf = c->max_wm_grf;
-   if (c->last_scratch) {
-      c->prog_data.total_scratch =
-	 c->last_scratch + 0x40;
+   if (brw_wm_is_glsl(&c->fp->program)) {
+       brw_wm_glsl_emit(c);
    } else {
-      c->prog_data.total_scratch = 0;
+       /* Augment fragment program.  Add instructions for pre- and
+	* post-fragment-program tasks such as interpolation and fogging.
+	*/
+       brw_wm_pass_fp(c);
+
+       /* Translate to intermediate representation.  Build register usage
+	* chains.
+	*/
+       brw_wm_pass0(c);
+
+       /* Dead code removal.
+	*/
+       brw_wm_pass1(c);
+
+       /* Hal optimization
+	*/
+       brw_wm_pass_hal (c);
+
+       /* Register allocation.
+	*/
+       c->grf_limit = BRW_WM_MAX_GRF/2;
+
+       /* This is where we start emitting gen4 code:
+	*/
+       brw_init_compile(&c->func);    
+
+       brw_wm_pass2(c);
+
+       c->prog_data.total_grf = c->max_wm_grf;
+       if (c->last_scratch) {
+	   c->prog_data.total_scratch =
+	       c->last_scratch + 0x40;
+       } else {
+	   c->prog_data.total_scratch = 0;
+       }
+
+       /* Emit GEN4 code.
+	*/
+       brw_wm_emit(c);
    }
-
-   /* Emit GEN4 code.
-    */
-   brw_wm_emit(c);
-
    /* get the program
     */
    program = brw_get_program(&c->func, &program_size);
diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h
index f5fddfdb68..4143d5be6c 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.h
+++ b/src/mesa/drivers/dri/i965/brw_wm.h
@@ -231,6 +231,14 @@ struct brw_wm_compile {
    GLuint grf_limit;
    GLuint max_wm_grf;
    GLuint last_scratch;
+
+   struct {
+	GLboolean inited;
+	struct brw_reg reg;
+   } wm_regs[PROGRAM_PAYLOAD+1][256][4];
+   struct brw_reg ret_reg;
+   GLuint reg_index;
+   GLuint tmp_index;
 };
 
 
@@ -259,4 +267,6 @@ void brw_wm_lookup_iz( GLuint line_aa,
 		       GLuint lookup,
 		       struct brw_wm_prog_key *key );
 
+GLboolean brw_wm_is_glsl(struct gl_fragment_program *fp);
+void brw_wm_glsl_emit(struct brw_wm_compile *c);
 #endif
diff --git a/src/mesa/drivers/dri/i965/brw_wm_emit.c b/src/mesa/drivers/dri/i965/brw_wm_emit.c
index 197a0ae13d..5660b55516 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_emit.c
@@ -229,20 +229,20 @@ static void emit_cinterp( struct brw_compile *p,
 			 GLuint mask,
 			 const struct brw_reg *arg0 )
 {
-   struct brw_reg interp[4];
-   GLuint nr = arg0[0].nr;
-   GLuint i;
-
-   interp[0] = brw_vec1_grf(nr, 0);
-   interp[1] = brw_vec1_grf(nr, 4);
-   interp[2] = brw_vec1_grf(nr+1, 0);
-   interp[3] = brw_vec1_grf(nr+1, 4);
-
-   for(i = 0; i < 4; i++ ) {
-      if (mask & (1<<i)) {
-	 brw_MOV(p, dst[i], suboffset(interp[i],3));	/* TODO: optimize away like other moves */
-      }
-   }
+	struct brw_reg interp[4];
+	GLuint nr = arg0[0].nr;
+	GLuint i;
+
+	interp[0] = brw_vec1_grf(nr, 0);
+	interp[1] = brw_vec1_grf(nr, 4);
+	interp[2] = brw_vec1_grf(nr+1, 0);
+	interp[3] = brw_vec1_grf(nr+1, 4);
+
+	for(i = 0; i < 4; i++ ) {
+		if (mask & (1<<i)) {
+			brw_MOV(p, dst[i], suboffset(interp[i],3));	/* TODO: optimize away like other moves */
+		}
+	}
 }
 
 
diff --git a/src/mesa/drivers/dri/i965/brw_wm_fp.c b/src/mesa/drivers/dri/i965/brw_wm_fp.c
index ff97d87dc4..403160c494 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_fp.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_fp.c
@@ -176,6 +176,7 @@ static struct prog_instruction *emit_insn(struct brw_wm_compile *c,
 {
    struct prog_instruction *inst = get_fp_inst(c);
    *inst = *inst0;
+   inst->Data = (void *)inst0;
    return inst;
 }
 
@@ -201,7 +202,6 @@ static struct prog_instruction * emit_op(struct brw_wm_compile *c,
    inst->SrcReg[0] = src0;
    inst->SrcReg[1] = src1;
    inst->SrcReg[2] = src2;
-   
    return inst;
 }
    
@@ -907,8 +907,10 @@ void brw_wm_pass_fp( struct brw_wm_compile *c )
 	  */
 	 out->DstReg.WriteMask = 0;
 	 break;
-
       case OPCODE_END:
+	 emit_fog(c);
+	 emit_fb_write(c);
+	 break;
       case OPCODE_PRINT:
 	 break;
 	 
@@ -917,15 +919,11 @@ void brw_wm_pass_fp( struct brw_wm_compile *c )
 	 break;
       }
    }
-   
-   emit_fog(c);
-   emit_fb_write(c);
-
 
    if (INTEL_DEBUG & DEBUG_WM) {
-      _mesa_printf("\n\n\npass_fp:\n");
-      print_insns( c->prog_instructions, c->nr_fp_insns );
-      _mesa_printf("\n");
+	   _mesa_printf("\n\n\npass_fp:\n");
+	   print_insns( c->prog_instructions, c->nr_fp_insns );
+	   _mesa_printf("\n");
    }
 }
 
diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
new file mode 100644
index 0000000000..cdd7976607
--- /dev/null
+++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
@@ -0,0 +1,1177 @@
+#include "macros.h"
+#include "shader/prog_parameter.h"
+#include "brw_context.h"
+#include "brw_eu.h"
+#include "brw_wm.h"
+
+/* Only guess, need a flag in gl_fragment_program later */
+GLboolean brw_wm_is_glsl(struct gl_fragment_program *fp)
+{
+    int i;
+    for (i = 0; i < fp->Base.NumInstructions; i++) {
+	struct prog_instruction *inst = &fp->Base.Instructions[i];
+	switch (inst->Opcode) {
+	    case OPCODE_IF:
+	    case OPCODE_ENDIF:
+	    case OPCODE_CAL:
+	    case OPCODE_BRK:
+	    case OPCODE_RET:
+	    case OPCODE_BGNLOOP:
+		return GL_TRUE; 
+	    default:
+		break;
+	}
+    }
+    return GL_FALSE; 
+}
+
+static void set_reg(struct brw_wm_compile *c, int file, int index, 
+	int component, struct brw_reg reg)
+{
+    c->wm_regs[file][index][component].reg = reg;
+    c->wm_regs[file][index][component].inited = GL_TRUE;
+}
+
+static int get_scalar_dst_index(struct prog_instruction *inst)
+{
+    int i;
+    for (i = 0; i < 4; i++)
+	if (inst->DstReg.WriteMask & (1<<i))
+	    break;
+    return i;
+}
+
+static struct brw_reg alloc_tmp(struct brw_wm_compile *c)
+{
+    struct brw_reg reg;
+    reg = brw_vec8_grf(c->tmp_index--, 0);
+    return reg;
+}
+
+static void release_tmps(struct brw_wm_compile *c)
+{
+    c->tmp_index = 127;
+}
+
+static struct brw_reg 
+get_reg(struct brw_wm_compile *c, int file, int index, int component, int nr, GLuint neg, GLuint abs)
+{
+    struct brw_reg reg;
+    switch (file) {
+	case PROGRAM_STATE_VAR:
+	case PROGRAM_CONSTANT:
+	case PROGRAM_UNIFORM:
+	    file = PROGRAM_STATE_VAR;
+	    break;
+	case PROGRAM_UNDEFINED:
+	    return brw_null_reg();	
+	default:
+	    break;
+    }
+
+    if(c->wm_regs[file][index][component].inited)
+	reg = c->wm_regs[file][index][component].reg;
+    else 
+	reg = brw_vec8_grf(c->reg_index, 0);
+
+    if(!c->wm_regs[file][index][component].inited) {
+	set_reg(c, file, index, component, reg);
+	c->reg_index++;
+    }
+
+    if (neg & (1<< component)) {
+	reg = negate(reg);
+    }
+    if (abs)
+	reg = brw_abs(reg);
+    return reg;
+}
+
+static void prealloc_reg(struct brw_wm_compile *c)
+{
+    int i, j;
+    struct brw_reg reg;
+    int nr_interp_regs = 0;
+    GLuint inputs = FRAG_BIT_WPOS | c->fp_interp_emitted;
+
+    for (i = 0; i < 4; i++) {
+	reg = (i < c->key.nr_depth_regs) 
+	    ? brw_vec8_grf(i*2, 0) : brw_vec8_grf(0, 0);
+	set_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH, i, reg);
+    }
+    c->reg_index += 2*c->key.nr_depth_regs;
+    {
+	int nr_params = c->fp->program.Base.Parameters->NumParameters;
+	struct gl_program_parameter_list *plist = 
+	    c->fp->program.Base.Parameters;
+	int index = 0;
+	c->prog_data.nr_params = 4*nr_params;
+	for (i = 0; i < nr_params; i++) {
+	    for (j = 0; j < 4; j++, index++) {
+		reg = brw_vec1_grf(c->reg_index + index/8, 
+			index%8);
+		c->prog_data.param[index] = 
+		    &plist->ParameterValues[i][j];
+		set_reg(c, PROGRAM_STATE_VAR, i, j, reg);
+	    }
+	}
+	c->nr_creg = 2*((4*nr_params+15)/16);
+	c->reg_index += c->nr_creg;
+    }
+    for (i = 0; i < FRAG_ATTRIB_MAX; i++) {
+	if (inputs & (1<<i)) {
+	    nr_interp_regs++;
+	    reg = brw_vec8_grf(c->reg_index, 0);
+	    for (j = 0; j < 4; j++)
+		set_reg(c, PROGRAM_PAYLOAD, i, j, reg);
+	    c->reg_index += 2;
+
+	}
+    }
+    c->prog_data.first_curbe_grf = c->key.nr_depth_regs * 2;
+    c->prog_data.urb_read_length = nr_interp_regs * 2;
+    c->prog_data.curb_read_length = c->nr_creg;
+    c->ret_reg = brw_uw1_reg(BRW_GENERAL_REGISTER_FILE, c->reg_index, 0);
+    c->reg_index++;
+}
+
+static struct brw_reg get_dst_reg(struct brw_wm_compile *c, 
+	struct prog_instruction *inst, int component, int nr)
+{
+    return get_reg(c, inst->DstReg.File, inst->DstReg.Index, component, nr,
+	    0, 0);
+}
+
+static struct brw_reg get_src_reg(struct brw_wm_compile *c, 
+	struct prog_src_register *src, int index, int nr)
+{
+    int component = GET_SWZ(src->Swizzle, index);
+    return get_reg(c, src->File, src->Index, component, nr, 
+	    src->NegateBase, src->Abs);
+}
+
+static void emit_abs( struct brw_wm_compile *c,
+		struct prog_instruction *inst)
+{
+    int i;
+    struct brw_compile *p = &c->func;
+    brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF);
+    for (i = 0; i < 4; i++) {
+	if (inst->DstReg.WriteMask & (1<<i)) {
+	    struct brw_reg src, dst;
+	    dst = get_dst_reg(c, inst, i, 1);
+	    src = get_src_reg(c, &inst->SrcReg[0], i, 1);
+	    brw_MOV(p, dst, brw_abs(src));
+	}
+    }
+    brw_set_saturate(p, 0);
+}
+
+static void emit_mov( struct brw_wm_compile *c,
+		struct prog_instruction *inst)
+{
+    int i;
+    struct brw_compile *p = &c->func;
+    GLuint mask = inst->DstReg.WriteMask;
+    brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF);
+    for (i = 0; i < 4; i++) {
+	if (mask & (1<<i)) {
+	    struct brw_reg src, dst;
+	    dst = get_dst_reg(c, inst, i, 1);
+	    src = get_src_reg(c, &inst->SrcReg[0], i, 1);
+	    brw_MOV(p, dst, src);
+	}
+    }
+    brw_set_saturate(p, 0);
+}
+
+static void emit_pixel_xy(struct brw_wm_compile *c,
+		struct prog_instruction *inst)
+{
+    struct brw_reg r1 = brw_vec1_grf(1, 0);
+    struct brw_reg r1_uw = retype(r1, BRW_REGISTER_TYPE_UW);
+
+    struct brw_reg dst0, dst1;
+    struct brw_compile *p = &c->func;
+    GLuint mask = inst->DstReg.WriteMask;
+
+    dst0 = get_dst_reg(c, inst, 0, 1);
+    dst1 = get_dst_reg(c, inst, 1, 1);
+    /* Calculate pixel centers by adding 1 or 0 to each of the
+     * micro-tile coordinates passed in r1.
+     */
+    if (mask & WRITEMASK_X) {
+	brw_ADD(p,
+		vec8(retype(dst0, BRW_REGISTER_TYPE_UW)),
+		stride(suboffset(r1_uw, 4), 2, 4, 0),
+		brw_imm_v(0x10101010));
+    }
+
+    if (mask & WRITEMASK_Y) {
+	brw_ADD(p,
+		vec8(retype(dst1, BRW_REGISTER_TYPE_UW)),
+		stride(suboffset(r1_uw, 5), 2, 4, 0),
+		brw_imm_v(0x11001100));
+    }
+
+}
+
+static void emit_delta_xy(struct brw_wm_compile *c,
+		struct prog_instruction *inst)
+{
+    struct brw_reg r1 = brw_vec1_grf(1, 0);
+    struct brw_reg dst0, dst1, src0, src1;
+    struct brw_compile *p = &c->func;
+    GLuint mask = inst->DstReg.WriteMask;
+
+    dst0 = get_dst_reg(c, inst, 0, 1);
+    dst1 = get_dst_reg(c, inst, 1, 1);
+    src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1);
+    src1 = get_src_reg(c, &inst->SrcReg[0], 1, 1);
+    /* Calc delta X,Y by subtracting origin in r1 from the pixel
+     * centers.
+     */
+    if (mask & WRITEMASK_X) {
+	brw_ADD(p,
+		dst0,
+		retype(src0, BRW_REGISTER_TYPE_UW),
+		negate(r1));
+    }
+
+    if (mask & WRITEMASK_Y) {
+	brw_ADD(p,
+		dst1,
+		retype(src1, BRW_REGISTER_TYPE_UW),
+		negate(suboffset(r1,1)));
+
+    }
+
+}
+
+
+static void fire_fb_write( struct brw_wm_compile *c,
+                           GLuint base_reg,
+                           GLuint nr )
+{
+    struct brw_compile *p = &c->func;
+
+    /* Pass through control information:
+     */
+    /*  mov (8) m1.0<1>:ud   r1.0<8;8,1>:ud   { Align1 NoMask } */
+    {
+	brw_push_insn_state(p);
+	brw_set_mask_control(p, BRW_MASK_DISABLE); /* ? */
+	brw_MOV(p,
+		brw_message_reg(base_reg + 1),
+		brw_vec8_grf(1, 0));
+	brw_pop_insn_state(p);
+    }
+    /* Send framebuffer write message: */
+    brw_fb_WRITE(p,
+	    retype(vec8(brw_null_reg()), BRW_REGISTER_TYPE_UW),
+	    base_reg,
+	    retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW),
+	    0,              /* render surface always 0 */
+	    nr,
+	    0,
+	    1);
+}
+
+static void emit_fb_write(struct brw_wm_compile *c,
+		struct prog_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    int nr = 2;
+    int channel;
+    struct brw_reg src0;//, src1, src2, dst;
+
+    /* Reserve a space for AA - may not be needed:
+     */
+    if (c->key.aa_dest_stencil_reg)
+	nr += 1;
+    {
+	brw_push_insn_state(p);
+	for (channel = 0; channel < 4; channel++) {
+	    src0 = get_src_reg(c,  &inst->SrcReg[0], channel, 1);
+	    /*  mov (8) m2.0<1>:ud   r28.0<8;8,1>:ud  { Align1 } */
+	    /*  mov (8) m6.0<1>:ud   r29.0<8;8,1>:ud  { Align1 SecHalf } */
+	    brw_MOV(p, brw_message_reg(nr + channel), src0);
+	}
+	/* skip over the regs populated above: */
+	nr += 8;
+	brw_pop_insn_state(p);
+    }
+    fire_fb_write(c, 0, nr);
+}
+
+static void emit_pixel_w( struct brw_wm_compile *c,
+		struct prog_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    GLuint mask = inst->DstReg.WriteMask;
+    if (mask & WRITEMASK_W) {
+	struct brw_reg dst, src0, delta0, delta1;
+	struct brw_reg interp3;
+
+	dst = get_dst_reg(c, inst, 3, 1);
+	src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1);
+	delta0 = get_src_reg(c, &inst->SrcReg[1], 0, 1);
+	delta1 = get_src_reg(c, &inst->SrcReg[1], 1, 1);
+
+	interp3 = brw_vec1_grf(src0.nr+1, 4);
+	/* Calc 1/w - just linterp wpos[3] optimized by putting the
+	 * result straight into a message reg.
+	 */
+	brw_LINE(p, brw_null_reg(), interp3, delta0);
+	brw_MAC(p, brw_message_reg(2), suboffset(interp3, 1), delta1);
+
+	/* Calc w */
+	brw_math_16( p, dst,
+		BRW_MATH_FUNCTION_INV,
+		BRW_MATH_SATURATE_NONE,
+		2, brw_null_reg(),
+		BRW_MATH_PRECISION_FULL);
+    }
+}
+
+static void emit_linterp(struct brw_wm_compile *c,
+		struct prog_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    GLuint mask = inst->DstReg.WriteMask;
+    struct brw_reg interp[4];
+    struct brw_reg dst, delta0, delta1;
+    struct brw_reg src0;
+
+    src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1);
+    delta0 = get_src_reg(c, &inst->SrcReg[1], 0, 1);
+    delta1 = get_src_reg(c, &inst->SrcReg[1], 1, 1);
+    GLuint nr = src0.nr;
+    int i;
+
+    interp[0] = brw_vec1_grf(nr, 0);
+    interp[1] = brw_vec1_grf(nr, 4);
+    interp[2] = brw_vec1_grf(nr+1, 0);
+    interp[3] = brw_vec1_grf(nr+1, 4);
+
+    for(i = 0; i < 4; i++ ) {
+	if (mask & (1<<i)) {
+	    dst = get_dst_reg(c, inst, i, 1);
+	    brw_LINE(p, brw_null_reg(), interp[i], delta0);
+	    brw_MAC(p, dst, suboffset(interp[i],1), delta1);
+	}
+    }
+}
+
+static void emit_cinterp(struct brw_wm_compile *c,
+		struct prog_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    GLuint mask = inst->DstReg.WriteMask;
+
+    struct brw_reg interp[4];
+    struct brw_reg dst, src0;
+
+    src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1);
+    GLuint nr = src0.nr;
+    int i;
+
+    interp[0] = brw_vec1_grf(nr, 0);
+    interp[1] = brw_vec1_grf(nr, 4);
+    interp[2] = brw_vec1_grf(nr+1, 0);
+    interp[3] = brw_vec1_grf(nr+1, 4);
+
+    for(i = 0; i < 4; i++ ) {
+	if (mask & (1<<i)) {
+	    dst = get_dst_reg(c, inst, i, 1);
+	    brw_MOV(p, dst, suboffset(interp[i],3));
+	}
+    }
+}
+
+static void emit_pinterp(struct brw_wm_compile *c,
+		struct prog_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    GLuint mask = inst->DstReg.WriteMask;
+
+    struct brw_reg interp[4];
+    struct brw_reg dst, delta0, delta1;
+    struct brw_reg src0, w;
+
+    src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1);
+    delta0 = get_src_reg(c, &inst->SrcReg[1], 0, 1);
+    delta1 = get_src_reg(c, &inst->SrcReg[1], 1, 1);
+    w = get_src_reg(c, &inst->SrcReg[2], 3, 1);
+    GLuint nr = src0.nr;
+    int i;
+
+    interp[0] = brw_vec1_grf(nr, 0);
+    interp[1] = brw_vec1_grf(nr, 4);
+    interp[2] = brw_vec1_grf(nr+1, 0);
+    interp[3] = brw_vec1_grf(nr+1, 4);
+
+    for(i = 0; i < 4; i++ ) {
+	if (mask & (1<<i)) {
+	    dst = get_dst_reg(c, inst, i, 1);
+	    brw_LINE(p, brw_null_reg(), interp[i], delta0);
+	    brw_MAC(p, dst, suboffset(interp[i],1), 
+		    delta1);
+	    brw_MUL(p, dst, dst, w);
+	}
+    }
+}
+
+static void emit_xpd(struct brw_wm_compile *c,
+		struct prog_instruction *inst)
+{
+    int i;
+    struct brw_compile *p = &c->func;
+    GLuint mask = inst->DstReg.WriteMask;
+    for (i = 0; i < 4; i++) {
+	GLuint i2 = (i+2)%3;
+	GLuint i1 = (i+1)%3;
+	if (mask & (1<<i)) {
+	    struct brw_reg src0, src1, dst;
+	    dst = get_dst_reg(c, inst, i, 1);
+	    src0 = negate(get_src_reg(c, &inst->SrcReg[0], i2, 1));
+	    src1 = get_src_reg(c, &inst->SrcReg[1], i1, 1);
+	    brw_MUL(p, brw_null_reg(), src0, src1);
+	    src0 = get_src_reg(c, &inst->SrcReg[0], i1, 1);
+	    src1 = get_src_reg(c, &inst->SrcReg[1], i2, 1);
+	    brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF);
+	    brw_MAC(p, dst, src0, src1);
+	    brw_set_saturate(p, 0);
+	}
+    }
+    brw_set_saturate(p, 0);
+}
+
+static void emit_dp3(struct brw_wm_compile *c,
+		struct prog_instruction *inst)
+{
+    struct brw_reg src0[3], src1[3], dst;
+    int i;
+    struct brw_compile *p = &c->func;
+    for (i = 0; i < 3; i++) {
+	src0[i] = get_src_reg(c, &inst->SrcReg[0], i, 1);
+	src1[i] = get_src_reg(c, &inst->SrcReg[1], i, 1);
+    }
+
+    dst = get_dst_reg(c, inst, get_scalar_dst_index(inst), 1);
+    brw_MUL(p, brw_null_reg(), src0[0], src1[0]);
+    brw_MAC(p, brw_null_reg(), src0[1], src1[1]);
+    brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+    brw_MAC(p, dst, src0[2], src1[2]);
+    brw_set_saturate(p, 0);
+}
+
+static void emit_dp4(struct brw_wm_compile *c,
+		struct prog_instruction *inst)
+{
+    struct brw_reg src0[4], src1[4], dst;
+    int i;
+    struct brw_compile *p = &c->func;
+    for (i = 0; i < 4; i++) {
+	src0[i] = get_src_reg(c, &inst->SrcReg[0], i, 1);
+	src1[i] = get_src_reg(c, &inst->SrcReg[1], i, 1);
+    }
+    dst = get_dst_reg(c, inst, get_scalar_dst_index(inst), 1);
+    brw_MUL(p, brw_null_reg(), src0[0], src1[0]);
+    brw_MAC(p, brw_null_reg(), src0[1], src1[1]);
+    brw_MAC(p, brw_null_reg(), src0[2], src1[2]);
+    brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+    brw_MAC(p, dst, src0[3], src1[3]);
+    brw_set_saturate(p, 0);
+}
+
+static void emit_dph(struct brw_wm_compile *c,
+		struct prog_instruction *inst)
+{
+    struct brw_reg src0[4], src1[4], dst;
+    int i;
+    struct brw_compile *p = &c->func;
+    for (i = 0; i < 4; i++) {
+	src0[i] = get_src_reg(c, &inst->SrcReg[0], i, 1);
+	src1[i] = get_src_reg(c, &inst->SrcReg[1], i, 1);
+    }
+    dst = get_dst_reg(c, inst, get_scalar_dst_index(inst), 1);
+    brw_MUL(p, brw_null_reg(), src0[0], src1[0]);
+    brw_MAC(p, brw_null_reg(), src0[1], src1[1]);
+    brw_MAC(p, dst, src0[2], src1[2]);
+    brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+    brw_ADD(p, dst, src0[3], src1[3]);
+    brw_set_saturate(p, 0);
+}
+
+static void emit_math1(struct brw_wm_compile *c,
+		struct prog_instruction *inst, GLuint func)
+{
+    struct brw_compile *p = &c->func;
+    struct brw_reg src0, dst;
+
+    src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1);
+    dst = get_dst_reg(c, inst, get_scalar_dst_index(inst), 1);
+    brw_MOV(p, brw_message_reg(2), src0);
+    brw_math(p,
+	    dst,
+	    func,
+	    (inst->SaturateMode != SATURATE_OFF) ? BRW_MATH_SATURATE_SATURATE : BRW_MATH_SATURATE_NONE,
+	    2,
+	    brw_null_reg(),
+	    BRW_MATH_DATA_VECTOR,
+	    BRW_MATH_PRECISION_FULL);
+}
+
+static void emit_rcp(struct brw_wm_compile *c,
+		struct prog_instruction *inst)
+{
+    emit_math1(c, inst, BRW_MATH_FUNCTION_INV);
+}
+
+static void emit_rsq(struct brw_wm_compile *c,
+		struct prog_instruction *inst)
+{
+    emit_math1(c, inst, BRW_MATH_FUNCTION_RSQ);
+}
+
+static void emit_sin(struct brw_wm_compile *c,
+		struct prog_instruction *inst)
+{
+    emit_math1(c, inst, BRW_MATH_FUNCTION_SIN);
+}
+
+static void emit_cos(struct brw_wm_compile *c,
+		struct prog_instruction *inst)
+{
+    emit_math1(c, inst, BRW_MATH_FUNCTION_COS);
+}
+
+static void emit_ex2(struct brw_wm_compile *c,
+		struct prog_instruction *inst)
+{
+    emit_math1(c, inst, BRW_MATH_FUNCTION_EXP);
+}
+
+static void emit_lg2(struct brw_wm_compile *c,
+		struct prog_instruction *inst)
+{
+    emit_math1(c, inst, BRW_MATH_FUNCTION_LOG);
+}
+
+static void emit_add(struct brw_wm_compile *c,
+		struct prog_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    struct brw_reg src0, src1, dst;
+    GLuint mask = inst->DstReg.WriteMask;
+    int i;
+    brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+    for (i = 0 ; i < 4; i++) {
+	if (mask & (1<<i)) {
+	    dst = get_dst_reg(c, inst, i, 1);
+	    src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
+	    src1 = get_src_reg(c, &inst->SrcReg[1], i, 1);
+	    brw_ADD(p, dst, src0, src1);
+	}
+    }
+    brw_set_saturate(p, 0);
+}
+
+static void emit_sub(struct brw_wm_compile *c,
+		struct prog_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    struct brw_reg src0, src1, dst;
+    GLuint mask = inst->DstReg.WriteMask;
+    int i;
+    brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+    for (i = 0 ; i < 4; i++) {
+	if (mask & (1<<i)) {
+	    dst = get_dst_reg(c, inst, i, 1);
+	    src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
+	    src1 = get_src_reg(c, &inst->SrcReg[1], i, 1);
+	    brw_ADD(p, dst, src0, negate(src1));
+	}
+    }
+    brw_set_saturate(p, 0);
+}
+
+static void emit_mul(struct brw_wm_compile *c,
+		struct prog_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    struct brw_reg src0, src1, dst;
+    GLuint mask = inst->DstReg.WriteMask;
+    int i;
+    brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+    for (i = 0 ; i < 4; i++) {
+	if (mask & (1<<i)) {
+	    dst = get_dst_reg(c, inst, i, 1);
+	    src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
+	    src1 = get_src_reg(c, &inst->SrcReg[1], i, 1);
+	    brw_MUL(p, dst, src0, src1);
+	}
+    }
+    brw_set_saturate(p, 0);
+}
+
+static void emit_frc(struct brw_wm_compile *c,
+		struct prog_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    struct brw_reg src0, dst;
+    GLuint mask = inst->DstReg.WriteMask;
+    int i;
+    brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+    for (i = 0 ; i < 4; i++) {
+	if (mask & (1<<i)) {
+	    dst = get_dst_reg(c, inst, i, 1);
+	    src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
+	    brw_FRC(p, dst, src0);
+	}
+    }
+    if (inst->SaturateMode != SATURATE_OFF)
+	brw_set_saturate(p, 0);
+}
+
+static void emit_flr(struct brw_wm_compile *c,
+		struct prog_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    struct brw_reg src0, dst;
+    GLuint mask = inst->DstReg.WriteMask;
+    int i;
+    brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+    for (i = 0 ; i < 4; i++) {
+	if (mask & (1<<i)) {
+	    dst = get_dst_reg(c, inst, i, 1);
+	    src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
+	    brw_RNDD(p, dst, src0);
+	}
+    }
+    brw_set_saturate(p, 0);
+}
+
+static void emit_max(struct brw_wm_compile *c,
+		struct prog_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    GLuint mask = inst->DstReg.WriteMask;
+    struct brw_reg src0, src1, dst;
+    int i;
+    brw_push_insn_state(p);
+    for (i = 0; i < 4; i++) {
+	if (mask & (1<<i)) {
+	    dst = get_dst_reg(c, inst, i, 1);
+	    src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
+	    src1 = get_src_reg(c, &inst->SrcReg[1], i, 1);
+	    brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+	    brw_MOV(p, dst, src0);
+	    brw_set_saturate(p, 0);
+
+	    brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, src0, src1);
+	    brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+	    brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
+	    brw_MOV(p, dst, src1);
+	    brw_set_saturate(p, 0);
+	    brw_set_predicate_control_flag_value(p, 0xff);
+	}
+    }
+    brw_pop_insn_state(p);
+}
+
+static void emit_min(struct brw_wm_compile *c,
+		struct prog_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    GLuint mask = inst->DstReg.WriteMask;
+    struct brw_reg src0, src1, dst;
+    int i;
+    brw_push_insn_state(p);
+    for (i = 0; i < 4; i++) {
+	if (mask & (1<<i)) {
+	    dst = get_dst_reg(c, inst, i, 1);
+	    src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
+	    src1 = get_src_reg(c, &inst->SrcReg[1], i, 1);
+	    brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+	    brw_MOV(p, dst, src0);
+	    brw_set_saturate(p, 0);
+
+	    brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, src1, src0);
+	    brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+	    brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
+	    brw_MOV(p, dst, src1);
+	    brw_set_saturate(p, 0);
+	    brw_set_predicate_control_flag_value(p, 0xff);
+	}
+    }
+    brw_pop_insn_state(p);
+}
+
+static void emit_pow(struct brw_wm_compile *c,
+		struct prog_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    struct brw_reg dst, src0, src1;
+    dst = get_dst_reg(c, inst, get_scalar_dst_index(inst), 1);
+    src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1);
+    src1 = get_src_reg(c, &inst->SrcReg[1], 0, 1);
+
+    brw_MOV(p, brw_message_reg(2), src0);
+    brw_MOV(p, brw_message_reg(3), src1);
+
+    brw_math(p,
+	    dst,
+	    BRW_MATH_FUNCTION_POW,
+	    (inst->SaturateMode != SATURATE_OFF) ? BRW_MATH_SATURATE_SATURATE : BRW_MATH_SATURATE_NONE,
+	    2,
+	    brw_null_reg(),
+	    BRW_MATH_DATA_VECTOR,
+	    BRW_MATH_PRECISION_FULL);
+}
+
+static void emit_lrp(struct brw_wm_compile *c,
+		struct prog_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    GLuint mask = inst->DstReg.WriteMask;
+    struct brw_reg dst, tmp1, tmp2, src0, src1, src2;
+    int i;
+    for (i = 0; i < 4; i++) {
+	if (mask & (1<<i)) {
+	    dst = get_dst_reg(c, inst, i, 1);
+	    src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
+
+	    src1 = get_src_reg(c, &inst->SrcReg[1], i, 1);
+
+	    if (src1.nr == dst.nr) {
+		tmp1 = alloc_tmp(c);
+		brw_MOV(p, tmp1, src1);
+	    } else
+		tmp1 = src1;
+
+	    src2 = get_src_reg(c, &inst->SrcReg[2], i, 1);
+	    if (src2.nr == dst.nr) {
+		tmp2 = alloc_tmp(c);
+		brw_MOV(p, tmp2, src2);
+	    } else
+		tmp2 = src2;
+
+	    brw_ADD(p, dst, negate(src0), brw_imm_f(1.0));
+	    brw_MUL(p, brw_null_reg(), dst, tmp2);
+	    brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+	    brw_MAC(p, dst, src0, tmp1);
+	    brw_set_saturate(p, 0);
+	}
+	release_tmps(c);
+    }
+}
+
+static void emit_mad(struct brw_wm_compile *c,
+		struct prog_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    GLuint mask = inst->DstReg.WriteMask;
+    struct brw_reg dst, src0, src1, src2;
+    int i;
+
+    for (i = 0; i < 4; i++) {
+	if (mask & (1<<i)) {
+	    dst = get_dst_reg(c, inst, i, 1);
+	    src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
+	    src1 = get_src_reg(c, &inst->SrcReg[1], i, 1);
+	    src2 = get_src_reg(c, &inst->SrcReg[2], i, 1);
+	    brw_MUL(p, dst, src0, src1);
+
+	    brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+	    brw_ADD(p, dst, dst, src2);
+	    brw_set_saturate(p, 0);
+	}
+    }
+}
+
+static void emit_sop(struct brw_wm_compile *c,
+		struct prog_instruction *inst, GLuint cond)
+{
+    struct brw_compile *p = &c->func;
+    GLuint mask = inst->DstReg.WriteMask;
+    struct brw_reg dst, src0, src1;
+    int i;
+
+    for (i = 0; i < 4; i++) {
+	if (mask & (1<<i)) {
+	    dst = get_dst_reg(c, inst, i, 1);
+	    src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
+	    src1 = get_src_reg(c, &inst->SrcReg[1], i, 1);
+	    brw_MOV(p, dst, brw_imm_f(0));
+	    brw_CMP(p, brw_null_reg(), cond, src0, src1);
+	    brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
+	    brw_MOV(p, dst, brw_imm_f(1.0));
+	    brw_set_predicate_control_flag_value(p, 0xff);
+	}
+    }
+}
+
+static void emit_slt(struct brw_wm_compile *c,
+		struct prog_instruction *inst)
+{
+    emit_sop(c, inst, BRW_CONDITIONAL_L);
+}
+
+static void emit_sle(struct brw_wm_compile *c,
+		struct prog_instruction *inst)
+{
+    emit_sop(c, inst, BRW_CONDITIONAL_LE);
+}
+
+static void emit_sgt(struct brw_wm_compile *c,
+		struct prog_instruction *inst)
+{
+    emit_sop(c, inst, BRW_CONDITIONAL_G);
+}
+
+static void emit_sge(struct brw_wm_compile *c,
+		struct prog_instruction *inst)
+{
+    emit_sop(c, inst, BRW_CONDITIONAL_GE);
+}
+
+static void emit_seq(struct brw_wm_compile *c,
+		struct prog_instruction *inst)
+{
+    emit_sop(c, inst, BRW_CONDITIONAL_EQ);
+}
+
+static void emit_sne(struct brw_wm_compile *c,
+		struct prog_instruction *inst)
+{
+    emit_sop(c, inst, BRW_CONDITIONAL_NEQ);
+}
+/* TODO
+   BIAS on SIMD8 not workind yet...
+ */	
+static void emit_txb(struct brw_wm_compile *c,
+		struct prog_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    struct brw_reg dst[4], src[4], payload_reg;
+    GLuint i;
+    payload_reg = get_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH, 0, 1, 0, 0);
+    for (i = 0; i < 4; i++) 
+	dst[i] = get_dst_reg(c, inst, i, 1);
+    for (i = 0; i < 4; i++)
+	src[i] = get_src_reg(c, &inst->SrcReg[0], i, 1);
+
+    switch (inst->TexSrcTarget) {
+	case TEXTURE_1D_INDEX:
+	    brw_MOV(p, brw_message_reg(2), src[0]);
+	    brw_MOV(p, brw_message_reg(3), brw_imm_f(0));
+	    brw_MOV(p, brw_message_reg(4), brw_imm_f(0));
+	    break;
+	case TEXTURE_2D_INDEX:
+	case TEXTURE_RECT_INDEX:
+	    brw_MOV(p, brw_message_reg(2), src[0]);
+	    brw_MOV(p, brw_message_reg(3), src[1]);
+	    brw_MOV(p, brw_message_reg(4), brw_imm_f(0));
+	    break;
+	default:
+	    brw_MOV(p, brw_message_reg(2), src[0]);
+	    brw_MOV(p, brw_message_reg(3), src[1]);
+	    brw_MOV(p, brw_message_reg(4), src[2]);
+	    break;
+    }
+    brw_MOV(p, brw_message_reg(5), src[3]);
+    brw_MOV(p, brw_message_reg(6), brw_imm_f(0));
+    brw_SAMPLE(p,
+	    retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW),
+	    1,
+	    retype(payload_reg, BRW_REGISTER_TYPE_UW),
+	    inst->TexSrcUnit + 1, /* surface */
+	    inst->TexSrcUnit,     /* sampler */
+	    inst->DstReg.WriteMask,
+	    BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS,
+	    4,
+	    4,
+	    0);
+}
+
+static void emit_tex(struct brw_wm_compile *c,
+		struct prog_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    struct brw_reg dst[4], src[4], payload_reg;
+    GLuint msg_len;
+    GLuint i, nr;
+    GLuint emit;
+
+    payload_reg = get_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH, 0, 1, 0, 0);
+    for (i = 0; i < 4; i++) 
+	dst[i] = get_dst_reg(c, inst, i, 1);
+    for (i = 0; i < 4; i++)
+	src[i] = get_src_reg(c, &inst->SrcReg[0], i, 1);
+
+
+    switch (inst->TexSrcTarget) {
+	case TEXTURE_1D_INDEX:
+	    emit = WRITEMASK_X;
+	    nr = 1;
+	    break;
+	case TEXTURE_2D_INDEX:
+	case TEXTURE_RECT_INDEX:
+	    emit = WRITEMASK_XY;
+	    nr = 2;
+	    break;
+	default:
+	    emit = WRITEMASK_XYZ;
+	    nr = 3;
+	    break;
+    }
+    msg_len = 1;
+
+    for (i = 0; i < nr; i++) {
+	static const GLuint swz[4] = {0,1,2,2};
+	if (emit & (1<<i))
+	    brw_MOV(p, brw_message_reg(msg_len+1), src[swz[i]]);
+	else
+	    brw_MOV(p, brw_message_reg(msg_len+1), brw_imm_f(0));
+	msg_len += 1;
+    }
+
+    brw_SAMPLE(p,
+	    retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW),
+	    1,
+	    retype(payload_reg, BRW_REGISTER_TYPE_UW),
+	    inst->TexSrcUnit + 1, /* surface */
+	    inst->TexSrcUnit,     /* sampler */
+	    inst->DstReg.WriteMask,
+	    BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE,
+	    4,
+	    4,
+	    0);
+}
+
+static void post_wm_emit( struct brw_wm_compile *c )
+{
+    GLuint nr_insns = c->fp->program.Base.NumInstructions;
+    GLuint insn, target_insn;
+    struct prog_instruction *inst1, *inst2;
+    struct brw_instruction *brw_inst1, *brw_inst2;
+    int offset;
+    for (insn = 0; insn < nr_insns; insn++) {
+	inst1 = &c->fp->program.Base.Instructions[insn];
+	brw_inst1 = inst1->Data;
+	switch (inst1->Opcode) {
+	    case OPCODE_CAL:
+		target_insn = inst1->BranchTarget;
+		inst2 = &c->fp->program.Base.Instructions[target_insn];
+		brw_inst2 = inst2->Data;
+		offset = brw_inst2 - brw_inst1;
+		brw_set_src1(brw_inst1, brw_imm_d(offset*16));
+		break;
+	    default:
+		break;
+	}
+    }
+}
+
+static void brw_wm_emit_glsl(struct brw_wm_compile *c)
+
+{
+#define MAX_IFSN 32
+#define MAX_LOOP_DEPTH 32
+    struct brw_instruction *if_inst[MAX_IFSN], *loop_inst[MAX_LOOP_DEPTH];
+    struct brw_instruction *inst0, *inst1;
+    int i, if_insn = 0, loop_insn = 0;
+    struct brw_compile *p = &c->func;
+    brw_init_compile(&c->func);
+    c->reg_index = 0;
+    prealloc_reg(c);
+    brw_set_compression_control(p, BRW_COMPRESSION_NONE);
+    for (i = 0; i < c->nr_fp_insns; i++) {
+	struct prog_instruction *inst = &c->prog_instructions[i];
+	struct prog_instruction *orig_inst;
+
+	if ((orig_inst = inst->Data) != 0)
+	    orig_inst->Data = current_insn(p);
+
+	switch (inst->Opcode) {
+	    case WM_PIXELXY:
+		emit_pixel_xy(c, inst);
+		break;
+	    case WM_DELTAXY: 
+		emit_delta_xy(c, inst);
+		break;
+	    case WM_PIXELW:
+		emit_pixel_w(c, inst);
+		break;	
+	    case WM_LINTERP:
+		emit_linterp(c, inst);
+		break;
+	    case WM_PINTERP:
+		emit_pinterp(c, inst);
+		break;
+	    case WM_CINTERP:
+		emit_cinterp(c, inst);
+		break;
+	    case WM_FB_WRITE:
+		emit_fb_write(c, inst);
+		break;
+	    case OPCODE_ABS:
+		emit_abs(c, inst);
+		break;
+	    case OPCODE_ADD:
+		emit_add(c, inst);
+		break;
+	    case OPCODE_SUB:
+		emit_sub(c, inst);
+		break;
+	    case OPCODE_FRC:
+		emit_frc(c, inst);
+		break;
+	    case OPCODE_FLR:
+		emit_flr(c, inst);
+		break;
+	    case OPCODE_LRP:
+		emit_lrp(c, inst);
+		break;
+	    case OPCODE_MOV:
+		emit_mov(c, inst);
+		break;
+	    case OPCODE_DP3:
+		emit_dp3(c, inst);
+		break;
+	    case OPCODE_DP4:
+		emit_dp4(c, inst);
+		break;
+	    case OPCODE_XPD:
+		emit_xpd(c, inst);
+		break;
+	    case OPCODE_DPH:
+		emit_dph(c, inst);
+		break;
+	    case OPCODE_RCP:
+		emit_rcp(c, inst);
+		break;
+	    case OPCODE_RSQ:
+		emit_rsq(c, inst);
+		break;
+	    case OPCODE_SIN:
+		emit_sin(c, inst);
+		break;
+	    case OPCODE_COS:
+		emit_cos(c, inst);
+		break;
+	    case OPCODE_EX2:
+		emit_ex2(c, inst);
+		break;
+	    case OPCODE_LG2:
+		emit_lg2(c, inst);
+		break;
+	    case OPCODE_MAX:	
+		emit_max(c, inst);
+		break;
+	    case OPCODE_MIN:	
+		emit_min(c, inst);
+		break;
+	    case OPCODE_SLT:
+		emit_slt(c, inst);
+		break;
+	    case OPCODE_SLE:
+		emit_sle(c, inst);
+		break;
+	    case OPCODE_SGT:
+		emit_sgt(c, inst);
+		break;
+	    case OPCODE_SGE:
+		emit_sge(c, inst);
+		break;
+	    case OPCODE_SEQ:
+		emit_seq(c, inst);
+		break;
+	    case OPCODE_SNE:
+		emit_sne(c, inst);
+		break;
+	    case OPCODE_MUL:
+		emit_mul(c, inst);
+		break;
+	    case OPCODE_POW:
+		emit_pow(c, inst);
+		break;
+	    case OPCODE_MAD:
+		emit_mad(c, inst);
+		break;
+	    case OPCODE_TEX:
+		emit_tex(c, inst);
+		break;
+	    case OPCODE_TXB:
+		emit_txb(c, inst);
+		break;
+	    case OPCODE_IF:
+		assert(if_insn < MAX_IFSN);
+		if_inst[if_insn++] = brw_IF(p, BRW_EXECUTE_8);
+		break;
+	    case OPCODE_ELSE:
+		if_inst[if_insn-1]  = brw_ELSE(p, if_inst[if_insn-1]);
+		break;
+	    case OPCODE_ENDIF:
+		assert(if_insn > 0);
+		brw_ENDIF(p, if_inst[--if_insn]);
+		break;
+	    case OPCODE_BGNSUB:
+	    case OPCODE_ENDSUB:
+		break;
+	    case OPCODE_CAL: 
+		brw_push_insn_state(p);
+		brw_set_mask_control(p, BRW_MASK_DISABLE);
+		brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+		brw_ADD(p, c->ret_reg, brw_ip_reg(), brw_imm_d(2*16));
+		orig_inst = inst->Data;
+		orig_inst->Data = current_insn(p);
+		brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
+		brw_pop_insn_state(p);
+		break;
+	    case OPCODE_RET:
+		brw_push_insn_state(p);
+		brw_set_mask_control(p, BRW_MASK_DISABLE);
+		brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+		brw_MOV(p, brw_ip_reg(), c->ret_reg);
+		brw_pop_insn_state(p);
+		break;
+	    case OPCODE_BGNLOOP:
+		loop_inst[loop_insn++] = brw_DO(p, BRW_EXECUTE_8);
+		break;
+	    case OPCODE_BRK:
+		brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
+		brw_BREAK(p);
+		brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+		break;
+	    case OPCODE_ENDLOOP: 
+		loop_insn--;
+		inst0 = inst1 = brw_WHILE(p, loop_inst[loop_insn]);
+		/* patch all the BREAK instructions from
+		   last BEGINLOOP */
+		while (inst0 > loop_inst[loop_insn]) {
+		    inst0--;
+		    if (inst0->header.opcode == BRW_OPCODE_BREAK) {
+			inst0->bits3.if_else.jump_count = inst1 - inst0 + 1;
+			inst0->bits3.if_else.pop_count = 0;
+		    }
+		}
+		break;
+	    default:
+		_mesa_printf("unsupported IR in fragment shader %d\n",
+			inst->Opcode);
+	}
+    }
+    post_wm_emit(c);
+}
+
+void brw_wm_glsl_emit(struct brw_wm_compile *c)
+{
+    brw_wm_pass_fp(c);
+    c->tmp_index = 127;
+    brw_wm_emit_glsl(c);
+    c->prog_data.total_grf = c->reg_index;
+    c->prog_data.total_scratch = 0;
+}
diff --git a/src/mesa/drivers/dri/i965/brw_wm_pass2.c b/src/mesa/drivers/dri/i965/brw_wm_pass2.c
index a1edbd6168..c1ce6a9b6b 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_pass2.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_pass2.c
@@ -328,7 +328,7 @@ void brw_wm_pass2( struct brw_wm_compile *c )
    c->state = PASS2_DONE;
 
    if (INTEL_DEBUG & DEBUG_WM) {
-      brw_wm_print_program(c, "pass2/done");
+       brw_wm_print_program(c, "pass2/done");
    }
 }
 
diff --git a/src/mesa/drivers/dri/i965/brw_wm_state.c b/src/mesa/drivers/dri/i965/brw_wm_state.c
index ff5cb31bdd..401864fc4e 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_state.c
@@ -34,6 +34,7 @@
 #include "brw_context.h"
 #include "brw_state.h"
 #include "brw_defines.h"
+#include "brw_wm.h"
 #include "bufmgr.h"
 
 /***********************************************************************
@@ -134,9 +135,13 @@ static void upload_wm_unit(struct brw_context *brw )
       if (fp->UsesKill || 
 	  brw->attribs.Color->AlphaEnabled) 
 	 wm.wm5.program_uses_killpixel = 1; 
+      
+      if (brw_wm_is_glsl(fp))
+	  wm.wm5.enable_8_pix = 1;
+      else
+	  wm.wm5.enable_16_pix = 1;
    }
 
-   wm.wm5.enable_16_pix = 1;
    wm.wm5.thread_dispatch_enable = 1;	/* AKA: color_write */
    wm.wm5.legacy_line_rast = 0;
    wm.wm5.legacy_global_depth_bias = 0;
-- 
cgit v1.2.3


From 4fc02ad000a0948ab77306980492924f5beebc0a Mon Sep 17 00:00:00 2001
From: Zou Nan hai <nanhai.zou@intel.com>
Date: Tue, 3 Jul 2007 15:27:43 +0800
Subject:  Fix a nasty bug...

---
 src/mesa/drivers/dri/i965/brw_vs_emit.c | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

(limited to 'src')

diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c
index fa94d5b1a8..7dc6f9bf93 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c
@@ -137,7 +137,7 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
 
    for (i = 0; i < 128; i++) {
        if (c->output_regs[i].used_in_src) {
-            c->regs[PROGRAM_OUTPUT][i] = brw_vec8_grf(reg, 0);
+            c->output_regs[i].reg = brw_vec8_grf(reg, 0);
             reg++;
         }
    }
@@ -958,6 +958,9 @@ void brw_vs_emit(struct brw_vs_compile *c )
    struct brw_instruction *if_inst[MAX_IFSN];
    struct brw_indirect stack_index = brw_indirect(0, 0);   
 
+   GLuint index;
+   GLuint file;
+
    if (INTEL_DEBUG & DEBUG_VS) {
       _mesa_printf("\n\n\nvs-emit:\n");
       _mesa_print_program(&c->vp->program.Base); 
@@ -998,8 +1001,8 @@ void brw_vs_emit(struct brw_vs_compile *c )
       if (inst->Opcode != OPCODE_SWZ)
 	  for (i = 0; i < 3; i++) {
 	      struct prog_src_register *src = &inst->SrcReg[i];
-	      GLuint index = src->Index;
-	      GLuint file = src->File;	
+	      index = src->Index;
+	      file = src->File;	
 	      if (file == PROGRAM_OUTPUT&&c->output_regs[index].used_in_src)
 		  args[i] = c->output_regs[index].reg;
 	      else
@@ -1009,8 +1012,13 @@ void brw_vs_emit(struct brw_vs_compile *c )
       /* Get dest regs.  Note that it is possible for a reg to be both
        * dst and arg, given the static allocation of registers.  So
        * care needs to be taken emitting multi-operation instructions.
-       */
-      dst = get_dst(c, inst->DstReg);
+       */ 
+      index = inst->DstReg.Index;
+      file = inst->DstReg.File;
+      if (file == PROGRAM_OUTPUT && c->output_regs[index].used_in_src)
+	  dst = c->output_regs[index].reg;
+      else
+	  dst = get_dst(c, inst->DstReg);
 
       switch (inst->Opcode) {
       case OPCODE_ABS:
@@ -1157,7 +1165,7 @@ void brw_vs_emit(struct brw_vs_compile *c )
       if (inst->DstReg.File == PROGRAM_OUTPUT
 	      &&inst->DstReg.Index != VERT_RESULT_HPOS
 	      &&c->output_regs[inst->DstReg.Index].used_in_src)
-	  brw_MOV(p, get_dst(c, inst->DstReg), dst);
+	  brw_MOV(p, dst, c->output_regs[inst->DstReg.Index].reg);
 
       release_tmps(c);
    }
-- 
cgit v1.2.3


From 285b326c606e9b2f90e4fe177b15b3fa23239b86 Mon Sep 17 00:00:00 2001
From: Zou Nan hai <nanhai.zou@intel.com>
Date: Wed, 4 Jul 2007 10:51:57 +0800
Subject:  fix issue with output as src register.

---
 src/mesa/drivers/dri/i965/brw_vs_emit.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src')

diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c
index 7dc6f9bf93..18ede5f6cd 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c
@@ -1165,7 +1165,7 @@ void brw_vs_emit(struct brw_vs_compile *c )
       if (inst->DstReg.File == PROGRAM_OUTPUT
 	      &&inst->DstReg.Index != VERT_RESULT_HPOS
 	      &&c->output_regs[inst->DstReg.Index].used_in_src)
-	  brw_MOV(p, dst, c->output_regs[inst->DstReg.Index].reg);
+	  brw_MOV(p, get_dst(c, inst->DstReg), dst);
 
       release_tmps(c);
    }
-- 
cgit v1.2.3


From 575f3e918f00bdc0faa4a173820015b24175696f Mon Sep 17 00:00:00 2001
From: Zou Nan hai <nanhai.zou@intel.com>
Date: Thu, 5 Jul 2007 11:10:24 +0800
Subject:  support "discard";

---
 src/mesa/drivers/dri/i965/brw_wm.h      |  1 +
 src/mesa/drivers/dri/i965/brw_wm_glsl.c | 15 +++++++++++++++
 2 files changed, 16 insertions(+)

(limited to 'src')

diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h
index 4143d5be6c..931c0038d4 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.h
+++ b/src/mesa/drivers/dri/i965/brw_wm.h
@@ -237,6 +237,7 @@ struct brw_wm_compile {
 	struct brw_reg reg;
    } wm_regs[PROGRAM_PAYLOAD+1][256][4];
    struct brw_reg ret_reg;
+   struct brw_reg emit_mask_reg;
    GLuint reg_index;
    GLuint tmp_index;
 };
diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
index cdd7976607..4988df2b0e 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
@@ -132,6 +132,7 @@ static void prealloc_reg(struct brw_wm_compile *c)
     c->prog_data.urb_read_length = nr_interp_regs * 2;
     c->prog_data.curb_read_length = c->nr_creg;
     c->ret_reg = brw_uw1_reg(BRW_GENERAL_REGISTER_FILE, c->reg_index, 0);
+    c->emit_mask_reg = brw_uw1_reg(BRW_GENERAL_REGISTER_FILE, c->reg_index, 1);
     c->reg_index++;
 }
 
@@ -768,6 +769,17 @@ static void emit_lrp(struct brw_wm_compile *c,
     }
 }
 
+static void emit_kil(struct brw_wm_compile *c)
+{
+	struct brw_compile *p = &c->func;
+	struct brw_reg depth = retype(brw_vec1_grf(0, 0), BRW_REGISTER_TYPE_UW);
+	brw_push_insn_state(p);
+	brw_set_mask_control(p, BRW_MASK_DISABLE);
+	brw_NOT(p, c->emit_mask_reg, brw_mask_reg(1)); //IMASK
+	brw_AND(p, depth, c->emit_mask_reg, depth);
+	brw_pop_insn_state(p);
+}
+
 static void emit_mad(struct brw_wm_compile *c,
 		struct prog_instruction *inst)
 {
@@ -1107,6 +1119,9 @@ static void brw_wm_emit_glsl(struct brw_wm_compile *c)
 	    case OPCODE_TXB:
 		emit_txb(c, inst);
 		break;
+	    case OPCODE_KIL_NV:
+		emit_kil(c);
+		break;
 	    case OPCODE_IF:
 		assert(if_insn < MAX_IFSN);
 		if_inst[if_insn++] = brw_IF(p, BRW_EXECUTE_8);
-- 
cgit v1.2.3


From 719cf0b7958d0dedf8727c97eaddb6a1f31977e1 Mon Sep 17 00:00:00 2001
From: Zou Nan hai <nanhai.zou@intel.com>
Date: Tue, 17 Jul 2007 11:19:52 +0800
Subject:  Use ProgramStringNotify

---
 src/mesa/drivers/dri/i965/brw_context.c | 27 ---------------------------
 src/mesa/shader/program.c               |  2 ++
 2 files changed, 2 insertions(+), 27 deletions(-)

(limited to 'src')

diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c
index badf178b68..8366f14dbe 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -62,30 +62,6 @@ static const struct dri_extension brw_extensions[] =
     { NULL,                                NULL }
 };
 
-static void brwLinkProgram(GLcontext *ctx, GLuint program)
-{
-        struct brw_context *brw = brw_context(ctx);
-        struct brw_vertex_program *vert_prog;
-        struct brw_fragment_program *frag_prog;
-        struct gl_shader_program *sh_prog;
-        _mesa_link_program(ctx, program);
-
-        sh_prog = _mesa_lookup_shader_program(ctx, program);
-	if (sh_prog) {
-	    sh_prog->FragmentProgram = 
-		_mesa_realloc(sh_prog->FragmentProgram,
-			sizeof(struct gl_fragment_program),
-			sizeof(struct brw_fragment_program));
-	    frag_prog = (struct brw_fragment_program *)sh_prog->FragmentProgram;
-	    frag_prog->id = brw->program_id++;
-	    sh_prog->VertexProgram = _mesa_realloc(sh_prog->VertexProgram,
-		    sizeof(struct gl_vertex_program),
-		    sizeof(struct brw_vertex_program));
-	    vert_prog = (struct brw_vertex_program *)sh_prog->VertexProgram;
-	    vert_prog->id = brw->program_id++;
-	}
-}
-
 static void brwUseProgram(GLcontext *ctx, GLuint program)
 {
         struct brw_context *brw = brw_context(ctx);
@@ -97,15 +73,12 @@ static void brwUseProgram(GLcontext *ctx, GLuint program)
             ctx->FragmentProgram.Enabled = GL_TRUE;
             brw->attribs.VertexProgram->Current = sh_prog->VertexProgram;
             brw->attribs.FragmentProgram->Current = sh_prog->FragmentProgram;
-            brw->state.dirty.brw |= BRW_NEW_VERTEX_PROGRAM;
-            brw->state.dirty.brw |= BRW_NEW_FRAGMENT_PROGRAM;
         }
 }
 
 static void brwInitProgFuncs( struct dd_function_table *functions )
 {
    functions->UseProgram = brwUseProgram;
-   functions->LinkProgram = brwLinkProgram;
 }
 static void brwInitDriverFunctions( struct dd_function_table *functions )
 {
diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c
index 4205919828..03be368a92 100644
--- a/src/mesa/shader/program.c
+++ b/src/mesa/shader/program.c
@@ -242,6 +242,8 @@ _mesa_init_vertex_program( GLcontext *ctx, struct gl_vertex_program *prog,
 struct gl_program *
 _mesa_new_program(GLcontext *ctx, GLenum target, GLuint id)
 {
+   if (ctx->Driver.NewProgram)
+        return ctx->Driver.NewProgram(ctx, target, id);
    switch (target) {
    case GL_VERTEX_PROGRAM_ARB: /* == GL_VERTEX_PROGRAM_NV */
       return _mesa_init_vertex_program(ctx, CALLOC_STRUCT(gl_vertex_program),
-- 
cgit v1.2.3


From c6d042acc94411b63f922ef68f24aa5426c0a69e Mon Sep 17 00:00:00 2001
From: Zou Nan hai <nanhai.zou@intel.com>
Date: Tue, 17 Jul 2007 16:52:03 +0800
Subject:   Fix SOP in fragment shader, brick is ok now.

---
 progs/glsl/CH06-brick.frag.txt          | 6 +-----
 src/mesa/drivers/dri/i965/brw_wm_glsl.c | 6 ++++--
 2 files changed, 5 insertions(+), 7 deletions(-)

(limited to 'src')

diff --git a/progs/glsl/CH06-brick.frag.txt b/progs/glsl/CH06-brick.frag.txt
index 388c5f9e66..06ef04e3af 100644
--- a/progs/glsl/CH06-brick.frag.txt
+++ b/progs/glsl/CH06-brick.frag.txt
@@ -23,11 +23,7 @@ void main()
     
     position = MCposition / BrickSize;
 
-//    if (fract(position.y * 0.5) > 0.5)
-//        position.x += 0.5;
-    float tmp;
-    tmp  = fract(position.y * 0.5);
-    if (tmp > 0.5)
+    if (fract(position.y * 0.5) > 0.5)
         position.x += 0.5;
 
     position = fract(position);
diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
index 4988df2b0e..09e7590367 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
@@ -811,18 +811,20 @@ static void emit_sop(struct brw_wm_compile *c,
     struct brw_reg dst, src0, src1;
     int i;
 
+    brw_push_insn_state(p);
     for (i = 0; i < 4; i++) {
 	if (mask & (1<<i)) {
 	    dst = get_dst_reg(c, inst, i, 1);
 	    src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
 	    src1 = get_src_reg(c, &inst->SrcReg[1], i, 1);
-	    brw_MOV(p, dst, brw_imm_f(0));
 	    brw_CMP(p, brw_null_reg(), cond, src0, src1);
+	    brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+	    brw_MOV(p, dst, brw_imm_f(0.0));
 	    brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
 	    brw_MOV(p, dst, brw_imm_f(1.0));
-	    brw_set_predicate_control_flag_value(p, 0xff);
 	}
     }
+    brw_pop_insn_state(p);
 }
 
 static void emit_slt(struct brw_wm_compile *c,
-- 
cgit v1.2.3


From c702a7100e2aa83241e89850a97bcc23e1c6fedb Mon Sep 17 00:00:00 2001
From: Zou Nan hai <nanhai.zou@intel.com>
Date: Tue, 24 Jul 2007 11:09:34 +0800
Subject:   DDX DDY support, not very accurate

---
 src/mesa/drivers/dri/i965/brw_wm.h      |  1 +
 src/mesa/drivers/dri/i965/brw_wm_fp.c   | 37 ++++++++++++++++++
 src/mesa/drivers/dri/i965/brw_wm_glsl.c | 66 ++++++++++++++++++++++++++++++++-
 3 files changed, 103 insertions(+), 1 deletion(-)

(limited to 'src')

diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h
index 931c0038d4..22e77287f4 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.h
+++ b/src/mesa/drivers/dri/i965/brw_wm.h
@@ -194,6 +194,7 @@ struct brw_wm_compile {
    GLuint nr_fp_insns;
    GLuint fp_temp;
    GLuint fp_interp_emitted;
+   GLuint fp_deriv_emitted;
 
    struct prog_src_register pixel_xy;
    struct prog_src_register delta_xy;
diff --git a/src/mesa/drivers/dri/i965/brw_wm_fp.c b/src/mesa/drivers/dri/i965/brw_wm_fp.c
index 403160c494..0a6e516b93 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_fp.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_fp.c
@@ -361,6 +361,37 @@ static void emit_interp( struct brw_wm_compile *c,
    c->fp_interp_emitted |= 1<<idx;
 }
 
+static void emit_ddx( struct brw_wm_compile *c,
+        const struct prog_instruction *inst )
+{
+    GLuint idx = inst->SrcReg[0].Index;
+    struct prog_src_register interp = src_reg(PROGRAM_PAYLOAD, idx);
+
+    c->fp_deriv_emitted |= 1<<idx;
+    emit_op(c,
+            OPCODE_DDX,
+            inst->DstReg,
+            0, 0, 0,
+            interp,
+            get_pixel_w(c),
+            src_undef());
+}
+
+static void emit_ddy( struct brw_wm_compile *c,
+        const struct prog_instruction *inst )
+{
+    GLuint idx = inst->SrcReg[0].Index;
+    struct prog_src_register interp = src_reg(PROGRAM_PAYLOAD, idx);
+
+    c->fp_deriv_emitted |= 1<<idx;
+    emit_op(c,
+            OPCODE_DDY,
+            inst->DstReg,
+            0, 0, 0,
+            interp,
+            get_pixel_w(c),
+            src_undef());
+}
 
 /***********************************************************************
  * Hacks to extend the program parameter and constant lists.
@@ -907,6 +938,12 @@ void brw_wm_pass_fp( struct brw_wm_compile *c )
 	  */
 	 out->DstReg.WriteMask = 0;
 	 break;
+      case OPCODE_DDX:
+	 emit_ddx(c, inst);
+	 break;
+      case OPCODE_DDY:
+         emit_ddy(c, inst);
+	break;
       case OPCODE_END:
 	 emit_fog(c);
 	 emit_fb_write(c);
diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
index 09e7590367..f47f139282 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
@@ -16,6 +16,8 @@ GLboolean brw_wm_is_glsl(struct gl_fragment_program *fp)
 	    case OPCODE_CAL:
 	    case OPCODE_BRK:
 	    case OPCODE_RET:
+	    case OPCODE_DDX:
+	    case OPCODE_DDY:
 	    case OPCODE_BGNLOOP:
 		return GL_TRUE; 
 	    default:
@@ -92,7 +94,7 @@ static void prealloc_reg(struct brw_wm_compile *c)
     int i, j;
     struct brw_reg reg;
     int nr_interp_regs = 0;
-    GLuint inputs = FRAG_BIT_WPOS | c->fp_interp_emitted;
+    GLuint inputs = FRAG_BIT_WPOS | c->fp_interp_emitted | c->fp_deriv_emitted;
 
     for (i = 0; i < 4; i++) {
 	reg = (i < c->key.nr_depth_regs) 
@@ -862,6 +864,62 @@ static void emit_sne(struct brw_wm_compile *c,
 {
     emit_sop(c, inst, BRW_CONDITIONAL_NEQ);
 }
+
+static void emit_ddx(struct brw_wm_compile *c,
+                struct prog_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    GLuint mask = inst->DstReg.WriteMask;
+    struct brw_reg interp[4];
+    struct brw_reg dst;
+    struct brw_reg src0, w;
+    GLuint nr, i;
+    src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1);
+    w = get_src_reg(c, &inst->SrcReg[1], 3, 1);
+    nr = src0.nr;
+    interp[0] = brw_vec1_grf(nr, 0);
+    interp[1] = brw_vec1_grf(nr, 4);
+    interp[2] = brw_vec1_grf(nr+1, 0);
+    interp[3] = brw_vec1_grf(nr+1, 4);
+    brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF);
+    for(i = 0; i < 4; i++ ) {
+        if (mask & (1<<i)) {
+            dst = get_dst_reg(c, inst, i, 1);
+            brw_MOV(p, dst, interp[i]);
+            brw_MUL(p, dst, dst, w);
+        }
+    }
+    brw_set_saturate(p, 0);
+}
+
+static void emit_ddy(struct brw_wm_compile *c,
+                struct prog_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    GLuint mask = inst->DstReg.WriteMask;
+    struct brw_reg interp[4];
+    struct brw_reg dst;
+    struct brw_reg src0, w;
+    GLuint nr, i;
+
+    src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1);
+    nr = src0.nr;
+    w = get_src_reg(c, &inst->SrcReg[1], 3, 1);
+    interp[0] = brw_vec1_grf(nr, 0);
+    interp[1] = brw_vec1_grf(nr, 4);
+    interp[2] = brw_vec1_grf(nr+1, 0);
+    interp[3] = brw_vec1_grf(nr+1, 4);
+    brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF);
+    for(i = 0; i < 4; i++ ) {
+        if (mask & (1<<i)) {
+            dst = get_dst_reg(c, inst, i, 1);
+            brw_MOV(p, dst, suboffset(interp[i], 1));
+            brw_MUL(p, dst, dst, w);
+        }
+    }
+    brw_set_saturate(p, 0);
+}
+
 /* TODO
    BIAS on SIMD8 not workind yet...
  */	
@@ -1088,6 +1146,12 @@ static void brw_wm_emit_glsl(struct brw_wm_compile *c)
 	    case OPCODE_MIN:	
 		emit_min(c, inst);
 		break;
+	    case OPCODE_DDX:
+		emit_ddx(c, inst);
+		break;
+	    case OPCODE_DDY:
+                emit_ddy(c, inst);
+                break;
 	    case OPCODE_SLT:
 		emit_slt(c, inst);
 		break;
-- 
cgit v1.2.3


From 25bda451bbdbc51a7a4346e2c809f335fb46db72 Mon Sep 17 00:00:00 2001
From: Zou Nan hai <nanhai.zou@intel.com>
Date: Tue, 18 Sep 2007 11:32:25 +0800
Subject: fix double free in 965-glsl branch

---
 src/mesa/drivers/dri/i965/brw_vs_emit.c   | 2 ++
 src/mesa/drivers/dri/i965/brw_wm_glsl.c   | 2 ++
 src/mesa/drivers/dri/i965/intel_context.c | 2 ++
 3 files changed, 6 insertions(+)

(limited to 'src')

diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c
index 18ede5f6cd..f689f7b305 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c
@@ -1173,4 +1173,6 @@ void brw_vs_emit(struct brw_vs_compile *c )
    end_inst = &p->store[p->nr_insn];
    emit_vertex_write(c);
    post_vs_emit(c, end_inst);
+   for (insn = 0; insn < nr_insns; insn++)
+       c->vp->program.Base.Instructions[insn].Data = NULL;
 }
diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
index f47f139282..f03866d9b9 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
@@ -1246,6 +1246,8 @@ static void brw_wm_emit_glsl(struct brw_wm_compile *c)
 	}
     }
     post_wm_emit(c);
+    for (i = 0; i < c->fp->program.Base.NumInstructions; i++)
+	c->fp->program.Base.Instructions[i].Data = NULL;
 }
 
 void brw_wm_glsl_emit(struct brw_wm_compile *c)
diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c
index 3215cc7218..35babcac23 100644
--- a/src/mesa/drivers/dri/i965/intel_context.c
+++ b/src/mesa/drivers/dri/i965/intel_context.c
@@ -555,6 +555,8 @@ void intelDestroyContext(__DRIcontextPrivate *driContextPriv)
 #endif
 
       /* free the Mesa context */
+      intel->ctx.VertexProgram.Current = NULL;
+      intel->ctx.FragmentProgram.Current = NULL;
       _mesa_destroy_context(&intel->ctx);
    }
 
-- 
cgit v1.2.3


From ec9e7bc753316cebed9c9ce12aa5513486c6b8d0 Mon Sep 17 00:00:00 2001
From: Zou Nan hai <nanhai.zou@intel.com>
Date: Tue, 18 Sep 2007 12:59:50 +0800
Subject:  ARB_shader_object ARB_vertex_shader ARB_fragment_shader in 965-glsl
 branch

---
 src/mesa/drivers/dri/i965/intel_context.c | 6 ++++++
 1 file changed, 6 insertions(+)

(limited to 'src')

diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c
index 35babcac23..ac8aa5bd52 100644
--- a/src/mesa/drivers/dri/i965/intel_context.c
+++ b/src/mesa/drivers/dri/i965/intel_context.c
@@ -82,6 +82,9 @@ int INTEL_DEBUG = (0);
 #define need_GL_EXT_multi_draw_arrays
 #define need_GL_EXT_secondary_color
 #define need_GL_VERSION_2_0
+#define need_GL_ARB_shader_objects
+#define need_GL_ARB_vertex_shader
+
 #include "extension_helper.h"
 
 #ifndef VERBOSE
@@ -185,6 +188,9 @@ const struct dri_extension card_extensions[] =
     { "GL_NV_blend_square",                NULL },
     { "GL_SGIS_generate_mipmap",           NULL },
     { "GL_ARB_shading_language_100",       GL_VERSION_2_0_functions},
+    { "GL_ARB_shader_objects",             GL_ARB_shader_objects_functions},
+    { "GL_ARB_vertex_shader",              GL_ARB_vertex_shader_functions},
+    { "GL_ARB_fragment_shader",            NULL },
     /* XXX not implement yet, to compile builtin glsl lib */
     { "GL_ARB_draw_buffers",               NULL },
     { NULL,                                NULL }
-- 
cgit v1.2.3


From 35a0634e358baac832d6e5a76630fcae57a948a7 Mon Sep 17 00:00:00 2001
From: Zou Nan hai <nanhai.zou@intel.com>
Date: Thu, 27 Sep 2007 15:47:00 +0800
Subject:  fix issue when only fragment shader or vertex shader is used

---
 src/mesa/drivers/dri/i965/brw_context.c | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

(limited to 'src')

diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c
index 8366f14dbe..2031d556c1 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -69,11 +69,18 @@ static void brwUseProgram(GLcontext *ctx, GLuint program)
         _mesa_use_program(ctx, program);
         sh_prog = ctx->Shader.CurrentProgram;
         if (sh_prog) {
-            ctx->VertexProgram.Enabled = GL_TRUE;
-            ctx->FragmentProgram.Enabled = GL_TRUE;
-            brw->attribs.VertexProgram->Current = sh_prog->VertexProgram;
-            brw->attribs.FragmentProgram->Current = sh_prog->FragmentProgram;
-        }
+	    if (sh_prog->VertexProgram) {
+		brw->attribs.VertexProgram->Current = sh_prog->VertexProgram;
+		ctx->VertexProgram.Enabled = GL_TRUE;
+	    }else
+		ctx->VertexProgram.Enabled = GL_FALSE;
+		
+	    if (sh_prog->FragmentProgram) {
+		brw->attribs.FragmentProgram->Current = sh_prog->FragmentProgram;
+		ctx->FragmentProgram.Enabled = GL_TRUE;
+	    } else
+		ctx->VertexProgram.Enabled = GL_FALSE;
+	}
 }
 
 static void brwInitProgFuncs( struct dd_function_table *functions )
-- 
cgit v1.2.3


From b1e549d1762536ebb3f7c11461c4554d4613c37a Mon Sep 17 00:00:00 2001
From: Zou Nan hai <nanhai.zou@intel.com>
Date: Thu, 27 Sep 2007 16:17:24 +0800
Subject:  handle INT op, still require high level handle of integer to be
 correct

---
 src/mesa/drivers/dri/i965/brw_wm_glsl.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

(limited to 'src')

diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
index f03866d9b9..4bce150491 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
@@ -12,6 +12,7 @@ GLboolean brw_wm_is_glsl(struct gl_fragment_program *fp)
 	struct prog_instruction *inst = &fp->Base.Instructions[i];
 	switch (inst->Opcode) {
 	    case OPCODE_IF:
+	    case OPCODE_INT:
 	    case OPCODE_ENDIF:
 	    case OPCODE_CAL:
 	    case OPCODE_BRK:
@@ -170,6 +171,24 @@ static void emit_abs( struct brw_wm_compile *c,
     brw_set_saturate(p, 0);
 }
 
+static void emit_mov_int( struct brw_wm_compile *c,
+		struct prog_instruction *inst)
+{
+    int i;
+    struct brw_compile *p = &c->func;
+    GLuint mask = inst->DstReg.WriteMask;
+    brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF);
+    for (i = 0; i < 4; i++) {
+	if (mask & (1<<i)) {
+	    struct brw_reg src, dst;
+	    dst = retype(get_dst_reg(c, inst, i, 1), BRW_REGISTER_TYPE_D);
+	    src = retype(get_src_reg(c, &inst->SrcReg[0], i, 1), BRW_REGISTER_TYPE_D);
+	    brw_MOV(p, dst, src);
+	}
+    }
+    brw_set_saturate(p, 0);
+}
+
 static void emit_mov( struct brw_wm_compile *c,
 		struct prog_instruction *inst)
 {
@@ -1107,6 +1126,9 @@ static void brw_wm_emit_glsl(struct brw_wm_compile *c)
 	    case OPCODE_LRP:
 		emit_lrp(c, inst);
 		break;
+	    case OPCODE_INT:
+		emit_mov_int(c, inst);
+		break;
 	    case OPCODE_MOV:
 		emit_mov(c, inst);
 		break;
-- 
cgit v1.2.3


From 4087c90effecdf2f466e2ddcf88ec2faf0db034f Mon Sep 17 00:00:00 2001
From: Zou Nan hai <nanhai.zou@intel.com>
Date: Fri, 28 Sep 2007 16:37:01 +0800
Subject: support nested function call in pixel shader

---
 src/mesa/drivers/dri/i965/brw_wm.h      |  2 +-
 src/mesa/drivers/dri/i965/brw_wm_glsl.c | 35 +++++++++++++++++++++++----------
 2 files changed, 26 insertions(+), 11 deletions(-)

(limited to 'src')

diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h
index 22e77287f4..ca9bc3a07b 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.h
+++ b/src/mesa/drivers/dri/i965/brw_wm.h
@@ -237,7 +237,7 @@ struct brw_wm_compile {
 	GLboolean inited;
 	struct brw_reg reg;
    } wm_regs[PROGRAM_PAYLOAD+1][256][4];
-   struct brw_reg ret_reg;
+   struct brw_reg stack;
    struct brw_reg emit_mask_reg;
    GLuint reg_index;
    GLuint tmp_index;
diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
index 4bce150491..c6fd724921 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
@@ -134,9 +134,10 @@ static void prealloc_reg(struct brw_wm_compile *c)
     c->prog_data.first_curbe_grf = c->key.nr_depth_regs * 2;
     c->prog_data.urb_read_length = nr_interp_regs * 2;
     c->prog_data.curb_read_length = c->nr_creg;
-    c->ret_reg = brw_uw1_reg(BRW_GENERAL_REGISTER_FILE, c->reg_index, 0);
-    c->emit_mask_reg = brw_uw1_reg(BRW_GENERAL_REGISTER_FILE, c->reg_index, 1);
+    c->emit_mask_reg = brw_uw1_reg(BRW_GENERAL_REGISTER_FILE, c->reg_index, 0);
     c->reg_index++;
+    c->stack =  brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, c->reg_index, 0);
+    c->reg_index += 2;
 }
 
 static struct brw_reg get_dst_reg(struct brw_wm_compile *c, 
@@ -1075,10 +1076,14 @@ static void brw_wm_emit_glsl(struct brw_wm_compile *c)
     struct brw_instruction *inst0, *inst1;
     int i, if_insn = 0, loop_insn = 0;
     struct brw_compile *p = &c->func;
+    struct brw_indirect stack_index = brw_indirect(0, 0);
+
     brw_init_compile(&c->func);
     c->reg_index = 0;
     prealloc_reg(c);
     brw_set_compression_control(p, BRW_COMPRESSION_NONE);
+    brw_MOV(p, get_addr_reg(stack_index), brw_address(c->stack));
+
     for (i = 0; i < c->nr_fp_insns; i++) {
 	struct prog_instruction *inst = &c->prog_instructions[i];
 	struct prog_instruction *orig_inst;
@@ -1227,19 +1232,29 @@ static void brw_wm_emit_glsl(struct brw_wm_compile *c)
 	    case OPCODE_CAL: 
 		brw_push_insn_state(p);
 		brw_set_mask_control(p, BRW_MASK_DISABLE);
-		brw_set_predicate_control(p, BRW_PREDICATE_NONE);
-		brw_ADD(p, c->ret_reg, brw_ip_reg(), brw_imm_d(2*16));
-		orig_inst = inst->Data;
-		orig_inst->Data = current_insn(p);
-		brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
-		brw_pop_insn_state(p);
+                brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+                brw_set_access_mode(p, BRW_ALIGN_1);
+                brw_ADD(p, deref_1uw(stack_index, 0), brw_ip_reg(), brw_imm_d(3*16));
+                brw_set_access_mode(p, BRW_ALIGN_16);
+                brw_ADD(p, get_addr_reg(stack_index),
+                         get_addr_reg(stack_index), brw_imm_d(4));
+                orig_inst = inst->Data;
+                orig_inst->Data = &p->store[p->nr_insn];
+                brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
+                brw_pop_insn_state(p);
 		break;
+
 	    case OPCODE_RET:
 		brw_push_insn_state(p);
 		brw_set_mask_control(p, BRW_MASK_DISABLE);
-		brw_set_predicate_control(p, BRW_PREDICATE_NONE);
-		brw_MOV(p, brw_ip_reg(), c->ret_reg);
+                brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+                brw_ADD(p, get_addr_reg(stack_index),
+                        get_addr_reg(stack_index), brw_imm_d(-4));
+                brw_set_access_mode(p, BRW_ALIGN_1);
+                brw_MOV(p, brw_ip_reg(), deref_1uw(stack_index, 0));
+                brw_set_access_mode(p, BRW_ALIGN_16);
 		brw_pop_insn_state(p);
+
 		break;
 	    case OPCODE_BGNLOOP:
 		loop_inst[loop_insn++] = brw_DO(p, BRW_EXECUTE_8);
-- 
cgit v1.2.3


From e75ae0dc792b9fe599b68d7a9ea0ab22413da424 Mon Sep 17 00:00:00 2001
From: Zou Nan hai <nanhai.zou@intel.com>
Date: Fri, 28 Sep 2007 17:04:48 +0800
Subject:  fix

---
 src/mesa/drivers/dri/i965/brw_wm_glsl.c | 2 --
 1 file changed, 2 deletions(-)

(limited to 'src')

diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
index c6fd724921..9b0b7aaa55 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
@@ -1232,7 +1232,6 @@ static void brw_wm_emit_glsl(struct brw_wm_compile *c)
 	    case OPCODE_CAL: 
 		brw_push_insn_state(p);
 		brw_set_mask_control(p, BRW_MASK_DISABLE);
-                brw_set_predicate_control(p, BRW_PREDICATE_NONE);
                 brw_set_access_mode(p, BRW_ALIGN_1);
                 brw_ADD(p, deref_1uw(stack_index, 0), brw_ip_reg(), brw_imm_d(3*16));
                 brw_set_access_mode(p, BRW_ALIGN_16);
@@ -1247,7 +1246,6 @@ static void brw_wm_emit_glsl(struct brw_wm_compile *c)
 	    case OPCODE_RET:
 		brw_push_insn_state(p);
 		brw_set_mask_control(p, BRW_MASK_DISABLE);
-                brw_set_predicate_control(p, BRW_PREDICATE_NONE);
                 brw_ADD(p, get_addr_reg(stack_index),
                         get_addr_reg(stack_index), brw_imm_d(-4));
                 brw_set_access_mode(p, BRW_ALIGN_1);
-- 
cgit v1.2.3


From b0b48798c7e854d2e36e0317bf94b7385e815242 Mon Sep 17 00:00:00 2001
From: Zou Nan hai <nanhai.zou@intel.com>
Date: Sat, 29 Sep 2007 15:00:52 +0800
Subject:  support continue, fix conditional

---
 src/mesa/drivers/dri/i965/brw_eu.h      |  1 +
 src/mesa/drivers/dri/i965/brw_eu_emit.c | 14 +++++++++
 src/mesa/drivers/dri/i965/brw_wm_glsl.c | 53 +++++++++++++++++++++++++++++++--
 3 files changed, 66 insertions(+), 2 deletions(-)

(limited to 'src')

diff --git a/src/mesa/drivers/dri/i965/brw_eu.h b/src/mesa/drivers/dri/i965/brw_eu.h
index 9b6581fd93..d44217d02f 100644
--- a/src/mesa/drivers/dri/i965/brw_eu.h
+++ b/src/mesa/drivers/dri/i965/brw_eu.h
@@ -815,6 +815,7 @@ struct brw_instruction *brw_WHILE(struct brw_compile *p,
 	       struct brw_instruction *patch_insn);
 
 struct brw_instruction *brw_BREAK(struct brw_compile *p);
+struct brw_instruction *brw_CONT(struct brw_compile *p);
 /* Forward jumps:
  */
 void brw_land_fwd_jump(struct brw_compile *p, 
diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c
index 7b95fbdac0..95f9f02753 100644
--- a/src/mesa/drivers/dri/i965/brw_eu_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c
@@ -611,6 +611,20 @@ struct brw_instruction *brw_BREAK(struct brw_compile *p)
    return insn;
 }
 
+struct brw_instruction *brw_CONT(struct brw_compile *p)
+{
+   struct brw_instruction *insn;
+   insn = next_insn(p, BRW_OPCODE_CONTINUE);
+   brw_set_dest(insn, brw_ip_reg());
+   brw_set_src0(insn, brw_ip_reg());
+   brw_set_src1(insn, brw_imm_d(0x0));
+   insn->header.compression_control = BRW_COMPRESSION_NONE;
+   insn->header.execution_size = BRW_EXECUTE_8;
+   insn->header.mask_control = BRW_MASK_DISABLE;
+   insn->bits3.if_else.pad0 = 0;
+   return insn;
+}
+
 /* DO/WHILE loop:
  */
 struct brw_instruction *brw_DO(struct brw_compile *p, GLuint execute_size)
diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
index 9b0b7aaa55..1f1e32ee47 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
@@ -940,6 +940,37 @@ static void emit_ddy(struct brw_wm_compile *c,
     brw_set_saturate(p, 0);
 }
 
+static void emit_wpos_xy(struct brw_wm_compile *c,
+                struct prog_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    GLuint mask = inst->DstReg.WriteMask;
+    struct brw_reg src0[2], dst[2];
+
+    dst[0] = get_dst_reg(c, inst, 0, 1);
+    dst[1] = get_dst_reg(c, inst, 1, 1);
+
+    src0[0] = get_src_reg(c, &inst->SrcReg[0], 0, 1);
+    src0[1] = get_src_reg(c, &inst->SrcReg[0], 1, 1);
+
+    /* Calc delta X,Y by subtracting origin in r1 from the pixel
+     * centers.
+     */
+    if (mask & WRITEMASK_X) {
+	brw_MOV(p,
+		dst[0],
+		retype(src0[0], BRW_REGISTER_TYPE_UW));
+    }
+
+    if (mask & WRITEMASK_Y) {
+	/* TODO -- window_height - Y */
+	brw_MOV(p,
+		dst[1],
+		negate(retype(src0[1], BRW_REGISTER_TYPE_UW)));
+
+    }
+}
+
 /* TODO
    BIAS on SIMD8 not workind yet...
  */	
@@ -1091,6 +1122,11 @@ static void brw_wm_emit_glsl(struct brw_wm_compile *c)
 	if ((orig_inst = inst->Data) != 0)
 	    orig_inst->Data = current_insn(p);
 
+	if (inst->CondUpdate)
+	    brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
+	else
+	    brw_set_conditionalmod(p, BRW_CONDITIONAL_NONE);
+
 	switch (inst->Opcode) {
 	    case WM_PIXELXY:
 		emit_pixel_xy(c, inst);
@@ -1110,6 +1146,9 @@ static void brw_wm_emit_glsl(struct brw_wm_compile *c)
 	    case WM_CINTERP:
 		emit_cinterp(c, inst);
 		break;
+	    case WM_WPOSXY:
+		emit_wpos_xy(c, inst);
+		break;
 	    case WM_FB_WRITE:
 		emit_fb_write(c, inst);
 		break;
@@ -1258,10 +1297,13 @@ static void brw_wm_emit_glsl(struct brw_wm_compile *c)
 		loop_inst[loop_insn++] = brw_DO(p, BRW_EXECUTE_8);
 		break;
 	    case OPCODE_BRK:
-		brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
 		brw_BREAK(p);
 		brw_set_predicate_control(p, BRW_PREDICATE_NONE);
 		break;
+	    case OPCODE_CONT:
+		brw_CONT(p);
+		brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+		break;
 	    case OPCODE_ENDLOOP: 
 		loop_insn--;
 		inst0 = inst1 = brw_WHILE(p, loop_inst[loop_insn]);
@@ -1272,13 +1314,20 @@ static void brw_wm_emit_glsl(struct brw_wm_compile *c)
 		    if (inst0->header.opcode == BRW_OPCODE_BREAK) {
 			inst0->bits3.if_else.jump_count = inst1 - inst0 + 1;
 			inst0->bits3.if_else.pop_count = 0;
-		    }
+		    } else if (inst0->header.opcode == BRW_OPCODE_CONTINUE) {
+                        inst0->bits3.if_else.jump_count = inst1 - inst0;
+                        inst0->bits3.if_else.pop_count = 0;
+                    }
 		}
 		break;
 	    default:
 		_mesa_printf("unsupported IR in fragment shader %d\n",
 			inst->Opcode);
 	}
+	if (inst->CondUpdate)
+	    brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
+	else
+	    brw_set_predicate_control(p, BRW_PREDICATE_NONE);
     }
     post_wm_emit(c);
     for (i = 0; i < c->fp->program.Base.NumInstructions; i++)
-- 
cgit v1.2.3


From 3d6c4109902b555a3f8076170d572c7caeb6cbfe Mon Sep 17 00:00:00 2001
From: Zou Nan hai <nanhai.zou@intel.com>
Date: Sun, 30 Sep 2007 13:47:05 +0800
Subject:  fragment shader function call fix, gl_FragCoord fix

---
 src/mesa/drivers/dri/i965/brw_eu.h      | 5 +++++
 src/mesa/drivers/dri/i965/brw_wm_glsl.c | 6 +++---
 2 files changed, 8 insertions(+), 3 deletions(-)

(limited to 'src')

diff --git a/src/mesa/drivers/dri/i965/brw_eu.h b/src/mesa/drivers/dri/i965/brw_eu.h
index d44217d02f..5c98767c3e 100644
--- a/src/mesa/drivers/dri/i965/brw_eu.h
+++ b/src/mesa/drivers/dri/i965/brw_eu.h
@@ -648,6 +648,11 @@ static __inline struct brw_reg deref_1uw(struct brw_indirect ptr, GLint offset)
    return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UW);
 }
 
+static __inline struct brw_reg deref_1ud(struct brw_indirect ptr, GLint offset)
+{
+   return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD);
+}
+
 static __inline struct brw_reg get_addr_reg(struct brw_indirect ptr)
 {
    return brw_address_reg(ptr.addr_subnr);
diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
index 1f1e32ee47..58cdf72e37 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
@@ -966,7 +966,7 @@ static void emit_wpos_xy(struct brw_wm_compile *c,
 	/* TODO -- window_height - Y */
 	brw_MOV(p,
 		dst[1],
-		negate(retype(src0[1], BRW_REGISTER_TYPE_UW)));
+		retype(src0[1], BRW_REGISTER_TYPE_UW));
 
     }
 }
@@ -1272,7 +1272,7 @@ static void brw_wm_emit_glsl(struct brw_wm_compile *c)
 		brw_push_insn_state(p);
 		brw_set_mask_control(p, BRW_MASK_DISABLE);
                 brw_set_access_mode(p, BRW_ALIGN_1);
-                brw_ADD(p, deref_1uw(stack_index, 0), brw_ip_reg(), brw_imm_d(3*16));
+                brw_ADD(p, deref_1ud(stack_index, 0), brw_ip_reg(), brw_imm_d(3*16));
                 brw_set_access_mode(p, BRW_ALIGN_16);
                 brw_ADD(p, get_addr_reg(stack_index),
                          get_addr_reg(stack_index), brw_imm_d(4));
@@ -1288,7 +1288,7 @@ static void brw_wm_emit_glsl(struct brw_wm_compile *c)
                 brw_ADD(p, get_addr_reg(stack_index),
                         get_addr_reg(stack_index), brw_imm_d(-4));
                 brw_set_access_mode(p, BRW_ALIGN_1);
-                brw_MOV(p, brw_ip_reg(), deref_1uw(stack_index, 0));
+                brw_MOV(p, brw_ip_reg(), deref_1ud(stack_index, 0));
                 brw_set_access_mode(p, BRW_ALIGN_16);
 		brw_pop_insn_state(p);
 
-- 
cgit v1.2.3


From ac985708f4820173bdc4509d032bdabeb93a0590 Mon Sep 17 00:00:00 2001
From: Zou Nan hai <nanhai.zou@intel.com>
Date: Mon, 8 Oct 2007 15:34:03 +0800
Subject:   Only vertex program fix, bypass tnl vertex program

---
 src/mesa/drivers/dri/i965/brw_context.c | 2 +-
 src/mesa/main/texenvprogram.c           | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

(limited to 'src')

diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c
index 2031d556c1..9266e73570 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -79,7 +79,7 @@ static void brwUseProgram(GLcontext *ctx, GLuint program)
 		brw->attribs.FragmentProgram->Current = sh_prog->FragmentProgram;
 		ctx->FragmentProgram.Enabled = GL_TRUE;
 	    } else
-		ctx->VertexProgram.Enabled = GL_FALSE;
+		ctx->FragmentProgram.Enabled = GL_FALSE;
 	}
 }
 
diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c
index 72b54b27d9..126a9e1179 100644
--- a/src/mesa/main/texenvprogram.c
+++ b/src/mesa/main/texenvprogram.c
@@ -1239,7 +1239,7 @@ _mesa_UpdateTexEnvProgram( GLcontext *ctx )
 
    /* If a conventional fragment program/shader isn't in effect... */
    if (!ctx->FragmentProgram._Enabled &&
-       !ctx->Shader.CurrentProgram) {
+       (!ctx->Shader.CurrentProgram || !ctx->Shader.CurrentProgram->FragmentProgram)) {
       make_state_key(ctx, &key);
       hash = hash_key(&key);
       
-- 
cgit v1.2.3


From 82d4aa40551fe86a04346c3eea944f8ce7ae8d28 Mon Sep 17 00:00:00 2001
From: Zou Nan hai <nanhai.zou@intel.com>
Date: Tue, 9 Oct 2007 14:14:59 +0800
Subject:   shadow sampler fix.   1. spec requite result (0, 0, 0, 1) instead
 of (0, 0, 0, 0)   2. support shadow sampler in simd8

---
 src/mesa/drivers/dri/i965/brw_wm_emit.c |  2 ++
 src/mesa/drivers/dri/i965/brw_wm_glsl.c | 12 +++++++++++-
 2 files changed, 13 insertions(+), 1 deletion(-)

(limited to 'src')

diff --git a/src/mesa/drivers/dri/i965/brw_wm_emit.c b/src/mesa/drivers/dri/i965/brw_wm_emit.c
index 5660b55516..1f7158f7a7 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_emit.c
@@ -702,6 +702,8 @@ static void emit_tex( struct brw_wm_compile *c,
 	      msgLength,
 	      0);	
 
+   if (shadow)
+       brw_MOV(p, dst[3], brw_imm_f(1.0));
 }
 
 
diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
index 58cdf72e37..8133c384f3 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
@@ -1027,8 +1027,10 @@ static void emit_tex(struct brw_wm_compile *c,
     GLuint msg_len;
     GLuint i, nr;
     GLuint emit;
+    GLboolean shadow = (c->key.shadowtex_mask & (1<<inst->TexSrcUnit)) ? 1 : 0;
 
     payload_reg = get_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH, 0, 1, 0, 0);
+
     for (i = 0; i < 4; i++) 
 	dst[i] = get_dst_reg(c, inst, i, 1);
     for (i = 0; i < 4; i++)
@@ -1061,6 +1063,11 @@ static void emit_tex(struct brw_wm_compile *c,
 	msg_len += 1;
     }
 
+    if (shadow) {
+	brw_MOV(p, brw_message_reg(5), brw_imm_f(0));
+	brw_MOV(p, brw_message_reg(6), src[2]);
+    }
+
     brw_SAMPLE(p,
 	    retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW),
 	    1,
@@ -1070,8 +1077,11 @@ static void emit_tex(struct brw_wm_compile *c,
 	    inst->DstReg.WriteMask,
 	    BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE,
 	    4,
-	    4,
+	    shadow ? 6 : 4,
 	    0);
+
+    if (shadow)
+	brw_MOV(p, dst[3], brw_imm_f(1.0));
 }
 
 static void post_wm_emit( struct brw_wm_compile *c )
-- 
cgit v1.2.3


From e2dff35f9589dd5616933654a2136584cb30ed18 Mon Sep 17 00:00:00 2001
From: Zou Nan hai <nanhai.zou@intel.com>
Date: Tue, 9 Oct 2007 14:26:01 +0800
Subject:   INT support

---
 src/mesa/drivers/dri/i965/brw_wm_glsl.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

(limited to 'src')

diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
index 8133c384f3..8ed9284096 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
@@ -172,7 +172,7 @@ static void emit_abs( struct brw_wm_compile *c,
     brw_set_saturate(p, 0);
 }
 
-static void emit_mov_int( struct brw_wm_compile *c,
+static void emit_int( struct brw_wm_compile *c,
 		struct prog_instruction *inst)
 {
     int i;
@@ -184,7 +184,7 @@ static void emit_mov_int( struct brw_wm_compile *c,
 	    struct brw_reg src, dst;
 	    dst = retype(get_dst_reg(c, inst, i, 1), BRW_REGISTER_TYPE_D);
 	    src = retype(get_src_reg(c, &inst->SrcReg[0], i, 1), BRW_REGISTER_TYPE_D);
-	    brw_MOV(p, dst, src);
+	    brw_RNDD(p, dst, src);
 	}
     }
     brw_set_saturate(p, 0);
@@ -1181,7 +1181,7 @@ static void brw_wm_emit_glsl(struct brw_wm_compile *c)
 		emit_lrp(c, inst);
 		break;
 	    case OPCODE_INT:
-		emit_mov_int(c, inst);
+		emit_int(c, inst);
 		break;
 	    case OPCODE_MOV:
 		emit_mov(c, inst);
-- 
cgit v1.2.3


From ae5aa1f90651a2a6168f687c95a069e78a0231bb Mon Sep 17 00:00:00 2001
From: Zou Nan hai <nanhai.zou@intel.com>
Date: Tue, 9 Oct 2007 14:35:28 +0800
Subject:  fix for prev commit

---
 src/mesa/drivers/dri/i965/brw_wm_glsl.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'src')

diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
index 8ed9284096..4b273fefe9 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
@@ -182,8 +182,8 @@ static void emit_int( struct brw_wm_compile *c,
     for (i = 0; i < 4; i++) {
 	if (mask & (1<<i)) {
 	    struct brw_reg src, dst;
-	    dst = retype(get_dst_reg(c, inst, i, 1), BRW_REGISTER_TYPE_D);
-	    src = retype(get_src_reg(c, &inst->SrcReg[0], i, 1), BRW_REGISTER_TYPE_D);
+	    dst = get_dst_reg(c, inst, i, 1) ;
+	    src = get_src_reg(c, &inst->SrcReg[0], i, 1);
 	    brw_RNDD(p, dst, src);
 	}
     }
-- 
cgit v1.2.3


From de803f538c16096c9e241cfdddc092ac2aa2504e Mon Sep 17 00:00:00 2001
From: Zou Nan hai <nanhai.zou@intel.com>
Date: Tue, 9 Oct 2007 15:05:10 +0800
Subject:   Non Square Matrix

---
 src/mesa/drivers/dri/i965/intel_context.c | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'src')

diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c
index ac8aa5bd52..a5d8be8386 100644
--- a/src/mesa/drivers/dri/i965/intel_context.c
+++ b/src/mesa/drivers/dri/i965/intel_context.c
@@ -82,6 +82,7 @@ int INTEL_DEBUG = (0);
 #define need_GL_EXT_multi_draw_arrays
 #define need_GL_EXT_secondary_color
 #define need_GL_VERSION_2_0
+#define need_GL_VERSION_2_1
 #define need_GL_ARB_shader_objects
 #define need_GL_ARB_vertex_shader
 
@@ -188,6 +189,7 @@ const struct dri_extension card_extensions[] =
     { "GL_NV_blend_square",                NULL },
     { "GL_SGIS_generate_mipmap",           NULL },
     { "GL_ARB_shading_language_100",       GL_VERSION_2_0_functions},
+    { "GL_ARB_shading_language_120",       GL_VERSION_2_1_functions},
     { "GL_ARB_shader_objects",             GL_ARB_shader_objects_functions},
     { "GL_ARB_vertex_shader",              GL_ARB_vertex_shader_functions},
     { "GL_ARB_fragment_shader",            NULL },
-- 
cgit v1.2.3


From 6c533ea2d1953152f7d95d6c984e0d287edb46c2 Mon Sep 17 00:00:00 2001
From: Kristian Høgsberg <krh@redhat.com>
Date: Tue, 16 Oct 2007 16:07:47 -0400
Subject: Handle fbconfigs and glx visuals separately.

The old implementation fetches fbconfigs or glx visuals once and assumes the list
describes both fbconfigs and glx visuals.  This patch splits it up and fetches
visuals and fbconfigs in two steps and keep the two lists separate.  A server
could have no glx visuals or no glx fbconfigs and the old code wouldn't know the
difference.
---
 src/glx/x11/glxclient.h |   4 +-
 src/glx/x11/glxcmds.c   |   7 +-
 src/glx/x11/glxext.c    | 267 +++++++++++++++++++++++-------------------------
 3 files changed, 133 insertions(+), 145 deletions(-)

(limited to 'src')

diff --git a/src/glx/x11/glxclient.h b/src/glx/x11/glxclient.h
index 0709f3ef26..b464e505fc 100644
--- a/src/glx/x11/glxclient.h
+++ b/src/glx/x11/glxclient.h
@@ -500,9 +500,9 @@ struct __GLXscreenConfigsRec {
 #endif
 
     /**
-     * Linked list of configurations for this screen.
+     * Linked list of glx visuals and  fbconfigs for this screen.
      */
-    __GLcontextModes *configs;
+    __GLcontextModes *visuals, *configs;
 
     /**
      * Per-screen dynamic GLX extension tracking.  The \c direct_support
diff --git a/src/glx/x11/glxcmds.c b/src/glx/x11/glxcmds.c
index 3e53dca319..707e398d1d 100644
--- a/src/glx/x11/glxcmds.c
+++ b/src/glx/x11/glxcmds.c
@@ -903,12 +903,12 @@ PUBLIC int glXGetConfig(Display *dpy, XVisualInfo *vis, int attribute,
 {
     __GLXdisplayPrivate *priv;
     __GLXscreenConfigs *psc;
+    __GLcontextModes *modes;
     int   status;
 
     status = GetGLXPrivScreenConfig( dpy, vis->screen, & priv, & psc );
     if ( status == Success ) {
-	const __GLcontextModes * const modes = _gl_context_modes_find_visual(
-					     psc->configs, vis->visualid );
+	modes = _gl_context_modes_find_visual(psc->visuals, vis->visualid);
 
 	/* Lookup attribute after first finding a match on the visual */
 	if ( modes != NULL ) {
@@ -1286,7 +1286,7 @@ PUBLIC XVisualInfo *glXChooseVisual(Display *dpy, int screen, int *attribList)
     ** Compute a score for those that do
     ** Remember which visual, if any, got the highest score
     */
-    for ( modes = psc->configs ; modes != NULL ; modes = modes->next ) {
+    for ( modes = psc->visuals ; modes != NULL ; modes = modes->next ) {
 	if ( fbconfigs_compatible( & test_config, modes )
 	     && ((best_config == NULL)
 		 || (fbconfig_compare( (const __GLcontextModes * const * const)&modes, &best_config ) < 0)) ) {
@@ -1654,6 +1654,7 @@ PUBLIC GLXFBConfig *glXGetFBConfigs(Display *dpy, int screen, int *nelements)
     __GLcontextModes ** config = NULL;
     int   i;
 
+    *nelements = 0;
     if ( (priv->screenConfigs != NULL)
 	 && (screen >= 0) && (screen <= ScreenCount(dpy))
 	 && (priv->screenConfigs[screen].configs != NULL)
diff --git a/src/glx/x11/glxext.c b/src/glx/x11/glxext.c
index 7b25ad717a..2a1fcf2b84 100644
--- a/src/glx/x11/glxext.c
+++ b/src/glx/x11/glxext.c
@@ -362,7 +362,8 @@ static void FreeScreenConfigs(__GLXdisplayPrivate *priv)
 	if (psc->driScreen.private)
 	    (*psc->driScreen.destroyScreen)(&psc->driScreen);
 	psc->driScreen.private = NULL;
-	__glxHashDestroy(psc->drawHash);
+	if (psc->drawHash)
+	    __glxHashDestroy(psc->drawHash);
 #endif
     }
     XFree((char*) priv->screenConfigs);
@@ -999,6 +1000,126 @@ CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc,
 
 #endif /* GLX_DIRECT_RENDERING */
 
+static __GLcontextModes *
+createConfigsFromProperties(Display *dpy, int nvisuals, int nprops,
+			    int screen, GLboolean tagged_only)
+{
+    INT32 buf[__GLX_TOTAL_CONFIG], *props;
+    unsigned prop_size;
+    __GLcontextModes *modes, *m;
+    int i;
+
+    if (nprops == 0)
+	return NULL;
+
+    /* FIXME: Is the __GLX_MIN_CONFIG_PROPS test correct for FBconfigs? */
+
+    /* Check number of properties */
+    if (nprops < __GLX_MIN_CONFIG_PROPS || nprops > __GLX_MAX_CONFIG_PROPS)
+	return NULL;
+
+    /* Allocate memory for our config structure */
+    modes = _gl_context_modes_create(nvisuals, sizeof(__GLcontextModes));
+    if (!modes)
+	return NULL;
+
+    prop_size = nprops * __GLX_SIZE_INT32;
+    if (prop_size <= sizeof(buf))
+	props = buf;
+    else
+	props = Xmalloc(prop_size);
+
+    /* Read each config structure and convert it into our format */
+    m = modes;
+    for (i = 0; i < nvisuals; i++) {
+	_XRead(dpy, (char *)props, prop_size);
+	__glXInitializeVisualConfigFromTags(m, nprops, props,
+					    tagged_only, GL_TRUE);
+	m->screen = screen;
+	m = m->next;
+    }
+
+    if (props != buf)
+	Xfree(props);
+
+    return modes;
+}
+
+static GLboolean
+getVisualConfigs(Display *dpy, __GLXdisplayPrivate *priv, int screen)
+{
+    xGLXGetVisualConfigsReq *req;
+    __GLXscreenConfigs *psc;
+    xGLXGetVisualConfigsReply reply;
+    
+    LockDisplay(dpy);
+
+    psc = priv->screenConfigs + screen;
+    psc->visuals = NULL;
+    GetReq(GLXGetVisualConfigs, req);
+    req->reqType = priv->majorOpcode;
+    req->glxCode = X_GLXGetVisualConfigs;
+    req->screen = screen;
+
+    if (!_XReply(dpy, (xReply*) &reply, 0, False))
+	goto out;
+
+    psc->visuals = createConfigsFromProperties(dpy,
+					       reply.numVisuals,
+					       reply.numProps,
+					       screen, GL_FALSE);
+
+ out:
+    UnlockDisplay(dpy);
+    return psc->visuals != NULL;
+}
+
+static GLboolean
+getFBConfigs(Display *dpy, __GLXdisplayPrivate *priv, int screen)
+{
+    xGLXGetFBConfigsReq *fb_req;
+    xGLXGetFBConfigsSGIXReq *sgi_req;
+    xGLXVendorPrivateWithReplyReq *vpreq;
+    xGLXGetFBConfigsReply reply;
+    __GLXscreenConfigs *psc;
+
+    psc = priv->screenConfigs + screen;
+    psc->serverGLXexts = __glXGetStringFromServer(dpy, priv->majorOpcode,
+						  X_GLXQueryServerString,
+						  screen, GLX_EXTENSIONS);
+
+    LockDisplay(dpy);
+
+    psc->configs = NULL;
+    if (atof(priv->serverGLXversion) >= 1.3) {
+	GetReq(GLXGetFBConfigs, fb_req);
+	fb_req->reqType = priv->majorOpcode;
+	fb_req->glxCode = X_GLXGetFBConfigs;
+	fb_req->screen = screen;
+    } else if (strstr(psc->serverGLXexts, "GLX_SGIX_fbconfig") != NULL) {
+	GetReqExtra(GLXVendorPrivateWithReply,
+		    sz_xGLXGetFBConfigsSGIXReq +
+		    sz_xGLXVendorPrivateWithReplyReq, vpreq);
+	sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq;
+	sgi_req->reqType = priv->majorOpcode;
+	sgi_req->glxCode = X_GLXVendorPrivateWithReply;
+	sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX;
+	sgi_req->screen = screen;
+    } else
+	goto out;
+
+    if (!_XReply(dpy, (xReply*) &reply, 0, False))
+	goto out;
+
+    psc->configs = createConfigsFromProperties(dpy,
+					       reply.numFBConfigs,
+					       reply.numAttribs * 2,
+					       screen, GL_TRUE);
+
+ out:
+    UnlockDisplay(dpy);
+    return psc->configs != NULL;
+}
 
 /*
 ** Allocate the memory for the per screen configs for each screen.
@@ -1006,17 +1127,8 @@ CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc,
 */
 static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv)
 {
-    xGLXGetVisualConfigsReq *req;
-    xGLXGetFBConfigsReq *fb_req;
-    xGLXVendorPrivateWithReplyReq *vpreq;
-    xGLXGetFBConfigsSGIXReq *sgi_req;
-    xGLXGetVisualConfigsReply reply;
     __GLXscreenConfigs *psc;
-    __GLcontextModes *config;
-    GLint i, j, nprops, screens;
-    INT32 buf[__GLX_TOTAL_CONFIG], *props;
-    unsigned supported_request = 0;
-    unsigned prop_size;
+    GLint i, screens;
 
     /*
     ** First allocate memory for the array of per screen configs.
@@ -1030,141 +1142,16 @@ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv)
     priv->screenConfigs = psc;
     
     priv->serverGLXversion = __glXGetStringFromServer(dpy, priv->majorOpcode,
-					 X_GLXQueryServerString,
-					 0, GLX_VERSION);
+						      X_GLXQueryServerString,
+						      0, GLX_VERSION);
     if ( priv->serverGLXversion == NULL ) {
 	FreeScreenConfigs(priv);
 	return GL_FALSE;
     }
 
-    if ( atof( priv->serverGLXversion ) >= 1.3 ) {
-	supported_request = 1;
-    }
-
-    /*
-    ** Now fetch each screens configs structures.  If a screen supports
-    ** GL (by returning a numVisuals > 0) then allocate memory for our
-    ** config structure and then fill it in.
-    */
     for (i = 0; i < screens; i++, psc++) {
-	if ( supported_request != 1 ) {
-	    psc->serverGLXexts = __glXGetStringFromServer(dpy, priv->majorOpcode,
-							  X_GLXQueryServerString,
-							  i, GLX_EXTENSIONS);
-	    if ( strstr( psc->serverGLXexts, "GLX_SGIX_fbconfig" ) != NULL ) {
-		supported_request = 2;
-	    }
-	    else {
-		supported_request = 3;
-	    }
-	}
-
-
-	LockDisplay(dpy);
-	switch( supported_request ) {
-	    case 1:
-	    GetReq(GLXGetFBConfigs,fb_req);
-	    fb_req->reqType = priv->majorOpcode;
-	    fb_req->glxCode = X_GLXGetFBConfigs;
-	    fb_req->screen = i;
-	    break;
-	   
-	    case 2:
-	    GetReqExtra(GLXVendorPrivateWithReply,
-			sz_xGLXGetFBConfigsSGIXReq-sz_xGLXVendorPrivateWithReplyReq,vpreq);
-	    sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq;
-	    sgi_req->reqType = priv->majorOpcode;
-	    sgi_req->glxCode = X_GLXVendorPrivateWithReply;
-	    sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX;
-	    sgi_req->screen = i;
-	    break;
-
-	    case 3:
-	    GetReq(GLXGetVisualConfigs,req);
-	    req->reqType = priv->majorOpcode;
-	    req->glxCode = X_GLXGetVisualConfigs;
-	    req->screen = i;
-	    break;
- 	}
-
-	if (!_XReply(dpy, (xReply*) &reply, 0, False)) {
-	    /* Something is busted. Punt. */
-	    UnlockDisplay(dpy);
-	    SyncHandle();
-	    FreeScreenConfigs(priv);
-	    return GL_FALSE;
-	}
-
-	if (!reply.numVisuals) {
-	    /* This screen does not support GL rendering */
-	    UnlockDisplay(dpy);
-	    continue;
-	}
-
-	/* FIXME: Is the __GLX_MIN_CONFIG_PROPS test correct for
-	 * FIXME: FBconfigs? 
-	 */
-	/* Check number of properties */
-	nprops = reply.numProps;
-	if ((nprops < __GLX_MIN_CONFIG_PROPS) ||
-	    (nprops > __GLX_MAX_CONFIG_PROPS)) {
-	    /* Huh?  Not in protocol defined limits.  Punt */
-	    UnlockDisplay(dpy);
-	    SyncHandle();
-	    FreeScreenConfigs(priv);
-	    return GL_FALSE;
-	}
-
-	/* Allocate memory for our config structure */
-	psc->configs = _gl_context_modes_create(reply.numVisuals,
-						sizeof(__GLcontextModes));
-	if (!psc->configs) {
-	    UnlockDisplay(dpy);
-	    SyncHandle();
-	    FreeScreenConfigs(priv);
-	    return GL_FALSE;
-	}
-
-	/* Allocate memory for the properties, if needed */
-	if ( supported_request != 3 ) {
-	    nprops *= 2;
-	}
-
-	prop_size = nprops * __GLX_SIZE_INT32;
-
-	if (prop_size <= sizeof(buf)) {
- 	    props = buf;
- 	} else {
-	    props = (INT32 *) Xmalloc(prop_size);
- 	} 
-
-	/* Read each config structure and convert it into our format */
-        config = psc->configs;
-	for (j = 0; j < reply.numVisuals; j++) {
-	    assert( config != NULL );
-	    _XRead(dpy, (char *)props, prop_size);
-
-	    if ( supported_request != 3 ) {
-		config->rgbMode = GL_TRUE;
-		config->drawableType = GLX_WINDOW_BIT;
-	    }
-	    else {
-		config->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT;
-	    }
-
-	    __glXInitializeVisualConfigFromTags( config, nprops, props,
-						 (supported_request != 3),
-						 GL_TRUE );
-	    if ( config->fbconfigID == GLX_DONT_CARE ) {
-		config->fbconfigID = config->visualID;
-	    }
-	    config->screen = i;
-	    config = config->next;
-	}
-	if (props != buf) {
-	    Xfree((char *)props);
-	}
-	UnlockDisplay(dpy);
+	getVisualConfigs(dpy, priv, i);
+	getFBConfigs(dpy, priv, i);
 
 #ifdef GLX_DIRECT_RENDERING
 	psc->scr = i;
-- 
cgit v1.2.3


From b4531121330fa85a072f129d11e8432b5294c789 Mon Sep 17 00:00:00 2001
From: Michel Dänzer <michel@tungstengraphics.com>
Date: Wed, 17 Oct 2007 18:26:31 +0200
Subject: i915: Don't emit 'empty' blit rectangles.

The hardware seems to interpret them differently and produce unexpected
results...
---
 src/mesa/drivers/dri/i915/intel_blit.c | 3 +++
 1 file changed, 3 insertions(+)

(limited to 'src')

diff --git a/src/mesa/drivers/dri/i915/intel_blit.c b/src/mesa/drivers/dri/i915/intel_blit.c
index b00b0d9e1b..2d4d00edef 100644
--- a/src/mesa/drivers/dri/i915/intel_blit.c
+++ b/src/mesa/drivers/dri/i915/intel_blit.c
@@ -402,6 +402,9 @@ intelClearWithBlit(GLcontext * ctx, GLbitfield mask)
             b = *box;
          }
 
+         if (b.x1 >= b.x2 || b.y1 >= b.y2)
+            continue;
+
          if (0)
             _mesa_printf("clear %d,%d..%d,%d, mask %x\n",
                          b.x1, b.y1, b.x2, b.y2, mask);
-- 
cgit v1.2.3


From 86b81ef5aa14a2fa7be6e5c319c00324028a1761 Mon Sep 17 00:00:00 2001
From: Michel Dänzer <michel@tungstengraphics.com>
Date: Wed, 17 Oct 2007 18:28:03 +0200
Subject: Don't call the driver clear hook when the effective scissor rectangle
 is empty.

---
 src/mesa/main/buffers.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

(limited to 'src')

diff --git a/src/mesa/main/buffers.c b/src/mesa/main/buffers.c
index cbbe3e8698..d9c18bfaaf 100644
--- a/src/mesa/main/buffers.c
+++ b/src/mesa/main/buffers.c
@@ -140,7 +140,9 @@ _mesa_Clear( GLbitfield mask )
       return;
    }
 
-   if (ctx->DrawBuffer->Width == 0 || ctx->DrawBuffer->Height == 0)
+   if (ctx->DrawBuffer->Width == 0 || ctx->DrawBuffer->Height == 0 ||
+       ctx->DrawBuffer->_Xmin >= ctx->DrawBuffer->_Xmax ||
+       ctx->DrawBuffer->_Ymin >= ctx->DrawBuffer->_Ymax)
       return;
 
    if (ctx->RenderMode == GL_RENDER) {
-- 
cgit v1.2.3


From 6c753ad51d05fcff260fcf8cccf613d47027171f Mon Sep 17 00:00:00 2001
From: Kristian Høgsberg <krh@redhat.com>
Date: Wed, 17 Oct 2007 15:05:47 -0400
Subject: Pull workaround for unset GLX_DRAWABLE_TYPE back in.

The old version just set GLX_DRAWABLE_TYPE to GLX_WINDOW_BIT for
configs received through glXGetVisualConfigs and to
GLX_WINDOW_BIT | GLX_PIXMAP_BIT for configs received as FBConfigs.
The X server needs to send this info, but keep the workaround for now.

Fixes #12835.
---
 src/glx/x11/glxext.c | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'src')

diff --git a/src/glx/x11/glxext.c b/src/glx/x11/glxext.c
index 2a1fcf2b84..4b78ca85c6 100644
--- a/src/glx/x11/glxext.c
+++ b/src/glx/x11/glxext.c
@@ -1033,6 +1033,8 @@ createConfigsFromProperties(Display *dpy, int nvisuals, int nprops,
     m = modes;
     for (i = 0; i < nvisuals; i++) {
 	_XRead(dpy, (char *)props, prop_size);
+	/* Older X servers don't send this so we default it here. */
+	m->drawableType = GLX_WINDOW_BIT;
 	__glXInitializeVisualConfigFromTags(m, nprops, props,
 					    tagged_only, GL_TRUE);
 	m->screen = screen;
-- 
cgit v1.2.3


From ad053d90f01852ee27e36a21402543562bf46ad6 Mon Sep 17 00:00:00 2001
From: Brian <brian.paul@tungstengraphics.com>
Date: Wed, 17 Oct 2007 14:30:18 -0600
Subject: Replace repeat_remainder() with a simpler macro that just casts args
 to unsigned.

---
 src/mesa/swrast/s_texfilter.c | 19 ++++++-------------
 1 file changed, 6 insertions(+), 13 deletions(-)

(limited to 'src')

diff --git a/src/mesa/swrast/s_texfilter.c b/src/mesa/swrast/s_texfilter.c
index c2a7512388..bb4e38623c 100644
--- a/src/mesa/swrast/s_texfilter.c
+++ b/src/mesa/swrast/s_texfilter.c
@@ -213,17 +213,10 @@ lerp_rgba_3d(GLchan result[4], GLfloat a, GLfloat b, GLfloat c,
 
 
 /**
- * Compute the remainder of a divided by b, but be careful with
- * negative values so that GL_REPEAT mode works right.
+ * If A is a signed integer, A % B doesn't give the right value for A < 0
+ * (in terms of texture repeat).  Just casting to unsigned fixes that.
  */
-static INLINE GLint
-repeat_remainder(GLint a, GLint b)
-{
-   if (a >= 0)
-      return a % b;
-   else
-      return (a + 1) % b + b - 1;
-}
+#define REMAINDER(A, B) ((unsigned) (A) % (unsigned) (B))
 
 
 /**
@@ -246,8 +239,8 @@ repeat_remainder(GLint a, GLint b)
          I1 = (I0 + 1) & (SIZE - 1);					\
       }									\
       else {								\
-         I0 = repeat_remainder(IFLOOR(U), SIZE);			\
-         I1 = repeat_remainder(I0 + 1, SIZE);				\
+         I0 = REMAINDER(IFLOOR(U), SIZE);				\
+         I1 = REMAINDER(I0 + 1, SIZE);					\
       }									\
       break;								\
    case GL_CLAMP_TO_EDGE:						\
@@ -366,7 +359,7 @@ repeat_remainder(GLint a, GLint b)
       if (img->_IsPowerOfTwo)						\
          I &= (SIZE - 1);						\
       else								\
-         I = repeat_remainder(I, SIZE);					\
+         I = REMAINDER(I, SIZE);					\
       break;								\
    case GL_CLAMP_TO_EDGE:						\
       {									\
-- 
cgit v1.2.3


From 366b2c690295ed4bd4dda429be945db814a069d6 Mon Sep 17 00:00:00 2001
From: Ian Romanick <idr@us.ibm.com>
Date: Wed, 17 Oct 2007 10:36:48 -0700
Subject: mga: Enable (trivial) support for GL_EXT_gpu_program_parameters.

---
 src/mesa/drivers/dri/mga/mga_xmesa.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

(limited to 'src')

diff --git a/src/mesa/drivers/dri/mga/mga_xmesa.c b/src/mesa/drivers/dri/mga/mga_xmesa.c
index 99a2ea0491..a6d78d0bf0 100644
--- a/src/mesa/drivers/dri/mga/mga_xmesa.c
+++ b/src/mesa/drivers/dri/mga/mga_xmesa.c
@@ -75,6 +75,7 @@
 #define need_GL_ARB_vertex_buffer_object
 #define need_GL_ARB_vertex_program
 #define need_GL_EXT_fog_coord
+#define need_GL_EXT_gpu_program_parameters
 #define need_GL_EXT_multi_draw_arrays
 #define need_GL_EXT_secondary_color
 #if 0
@@ -416,8 +417,9 @@ static const struct dri_extension card_extensions[] =
    { NULL,                            NULL }
 };
 
-static const struct dri_extension ARB_vp_extension[] = {
+static const struct dri_extension ARB_vp_extensions[] = {
    { "GL_ARB_vertex_program",         GL_ARB_vertex_program_functions },
+   { "GL_EXT_gpu_program_parameters", GL_EXT_gpu_program_parameters_functions },
    { NULL,                            NULL }
 };
 
@@ -622,7 +624,7 @@ mgaCreateContext( const __GLcontextModes *mesaVis,
    }
 
    if ( driQueryOptionb( &mmesa->optionCache, "arb_vertex_program" ) ) {
-      driInitSingleExtension( ctx, ARB_vp_extension );
+      driInitExtensions(ctx, ARB_vp_extensions, GL_FALSE);
    }
    
    if ( driQueryOptionb( &mmesa->optionCache, "nv_vertex_program" ) ) {
@@ -985,7 +987,7 @@ __GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp)
 
    driInitExtensions( NULL, card_extensions, GL_FALSE );
    driInitExtensions( NULL, g400_extensions, GL_FALSE );
-   driInitSingleExtension( NULL, ARB_vp_extension );
+   driInitExtensions(NULL, ARB_vp_extensions, GL_FALSE);
    driInitExtensions( NULL, NV_vp_extensions, GL_FALSE );
 
    if (!mgaInitDriver(psp))
-- 
cgit v1.2.3


From 374158b0440b24b71389d06fdf306b176c1186e7 Mon Sep 17 00:00:00 2001
From: Ian Romanick <idr@us.ibm.com>
Date: Wed, 17 Oct 2007 10:39:24 -0700
Subject: mga: Enable (trivial) support for GL_APPLE_vertex_array_object, bump
 DRIVER_DATE

---
 src/mesa/drivers/dri/mga/mga_xmesa.c | 2 ++
 src/mesa/drivers/dri/mga/mgadd.c     | 2 +-
 2 files changed, 3 insertions(+), 1 deletion(-)

(limited to 'src')

diff --git a/src/mesa/drivers/dri/mga/mga_xmesa.c b/src/mesa/drivers/dri/mga/mga_xmesa.c
index a6d78d0bf0..2f3516fd38 100644
--- a/src/mesa/drivers/dri/mga/mga_xmesa.c
+++ b/src/mesa/drivers/dri/mga/mga_xmesa.c
@@ -81,6 +81,7 @@
 #if 0
 #define need_GL_EXT_paletted_texture
 #endif
+#define need_GL_APPLE_vertex_array_object
 #define need_GL_NV_vertex_program
 #include "extension_helper.h"
 
@@ -412,6 +413,7 @@ static const struct dri_extension card_extensions[] =
 #endif
    { "GL_EXT_secondary_color",        GL_EXT_secondary_color_functions },
    { "GL_EXT_stencil_wrap",           NULL },
+   { "GL_APPLE_vertex_array_object",  GL_APPLE_vertex_array_object_functions },
    { "GL_MESA_ycbcr_texture",         NULL },
    { "GL_SGIS_generate_mipmap",       NULL },
    { NULL,                            NULL }
diff --git a/src/mesa/drivers/dri/mga/mgadd.c b/src/mesa/drivers/dri/mga/mgadd.c
index b1d5e0c48f..6d18bd83d8 100644
--- a/src/mesa/drivers/dri/mga/mgadd.c
+++ b/src/mesa/drivers/dri/mga/mgadd.c
@@ -41,7 +41,7 @@
 #include "mga_xmesa.h"
 #include "utils.h"
 
-#define DRIVER_DATE	"20061030"
+#define DRIVER_DATE	"20071017"
 
 
 /***************************************
-- 
cgit v1.2.3


From 42a4386a4c18932221c59607e6d22b864a2577fb Mon Sep 17 00:00:00 2001
From: Ian Romanick <idr@us.ibm.com>
Date: Wed, 17 Oct 2007 12:07:04 -0700
Subject: Initial support for ARB_depth_texture

Currently only GL_DEPTH_COMPONENT16 are supported.  I don't know what the
hardware bits are to select the other formats, but it shouldn't be too hard
to figure out.
---
 src/mesa/drivers/dri/r300/r300_context.c  |  4 ++-
 src/mesa/drivers/dri/r300/r300_tex.c      | 32 ++++++++++++++++++++++++
 src/mesa/drivers/dri/r300/r300_tex.h      |  2 ++
 src/mesa/drivers/dri/r300/r300_texstate.c | 41 ++++++++++++++++++++++++++++++-
 4 files changed, 77 insertions(+), 2 deletions(-)

(limited to 'src')

diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c
index 14e0f052fd..d2ed3105d1 100644
--- a/src/mesa/drivers/dri/r300/r300_context.c
+++ b/src/mesa/drivers/dri/r300/r300_context.c
@@ -93,6 +93,8 @@ int hw_tcl_on = 1;
 
 const struct dri_extension card_extensions[] = {
   /* *INDENT-OFF* */
+  {"GL_ARB_depth_texture",		NULL},
+  {"GL_ARB_fragment_program",		NULL},
   {"GL_ARB_multisample",		GL_ARB_multisample_functions},
   {"GL_ARB_multitexture",		NULL},
   {"GL_ARB_texture_border_clamp",	NULL},
@@ -105,7 +107,6 @@ const struct dri_extension card_extensions[] = {
   {"GL_ARB_texture_mirrored_repeat",	NULL},
   {"GL_ARB_vertex_buffer_object",	GL_ARB_vertex_buffer_object_functions},
   {"GL_ARB_vertex_program",		GL_ARB_vertex_program_functions},
-  {"GL_ARB_fragment_program",		NULL},
   {"GL_EXT_blend_equation_separate",	GL_EXT_blend_equation_separate_functions},
   {"GL_EXT_blend_func_separate",	GL_EXT_blend_func_separate_functions},
   {"GL_EXT_blend_minmax",		GL_EXT_blend_minmax_functions},
@@ -130,6 +131,7 @@ const struct dri_extension card_extensions[] = {
   {"GL_NV_blend_square",		NULL},
   {"GL_NV_vertex_program",		GL_NV_vertex_program_functions},
   {"GL_SGIS_generate_mipmap",		NULL},
+  {"GL_SGIX_depth_texture",		NULL},
   {NULL,				NULL}
   /* *INDENT-ON* */
 };
diff --git a/src/mesa/drivers/dri/r300/r300_tex.c b/src/mesa/drivers/dri/r300/r300_tex.c
index 1805cecd0a..adf69a3c25 100644
--- a/src/mesa/drivers/dri/r300/r300_tex.c
+++ b/src/mesa/drivers/dri/r300/r300_tex.c
@@ -482,6 +482,25 @@ static const struct gl_texture_format *r300ChooseTextureFormat(GLcontext * ctx,
 	case GL_RGBA32F_ARB:
 		return &_mesa_texformat_rgba_float32;
 
+	case GL_DEPTH_COMPONENT:
+	case GL_DEPTH_COMPONENT16:
+	case GL_DEPTH_COMPONENT24:
+	case GL_DEPTH_COMPONENT32:
+#if 0
+		switch (type) {
+		case GL_UNSIGNED_BYTE:
+		case GL_UNSIGNED_SHORT:
+			return &_mesa_texformat_z16;
+		case GL_UNSIGNED_INT:
+			return &_mesa_texformat_z32;
+		case GL_UNSIGNED_INT_24_8_EXT:
+		default:
+			return &_mesa_texformat_z24_s8;
+		}
+#else
+		return &_mesa_texformat_z16;
+#endif
+
 	default:
 		_mesa_problem(ctx,
 			      "unexpected internalFormat 0x%x in r300ChooseTextureFormat",
@@ -1057,6 +1076,19 @@ static void r300TexParameter(GLcontext * ctx, GLenum target,
 		driSwapOutTextureObject((driTextureObject *) t);
 		break;
 
+	case GL_DEPTH_TEXTURE_MODE:
+		if (texObj->Image[0][texObj->BaseLevel]->TexFormat->BaseFormat 
+		    == GL_DEPTH_COMPONENT) {
+			r300SetDepthTexMode(texObj);
+			break;
+		} else {
+			/* If the texture isn't a depth texture, changing this
+			 * state won't cause any changes to the hardware.
+			 * Don't force a flush of texture state.
+			 */
+			return;
+		}
+
 	default:
 		return;
 	}
diff --git a/src/mesa/drivers/dri/r300/r300_tex.h b/src/mesa/drivers/dri/r300/r300_tex.h
index f67a8e6ba6..b86d45bfe0 100644
--- a/src/mesa/drivers/dri/r300/r300_tex.h
+++ b/src/mesa/drivers/dri/r300/r300_tex.h
@@ -35,6 +35,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #ifndef __r300_TEX_H__
 #define __r300_TEX_H__
 
+extern void r300SetDepthTexMode(struct gl_texture_object *tObj);
+
 extern void r300SetTexOffset(__DRIcontext *pDRICtx, GLint texname,
 			     unsigned long long offset, GLint depth,
 			     GLuint pitch);
diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c
index 1d2909fd21..1c9851afb2 100644
--- a/src/mesa/drivers/dri/r300/r300_texstate.c
+++ b/src/mesa/drivers/dri/r300/r300_texstate.c
@@ -115,11 +115,45 @@ static const struct tx_table {
 	_ASSIGN(LUMINANCE_ALPHA_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, Y, FL_I16A16)),
 	_ASSIGN(INTENSITY_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, X, FL_I32)),
 	_ASSIGN(INTENSITY_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, X, FL_I16)),
+	_ASSIGN(Z16, R300_EASY_TX_FORMAT(X, X, X, X, X16)),
+#if 0
+	_ASSIGN(Z24_S8, R300_EASY_TX_FORMAT(X, X, X, X, X24_Y8)),
+	_ASSIGN(Z32, R300_EASY_TX_FORMAT(X, X, X, X, X32)),
+#endif
 	/* *INDENT-ON* */
 };
 
 #undef _ASSIGN
 
+void r300SetDepthTexMode(struct gl_texture_object *tObj)
+{
+	r300TexObjPtr t;
+
+	if (!tObj)
+		return;
+
+	t = (r300TexObjPtr) tObj->DriverData;
+
+	switch (tObj->DepthMode) {
+	case GL_LUMINANCE:
+		t->format = R300_EASY_TX_FORMAT(X, X, X, X, X16);
+		break;
+	case GL_INTENSITY:
+		t->format = R300_EASY_TX_FORMAT(X, X, X, ONE, X16);
+		break;
+	case GL_ALPHA:
+		t->format = R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X16);
+		break;
+	default:
+		/* Error...which should have already been caught by higher
+		 * levels of Mesa.
+		 */
+		ASSERT(0);
+		break;
+	}
+}
+
+
 /**
  * This function computes the number of bytes of storage needed for
  * the given texture object (all mipmap levels, all cube faces).
@@ -146,7 +180,12 @@ static void r300SetTexImages(r300ContextPtr rmesa,
 	 */
 	if (!t->image_override
 	    && VALID_FORMAT(baseImage->TexFormat->MesaFormat)) {
-		t->format = tx_table[baseImage->TexFormat->MesaFormat].format;
+		if (baseImage->TexFormat->BaseFormat == GL_DEPTH_COMPONENT) {
+			r300SetDepthTexMode(tObj);
+		} else {
+			t->format = tx_table[baseImage->TexFormat->MesaFormat].format;
+		}
+
 		t->filter |= tx_table[baseImage->TexFormat->MesaFormat].filter;
 	} else if (!t->image_override) {
 		_mesa_problem(NULL, "unexpected texture format in %s",
-- 
cgit v1.2.3


From a663e846b63c33685a9e88c8904f5e3a225f6e85 Mon Sep 17 00:00:00 2001
From: Ian Romanick <idr@us.ibm.com>
Date: Wed, 17 Oct 2007 13:11:01 -0700
Subject: Framework for supporting z24_s8 and z32 depth textures on r300.

---
 src/mesa/drivers/dri/r300/r300_reg.h      |  8 ++++++
 src/mesa/drivers/dri/r300/r300_texstate.c | 47 +++++++++++++++++++++++++++----
 2 files changed, 49 insertions(+), 6 deletions(-)

(limited to 'src')

diff --git a/src/mesa/drivers/dri/r300/r300_reg.h b/src/mesa/drivers/dri/r300/r300_reg.h
index 1baa74c526..ee556d347e 100644
--- a/src/mesa/drivers/dri/r300/r300_reg.h
+++ b/src/mesa/drivers/dri/r300/r300_reg.h
@@ -886,6 +886,14 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #	define R300_TX_FORMAT_A8R8G8B8	    	    0x13     /* no swizzle */
 #	define R300_TX_FORMAT_B8G8_B8G8	    	    0x14     /* no swizzle */
 #	define R300_TX_FORMAT_G8R8_G8B8	    	    0x15     /* no swizzle */
+
+	/* These two values are wrong, but they're the only values that
+	 * produce any even vaguely correct results.  Can r300 only do 16-bit
+	 * depth textures?
+	 */
+#	define R300_TX_FORMAT_X24_Y8	    	    0x1e
+#	define R300_TX_FORMAT_X32	    	    0x1e
+
 	/* 0x16 - some 16 bit green format.. ?? */
 #	define R300_TX_FORMAT_UNK25		   (1 << 25) /* no swizzle */
 #	define R300_TX_FORMAT_CUBIC_MAP		   (1 << 26)
diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c
index 1c9851afb2..efa201a52d 100644
--- a/src/mesa/drivers/dri/r300/r300_texstate.c
+++ b/src/mesa/drivers/dri/r300/r300_texstate.c
@@ -116,10 +116,8 @@ static const struct tx_table {
 	_ASSIGN(INTENSITY_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, X, FL_I32)),
 	_ASSIGN(INTENSITY_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, X, FL_I16)),
 	_ASSIGN(Z16, R300_EASY_TX_FORMAT(X, X, X, X, X16)),
-#if 0
 	_ASSIGN(Z24_S8, R300_EASY_TX_FORMAT(X, X, X, X, X24_Y8)),
 	_ASSIGN(Z32, R300_EASY_TX_FORMAT(X, X, X, X, X32)),
-#endif
 	/* *INDENT-ON* */
 };
 
@@ -127,6 +125,24 @@ static const struct tx_table {
 
 void r300SetDepthTexMode(struct gl_texture_object *tObj)
 {
+	static const GLuint formats[3][3] = {
+		{
+			R300_EASY_TX_FORMAT(X, X, X, X, X16),
+			R300_EASY_TX_FORMAT(X, X, X, ONE, X16),
+			R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X16),
+		},
+		{
+			R300_EASY_TX_FORMAT(X, X, X, X, X24_Y8),
+			R300_EASY_TX_FORMAT(X, X, X, ONE, X24_Y8),
+			R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X24_Y8),
+		},
+		{
+			R300_EASY_TX_FORMAT(X, X, X, X, X32),
+			R300_EASY_TX_FORMAT(X, X, X, ONE, X32),
+			R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X32),
+		},
+	};
+	const GLuint *format;
 	r300TexObjPtr t;
 
 	if (!tObj)
@@ -134,22 +150,41 @@ void r300SetDepthTexMode(struct gl_texture_object *tObj)
 
 	t = (r300TexObjPtr) tObj->DriverData;
 
+
+	switch (tObj->Image[0][tObj->BaseLevel]->TexFormat->MesaFormat) {
+	case MESA_FORMAT_Z16:
+		format = formats[0];
+		break;
+	case MESA_FORMAT_Z24_S8:
+		format = formats[1];
+		break;
+	case MESA_FORMAT_Z32:
+		format = formats[2];
+		break;
+	default:
+		/* Error...which should have already been caught by higher
+		 * levels of Mesa.
+		 */
+		ASSERT(0);
+		return;
+	}
+
 	switch (tObj->DepthMode) {
 	case GL_LUMINANCE:
-		t->format = R300_EASY_TX_FORMAT(X, X, X, X, X16);
+		t->format = format[0];
 		break;
 	case GL_INTENSITY:
-		t->format = R300_EASY_TX_FORMAT(X, X, X, ONE, X16);
+		t->format = format[1];
 		break;
 	case GL_ALPHA:
-		t->format = R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X16);
+		t->format = format[2];
 		break;
 	default:
 		/* Error...which should have already been caught by higher
 		 * levels of Mesa.
 		 */
 		ASSERT(0);
-		break;
+		return;
 	}
 }
 
-- 
cgit v1.2.3


From 950fff0f9a330c50a627ced2e8cff2fb4689bee0 Mon Sep 17 00:00:00 2001
From: Michel Dänzer <michel@tungstengraphics.com>
Date: Thu, 18 Oct 2007 18:30:15 +0200
Subject: i915: Add some sanity checks to blit command debugging code.

---
 src/mesa/drivers/dri/i915/i915_debug.c | 37 +++++++++++++++++++---------------
 1 file changed, 21 insertions(+), 16 deletions(-)

(limited to 'src')

diff --git a/src/mesa/drivers/dri/i915/i915_debug.c b/src/mesa/drivers/dri/i915/i915_debug.c
index c0e1242a0e..8eb1c5b49e 100644
--- a/src/mesa/drivers/dri/i915/i915_debug.c
+++ b/src/mesa/drivers/dri/i915/i915_debug.c
@@ -376,20 +376,25 @@ static void BR13( struct debug_stream *stream,
 }
 
 
-static void BR22( struct debug_stream *stream,
-		  GLuint val )
+static void BR2223( struct debug_stream *stream,
+		    GLuint val22, GLuint val23 )
 {
-   PRINTF("\t0x%08x\n",  val);
-   BITS(val, 31, 16, "dest y1");
-   BITS(val, 15, 0,  "dest x1");
-}
+   union { GLuint val; short field[2]; } BR22, BR23;
 
-static void BR23( struct debug_stream *stream,
-		  GLuint val )
-{
-   PRINTF("\t0x%08x\n",  val);
-   BITS(val, 31, 16, "dest y2");
-   BITS(val, 15, 0,  "dest x2");
+   BR22.val = val22;
+   BR23.val = val23;
+
+   PRINTF("\t0x%08x\n",  val22);
+   BITS(val22, 31, 16, "dest y1");
+   BITS(val22, 15, 0,  "dest x1");
+
+   PRINTF("\t0x%08x\n",  val23);
+   BITS(val23, 31, 16, "dest y2");
+   BITS(val23, 15, 0,  "dest x2");
+
+   /* The blit engine may produce unexpected results when these aren't met */
+   assert(BR22.field[0] < BR23.field[0]);
+   assert(BR22.field[1] < BR23.field[1]);
 }
 
 static void BR09( struct debug_stream *stream,
@@ -436,8 +441,8 @@ static GLboolean debug_copy_blit( struct debug_stream *stream,
    PRINTF("\t0x%08x\n",  ptr[j++]);
    
    BR13(stream, ptr[j++]);
-   BR22(stream, ptr[j++]);
-   BR23(stream, ptr[j++]);
+   BR2223(stream, ptr[j], ptr[j+1]);
+   j += 2;
    BR09(stream, ptr[j++]);
    BR26(stream, ptr[j++]);
    BR11(stream, ptr[j++]);
@@ -459,8 +464,8 @@ static GLboolean debug_color_blit( struct debug_stream *stream,
    PRINTF("\t0x%08x\n",  ptr[j++]);
 
    BR13(stream, ptr[j++]);
-   BR22(stream, ptr[j++]);
-   BR23(stream, ptr[j++]);
+   BR2223(stream, ptr[j], ptr[j+1]);
+   j += 2;
    BR09(stream, ptr[j++]);
    BR16(stream, ptr[j++]);
 
-- 
cgit v1.2.3


From 2667e5642ffb2081450a167af1213899280da42d Mon Sep 17 00:00:00 2001
From: Brian <brian.paul@tungstengraphics.com>
Date: Mon, 22 Oct 2007 17:50:17 -0600
Subject: don't apply ColorMask to main gc

---
 src/mesa/drivers/x11/xm_dd.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

(limited to 'src')

diff --git a/src/mesa/drivers/x11/xm_dd.c b/src/mesa/drivers/x11/xm_dd.c
index c8546236fb..4c8bf5f656 100644
--- a/src/mesa/drivers/x11/xm_dd.c
+++ b/src/mesa/drivers/x11/xm_dd.c
@@ -159,7 +159,6 @@ index_mask( GLcontext *ctx, GLuint mask )
          m = (unsigned long) mask;
       }
       XMesaSetPlaneMask( xmesa->display, xmbuf->cleargc, m );
-      XMesaSetPlaneMask( xmesa->display, xmbuf->gc, m );
    }
 }
 
@@ -191,7 +190,6 @@ color_mask(GLcontext *ctx,
          if (bmask)   m |= GET_BLUEMASK(xmesa->xm_visual);
       }
       XMesaSetPlaneMask( xmesa->display, xmbuf->cleargc, m );
-      XMesaSetPlaneMask( xmesa->display, xmbuf->gc, m );
    }
 }
 
@@ -450,13 +448,13 @@ xmesa_DrawPixels_8R8G8B( GLcontext *ctx,
        ctx->_ImageTransferState == 0 &&  /* no color tables, scale/bias, etc */
        ctx->Pixel.ZoomX == 1.0 &&        /* no zooming */
        ctx->Pixel.ZoomY == 1.0 &&
-       xrb->pixmap &&
+       xrb->pixmap &&                    /* drawing to pixmap or window */
        xrb->Base.AlphaBits == 0)
    {
       const XMesaContext xmesa = XMESA_CONTEXT(ctx);
       XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer);
       XMesaDisplay *dpy = xmesa->xm_visual->display;
-      const XMesaGC gc = xmbuf->gc;
+      const XMesaGC gc = xmbuf->cleargc;  /* effected by glColorMask */
       int dstX = x;
       int dstY = y;
       int w = width;
@@ -551,7 +549,7 @@ xmesa_DrawPixels_5R6G5B( GLcontext *ctx,
    const SWcontext *swrast = SWRAST_CONTEXT( ctx );
    XMesaDisplay *dpy = xmesa->xm_visual->display;
    XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer);
-   const XMesaGC gc = xmbuf->gc;
+   const XMesaGC gc = xmbuf->cleargc;  /* effected by glColorMask */
 
    ASSERT(dpy);
    ASSERT(gc);
@@ -560,7 +558,7 @@ xmesa_DrawPixels_5R6G5B( GLcontext *ctx,
    if (swrast->NewState)
       _swrast_validate_derived( ctx );
 
-   if (xrb->pixmap &&
+   if (xrb->pixmap &&       /* drawing to pixmap or window */
        format == GL_RGB &&
        type == GL_UNSIGNED_SHORT_5_6_5 &&
        !ctx->Color.DitherFlag &&  /* no dithering */
@@ -651,7 +649,8 @@ xmesa_CopyPixels( GLcontext *ctx,
    const XMesaContext xmesa = XMESA_CONTEXT(ctx);
    const SWcontext *swrast = SWRAST_CONTEXT( ctx );
    XMesaDisplay *dpy = xmesa->xm_visual->display;
-   const XMesaGC gc = ((XMesaBuffer) ctx->DrawBuffer)->gc;
+   XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer);
+   const XMesaGC gc = xmbuf->cleargc;  /* effected by glColorMask */
    struct xmesa_renderbuffer *srcXrb
       = xmesa_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer->Wrapped);
    struct xmesa_renderbuffer *dstXrb
-- 
cgit v1.2.3


From 2a8e9bb00f8cf830783cbc20a2a57f31b19491ea Mon Sep 17 00:00:00 2001
From: Brian <brian.paul@tungstengraphics.com>
Date: Tue, 23 Oct 2007 10:24:53 -0600
Subject: bump up MAX_INSTRUCTIONS and add an assertion to catch emitting too
 many instructions

---
 src/mesa/main/texenvprogram.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

(limited to 'src')

diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c
index 9c84da985e..935eb44a32 100644
--- a/src/mesa/main/texenvprogram.c
+++ b/src/mesa/main/texenvprogram.c
@@ -35,10 +35,11 @@
 #include "texenvprogram.h"
 
 /**
- * According to Glean's texCombine test, no more than 21 instructions
- * are needed.  Allow a few extra just in case.
+ * This MAX is probably a bit generous, but that's OK.  There can be
+ * up to four instructions per texture unit (TEX + 3 for combine),
+ * then there's fog and specular add.
  */
-#define MAX_INSTRUCTIONS ((MAX_TEXTURE_UNITS * 6) + 10) /* see bug 9829 */
+#define MAX_INSTRUCTIONS ((MAX_TEXTURE_UNITS * 4) + 12)
 
 #define DISASSEM (MESA_VERBOSE & VERBOSE_DISASSEM)
 
@@ -476,7 +477,9 @@ emit_op(struct texenv_fragment_program *p,
 {
    GLuint nr = p->program->Base.NumInstructions++;
    struct prog_instruction *inst = &p->program->Base.Instructions[nr];
-      
+
+   assert(nr < MAX_INSTRUCTIONS);
+
    _mesa_init_instructions(inst, 1);
    inst->Opcode = op;
    
-- 
cgit v1.2.3


From c9d495c6f064aacd1e072033b9c17a83b8c37fa1 Mon Sep 17 00:00:00 2001
From: Brian <brian.paul@tungstengraphics.com>
Date: Tue, 23 Oct 2007 10:55:24 -0600
Subject: properly init dst reg's CondMask/Swizzle fields

---
 src/mesa/main/texenvprogram.c | 4 ++--
 src/mesa/tnl/t_vp_build.c     | 6 +++---
 2 files changed, 5 insertions(+), 5 deletions(-)

(limited to 'src')

diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c
index 935eb44a32..38be039084 100644
--- a/src/mesa/main/texenvprogram.c
+++ b/src/mesa/main/texenvprogram.c
@@ -461,8 +461,8 @@ static void emit_dst( struct prog_dst_register *dst,
    dst->File = ureg.file;
    dst->Index = ureg.idx;
    dst->WriteMask = mask;
-   dst->CondMask = 0;
-   dst->CondSwizzle = 0;
+   dst->CondMask = COND_TR;  /* always pass cond test */
+   dst->CondSwizzle = SWIZZLE_NOOP;
 }
 
 static struct prog_instruction *
diff --git a/src/mesa/tnl/t_vp_build.c b/src/mesa/tnl/t_vp_build.c
index 6a6db06285..b7bc197723 100644
--- a/src/mesa/tnl/t_vp_build.c
+++ b/src/mesa/tnl/t_vp_build.c
@@ -489,8 +489,8 @@ static void emit_dst( struct prog_dst_register *dst,
    dst->Index = reg.idx;
    /* allow zero as a shorthand for xyzw */
    dst->WriteMask = mask ? mask : WRITEMASK_XYZW; 
-   dst->CondMask = COND_TR;
-   dst->CondSwizzle = 0;
+   dst->CondMask = COND_TR;  /* always pass cond test */
+   dst->CondSwizzle = SWIZZLE_NOOP;
    dst->CondSrc = 0;
    dst->pad = 0;
 }
@@ -513,7 +513,7 @@ static void debug_insn( struct prog_instruction *inst, const char *fn,
 
 
 static void emit_op3fn(struct tnl_program *p,
-		       GLuint op,
+                       enum prog_opcode op,
 		       struct ureg dest,
 		       GLuint mask,
 		       struct ureg src0,
-- 
cgit v1.2.3


From e48f0b09abe42aa3393a492af07e53b76ad0ff3c Mon Sep 17 00:00:00 2001
From: Brian <brian.paul@tungstengraphics.com>
Date: Wed, 24 Oct 2007 11:37:05 -0600
Subject: Implement gl_PointCoord attribute for GLSL fragment shaders.

Contains the normalized fragment position within a point sprite.
---
 src/mesa/shader/slang/slang_codegen.c |   6 +-
 src/mesa/shader/slang/slang_compile.c |  11 ++++
 src/mesa/swrast/s_fog.c               |   1 -
 src/mesa/swrast/s_fragprog.c          |   1 +
 src/mesa/swrast/s_points.c            | 117 +++++++++++++++++++---------------
 src/mesa/swrast/s_span.c              |   2 +-
 6 files changed, 85 insertions(+), 53 deletions(-)

(limited to 'src')

diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index d368009ca5..a44e42b6d6 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -282,6 +282,8 @@ sampler_to_texture_index(const slang_type_specifier_type type)
 }
 
 
+#define SWIZZLE_ZWWW MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W)
+
 /**
  * Return the VERT_ATTRIB_* or FRAG_ATTRIB_* value that corresponds to
  * a vertex or fragment program input variable.  Return -1 if the input
@@ -316,9 +318,11 @@ _slang_input_index(const char *name, GLenum target, GLuint *swizzleOut)
       { "gl_FragCoord", FRAG_ATTRIB_WPOS, SWIZZLE_NOOP },
       { "gl_Color", FRAG_ATTRIB_COL0, SWIZZLE_NOOP },
       { "gl_SecondaryColor", FRAG_ATTRIB_COL1, SWIZZLE_NOOP },
-      { "gl_FogFragCoord", FRAG_ATTRIB_FOGC, SWIZZLE_XXXX },
       { "gl_TexCoord", FRAG_ATTRIB_TEX0, SWIZZLE_NOOP },
+      /* note: we're packing several quantities into the fogcoord vector */
+      { "gl_FogFragCoord", FRAG_ATTRIB_FOGC, SWIZZLE_XXXX },
       { "gl_FrontFacing", FRAG_ATTRIB_FOGC, SWIZZLE_YYYY }, /*XXX*/
+      { "gl_PointCoord", FRAG_ATTRIB_FOGC, SWIZZLE_ZWWW },
       { NULL, 0, SWIZZLE_NOOP }
    };
    GLuint i;
diff --git a/src/mesa/shader/slang/slang_compile.c b/src/mesa/shader/slang/slang_compile.c
index 4e29e8dcc9..2be89a5ce0 100644
--- a/src/mesa/shader/slang/slang_compile.c
+++ b/src/mesa/shader/slang/slang_compile.c
@@ -1983,6 +1983,10 @@ static const byte slang_120_core_gc[] = {
 #include "library/slang_120_core_gc.h"
 };
 
+static const byte slang_120_fragment_gc[] = {
+#include "library/slang_builtin_120_fragment_gc.h"
+};
+
 static const byte slang_common_builtin_gc[] = {
 #include "library/slang_common_builtin_gc.h"
 };
@@ -2059,6 +2063,13 @@ compile_object(grammar * id, const char *source, slang_code_object * object,
                              SLANG_UNIT_FRAGMENT_BUILTIN, infolog, NULL,
                              &object->builtin[SLANG_BUILTIN_COMMON], NULL))
             return GL_FALSE;
+#if FEATURE_ARB_shading_language_120
+         if (!compile_binary(slang_120_fragment_gc,
+                             &object->builtin[SLANG_BUILTIN_TARGET],
+                             SLANG_UNIT_FRAGMENT_BUILTIN, infolog, NULL,
+                             &object->builtin[SLANG_BUILTIN_COMMON], NULL))
+            return GL_FALSE;
+#endif
       }
       else if (type == SLANG_UNIT_VERTEX_SHADER) {
          if (!compile_binary(slang_vertex_builtin_gc,
diff --git a/src/mesa/swrast/s_fog.c b/src/mesa/swrast/s_fog.c
index ed47964a66..7b143f6e5b 100644
--- a/src/mesa/swrast/s_fog.c
+++ b/src/mesa/swrast/s_fog.c
@@ -168,7 +168,6 @@ _swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span )
    GLfloat rFog, gFog, bFog;
 
    ASSERT(swrast->_FogEnabled);
-   ASSERT(swrast->_ActiveAttribMask & FRAG_BIT_FOGC);
    ASSERT(span->arrayMask & SPAN_RGBA);
 
    /* compute (scaled) fog color */
diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c
index 14c9868c18..6656ebc0d0 100644
--- a/src/mesa/swrast/s_fragprog.c
+++ b/src/mesa/swrast/s_fragprog.c
@@ -113,6 +113,7 @@ init_machine(GLcontext *ctx, struct gl_program_machine *machine,
    machine->DerivY = (GLfloat (*)[4]) span->attrStepY;
    machine->NumDeriv = FRAG_ATTRIB_MAX;
 
+   /* if running a GLSL program (not ARB_fragment_program) */
    if (ctx->Shader.CurrentProgram) {
       /* Store front/back facing value in register FOGC.Y */
       machine->Attribs[FRAG_ATTRIB_FOGC][col][1] = (GLfloat) ctx->_Facing;
diff --git a/src/mesa/swrast/s_points.c b/src/mesa/swrast/s_points.c
index d54adc8fd1..ce73365a4e 100644
--- a/src/mesa/swrast/s_points.c
+++ b/src/mesa/swrast/s_points.c
@@ -55,7 +55,7 @@ sprite_point(GLcontext *ctx, const SWvertex *vert)
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    SWspan span;
    GLfloat size;
-   GLuint tCoords[MAX_TEXTURE_COORD_UNITS];
+   GLuint tCoords[MAX_TEXTURE_COORD_UNITS + 1];
    GLuint numTcoords = 0;
    GLfloat t0, dtdy;
 
@@ -99,57 +99,71 @@ sprite_point(GLcontext *ctx, const SWvertex *vert)
    span.attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0F;
    span.attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0F;
 
-   ATTRIB_LOOP_BEGIN
-      if (attr >= FRAG_ATTRIB_TEX0 && attr < FRAG_ATTRIB_VAR0) {
-         const GLuint u = attr - FRAG_ATTRIB_TEX0;
-         /* a texcoord */
-         if (ctx->Point.CoordReplace[u]) {
-            GLfloat s, r, dsdx;
-
-            s = 0.0;
-            dsdx = 1.0 / size;
-
-            if (ctx->Point.SpriteOrigin == GL_LOWER_LEFT) {
-               t0 = 0.0;
-               dtdy = 1.0 / size;
-            }
-            else {
-               /* GL_UPPER_LEFT */
-               t0 = 1.0;
-               dtdy = -1.0 / size;
-            }
-            tCoords[numTcoords++] = attr;
-
-            if (ctx->Point.SpriteRMode == GL_ZERO)
-               r = 0.0F;
-            else if (ctx->Point.SpriteRMode == GL_S)
-               r = vert->attrib[attr][0];
-            else /* GL_R */
-               r = vert->attrib[attr][2];
-
-            span.attrStart[attr][0] = s;
-            span.attrStart[attr][1] = 0.0; /* overwritten below */
-            span.attrStart[attr][2] = r;
-            span.attrStart[attr][3] = 1.0;
-
-            span.attrStepX[attr][0] = dsdx;
-            span.attrStepX[attr][1] = 0.0;
-            span.attrStepX[attr][2] = 0.0;
-            span.attrStepX[attr][3] = 0.0;
-
-            span.attrStepY[attr][0] = 0.0;
-            span.attrStepY[attr][1] = dtdy;
-            span.attrStepY[attr][2] = 0.0;
-            span.attrStepY[attr][3] = 0.0;
+   {
+      GLfloat s, r, dsdx;
+
+      /* texcoord / pointcoord interpolants */
+      s = 0.0;
+      dsdx = 1.0 / size;
+      if (ctx->Point.SpriteOrigin == GL_LOWER_LEFT) {
+         t0 = 0.0;
+         dtdy = 1.0 / size;
+      }
+      else {
+         /* GL_UPPER_LEFT */
+         t0 = 1.0;
+         dtdy = -1.0 / size;
+      }
 
+      ATTRIB_LOOP_BEGIN
+         if (attr >= FRAG_ATTRIB_TEX0 && attr < FRAG_ATTRIB_VAR0) {
+            const GLuint u = attr - FRAG_ATTRIB_TEX0;
+            /* a texcoord */
+            if (ctx->Point.CoordReplace[u]) {
+               tCoords[numTcoords++] = attr;
+
+               if (ctx->Point.SpriteRMode == GL_ZERO)
+                  r = 0.0F;
+               else if (ctx->Point.SpriteRMode == GL_S)
+                  r = vert->attrib[attr][0];
+               else /* GL_R */
+                  r = vert->attrib[attr][2];
+
+               span.attrStart[attr][0] = s;
+               span.attrStart[attr][1] = 0.0; /* overwritten below */
+               span.attrStart[attr][2] = r;
+               span.attrStart[attr][3] = 1.0;
+
+               span.attrStepX[attr][0] = dsdx;
+               span.attrStepX[attr][1] = 0.0;
+               span.attrStepX[attr][2] = 0.0;
+               span.attrStepX[attr][3] = 0.0;
+
+               span.attrStepY[attr][0] = 0.0;
+               span.attrStepY[attr][1] = dtdy;
+               span.attrStepY[attr][2] = 0.0;
+               span.attrStepY[attr][3] = 0.0;
+
+               continue;
+            }
+         }
+         else if (attr == FRAG_ATTRIB_FOGC) {
+            /* GLSL gl_PointCoord is stored in fog.zw */
+            span.attrStart[FRAG_ATTRIB_FOGC][2] = 0.0;
+            span.attrStart[FRAG_ATTRIB_FOGC][3] = 0.0; /* t0 set below */
+            span.attrStepX[FRAG_ATTRIB_FOGC][2] = dsdx;
+            span.attrStepX[FRAG_ATTRIB_FOGC][3] = 0.0;
+            span.attrStepY[FRAG_ATTRIB_FOGC][2] = 0.0;
+            span.attrStepY[FRAG_ATTRIB_FOGC][3] = dtdy;
+            tCoords[numTcoords++] = FRAG_ATTRIB_FOGC;
             continue;
          }
-      }
-      /* use vertex's texcoord/attrib */
-      COPY_4V(span.attrStart[attr], vert->attrib[attr]);
-      ASSIGN_4V(span.attrStepX[attr], 0, 0, 0, 0);
-      ASSIGN_4V(span.attrStepY[attr], 0, 0, 0, 0);
-   ATTRIB_LOOP_END
+         /* use vertex's texcoord/attrib */
+         COPY_4V(span.attrStart[attr], vert->attrib[attr]);
+         ASSIGN_4V(span.attrStepX[attr], 0, 0, 0, 0);
+         ASSIGN_4V(span.attrStepY[attr], 0, 0, 0, 0);
+      ATTRIB_LOOP_END;
+   }
 
    /* compute pos, bounds and render */
    {
@@ -184,7 +198,10 @@ sprite_point(GLcontext *ctx, const SWvertex *vert)
          GLuint i;
          /* setup texcoord T for this row */
          for (i = 0; i < numTcoords; i++) {
-            span.attrStart[tCoords[i]][1] = tcoord;
+            if (tCoords[i] == FRAG_ATTRIB_FOGC)
+               span.attrStart[FRAG_ATTRIB_FOGC][3] = tcoord;
+            else
+               span.attrStart[tCoords[i]][1] = tcoord;
          }
 
          /* these might get changed by span clipping */
diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c
index f1e58bd3d8..000e192a4a 100644
--- a/src/mesa/swrast/s_span.c
+++ b/src/mesa/swrast/s_span.c
@@ -1183,7 +1183,7 @@ shade_texture_span(GLcontext *ctx, SWspan *span)
       if (span->primitive == GL_BITMAP && span->array->ChanType != GL_FLOAT) {
          convert_color_type(span, GL_FLOAT, 0);
       }
-      if (span->primitive != GL_POINT) {
+      if (span->primitive != GL_POINT || ctx->Point.PointSprite) {
          /* for points, we populated the arrays already */
          interpolate_active_attribs(ctx, span, ~0);
       }
-- 
cgit v1.2.3


From 5e9272c748fba836c716346f1c527e7d139083a4 Mon Sep 17 00:00:00 2001
From: Brian <brian.paul@tungstengraphics.com>
Date: Wed, 24 Oct 2007 12:43:02 -0600
Subject: add to git

---
 .../slang/library/slang_builtin_120_common_gc.h    | 104 +++++++++++++++++++++
 .../slang/library/slang_builtin_120_fragment_gc.h  |   5 +
 2 files changed, 109 insertions(+)
 create mode 100644 src/mesa/shader/slang/library/slang_builtin_120_common_gc.h
 create mode 100644 src/mesa/shader/slang/library/slang_builtin_120_fragment_gc.h

(limited to 'src')

diff --git a/src/mesa/shader/slang/library/slang_builtin_120_common_gc.h b/src/mesa/shader/slang/library/slang_builtin_120_common_gc.h
new file mode 100644
index 0000000000..fc1a944217
--- /dev/null
+++ b/src/mesa/shader/slang/library/slang_builtin_120_common_gc.h
@@ -0,0 +1,104 @@
+
+/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED FROM THE FOLLOWING FILE: */
+/* slang_builtin_120_common.gc */
+
+3,1,0,26,0,109,97,116,114,105,120,67,111,109,112,77,117,108,116,0,1,0,0,26,109,0,0,1,0,0,26,110,0,
+0,0,1,8,58,109,97,116,50,120,51,0,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,48,0,18,109,0,16,10,
+49,0,57,18,110,0,16,10,49,0,57,48,0,0,0,0,1,0,28,0,109,97,116,114,105,120,67,111,109,112,77,117,
+108,116,0,1,0,0,28,109,0,0,1,0,0,28,110,0,0,0,1,8,58,109,97,116,50,120,52,0,18,109,0,16,8,48,0,57,
+18,110,0,16,8,48,0,57,48,0,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,48,0,0,0,0,1,0,27,0,109,
+97,116,114,105,120,67,111,109,112,77,117,108,116,0,1,0,0,27,109,0,0,1,0,0,27,110,0,0,0,1,8,58,109,
+97,116,51,120,50,0,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,48,0,18,109,0,16,10,49,0,57,18,110,
+0,16,10,49,0,57,48,0,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,48,0,0,0,0,1,0,30,0,109,97,116,
+114,105,120,67,111,109,112,77,117,108,116,0,1,0,0,30,109,0,0,1,0,0,30,110,0,0,0,1,8,58,109,97,116,
+51,120,52,0,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,48,0,18,109,0,16,10,49,0,57,18,110,0,16,10,
+49,0,57,48,0,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,48,0,0,0,0,1,0,29,0,109,97,116,114,105,
+120,67,111,109,112,77,117,108,116,0,1,0,0,29,109,0,0,1,0,0,29,110,0,0,0,1,8,58,109,97,116,52,120,
+50,0,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,48,0,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,
+57,48,0,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,48,0,18,109,0,16,10,51,0,57,18,110,0,16,10,
+51,0,57,48,0,0,0,0,1,0,31,0,109,97,116,114,105,120,67,111,109,112,77,117,108,116,0,1,0,0,31,109,0,
+0,1,0,0,31,110,0,0,0,1,8,58,109,97,116,52,120,51,0,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,48,
+0,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,48,0,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,
+48,0,18,109,0,16,10,51,0,57,18,110,0,16,10,51,0,57,48,0,0,0,0,1,0,13,0,111,117,116,101,114,80,114,
+111,100,117,99,116,0,1,0,0,10,99,0,0,1,0,0,10,114,0,0,0,1,8,58,109,97,116,50,0,18,99,0,59,120,0,18,
+114,0,59,120,0,48,0,18,99,0,59,121,0,18,114,0,59,120,0,48,0,18,99,0,59,120,0,18,114,0,59,121,0,48,
+0,18,99,0,59,121,0,18,114,0,59,121,0,48,0,0,0,0,1,0,14,0,111,117,116,101,114,80,114,111,100,117,99,
+116,0,1,0,0,11,99,0,0,1,0,0,11,114,0,0,0,1,8,58,109,97,116,51,0,18,99,0,59,120,0,18,114,0,59,120,0,
+48,0,18,99,0,59,121,0,18,114,0,59,120,0,48,0,18,99,0,59,122,0,18,114,0,59,120,0,48,0,18,99,0,59,
+120,0,18,114,0,59,121,0,48,0,18,99,0,59,121,0,18,114,0,59,121,0,48,0,18,99,0,59,122,0,18,114,0,59,
+121,0,48,0,18,99,0,59,120,0,18,114,0,59,122,0,48,0,18,99,0,59,121,0,18,114,0,59,122,0,48,0,18,99,0,
+59,122,0,18,114,0,59,122,0,48,0,0,0,0,1,0,15,0,111,117,116,101,114,80,114,111,100,117,99,116,0,1,0,
+0,12,99,0,0,1,0,0,12,114,0,0,0,1,8,58,109,97,116,52,0,18,99,0,59,120,0,18,114,0,59,120,0,48,0,18,
+99,0,59,121,0,18,114,0,59,120,0,48,0,18,99,0,59,122,0,18,114,0,59,120,0,48,0,18,99,0,59,119,0,18,
+114,0,59,120,0,48,0,18,99,0,59,120,0,18,114,0,59,121,0,48,0,18,99,0,59,121,0,18,114,0,59,121,0,48,
+0,18,99,0,59,122,0,18,114,0,59,121,0,48,0,18,99,0,59,119,0,18,114,0,59,121,0,48,0,18,99,0,59,120,0,
+18,114,0,59,122,0,48,0,18,99,0,59,121,0,18,114,0,59,122,0,48,0,18,99,0,59,122,0,18,114,0,59,122,0,
+48,0,18,99,0,59,119,0,18,114,0,59,122,0,48,0,18,99,0,59,120,0,18,114,0,59,119,0,48,0,18,99,0,59,
+121,0,18,114,0,59,119,0,48,0,18,99,0,59,122,0,18,114,0,59,119,0,48,0,18,99,0,59,119,0,18,114,0,59,
+119,0,48,0,0,0,0,1,0,26,0,111,117,116,101,114,80,114,111,100,117,99,116,0,1,0,0,11,99,0,0,1,0,0,10,
+114,0,0,0,1,8,58,109,97,116,50,120,51,0,18,99,0,59,120,0,18,114,0,59,120,0,48,0,18,99,0,59,121,0,
+18,114,0,59,120,0,48,0,18,99,0,59,122,0,18,114,0,59,120,0,48,0,18,99,0,59,120,0,18,114,0,59,121,0,
+48,0,18,99,0,59,121,0,18,114,0,59,121,0,48,0,18,99,0,59,122,0,18,114,0,59,121,0,48,0,0,0,0,1,0,27,
+0,111,117,116,101,114,80,114,111,100,117,99,116,0,1,0,0,10,99,0,0,1,0,0,11,114,0,0,0,1,8,58,109,97,
+116,51,120,50,0,18,99,0,59,120,0,18,114,0,59,120,0,48,0,18,99,0,59,121,0,18,114,0,59,120,0,48,0,18,
+99,0,59,120,0,18,114,0,59,121,0,48,0,18,99,0,59,121,0,18,114,0,59,121,0,48,0,18,99,0,59,120,0,18,
+114,0,59,122,0,48,0,18,99,0,59,121,0,18,114,0,59,122,0,48,0,0,0,0,1,0,28,0,111,117,116,101,114,80,
+114,111,100,117,99,116,0,1,0,0,12,99,0,0,1,0,0,10,114,0,0,0,1,8,58,109,97,116,50,120,52,0,18,99,0,
+59,120,0,18,114,0,59,120,0,48,0,18,99,0,59,121,0,18,114,0,59,120,0,48,0,18,99,0,59,122,0,18,114,0,
+59,120,0,48,0,18,99,0,59,119,0,18,114,0,59,120,0,48,0,18,99,0,59,120,0,18,114,0,59,121,0,48,0,18,
+99,0,59,121,0,18,114,0,59,121,0,48,0,18,99,0,59,122,0,18,114,0,59,121,0,48,0,18,99,0,59,119,0,18,
+114,0,59,121,0,48,0,0,0,0,1,0,29,0,111,117,116,101,114,80,114,111,100,117,99,116,0,1,0,0,10,99,0,0,
+1,0,0,12,114,0,0,0,1,8,58,109,97,116,52,120,50,0,18,99,0,59,120,0,18,114,0,59,120,0,48,0,18,99,0,
+59,121,0,18,114,0,59,120,0,48,0,18,99,0,59,120,0,18,114,0,59,121,0,48,0,18,99,0,59,121,0,18,114,0,
+59,121,0,48,0,18,99,0,59,120,0,18,114,0,59,122,0,48,0,18,99,0,59,121,0,18,114,0,59,122,0,48,0,18,
+99,0,59,120,0,18,114,0,59,119,0,48,0,18,99,0,59,121,0,18,114,0,59,119,0,48,0,0,0,0,1,0,30,0,111,
+117,116,101,114,80,114,111,100,117,99,116,0,1,0,0,12,99,0,0,1,0,0,11,114,0,0,0,1,8,58,109,97,116,
+51,120,52,0,18,99,0,59,120,0,18,114,0,59,120,0,48,0,18,99,0,59,121,0,18,114,0,59,120,0,48,0,18,99,
+0,59,122,0,18,114,0,59,120,0,48,0,18,99,0,59,119,0,18,114,0,59,120,0,48,0,18,99,0,59,120,0,18,114,
+0,59,121,0,48,0,18,99,0,59,121,0,18,114,0,59,121,0,48,0,18,99,0,59,122,0,18,114,0,59,121,0,48,0,18,
+99,0,59,119,0,18,114,0,59,121,0,48,0,18,99,0,59,120,0,18,114,0,59,122,0,48,0,18,99,0,59,121,0,18,
+114,0,59,122,0,48,0,18,99,0,59,122,0,18,114,0,59,122,0,48,0,18,99,0,59,119,0,18,114,0,59,122,0,48,
+0,0,0,0,1,0,31,0,111,117,116,101,114,80,114,111,100,117,99,116,0,1,0,0,11,99,0,0,1,0,0,12,114,0,0,
+0,1,8,58,109,97,116,52,120,51,0,18,99,0,59,120,0,18,114,0,59,120,0,48,0,18,99,0,59,121,0,18,114,0,
+59,120,0,48,0,18,99,0,59,122,0,18,114,0,59,120,0,48,0,18,99,0,59,120,0,18,114,0,59,121,0,48,0,18,
+99,0,59,121,0,18,114,0,59,121,0,48,0,18,99,0,59,122,0,18,114,0,59,121,0,48,0,18,99,0,59,120,0,18,
+114,0,59,122,0,48,0,18,99,0,59,121,0,18,114,0,59,122,0,48,0,18,99,0,59,122,0,18,114,0,59,122,0,48,
+0,18,99,0,59,120,0,18,114,0,59,119,0,48,0,18,99,0,59,121,0,18,114,0,59,119,0,48,0,18,99,0,59,122,0,
+18,114,0,59,119,0,48,0,0,0,0,1,0,13,0,116,114,97,110,115,112,111,115,101,0,1,0,0,13,109,0,0,0,1,8,
+58,109,97,116,50,0,18,109,0,16,8,48,0,57,59,120,0,0,18,109,0,16,10,49,0,57,59,120,0,0,18,109,0,16,
+8,48,0,57,59,121,0,0,18,109,0,16,10,49,0,57,59,121,0,0,0,0,0,1,0,14,0,116,114,97,110,115,112,111,
+115,101,0,1,0,0,14,109,0,0,0,1,8,58,109,97,116,51,0,18,109,0,16,8,48,0,57,59,120,0,0,18,109,0,16,
+10,49,0,57,59,120,0,0,18,109,0,16,10,50,0,57,59,120,0,0,18,109,0,16,8,48,0,57,59,121,0,0,18,109,0,
+16,10,49,0,57,59,121,0,0,18,109,0,16,10,50,0,57,59,121,0,0,18,109,0,16,8,48,0,57,59,122,0,0,18,109,
+0,16,10,49,0,57,59,122,0,0,18,109,0,16,10,50,0,57,59,122,0,0,0,0,0,1,0,15,0,116,114,97,110,115,112,
+111,115,101,0,1,0,0,15,109,0,0,0,1,8,58,109,97,116,52,0,18,109,0,16,8,48,0,57,59,120,0,0,18,109,0,
+16,10,49,0,57,59,120,0,0,18,109,0,16,10,50,0,57,59,120,0,0,18,109,0,16,10,51,0,57,59,120,0,0,18,
+109,0,16,8,48,0,57,59,121,0,0,18,109,0,16,10,49,0,57,59,121,0,0,18,109,0,16,10,50,0,57,59,121,0,0,
+18,109,0,16,10,51,0,57,59,121,0,0,18,109,0,16,8,48,0,57,59,122,0,0,18,109,0,16,10,49,0,57,59,122,0,
+0,18,109,0,16,10,50,0,57,59,122,0,0,18,109,0,16,10,51,0,57,59,122,0,0,18,109,0,16,8,48,0,57,59,119,
+0,0,18,109,0,16,10,49,0,57,59,119,0,0,18,109,0,16,10,50,0,57,59,119,0,0,18,109,0,16,10,51,0,57,59,
+119,0,0,0,0,0,1,0,26,0,116,114,97,110,115,112,111,115,101,0,1,0,0,27,109,0,0,0,1,8,58,109,97,116,
+50,120,51,0,18,109,0,16,8,48,0,57,59,120,0,0,18,109,0,16,10,49,0,57,59,120,0,0,18,109,0,16,10,50,0,
+57,59,120,0,0,18,109,0,16,8,48,0,57,59,121,0,0,18,109,0,16,10,49,0,57,59,121,0,0,18,109,0,16,10,50,
+0,57,59,121,0,0,0,0,0,1,0,27,0,116,114,97,110,115,112,111,115,101,0,1,0,0,26,109,0,0,0,1,8,58,109,
+97,116,51,120,50,0,18,109,0,16,8,48,0,57,59,120,0,0,18,109,0,16,10,49,0,57,59,120,0,0,18,109,0,16,
+8,48,0,57,59,121,0,0,18,109,0,16,10,49,0,57,59,121,0,0,18,109,0,16,8,48,0,57,59,122,0,0,18,109,0,
+16,10,49,0,57,59,122,0,0,0,0,0,1,0,28,0,116,114,97,110,115,112,111,115,101,0,1,0,0,29,109,0,0,0,1,
+8,58,109,97,116,50,120,52,0,18,109,0,16,8,48,0,57,59,120,0,0,18,109,0,16,10,49,0,57,59,120,0,0,18,
+109,0,16,10,50,0,57,59,120,0,0,18,109,0,16,10,51,0,57,59,120,0,0,18,109,0,16,8,48,0,57,59,121,0,0,
+18,109,0,16,10,49,0,57,59,121,0,0,18,109,0,16,10,50,0,57,59,121,0,0,18,109,0,16,10,51,0,57,59,121,
+0,0,0,0,0,1,0,29,0,116,114,97,110,115,112,111,115,101,0,1,0,0,28,109,0,0,0,1,8,58,109,97,116,52,
+120,50,0,18,109,0,16,8,48,0,57,59,120,0,0,18,109,0,16,10,49,0,57,59,120,0,0,18,109,0,16,8,48,0,57,
+59,121,0,0,18,109,0,16,10,49,0,57,59,121,0,0,18,109,0,16,8,48,0,57,59,122,0,0,18,109,0,16,10,49,0,
+57,59,122,0,0,18,109,0,16,8,48,0,57,59,119,0,0,18,109,0,16,10,49,0,57,59,119,0,0,0,0,0,1,0,30,0,
+116,114,97,110,115,112,111,115,101,0,1,0,0,31,109,0,0,0,1,8,58,109,97,116,51,120,52,0,18,109,0,16,
+8,48,0,57,59,120,0,0,18,109,0,16,10,49,0,57,59,120,0,0,18,109,0,16,10,50,0,57,59,120,0,0,18,109,0,
+16,10,51,0,57,59,120,0,0,18,109,0,16,8,48,0,57,59,121,0,0,18,109,0,16,10,49,0,57,59,121,0,0,18,109,
+0,16,10,50,0,57,59,121,0,0,18,109,0,16,10,51,0,57,59,121,0,0,18,109,0,16,8,48,0,57,59,122,0,0,18,
+109,0,16,10,49,0,57,59,122,0,0,18,109,0,16,10,50,0,57,59,122,0,0,18,109,0,16,10,51,0,57,59,122,0,0,
+0,0,0,1,0,31,0,116,114,97,110,115,112,111,115,101,0,1,0,0,30,109,0,0,0,1,8,58,109,97,116,52,120,51,
+0,18,109,0,16,8,48,0,57,59,120,0,0,18,109,0,16,10,49,0,57,59,120,0,0,18,109,0,16,10,50,0,57,59,120,
+0,0,18,109,0,16,8,48,0,57,59,121,0,0,18,109,0,16,10,49,0,57,59,121,0,0,18,109,0,16,10,50,0,57,59,
+121,0,0,18,109,0,16,8,48,0,57,59,122,0,0,18,109,0,16,10,49,0,57,59,122,0,0,18,109,0,16,10,50,0,57,
+59,122,0,0,18,109,0,16,8,48,0,57,59,119,0,0,18,109,0,16,10,49,0,57,59,119,0,0,18,109,0,16,10,50,0,
+57,59,119,0,0,0,0,0,0
diff --git a/src/mesa/shader/slang/library/slang_builtin_120_fragment_gc.h b/src/mesa/shader/slang/library/slang_builtin_120_fragment_gc.h
new file mode 100644
index 0000000000..2400b273d8
--- /dev/null
+++ b/src/mesa/shader/slang/library/slang_builtin_120_fragment_gc.h
@@ -0,0 +1,5 @@
+
+/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED FROM THE FOLLOWING FILE: */
+/* slang_builtin_120_fragment.gc */
+
+3,2,2,3,10,1,103,108,95,80,111,105,110,116,67,111,111,114,100,0,0,0,0
-- 
cgit v1.2.3


From 26479fa3b3a7c911617192c56e54fbe298fdd7f3 Mon Sep 17 00:00:00 2001
From: Brian <brian.paul@tungstengraphics.com>
Date: Wed, 24 Oct 2007 16:24:06 -0600
Subject: don't build x86, x86-64 dirs if not needed

---
 src/mesa/Makefile | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

(limited to 'src')

diff --git a/src/mesa/Makefile b/src/mesa/Makefile
index a47cd4c023..3722593f21 100644
--- a/src/mesa/Makefile
+++ b/src/mesa/Makefile
@@ -153,8 +153,13 @@ depend: $(ALL_SOURCES)
 
 
 subdirs:
-	@ (cd x86 ; $(MAKE))
-	@ (cd x86-64 ; $(MAKE))
+	@ if [ `echo $(ASM_FLAGS) | grep USE_X86_ASM` ] ; then \
+		(cd x86 ; $(MAKE)) ; \
+	fi
+	@ if [ `echo $(ASM_FLAGS) | grep USE_X86_64_ASM` ] ; then \
+		(cd x86 ; $(MAKE)) ; \
+		(cd x86-64 ; $(MAKE)) ; \
+	fi
 
 
 install: default gl.pc
-- 
cgit v1.2.3


From 6dcf65ff0d6fcea9c7e3ae51d51eac6f9a030e47 Mon Sep 17 00:00:00 2001
From: Brian <brian.paul@tungstengraphics.com>
Date: Thu, 25 Oct 2007 11:10:10 -0600
Subject: simplify/fix the ASM_FLAGS tests (bug 12931)

---
 src/mesa/Makefile | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'src')

diff --git a/src/mesa/Makefile b/src/mesa/Makefile
index 3722593f21..8e35efb7dc 100644
--- a/src/mesa/Makefile
+++ b/src/mesa/Makefile
@@ -153,10 +153,10 @@ depend: $(ALL_SOURCES)
 
 
 subdirs:
-	@ if [ `echo $(ASM_FLAGS) | grep USE_X86_ASM` ] ; then \
+	@ if echo $(ASM_FLAGS) | grep USE_X86_ASM ; then \
 		(cd x86 ; $(MAKE)) ; \
 	fi
-	@ if [ `echo $(ASM_FLAGS) | grep USE_X86_64_ASM` ] ; then \
+	@ if echo $(ASM_FLAGS) | grep USE_X86_64_ASM ; then \
 		(cd x86 ; $(MAKE)) ; \
 		(cd x86-64 ; $(MAKE)) ; \
 	fi
-- 
cgit v1.2.3


From ff042bfdeeeb0a3d658d5ab1dbdcac7b67aac0f8 Mon Sep 17 00:00:00 2001
From: Brian <brian.paul@tungstengraphics.com>
Date: Thu, 25 Oct 2007 14:46:35 -0600
Subject: use grep -q

---
 src/mesa/Makefile | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'src')

diff --git a/src/mesa/Makefile b/src/mesa/Makefile
index 8e35efb7dc..77bb7be480 100644
--- a/src/mesa/Makefile
+++ b/src/mesa/Makefile
@@ -153,10 +153,10 @@ depend: $(ALL_SOURCES)
 
 
 subdirs:
-	@ if echo $(ASM_FLAGS) | grep USE_X86_ASM ; then \
+	@ if echo "$(ASM_FLAGS)" | grep -q USE_X86_ASM ; then \
 		(cd x86 ; $(MAKE)) ; \
 	fi
-	@ if echo $(ASM_FLAGS) | grep USE_X86_64_ASM ; then \
+	@ if echo "$(ASM_FLAGS)" | grep -q USE_X86_64_ASM ; then \
 		(cd x86 ; $(MAKE)) ; \
 		(cd x86-64 ; $(MAKE)) ; \
 	fi
-- 
cgit v1.2.3


From b59dbd822f353cbf0db404f14c2721c79cde79fc Mon Sep 17 00:00:00 2001
From: Alan Hourihane <alanh@tungstengraphics.com>
Date: Sun, 28 Oct 2007 20:07:37 +0000
Subject: Only set R_MODE with NV_point_sprite

---
 src/mesa/main/attrib.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'src')

diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c
index 3199c9b426..07ec285eeb 100644
--- a/src/mesa/main/attrib.c
+++ b/src/mesa/main/attrib.c
@@ -1102,7 +1102,8 @@ _mesa_PopAttrib(void)
                                    (GLint) point->CoordReplace[u]);
                   }
                   _mesa_set_enable(ctx, GL_POINT_SPRITE_NV,point->PointSprite);
-                  _mesa_PointParameteriNV(GL_POINT_SPRITE_R_MODE_NV,
+                  if (ctx->Extensions.NV_point_sprite)
+                     _mesa_PointParameteriNV(GL_POINT_SPRITE_R_MODE_NV,
                                           ctx->Point.SpriteRMode);
                   _mesa_PointParameterfEXT(GL_POINT_SPRITE_COORD_ORIGIN,
                                            (GLfloat)ctx->Point.SpriteOrigin);
-- 
cgit v1.2.3


From 40133487dbdd14456a8a4f6a5716f57a36eb1ea7 Mon Sep 17 00:00:00 2001
From: Brian <brian.paul@tungstengraphics.com>
Date: Mon, 29 Oct 2007 10:01:15 -0600
Subject: disable ctx->Driver.NewProgram() call in _mesa_new_program()

This was causing infinite recursive calls w/ software drivers.
All vertex/fragment shaders should be allocated by calling
ctx->Driver.NewProgram(), not by calling _mesa_new_program().
---
 src/mesa/shader/program.c | 5 +++++
 1 file changed, 5 insertions(+)

(limited to 'src')

diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c
index 11330e2432..43e6fb0be0 100644
--- a/src/mesa/shader/program.c
+++ b/src/mesa/shader/program.c
@@ -285,8 +285,13 @@ _mesa_init_vertex_program( GLcontext *ctx, struct gl_vertex_program *prog,
 struct gl_program *
 _mesa_new_program(GLcontext *ctx, GLenum target, GLuint id)
 {
+#if 0
+   /* This was added by Nan hai Zou but disabled by BrianP since it
+    * causes infinite recursive calls.
+    */
    if (ctx->Driver.NewProgram)
         return ctx->Driver.NewProgram(ctx, target, id);
+#endif
    switch (target) {
    case GL_VERTEX_PROGRAM_ARB: /* == GL_VERTEX_PROGRAM_NV */
       return _mesa_init_vertex_program(ctx, CALLOC_STRUCT(gl_vertex_program),
-- 
cgit v1.2.3


From 1421bffb180e2e1a8f0c16f61768805666492ed2 Mon Sep 17 00:00:00 2001
From: Chris Rankin <rankincj@yahoo.com>
Date: Mon, 29 Oct 2007 14:37:32 -0400
Subject: Remember to call XSync() before resetting X error handler.

---
 src/glx/x11/glxcmds.c | 1 +
 1 file changed, 1 insertion(+)

(limited to 'src')

diff --git a/src/glx/x11/glxcmds.c b/src/glx/x11/glxcmds.c
index 707e398d1d..1497c6b30e 100644
--- a/src/glx/x11/glxcmds.c
+++ b/src/glx/x11/glxcmds.c
@@ -106,6 +106,7 @@ static void GarbageCollectDRIDrawables(Display *dpy, __GLXscreenConfigs *sc)
 	} while (__glxHashNext(sc->drawHash, &draw, (void *)&pdraw) == 1);
     }
 
+    XSync(dpy, GL_FALSE);
     XSetErrorHandler(oldXErrorHandler);
 }
 
-- 
cgit v1.2.3


From 38fdb47d26055e19d50cd407266b56ed4317ae0a Mon Sep 17 00:00:00 2001
From: Jesse Barnes <jesse.barnes@intel.com>
Date: Mon, 29 Oct 2007 11:56:31 -0700
Subject: Refactor and fix core vblank support

Consolidate support for synchronizing to and retrieving vblank counters.  Also
fix the core vblank code to return monotonic MSC counters, which are required
by some GLX extensions.  Adding support for multiple pipes to a low level
driver is fairly easy, the Intel 965 driver provides simple example code (see
intel_buffers.c:intelWindowMoved()).

The new code bumps the media stream counter extension version to 2 and adds a
new getDrawableMSC callback.  This callback takes a drawablePrivate pointer,
which is used to calculate the MSC value seen by clients based on the actual
vblank counter(s) returned from the kernel.  The new drawable private fields
are as follows:
  - vblSeq - used for tracking vblank counts for buffer swapping
  - vblFlags - flags (e.g. current pipe), updated by low level driver
  - msc_base - MSC counter from the last time the current pipe changed
  - vblank_base - kernel DRM vblank counter from the last time the pipe changed

Using the above variables, the core vblank code (in vblank.c) can calculate a
monotonic MSC value.  The low level DRI drivers are responsible for updating
the current pipe (by setting VBLANK_FLAG_SECONDARY for example in vblFlags)
along with msc_base and vblank_base whenever the pipe associated with a given
drawable changes (again, see intelWindowMoved for an example of this).

Drivers should fill in the GetDrawableMSC DriverAPIRec field to point to
driDrawableGetMSC32 and add code for pipe switching as outlined above to fully
support the new scheme.
---
 include/GL/internal/dri_interface.h            | 14 +++-
 src/glx/x11/glxcmds.c                          | 43 +++++++-----
 src/mesa/drivers/dri/common/dri_util.c         | 14 +++-
 src/mesa/drivers/dri/common/dri_util.h         | 34 ++++++++++
 src/mesa/drivers/dri/common/vblank.c           | 94 +++++++++++++++++++++-----
 src/mesa/drivers/dri/common/vblank.h           |  6 +-
 src/mesa/drivers/dri/ffb/ffb_xmesa.c           |  1 +
 src/mesa/drivers/dri/i810/i810screen.c         |  1 +
 src/mesa/drivers/dri/i915/intel_buffers.c      | 55 +++++++++------
 src/mesa/drivers/dri/i915/intel_context.c      | 16 ++---
 src/mesa/drivers/dri/i915/intel_fbo.h          |  2 -
 src/mesa/drivers/dri/i915/intel_screen.c       |  1 +
 src/mesa/drivers/dri/i965/intel_blit.c         |  3 +-
 src/mesa/drivers/dri/i965/intel_buffers.c      | 46 +++++++++++++
 src/mesa/drivers/dri/i965/intel_context.c      | 17 +++--
 src/mesa/drivers/dri/i965/intel_context.h      |  5 --
 src/mesa/drivers/dri/i965/intel_screen.c       |  1 +
 src/mesa/drivers/dri/mach64/mach64_context.c   |  6 +-
 src/mesa/drivers/dri/mach64/mach64_context.h   |  2 -
 src/mesa/drivers/dri/mach64/mach64_ioctl.c     |  4 +-
 src/mesa/drivers/dri/mach64/mach64_ioctl.h     |  2 +-
 src/mesa/drivers/dri/mach64/mach64_screen.c    |  1 +
 src/mesa/drivers/dri/mga/mga_xmesa.c           |  8 ++-
 src/mesa/drivers/dri/mga/mgacontext.h          |  5 --
 src/mesa/drivers/dri/mga/mgaioctl.c            |  3 +-
 src/mesa/drivers/dri/nouveau/nouveau_context.c |  2 +-
 src/mesa/drivers/dri/nouveau/nouveau_context.h |  4 --
 src/mesa/drivers/dri/nouveau/nouveau_screen.c  |  1 +
 src/mesa/drivers/dri/r128/r128_context.c       |  6 +-
 src/mesa/drivers/dri/r128/r128_context.h       |  5 --
 src/mesa/drivers/dri/r128/r128_ioctl.c         |  8 +--
 src/mesa/drivers/dri/r128/r128_ioctl.h         |  4 +-
 src/mesa/drivers/dri/r128/r128_screen.c        |  1 +
 src/mesa/drivers/dri/r200/r200_context.c       |  6 +-
 src/mesa/drivers/dri/r200/r200_context.h       |  5 +-
 src/mesa/drivers/dri/r200/r200_ioctl.c         |  8 +--
 src/mesa/drivers/dri/r200/r200_ioctl.h         |  4 +-
 src/mesa/drivers/dri/r300/radeon_context.c     |  7 +-
 src/mesa/drivers/dri/r300/radeon_context.h     |  5 +-
 src/mesa/drivers/dri/r300/radeon_ioctl.c       |  8 +--
 src/mesa/drivers/dri/r300/radeon_ioctl.h       |  4 +-
 src/mesa/drivers/dri/radeon/radeon_context.c   |  3 +-
 src/mesa/drivers/dri/radeon/radeon_screen.c    |  2 +
 src/mesa/drivers/dri/sis/sis_screen.c          |  1 +
 src/mesa/drivers/dri/tdfx/tdfx_screen.c        |  1 +
 src/mesa/drivers/dri/unichrome/via_context.c   |  6 +-
 src/mesa/drivers/dri/unichrome/via_context.h   |  3 -
 src/mesa/drivers/dri/unichrome/via_ioctl.c     | 14 ++--
 src/mesa/drivers/dri/unichrome/via_ioctl.h     |  4 +-
 src/mesa/drivers/dri/unichrome/via_screen.c    |  1 +
 50 files changed, 332 insertions(+), 165 deletions(-)

(limited to 'src')

diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index e7fbf8e8b8..1b637afaf3 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -170,7 +170,7 @@ struct __DRIframeTrackingExtensionRec {
  * Used by drivers that implement the GLX_SGI_video_sync extension.
  */
 #define __DRI_MEDIA_STREAM_COUNTER "DRI_MediaStreamCounter"
-#define __DRI_MEDIA_STREAM_COUNTER_VERSION 1
+#define __DRI_MEDIA_STREAM_COUNTER_VERSION 2
 struct __DRImediaStreamCounterExtensionRec {
     __DRIextension base;
 
@@ -189,6 +189,18 @@ struct __DRImediaStreamCounterExtensionRec {
     int (*waitForMSC)(__DRIdrawable *drawable,
 		      int64_t target_msc, int64_t divisor, int64_t remainder,
 		      int64_t * msc, int64_t * sbc);
+
+    /**
+     * Like the screen version of getMSC, but also takes a drawable so that
+     * the appropriate pipe's counter can be retrieved.
+     *
+     * Get the number of vertical refreshes since some point in time before
+     * this function was first called (i.e., system start up).
+     *
+     * \since Internal API version 2
+     */
+    int (*getDrawableMSC)(__DRIscreen *screen, void *drawablePrivate,
+			  int64_t *msc);
 };
 
 
diff --git a/src/glx/x11/glxcmds.c b/src/glx/x11/glxcmds.c
index 707e398d1d..7e8a0c146d 100644
--- a/src/glx/x11/glxcmds.c
+++ b/src/glx/x11/glxcmds.c
@@ -1941,13 +1941,24 @@ static int __glXGetVideoSyncSGI(unsigned int *count)
    if ( (gc != NULL) && gc->isDirect ) {
       __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy,
 							    gc->screen );
-      if (psc->msc != NULL && psc->driScreen.private != NULL) {
-	 int       ret;
-	 int64_t   temp;
-
-	 ret = psc->msc->getMSC(&psc->driScreen, &temp);
-	 *count = (unsigned) temp;
-	 return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
+      if ( psc->msc && psc->driScreen.private ) {
+          __DRIdrawable * const pdraw = 
+              GetDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
+	  int64_t temp; 
+	  int ret;
+ 
+ 	  /*
+ 	   * Try to use getDrawableMSC first so we get the right
+ 	   * counter...
+ 	   */
+	  if (psc->msc->base.version >= 2 && psc->msc->getDrawableMSC)
+	      ret = (*psc->msc->getDrawableMSC)( &psc->driScreen,
+						 pdraw->private,
+						 & temp);
+	  else
+	      ret = (*psc->msc->getMSC)( &psc->driScreen, & temp);
+	  *count = (unsigned) temp;
+	  return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
       }
    }
 #else
@@ -1970,16 +1981,14 @@ static int __glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count
       if (psc->msc != NULL && psc->driScreen.private ) {
 	 __DRIdrawable * const pdraw = 
 	     GetDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
-	 if (pdraw != NULL) {
-	    int       ret;
-	    int64_t   msc;
-	    int64_t   sbc;
-
-	    ret = (*psc->msc->waitForMSC)(pdraw, 0,
-					  divisor, remainder, &msc, &sbc);
-	    *count = (unsigned) msc;
-	    return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
-	 }
+	 int       ret;
+	 int64_t   msc;
+	 int64_t   sbc;
+
+	 ret = (*psc->msc->waitForMSC)(pdraw, 0, divisor, remainder, &msc,
+				       &sbc);
+	 *count = (unsigned) msc;
+	 return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
       }
    }
 #else
diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c
index d59ea0ddad..2e2e64c4d1 100644
--- a/src/mesa/drivers/dri/common/dri_util.c
+++ b/src/mesa/drivers/dri/common/dri_util.c
@@ -356,10 +356,18 @@ static void driSwapBuffers(__DRIdrawable *drawable)
 				   &rect, 1, GL_TRUE);
 }
 
+static int driDrawableGetMSC( __DRIscreen *screen, void *drawablePrivate,
+			      int64_t *msc )
+{
+    __DRIscreenPrivate *sPriv = screen->private;
+
+    return sPriv->DriverAPI.GetDrawableMSC( sPriv, drawablePrivate, msc );
+}
+
 /**
  * Called directly from a number of higher-level GLX functions.
  */
-static int driGetMSC( __DRIscreen *screen, int64_t *msc )
+static int driGetMSC( __DRIscreen *screen, void *drawablePrivate, int64_t *msc )
 {
     __DRIscreenPrivate *sPriv = screen->private;
 
@@ -396,6 +404,7 @@ const __DRImediaStreamCounterExtension driMediaStreamCounterExtension = {
     { __DRI_MEDIA_STREAM_COUNTER, __DRI_MEDIA_STREAM_COUNTER_VERSION },
     driGetMSC,
     driWaitForMSC,
+    driDrawableGetMSC,
 };
 
 static void driCopySubBuffer(__DRIdrawable *drawable,
@@ -471,6 +480,8 @@ static void *driCreateNewDrawable(__DRIscreen *screen,
     pdp->numBackClipRects = 0;
     pdp->pClipRects = NULL;
     pdp->pBackClipRects = NULL;
+    pdp->vblSeq = 0;
+    pdp->vblFlags = 0;
 
     psp = (__DRIscreenPrivate *)screen->private;
     pdp->driScreenPriv = psp;
@@ -485,6 +496,7 @@ static void *driCreateNewDrawable(__DRIscreen *screen,
     pdraw->private = pdp;
     pdraw->destroyDrawable = driDestroyDrawable;
     pdraw->swapBuffers = driSwapBuffers;  /* called by glXSwapBuffers() */
+    pdp->msc_base = 0;
 
     /* This special default value is replaced with the configured
      * default value when the drawable is first bound to a direct
diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h
index 91992a9a24..def0775839 100644
--- a/src/mesa/drivers/dri/common/dri_util.h
+++ b/src/mesa/drivers/dri/common/dri_util.h
@@ -206,6 +206,14 @@ struct __DriverAPIRec {
      */
     void (*setTexOffset)(__DRIcontext *pDRICtx, GLint texname,
 			 unsigned long long offset, GLint depth, GLuint pitch);
+
+    /**
+     * New version of GetMSC so we can pass drawable data to the low level
+     * DRM driver (e.g. pipe info).
+     */
+    int (*GetDrawableMSC) ( __DRIscreenPrivate * priv,
+			    __DRIdrawablePrivate *drawablePrivate,
+			    int64_t *count);
 };
 
 
@@ -317,6 +325,32 @@ struct __DRIdrawablePrivateRec {
     drm_clip_rect_t *pBackClipRects;
     /*@}*/
 
+    /**
+     * \name Vertical blank tracking information
+     * Used for waiting on vertical blank events.
+     */
+    /*@{*/
+    unsigned int vblSeq;
+    unsigned int vblFlags;
+    /*@}*/
+
+    /**
+     * \name Monotonic MSC tracking
+     *
+     * Low level driver is responsible for updating msc_base and
+     * vblSeq values so that higher level code can calculate
+     * a new msc value or msc target for a WaitMSC call.  The new value
+     * will be:
+     *   msc = msc_base + get_vblank_count() - vblank_base;
+     *
+     * And for waiting on a value, core code will use:
+     *   actual_target = target_msc - msc_base + vblank_base;
+     */
+    /*@{*/
+    int64_t vblank_base;
+    int64_t msc_base;
+    /*@}*/
+
     /**
      * Pointer to context to which this drawable is currently bound.
      */
diff --git a/src/mesa/drivers/dri/common/vblank.c b/src/mesa/drivers/dri/common/vblank.c
index 3b5acfecb1..0596440463 100644
--- a/src/mesa/drivers/dri/common/vblank.c
+++ b/src/mesa/drivers/dri/common/vblank.c
@@ -35,6 +35,16 @@
 #include "vblank.h"
 #include "xmlpool.h"
 
+static unsigned int msc_to_vblank(__DRIdrawablePrivate * dPriv, int64_t msc)
+{
+   return (unsigned int)(msc - dPriv->msc_base + dPriv->vblank_base);
+}
+
+static int64_t vblank_to_msc(__DRIdrawablePrivate * dPriv, unsigned int vblank)
+{
+   return (int64_t)(vblank - dPriv->vblank_base + dPriv->msc_base);
+}
+
 
 /****************************************************************************/
 /**
@@ -42,7 +52,7 @@
  *
  * Stores the 64-bit count of vertical refreshes since some (arbitrary)
  * point in time in \c count.  Unless the value wraps around, which it
- * may, it will never decrease.
+ * may, it will never decrease for a given drawable.
  *
  * \warning This function is called from \c glXGetVideoSyncSGI, which expects
  * a \c count of type \c unsigned (32-bit), and \c glXGetSyncValuesOML, which 
@@ -50,11 +60,14 @@
  * currently always returns a \c sequence of type \c unsigned.
  *
  * \param priv   Pointer to the DRI screen private struct.
+ * \param dPriv  Pointer to the DRI drawable private struct
  * \param count  Storage to hold MSC counter.
  * \return       Zero is returned on success.  A negative errno value
  *               is returned on failure.
  */
-int driGetMSC32( __DRIscreenPrivate * priv, int64_t * count )
+int driDrawableGetMSC32( __DRIscreenPrivate * priv,
+			 __DRIdrawablePrivate * dPriv,
+			 int64_t * count)
 {
    drmVBlank vbl;
    int ret;
@@ -63,13 +76,46 @@ int driGetMSC32( __DRIscreenPrivate * priv, int64_t * count )
 
    vbl.request.type = DRM_VBLANK_RELATIVE;
    vbl.request.sequence = 0;
+   if ( dPriv && dPriv->vblFlags & VBLANK_FLAG_SECONDARY )
+      vbl.request.type |= DRM_VBLANK_SECONDARY;
 
    ret = drmWaitVBlank( priv->fd, &vbl );
-   *count = (int64_t)vbl.reply.sequence;
+
+   if (dPriv) {
+      *count = vblank_to_msc(dPriv, vbl.reply.sequence);
+   } else {
+      /* Old driver (no knowledge of drawable MSC callback) */
+      *count = vbl.reply.sequence;
+   }
 
    return ret;
 }
 
+/**
+ * Get the current MSC refresh counter.
+ *
+ * Stores the 64-bit count of vertical refreshes since some (arbitrary)
+ * point in time in \c count.  Unless the value wraps around, which it
+ * may, it will never decrease.
+ *
+ * \warning This function is called from \c glXGetVideoSyncSGI, which expects
+ * a \c count of type \c unsigned (32-bit), and \c glXGetSyncValuesOML, which 
+ * expects a \c count of type \c int64_t (signed 64-bit).  The kernel ioctl 
+ * currently always returns a \c sequence of type \c unsigned.
+ *
+ * Since this function doesn't take a drawable, it may end up getting the MSC
+ * value from a pipe not associated with the caller's context, resuling in
+ * undesired behavior.
+ *
+ * \param priv   Pointer to the DRI screen private struct.
+ * \param count  Storage to hold MSC counter.
+ * \return       Zero is returned on success.  A negative errno value
+ *               is returned on failure.
+ */
+int driGetMSC32( __DRIscreenPrivate * priv, int64_t * count )
+{
+   return driDrawableGetMSC32(priv, NULL, count);
+}
 
 /****************************************************************************/
 /**
@@ -123,7 +169,9 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv,
           */
          vbl.request.type = dont_wait ? DRM_VBLANK_RELATIVE :
                                         DRM_VBLANK_ABSOLUTE;
-         vbl.request.sequence = next;
+         vbl.request.sequence = next ? msc_to_vblank(priv, next) : 0;
+	 if ( priv->vblFlags & VBLANK_FLAG_SECONDARY )
+	    vbl.request.type |= DRM_VBLANK_SECONDARY;
 
 	 if ( drmWaitVBlank( priv->driScreenPriv->fd, &vbl ) != 0 ) {
 	    /* FIXME: This doesn't seem like the right thing to return here.
@@ -131,8 +179,10 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv,
 	    return GLX_BAD_CONTEXT;
 	 }
 
+	 *msc = vblank_to_msc(priv, vbl.reply.sequence);
+
          dont_wait = 0;
-         if (target_msc != 0 && vbl.reply.sequence == target)
+         if (target_msc != 0 && *msc == target)
             break;
 
          /* Assuming the wait-done test fails, the next refresh to wait for
@@ -142,9 +192,9 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv,
           * If this refresh has already happened, we add divisor to obtain 
           * the next refresh after the current one that will satisfy it.
           */
-         r = (vbl.reply.sequence % (unsigned int)divisor);
-         next = (vbl.reply.sequence - r + (unsigned int)remainder);
-         if (next <= vbl.reply.sequence) next += (unsigned int)divisor;
+         r = (*msc % (unsigned int)divisor);
+         next = (*msc - r + (unsigned int)remainder);
+         if (next <= *msc) next += (unsigned int)divisor;
 
       } while ( r != (unsigned int)remainder );
    }
@@ -154,7 +204,10 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv,
        */
 
       vbl.request.type = DRM_VBLANK_ABSOLUTE;
-      vbl.request.sequence = target_msc;
+      vbl.request.sequence = target_msc ? msc_to_vblank(priv, target_msc) : 0;
+
+      if ( priv->vblFlags & VBLANK_FLAG_SECONDARY )
+	 vbl.request.type |= DRM_VBLANK_SECONDARY;
 
       if ( drmWaitVBlank( priv->driScreenPriv->fd, &vbl ) != 0 ) {
 	 /* FIXME: This doesn't seem like the right thing to return here.
@@ -163,8 +216,8 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv,
       }
    }
 
-   *msc  = (target_msc & 0xffffffff00000000LL);
-   *msc |= vbl.reply.sequence;
+   *msc = vblank_to_msc(priv, vbl.reply.sequence);
+
    if ( *msc < target_msc ) {
       *msc += 0x0000000100000000LL;
    }
@@ -252,16 +305,21 @@ static int do_wait( drmVBlank * vbl, GLuint * vbl_seq, int fd )
  * direct rendering context.
  */
 
-void driDrawableInitVBlank( __DRIdrawablePrivate *priv, GLuint flags,
-			    GLuint *vbl_seq )
+void driDrawableInitVBlank( __DRIdrawablePrivate *priv )
 {
    if ( priv->swap_interval == (unsigned)-1 ) {
       /* Get current vertical blank sequence */
-      drmVBlank vbl = { .request={ .type = DRM_VBLANK_RELATIVE, .sequence = 0 } };
-      do_wait( &vbl, vbl_seq, priv->driScreenPriv->fd );
-
-      priv->swap_interval = (flags & (VBLANK_FLAG_THROTTLE |
-				      VBLANK_FLAG_SYNC)) != 0 ? 1 : 0;
+      drmVBlank vbl;
+ 
+      vbl.request.type = DRM_VBLANK_RELATIVE;
+      if ( priv->vblFlags & VBLANK_FLAG_SECONDARY )
+ 	 vbl.request.type |= DRM_VBLANK_SECONDARY;
+      vbl.request.sequence = 0;
+      do_wait( &vbl, &priv->vblSeq, priv->driScreenPriv->fd );
+      priv->vblank_base = priv->vblSeq;
+
+      priv->swap_interval =
+ 	 (priv->vblFlags & (VBLANK_FLAG_THROTTLE | VBLANK_FLAG_SYNC)) ? 1 : 0;
    }
 }
 
diff --git a/src/mesa/drivers/dri/common/vblank.h b/src/mesa/drivers/dri/common/vblank.h
index ec83adc78d..e8550b2812 100644
--- a/src/mesa/drivers/dri/common/vblank.h
+++ b/src/mesa/drivers/dri/common/vblank.h
@@ -46,11 +46,13 @@
 					  */
 
 extern int driGetMSC32( __DRIscreenPrivate * priv, int64_t * count );
+extern int driDrawableGetMSC32( __DRIscreenPrivate * priv,
+				__DRIdrawablePrivate * drawablePrivate,
+				int64_t * count);
 extern int driWaitForMSC32( __DRIdrawablePrivate *priv,
     int64_t target_msc, int64_t divisor, int64_t remainder, int64_t * msc );
 extern GLuint driGetDefaultVBlankFlags( const driOptionCache *optionCache );
-extern void driDrawableInitVBlank ( __DRIdrawablePrivate *priv, GLuint flags,
-				    GLuint *vbl_seq );
+extern void driDrawableInitVBlank ( __DRIdrawablePrivate *priv );
 extern unsigned driGetVBlankInterval( const  __DRIdrawablePrivate *priv,
 				      GLuint flags );
 extern void driGetCurrentVBlank( const  __DRIdrawablePrivate *priv,
diff --git a/src/mesa/drivers/dri/ffb/ffb_xmesa.c b/src/mesa/drivers/dri/ffb/ffb_xmesa.c
index 3a5551eeb3..173c5fa952 100644
--- a/src/mesa/drivers/dri/ffb/ffb_xmesa.c
+++ b/src/mesa/drivers/dri/ffb/ffb_xmesa.c
@@ -615,6 +615,7 @@ static const struct __DriverAPIRec ffbAPI = {
    .UnbindContext   = ffbUnbindContext,
    .GetSwapInfo     = NULL,
    .GetMSC          = NULL,
+   .GetDrawableMSC  = NULL,
    .WaitForMSC      = NULL,
    .WaitForSBC      = NULL,
    .SwapBuffersMSC  = NULL
diff --git a/src/mesa/drivers/dri/i810/i810screen.c b/src/mesa/drivers/dri/i810/i810screen.c
index 3c7ec96ff3..1a0d3c33d7 100644
--- a/src/mesa/drivers/dri/i810/i810screen.c
+++ b/src/mesa/drivers/dri/i810/i810screen.c
@@ -413,6 +413,7 @@ static const struct __DriverAPIRec i810API = {
    .UnbindContext   = i810UnbindContext,
    .GetSwapInfo     = NULL,
    .GetMSC          = NULL,
+   .GetDrawableMSC  = NULL,
    .WaitForMSC      = NULL,
    .WaitForSBC      = NULL,
    .SwapBuffersMSC  = NULL
diff --git a/src/mesa/drivers/dri/i915/intel_buffers.c b/src/mesa/drivers/dri/i915/intel_buffers.c
index 46a67b141e..faa13adbcb 100644
--- a/src/mesa/drivers/dri/i915/intel_buffers.c
+++ b/src/mesa/drivers/dri/i915/intel_buffers.c
@@ -243,7 +243,7 @@ intelWindowMoved(struct intel_context *intel)
 				     .y2 = sarea->planeB_y + sarea->planeB_h };
       GLint areaA = driIntersectArea( drw_rect, planeA_rect );
       GLint areaB = driIntersectArea( drw_rect, planeB_rect );
-      GLuint flags = intel_fb->vblank_flags;
+      GLuint flags = dPriv->vblFlags;
       GLboolean pf_active;
       GLint pf_planes;
 
@@ -311,19 +311,24 @@ intelWindowMoved(struct intel_context *intel)
       /* Update vblank info
        */
       if (areaB > areaA || (areaA == areaB && areaB > 0)) {
-	 flags = intel_fb->vblank_flags | VBLANK_FLAG_SECONDARY;
+	 flags = dPriv->vblFlags | VBLANK_FLAG_SECONDARY;
       } else {
-	 flags = intel_fb->vblank_flags & ~VBLANK_FLAG_SECONDARY;
+	 flags = dPriv->vblFlags & ~VBLANK_FLAG_SECONDARY;
       }
 
-      if (flags != intel_fb->vblank_flags && intel_fb->vblank_flags &&
-	  !(intel_fb->vblank_flags & VBLANK_FLAG_NO_IRQ)) {
+      /* Check to see if we changed pipes */
+      if (flags != dPriv->vblFlags && dPriv->vblFlags &&
+	  !(dPriv->vblFlags & VBLANK_FLAG_NO_IRQ)) {
+	 int64_t count;
 	 drmVBlank vbl;
 	 int i;
 
+	 /*
+	  * Deal with page flipping
+	  */
 	 vbl.request.type = DRM_VBLANK_ABSOLUTE;
 
-	 if ( intel_fb->vblank_flags & VBLANK_FLAG_SECONDARY ) {
+	 if ( dPriv->vblFlags & VBLANK_FLAG_SECONDARY ) {
 	    vbl.request.type |= DRM_VBLANK_SECONDARY;
 	 }
 
@@ -337,9 +342,19 @@ intelWindowMoved(struct intel_context *intel)
 	    drmWaitVBlank(intel->driFd, &vbl);
 	 }
 
-	 intel_fb->vblank_flags = flags;
-	 driGetCurrentVBlank(dPriv, intel_fb->vblank_flags, &intel_fb->vbl_seq);
-	 intel_fb->vbl_waited = intel_fb->vbl_seq;
+	 /*
+	  * Update msc_base from old pipe
+	  */
+	 driDrawableGetMSC32(dPriv->driScreenPriv, dPriv, &count);
+	 dPriv->msc_base = count;
+	 /*
+	  * Then get new vblank_base and vblSeq values
+	  */
+	 dPriv->vblFlags = flags;
+	 driGetCurrentVBlank(dPriv, dPriv->vblFlags, &dPriv->vblSeq);
+	 dPriv->vblank_base = dPriv->vblSeq;
+
+	 intel_fb->vbl_waited = dPriv->vblSeq;
 
 	 for (i = 0; i < intel_fb->pf_num_pages; i++) {
 	    if (intel_fb->color_rb[i])
@@ -347,7 +362,7 @@ intelWindowMoved(struct intel_context *intel)
 	 }
       }
    } else {
-      intel_fb->vblank_flags &= ~VBLANK_FLAG_SECONDARY;
+      dPriv->vblFlags &= ~VBLANK_FLAG_SECONDARY;
    }
 
    /* Update Mesa's notion of window size */
@@ -820,10 +835,10 @@ intelSwapBuffers(__DRIdrawablePrivate * dPriv)
  */
 
 static GLboolean
-intelScheduleSwap(const __DRIdrawablePrivate * dPriv, GLboolean *missed_target)
+intelScheduleSwap(__DRIdrawablePrivate * dPriv, GLboolean *missed_target)
 {
    struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
-   unsigned int interval = driGetVBlankInterval(dPriv, intel_fb->vblank_flags);
+   unsigned int interval = driGetVBlankInterval(dPriv, dPriv->vblFlags);
    struct intel_context *intel =
       intelScreenContext(dPriv->driScreenPriv->private);
    const intelScreenPrivate *intelScreen = intel->intelScreen;
@@ -831,24 +846,24 @@ intelScheduleSwap(const __DRIdrawablePrivate * dPriv, GLboolean *missed_target)
    drm_i915_vblank_swap_t swap;
    GLboolean ret;
 
-   if (!intel_fb->vblank_flags ||
-       (intel_fb->vblank_flags & VBLANK_FLAG_NO_IRQ) ||
+   if (!dPriv->vblFlags ||
+       (dPriv->vblFlags & VBLANK_FLAG_NO_IRQ) ||
        intelScreen->current_rotation != 0 ||
        intelScreen->drmMinor < (intel_fb->pf_active ? 9 : 6))
       return GL_FALSE;
 
    swap.seqtype = DRM_VBLANK_ABSOLUTE;
 
-   if (intel_fb->vblank_flags & VBLANK_FLAG_SYNC) {
+   if (dPriv->vblFlags & VBLANK_FLAG_SYNC) {
       swap.seqtype |= DRM_VBLANK_NEXTONMISS;
    } else if (interval == 0) {
       return GL_FALSE;
    }
 
    swap.drawable = dPriv->hHWDrawable;
-   target = swap.sequence = intel_fb->vbl_seq + interval;
+   target = swap.sequence = dPriv->vblSeq + interval;
 
-   if ( intel_fb->vblank_flags & VBLANK_FLAG_SECONDARY ) {
+   if ( dPriv->vblFlags & VBLANK_FLAG_SECONDARY ) {
       swap.seqtype |= DRM_VBLANK_SECONDARY;
    }
 
@@ -866,14 +881,14 @@ intelScheduleSwap(const __DRIdrawablePrivate * dPriv, GLboolean *missed_target)
 
    if (!drmCommandWriteRead(intel->driFd, DRM_I915_VBLANK_SWAP, &swap,
 			    sizeof(swap))) {
-      intel_fb->vbl_seq = swap.sequence;
+      dPriv->vblSeq = swap.sequence;
       swap.sequence -= target;
       *missed_target = swap.sequence > 0 && swap.sequence <= (1 << 23);
 
       intel_get_renderbuffer(&intel_fb->Base, BUFFER_BACK_LEFT)->vbl_pending =
 	 intel_get_renderbuffer(&intel_fb->Base,
 				BUFFER_FRONT_LEFT)->vbl_pending =
-	 intel_fb->vbl_seq;
+	 dPriv->vblSeq;
 
       if (swap.seqtype & DRM_VBLANK_FLIP) {
 	 intel_flip_renderbuffers(intel_fb);
@@ -918,7 +933,7 @@ intelSwapBuffers(__DRIdrawablePrivate * dPriv)
 
          if (screen->current_rotation != 0 ||
 	     !intelScheduleSwap(dPriv, &missed_target)) {
-	    driWaitForVBlank(dPriv, &intel_fb->vbl_seq, intel_fb->vblank_flags,
+	    driWaitForVBlank(dPriv, &dPriv->vblSeq, dPriv->vblFlags,
 			     &missed_target);
 
 	    if (screen->current_rotation != 0 || !intelPageFlip(dPriv)) {
diff --git a/src/mesa/drivers/dri/i915/intel_context.c b/src/mesa/drivers/dri/i915/intel_context.c
index d7af432ad6..b85b0c2939 100644
--- a/src/mesa/drivers/dri/i915/intel_context.c
+++ b/src/mesa/drivers/dri/i915/intel_context.c
@@ -616,18 +616,17 @@ intelMakeCurrent(__DRIcontextPrivate * driContextPriv,
 	    if (driDrawPriv->swap_interval == (unsigned)-1) {
 	       int i;
 
-	       intel_fb->vblank_flags = (intel->intelScreen->irq_active != 0)
+	       driDrawPriv->vblFlags = (intel->intelScreen->irq_active != 0)
 		  ? driGetDefaultVBlankFlags(&intel->optionCache)
 		 : VBLANK_FLAG_NO_IRQ;
 
 	       (*dri_interface->getUST) (&intel_fb->swap_ust);
-	       driDrawableInitVBlank(driDrawPriv, intel_fb->vblank_flags,
-				     &intel_fb->vbl_seq);
-	       intel_fb->vbl_waited = intel_fb->vbl_seq;
+	       driDrawableInitVBlank(driDrawPriv);
+	       intel_fb->vbl_waited = driDrawPriv->vblSeq;
 
 	       for (i = 0; i < (intel->intelScreen->third.handle ? 3 : 2); i++) {
 		  if (intel_fb->color_rb[i])
-		     intel_fb->color_rb[i]->vbl_pending = intel_fb->vbl_seq;
+		     intel_fb->color_rb[i]->vbl_pending = driDrawPriv->vblSeq;
 	       }
 	    }
 	    intel->driDrawable = driDrawPriv;
@@ -731,6 +730,7 @@ intelContendedLock(struct intel_context *intel, GLuint flags)
  */
 void LOCK_HARDWARE( struct intel_context *intel )
 {
+    __DRIdrawablePrivate *dPriv = intel->driDrawable;
     char __ret=0;
     struct intel_framebuffer *intel_fb = NULL;
     struct intel_renderbuffer *intel_rb = NULL;
@@ -748,14 +748,14 @@ void LOCK_HARDWARE( struct intel_context *intel )
 				    BUFFER_BACK_LEFT);
     }
 
-    if (intel_rb && intel_fb->vblank_flags &&
-	!(intel_fb->vblank_flags & VBLANK_FLAG_NO_IRQ) &&
+    if (intel_rb && dPriv->vblFlags &&
+	!(dPriv->vblFlags & VBLANK_FLAG_NO_IRQ) &&
 	(intel_fb->vbl_waited - intel_rb->vbl_pending) > (1<<23)) {
 	drmVBlank vbl;
 
 	vbl.request.type = DRM_VBLANK_ABSOLUTE;
 
-	if ( intel_fb->vblank_flags & VBLANK_FLAG_SECONDARY ) {
+	if ( dPriv->vblFlags & VBLANK_FLAG_SECONDARY ) {
 	    vbl.request.type |= DRM_VBLANK_SECONDARY;
 	}
 
diff --git a/src/mesa/drivers/dri/i915/intel_fbo.h b/src/mesa/drivers/dri/i915/intel_fbo.h
index 411d634231..f9a11d02e3 100644
--- a/src/mesa/drivers/dri/i915/intel_fbo.h
+++ b/src/mesa/drivers/dri/i915/intel_fbo.h
@@ -50,8 +50,6 @@ struct intel_framebuffer
 
    /* VBI
     */
-   GLuint vbl_seq;
-   GLuint vblank_flags;
    GLuint vbl_waited;
 
    int64_t swap_ust;
diff --git a/src/mesa/drivers/dri/i915/intel_screen.c b/src/mesa/drivers/dri/i915/intel_screen.c
index 8be5d910a0..25f5efa7bc 100644
--- a/src/mesa/drivers/dri/i915/intel_screen.c
+++ b/src/mesa/drivers/dri/i915/intel_screen.c
@@ -790,6 +790,7 @@ static const struct __DriverAPIRec intelAPI = {
    .UnbindContext = intelUnbindContext,
    .GetSwapInfo = intelGetSwapInfo,
    .GetMSC = driGetMSC32,
+   .GetDrawableMSC = driDrawableGetMSC32,
    .WaitForMSC = driWaitForMSC32,
    .WaitForSBC = NULL,
    .SwapBuffersMSC = NULL,
diff --git a/src/mesa/drivers/dri/i965/intel_blit.c b/src/mesa/drivers/dri/i965/intel_blit.c
index d1c1c8afb6..6343f613cc 100644
--- a/src/mesa/drivers/dri/i965/intel_blit.c
+++ b/src/mesa/drivers/dri/i965/intel_blit.c
@@ -76,7 +76,8 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv,
    if (!rect)
    {
        UNLOCK_HARDWARE( intel );
-       driWaitForVBlank( dPriv, &intel->vbl_seq, intel->vblank_flags, & missed_target );
+       driWaitForVBlank( dPriv, &dPriv->vblSeq, dPriv->vblFlags,
+			 &missed_target );
        LOCK_HARDWARE( intel );
    }
 
diff --git a/src/mesa/drivers/dri/i965/intel_buffers.c b/src/mesa/drivers/dri/i965/intel_buffers.c
index 6c8b073502..96ef9d8c20 100644
--- a/src/mesa/drivers/dri/i965/intel_buffers.c
+++ b/src/mesa/drivers/dri/i965/intel_buffers.c
@@ -33,6 +33,8 @@
 #include "context.h"
 #include "framebuffer.h"
 #include "macros.h"
+#include "utils.h"
+#include "vblank.h"
 #include "swrast/swrast.h"
 
 GLboolean intel_intersect_cliprects( drm_clip_rect_t *dst,
@@ -190,6 +192,50 @@ void intelWindowMoved( struct intel_context *intel )
       }
    }
 
+   /* Get updated plane info so we sync against the right vblank counter */
+   if (intel->intelScreen->driScrnPriv->ddx_version.minor >= 7) {
+      drmI830Sarea *sarea = intel->sarea;
+      drm_clip_rect_t drw_rect = { .x1 = dPriv->x, .x2 = dPriv->x + dPriv->w,
+				   .y1 = dPriv->y, .y2 = dPriv->y + dPriv->h };
+      drm_clip_rect_t planeA_rect = { .x1 = sarea->planeA_x, .y1 = sarea->planeA_y,
+				     .x2 = sarea->planeA_x + sarea->planeA_w,
+				     .y2 = sarea->planeA_y + sarea->planeA_h };
+      drm_clip_rect_t planeB_rect = { .x1 = sarea->planeB_x, .y1 = sarea->planeB_y,
+				     .x2 = sarea->planeB_x + sarea->planeB_w,
+				     .y2 = sarea->planeB_y + sarea->planeB_h };
+      GLint areaA = driIntersectArea( drw_rect, planeA_rect );
+      GLint areaB = driIntersectArea( drw_rect, planeB_rect );
+      GLuint flags = dPriv->vblFlags;
+
+      /* Update vblank info
+       */
+      if (areaB > areaA || (areaA == areaB && areaB > 0)) {
+	 flags = dPriv->vblFlags | VBLANK_FLAG_SECONDARY;
+      } else {
+	 flags = dPriv->vblFlags & ~VBLANK_FLAG_SECONDARY;
+      }
+
+      /* Check to see if we changed pipes */
+      if (flags != dPriv->vblFlags && dPriv->vblFlags &&
+	  !(dPriv->vblFlags & VBLANK_FLAG_NO_IRQ)) {
+	 int64_t count;
+
+	 /*
+	  * Update msc_base from old pipe
+	  */
+	 driDrawableGetMSC32(dPriv->driScreenPriv, dPriv, &count);
+	 dPriv->msc_base = count;
+	 /*
+	  * Then get new vblank_base and vblSeq values
+	  */
+	 dPriv->vblFlags = flags;
+	 driGetCurrentVBlank(dPriv, dPriv->vblFlags, &dPriv->vblSeq);
+	 dPriv->vblank_base = dPriv->vblSeq;
+      }
+   } else {
+      dPriv->vblFlags &= ~VBLANK_FLAG_SECONDARY;
+   }
+
    _mesa_resize_framebuffer(&intel->ctx,
 			    (GLframebuffer*)dPriv->driverPrivate,
 			    dPriv->w, dPriv->h);
diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c
index 9850997aad..d654d2d30d 100644
--- a/src/mesa/drivers/dri/i965/intel_context.c
+++ b/src/mesa/drivers/dri/i965/intel_context.c
@@ -342,8 +342,8 @@ GLboolean intelInitContext( struct intel_context *intel,
    GLcontext *shareCtx = (GLcontext *) sharedContextPrivate;
    __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
    intelScreenPrivate *intelScreen = (intelScreenPrivate *)sPriv->private;
-   volatile drmI830Sarea *saPriv = (volatile drmI830Sarea *)
-      (((GLubyte *)sPriv->pSAREA)+intelScreen->sarea_priv_offset);
+   volatile drmI830Sarea *saPriv = (drmI830Sarea *)
+     (((GLubyte *)sPriv->pSAREA)+intelScreen->sarea_priv_offset);
 
    if (!_mesa_initialize_context(&intel->ctx,
 				 mesaVis, shareCtx, 
@@ -361,9 +361,6 @@ GLboolean intelInitContext( struct intel_context *intel,
    driParseConfigFiles (&intel->optionCache, &intelScreen->optionCache,
 		   intel->driScreen->myNum, "i965");
 
-   intel->vblank_flags = (intel->intelScreen->irq_active != 0)
-	   ? driGetDefaultVBlankFlags(&intel->optionCache) : VBLANK_FLAG_NO_IRQ;
-
    ctx->Const.MaxTextureMaxAnisotropy = 2.0;
 
    if (getenv("INTEL_STRICT_CONFORMANCE")) {
@@ -592,17 +589,19 @@ GLboolean intelMakeCurrent(__DRIcontextPrivate *driContextPriv,
    if (driContextPriv) {
       struct intel_context *intel = (struct intel_context *) driContextPriv->driverPrivate;
 
+      driDrawPriv->vblFlags = (intel->intelScreen->irq_active != 0)
+	  ? driGetDefaultVBlankFlags(&intel->optionCache) : VBLANK_FLAG_NO_IRQ;
+
+
       if (intel->driReadDrawable != driReadPriv) {
           intel->driReadDrawable = driReadPriv;
       }
 
       if ( intel->driDrawable != driDrawPriv ) {
-	 /* Shouldn't the readbuffer be stored also? */
-	 driDrawableInitVBlank( driDrawPriv, intel->vblank_flags,
-		      &intel->vbl_seq );
-
 	 intel->driDrawable = driDrawPriv;
 	 intelWindowMoved( intel );
+	 /* Shouldn't the readbuffer be stored also? */
+	 driDrawableInitVBlank( driDrawPriv );
       }
 
       _mesa_make_current(&intel->ctx,
diff --git a/src/mesa/drivers/dri/i965/intel_context.h b/src/mesa/drivers/dri/i965/intel_context.h
index 65898caaa7..5848d0c1ba 100644
--- a/src/mesa/drivers/dri/i965/intel_context.h
+++ b/src/mesa/drivers/dri/i965/intel_context.h
@@ -231,11 +231,6 @@ struct intel_context
     */
    driOptionCache optionCache;
 
-   /* VBI
-    */
-   GLuint vbl_seq;
-   GLuint vblank_flags;
-
    int64_t swap_ust;
    int64_t swap_missed_ust;
 
diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c
index e35f7da938..77fd9e386a 100644
--- a/src/mesa/drivers/dri/i965/intel_screen.c
+++ b/src/mesa/drivers/dri/i965/intel_screen.c
@@ -549,6 +549,7 @@ static const struct __DriverAPIRec intelAPI = {
    .UnbindContext   = intelUnbindContext,
    .GetSwapInfo     = intelGetSwapInfo,
    .GetMSC          = driGetMSC32,
+   .GetDrawableMSC  = driDrawableGetMSC32,
    .WaitForMSC      = driWaitForMSC32,
    .WaitForSBC      = NULL,
    .SwapBuffersMSC  = NULL,
diff --git a/src/mesa/drivers/dri/mach64/mach64_context.c b/src/mesa/drivers/dri/mach64/mach64_context.c
index ad661e198c..138e84decb 100644
--- a/src/mesa/drivers/dri/mach64/mach64_context.c
+++ b/src/mesa/drivers/dri/mach64/mach64_context.c
@@ -100,6 +100,7 @@ GLboolean mach64CreateContext( const __GLcontextModes *glVisual,
 {
    GLcontext *ctx, *shareCtx;
    __DRIscreenPrivate *driScreen = driContextPriv->driScreenPriv;
+   __DRIdrawablePrivate *dPriv = driContextPriv->driDrawablePriv;
    struct dd_function_table functions;
    mach64ContextPtr mmesa;
    mach64ScreenPtr mach64Screen;
@@ -253,7 +254,7 @@ GLboolean mach64CreateContext( const __GLcontextModes *glVisual,
 
    mmesa->do_irqs = (mmesa->mach64Screen->irq && !getenv("MACH64_NO_IRQS"));
 
-   mmesa->vblank_flags = (mmesa->do_irqs)
+   dPriv->vblFlags = (mmesa->do_irqs)
       ? driGetDefaultVBlankFlags(&mmesa->optionCache) : VBLANK_FLAG_NO_IRQ;
 
    driContextPriv->driverPrivate = (void *)mmesa;
@@ -330,8 +331,7 @@ mach64MakeCurrent( __DRIcontextPrivate *driContextPriv,
       }
 
       
-      driDrawableInitVBlank( driDrawPriv, newMach64Ctx->vblank_flags,
-			     &newMach64Ctx->vbl_seq );
+      driDrawableInitVBlank( driDrawPriv );
 
       if ( newMach64Ctx->driDrawable != driDrawPriv ) {
 	 newMach64Ctx->driDrawable = driDrawPriv;
diff --git a/src/mesa/drivers/dri/mach64/mach64_context.h b/src/mesa/drivers/dri/mach64/mach64_context.h
index 8d89452412..c602333024 100644
--- a/src/mesa/drivers/dri/mach64/mach64_context.h
+++ b/src/mesa/drivers/dri/mach64/mach64_context.h
@@ -263,8 +263,6 @@ struct mach64_context {
 
    /* VBI
     */
-   GLuint vbl_seq;
-   GLuint vblank_flags;
    GLuint do_irqs;
 
    /* Configuration cache
diff --git a/src/mesa/drivers/dri/mach64/mach64_ioctl.c b/src/mesa/drivers/dri/mach64/mach64_ioctl.c
index 36e7d3c5d3..7405a27f8e 100644
--- a/src/mesa/drivers/dri/mach64/mach64_ioctl.c
+++ b/src/mesa/drivers/dri/mach64/mach64_ioctl.c
@@ -279,7 +279,7 @@ static int mach64WaitForFrameCompletion( mach64ContextPtr mmesa )
 
 /* Copy the back color buffer to the front color buffer.
  */
-void mach64CopyBuffer( const __DRIdrawablePrivate *dPriv )
+void mach64CopyBuffer( __DRIdrawablePrivate *dPriv )
 {
    mach64ContextPtr mmesa;
    GLint nbox, i, ret;
@@ -320,7 +320,7 @@ void mach64CopyBuffer( const __DRIdrawablePrivate *dPriv )
 #endif
 
    UNLOCK_HARDWARE( mmesa );
-   driWaitForVBlank( dPriv, &mmesa->vbl_seq, mmesa->vblank_flags, &missed_target );
+   driWaitForVBlank( dPriv, &dPriv->vblSeq, dPriv->vblFlags, &missed_target );
    LOCK_HARDWARE( mmesa );
 
    /* use front buffer cliprects */
diff --git a/src/mesa/drivers/dri/mach64/mach64_ioctl.h b/src/mesa/drivers/dri/mach64/mach64_ioctl.h
index 52fe863484..c28bf31c49 100644
--- a/src/mesa/drivers/dri/mach64/mach64_ioctl.h
+++ b/src/mesa/drivers/dri/mach64/mach64_ioctl.h
@@ -78,7 +78,7 @@ extern void mach64FireBlitLocked( mach64ContextPtr mmesa, void *buffer,
 				  GLint offset, GLint pitch, GLint format,
 				  GLint x, GLint y, GLint width, GLint height );
 
-extern void mach64CopyBuffer( const __DRIdrawablePrivate *dPriv );
+extern void mach64CopyBuffer( __DRIdrawablePrivate *dPriv );
 #if ENABLE_PERF_BOXES
 extern void mach64PerformanceCounters( mach64ContextPtr mmesa );
 extern void mach64PerformanceBoxesLocked( mach64ContextPtr mmesa );
diff --git a/src/mesa/drivers/dri/mach64/mach64_screen.c b/src/mesa/drivers/dri/mach64/mach64_screen.c
index 04eb081514..a04b775484 100644
--- a/src/mesa/drivers/dri/mach64/mach64_screen.c
+++ b/src/mesa/drivers/dri/mach64/mach64_screen.c
@@ -484,6 +484,7 @@ static struct __DriverAPIRec mach64API = {
    .UnbindContext   = mach64UnbindContext,
    .GetSwapInfo     = NULL,
    .GetMSC          = driGetMSC32,
+   .GetDrawableMSC  = driDrawableGetMSC32,
    .WaitForMSC      = driWaitForMSC32,
    .WaitForSBC      = NULL,
    .SwapBuffersMSC  = NULL
diff --git a/src/mesa/drivers/dri/mga/mga_xmesa.c b/src/mesa/drivers/dri/mga/mga_xmesa.c
index 2f3516fd38..31042f9739 100644
--- a/src/mesa/drivers/dri/mga/mga_xmesa.c
+++ b/src/mesa/drivers/dri/mga/mga_xmesa.c
@@ -452,6 +452,7 @@ mgaCreateContext( const __GLcontextModes *mesaVis,
    GLcontext *ctx, *shareCtx;
    mgaContextPtr mmesa;
    __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+   __DRIdrawablePrivate *dPriv = driContextPriv->driDrawablePriv;
    mgaScreenPrivate *mgaScreen = (mgaScreenPrivate *)sPriv->private;
    drm_mga_sarea_t *saPriv = (drm_mga_sarea_t *)(((char*)sPriv->pSAREA)+
 					      mgaScreen->sarea_priv_offset);
@@ -650,7 +651,7 @@ mgaCreateContext( const __GLcontextModes *mesaVis,
 				    debug_control );
 #endif
 
-   mmesa->vblank_flags = (mmesa->mgaScreen->irq == 0)
+   dPriv->vblFlags = (mmesa->mgaScreen->irq == 0)
        ? VBLANK_FLAG_NO_IRQ : driGetDefaultVBlankFlags(&mmesa->optionCache);
 
    (*dri_interface->getUST)( & mmesa->swap_ust );
@@ -882,8 +883,8 @@ mgaMakeCurrent(__DRIcontextPrivate *driContextPriv,
       mgaContextPtr mmesa = (mgaContextPtr) driContextPriv->driverPrivate;
 
       if (mmesa->driDrawable != driDrawPriv) {
-	 driDrawableInitVBlank( driDrawPriv, mmesa->vblank_flags,
-				&mmesa->vbl_seq );
+	 driDrawableInitVBlank( driDrawPriv );
+
 	 mmesa->driDrawable = driDrawPriv;
 	 mmesa->dirty = ~0; 
 	 mmesa->dirty_cliprects = (MGA_FRONT|MGA_BACK); 
@@ -948,6 +949,7 @@ static const struct __DriverAPIRec mgaAPI = {
    .UnbindContext   = mgaUnbindContext,
    .GetSwapInfo     = getSwapInfo,
    .GetMSC          = driGetMSC32,
+   .GetDrawableMSC  = driDrawableGetMSC32,
    .WaitForMSC      = driWaitForMSC32,
    .WaitForSBC      = NULL,
    .SwapBuffersMSC  = NULL
diff --git a/src/mesa/drivers/dri/mga/mgacontext.h b/src/mesa/drivers/dri/mga/mgacontext.h
index 2124006ade..2681976fc2 100644
--- a/src/mesa/drivers/dri/mga/mgacontext.h
+++ b/src/mesa/drivers/dri/mga/mgacontext.h
@@ -258,11 +258,6 @@ struct mga_context_t {
    drmBufPtr  vertex_dma_buffer;
    drmBufPtr  iload_buffer;
 
-   /* VBI
-    */
-   GLuint vbl_seq;
-   GLuint vblank_flags;
-
    int64_t swap_ust;
    int64_t swap_missed_ust;
 
diff --git a/src/mesa/drivers/dri/mga/mgaioctl.c b/src/mesa/drivers/dri/mga/mgaioctl.c
index 679d688925..94126a31f9 100644
--- a/src/mesa/drivers/dri/mga/mgaioctl.c
+++ b/src/mesa/drivers/dri/mga/mgaioctl.c
@@ -428,8 +428,7 @@ void mgaCopyBuffer( const __DRIdrawablePrivate *dPriv )
    FLUSH_BATCH( mmesa );
 
    mgaWaitForFrameCompletion( mmesa );
-   driWaitForVBlank( dPriv, & mmesa->vbl_seq, mmesa->vblank_flags,
-		     & missed_target );
+   driWaitForVBlank( dPriv, & dPriv->vblSeq, dPriv->vblFlags, & missed_target );
    if ( missed_target ) {
       mmesa->swap_missed_count++;
       (void) (*dri_interface->getUST)( & mmesa->swap_missed_ust );
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c
index a8569a9f15..5ef24d8270 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_context.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c
@@ -283,7 +283,7 @@ GLboolean nouveauMakeCurrent( __DRIcontextPrivate *driContextPriv,
 		struct gl_framebuffer *read_fb =
 			(struct gl_framebuffer*)driReadPriv->driverPrivate;
 
-		driDrawableInitVBlank(driDrawPriv, nmesa->vblank_flags, &nmesa->vblank_seq );
+		driDrawableInitVBlank(driDrawPriv);
 		nmesa->driDrawable = driDrawPriv;
 
 		_mesa_resize_framebuffer(nmesa->glCtx, draw_fb,
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h
index 9aff0ee668..a617dd6282 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_context.h
+++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h
@@ -182,10 +182,6 @@ typedef struct nouveau_context {
 	/* Configuration cache */
 	driOptionCache optionCache;
 
-	/* vblank stuff */
-	uint32_t vblank_flags;
-	uint32_t vblank_seq;
-
 	GLuint new_state;
 	GLuint new_render_state;
 	GLuint render_index;
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c
index 3e7bab63f3..533b4b1e6e 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_screen.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c
@@ -205,6 +205,7 @@ static const struct __DriverAPIRec nouveauAPI = {
 	.UnbindContext   = nouveauUnbindContext,
 	.GetSwapInfo     = nouveauGetSwapInfo,
 	.GetMSC          = driGetMSC32,
+	.GetDrawableMSC  = driDrawableGetMSC32,
 	.WaitForMSC      = driWaitForMSC32,
 	.WaitForSBC      = NULL,
 	.SwapBuffersMSC  = NULL,
diff --git a/src/mesa/drivers/dri/r128/r128_context.c b/src/mesa/drivers/dri/r128/r128_context.c
index c9fe11f38b..25efe5e4cd 100644
--- a/src/mesa/drivers/dri/r128/r128_context.c
+++ b/src/mesa/drivers/dri/r128/r128_context.c
@@ -113,6 +113,7 @@ GLboolean r128CreateContext( const __GLcontextModes *glVisual,
 {
    GLcontext *ctx, *shareCtx;
    __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+   __DRIdrawablePrivate *dPriv = driContextPriv->driDrawablePriv;
    struct dd_function_table functions;
    r128ContextPtr rmesa;
    r128ScreenPtr r128scrn;
@@ -262,7 +263,7 @@ GLboolean r128CreateContext( const __GLcontextModes *glVisual,
    r128DDInitSpanFuncs( ctx );
    r128DDInitState( rmesa );
 
-   rmesa->vblank_flags = (rmesa->r128Screen->irq != 0)
+   dPriv->vblFlags = (rmesa->r128Screen->irq != 0)
        ? driGetDefaultVBlankFlags(&rmesa->optionCache) : VBLANK_FLAG_NO_IRQ;
 
    driContextPriv->driverPrivate = (void *)rmesa;
@@ -347,8 +348,7 @@ r128MakeCurrent( __DRIcontextPrivate *driContextPriv,
 	 newR128Ctx->dirty = R128_UPLOAD_ALL;
       }
 
-      driDrawableInitVBlank( driDrawPriv, newR128Ctx->vblank_flags,
-			     &newR128Ctx->vbl_seq );
+      driDrawableInitVBlank( driDrawPriv );
       newR128Ctx->driDrawable = driDrawPriv;
 
       _mesa_make_current( newR128Ctx->glCtx,
diff --git a/src/mesa/drivers/dri/r128/r128_context.h b/src/mesa/drivers/dri/r128/r128_context.h
index c51dd7fa58..3f7416e9cc 100644
--- a/src/mesa/drivers/dri/r128/r128_context.h
+++ b/src/mesa/drivers/dri/r128/r128_context.h
@@ -210,11 +210,6 @@ struct r128_context {
    GLuint c_textureBytes;
    GLuint c_vertexBuffers;
 
-   /* VBI
-    */
-   GLuint vbl_seq;
-   GLuint vblank_flags;
-
    /* Configuration cache
     */
    driOptionCache optionCache;
diff --git a/src/mesa/drivers/dri/r128/r128_ioctl.c b/src/mesa/drivers/dri/r128/r128_ioctl.c
index b0dba7d04e..e04c0872f0 100644
--- a/src/mesa/drivers/dri/r128/r128_ioctl.c
+++ b/src/mesa/drivers/dri/r128/r128_ioctl.c
@@ -249,7 +249,7 @@ static int r128WaitForFrameCompletion( r128ContextPtr rmesa )
 
 /* Copy the back color buffer to the front color buffer.
  */
-void r128CopyBuffer( const __DRIdrawablePrivate *dPriv )
+void r128CopyBuffer( __DRIdrawablePrivate *dPriv )
 {
    r128ContextPtr rmesa;
    GLint nbox, i, ret;
@@ -282,7 +282,7 @@ void r128CopyBuffer( const __DRIdrawablePrivate *dPriv )
    }
 
    UNLOCK_HARDWARE( rmesa );
-   driWaitForVBlank( dPriv, &rmesa->vbl_seq, rmesa->vblank_flags, &missed_target );
+   driWaitForVBlank( dPriv, &dPriv->vblSeq, dPriv->vblFlags, &missed_target );
    LOCK_HARDWARE( rmesa );
 
    nbox = dPriv->numClipRects;	/* must be in locked region */
@@ -328,7 +328,7 @@ void r128CopyBuffer( const __DRIdrawablePrivate *dPriv )
 #endif
 }
 
-void r128PageFlip( const __DRIdrawablePrivate *dPriv )
+void r128PageFlip( __DRIdrawablePrivate *dPriv )
 {
    r128ContextPtr rmesa;
    GLint ret;
@@ -359,7 +359,7 @@ void r128PageFlip( const __DRIdrawablePrivate *dPriv )
    }
 
    UNLOCK_HARDWARE( rmesa );
-   driWaitForVBlank( dPriv, &rmesa->vbl_seq, rmesa->vblank_flags, &missed_target );
+   driWaitForVBlank( dPriv, &dPriv->vblSeq, dPriv->vblFlags, &missed_target );
    LOCK_HARDWARE( rmesa );
 
    /* The kernel will have been initialized to perform page flipping
diff --git a/src/mesa/drivers/dri/r128/r128_ioctl.h b/src/mesa/drivers/dri/r128/r128_ioctl.h
index 95779f09be..0f9d11fe69 100644
--- a/src/mesa/drivers/dri/r128/r128_ioctl.h
+++ b/src/mesa/drivers/dri/r128/r128_ioctl.h
@@ -86,8 +86,8 @@ extern void r128ReadDepthSpanLocked( r128ContextPtr rmesa,
 extern void r128ReadDepthPixelsLocked( r128ContextPtr rmesa, GLuint n,
 				       const GLint x[], const GLint y[] );
 
-extern void r128CopyBuffer( const __DRIdrawablePrivate *dPriv );
-extern void r128PageFlip( const __DRIdrawablePrivate *dPriv );
+extern void r128CopyBuffer( __DRIdrawablePrivate *dPriv );
+extern void r128PageFlip( __DRIdrawablePrivate *dPriv );
 void r128WaitForVBlank( r128ContextPtr rmesa );
 
 extern void r128WaitForIdleLocked( r128ContextPtr rmesa );
diff --git a/src/mesa/drivers/dri/r128/r128_screen.c b/src/mesa/drivers/dri/r128/r128_screen.c
index 9d65ebddf7..719f9367c0 100644
--- a/src/mesa/drivers/dri/r128/r128_screen.c
+++ b/src/mesa/drivers/dri/r128/r128_screen.c
@@ -411,6 +411,7 @@ static struct __DriverAPIRec r128API = {
    .UnbindContext   = r128UnbindContext,
    .GetSwapInfo     = NULL,
    .GetMSC          = driGetMSC32,
+   .GetDrawableMSC  = driDrawableGetMSC32,
    .WaitForMSC      = driWaitForMSC32,
    .WaitForSBC      = NULL,
    .SwapBuffersMSC  = NULL
diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c
index 8f43a2f312..2b188897f1 100644
--- a/src/mesa/drivers/dri/r200/r200_context.c
+++ b/src/mesa/drivers/dri/r200/r200_context.c
@@ -248,6 +248,7 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,
 			     void *sharedContextPrivate)
 {
    __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+   __DRIdrawablePrivate *dPriv = driContextPriv->driDrawablePriv;
    radeonScreenPtr screen = (radeonScreenPtr)(sPriv->private);
    struct dd_function_table functions;
    r200ContextPtr rmesa;
@@ -499,7 +500,7 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,
 	      fthrottle_mode,
 	      rmesa->r200Screen->irq);
 
-   rmesa->vblank_flags = (rmesa->r200Screen->irq != 0)
+   dPriv->vblFlags = (rmesa->r200Screen->irq != 0)
        ? driGetDefaultVBlankFlags(&rmesa->optionCache) : VBLANK_FLAG_NO_IRQ;
 
    rmesa->prefer_gart_client_texturing = 
@@ -667,8 +668,7 @@ r200MakeCurrent( __DRIcontextPrivate *driContextPriv,
 	 fprintf(stderr, "%s ctx %p\n", __FUNCTION__, (void *)newCtx->glCtx);
 
       if ( newCtx->dri.drawable != driDrawPriv ) {
-	 driDrawableInitVBlank( driDrawPriv, newCtx->vblank_flags,
-				&newCtx->vbl_seq );
+	  driDrawableInitVBlank( driDrawPriv );
       }
 
       newCtx->dri.readable = driReadPriv;
diff --git a/src/mesa/drivers/dri/r200/r200_context.h b/src/mesa/drivers/dri/r200/r200_context.h
index c80180bdbc..be73507995 100644
--- a/src/mesa/drivers/dri/r200/r200_context.h
+++ b/src/mesa/drivers/dri/r200/r200_context.h
@@ -893,11 +893,8 @@ struct r200_context {
    GLuint TexGenCompSel;
    GLmatrix tmpmat;
 
-   /* VBI / buffer swap
+   /* buffer swap
     */
-   GLuint vbl_seq;
-   GLuint vblank_flags;
-
    int64_t swap_ust;
    int64_t swap_missed_ust;
 
diff --git a/src/mesa/drivers/dri/r200/r200_ioctl.c b/src/mesa/drivers/dri/r200/r200_ioctl.c
index c9c5a86172..2ab9ff8a46 100644
--- a/src/mesa/drivers/dri/r200/r200_ioctl.c
+++ b/src/mesa/drivers/dri/r200/r200_ioctl.c
@@ -419,7 +419,7 @@ static void r200WaitForFrameCompletion( r200ContextPtr rmesa )
 
 /* Copy the back color buffer to the front color buffer.
  */
-void r200CopyBuffer( const __DRIdrawablePrivate *dPriv,
+void r200CopyBuffer( __DRIdrawablePrivate *dPriv,
 		      const drm_clip_rect_t	 *rect)
 {
    r200ContextPtr rmesa;
@@ -449,7 +449,7 @@ void r200CopyBuffer( const __DRIdrawablePrivate *dPriv,
    if (!rect)
    {
        UNLOCK_HARDWARE( rmesa );
-       driWaitForVBlank( dPriv, & rmesa->vbl_seq, rmesa->vblank_flags, & missed_target );
+       driWaitForVBlank( dPriv, & dPriv->vblSeq, dPriv->vblFlags, & missed_target );
        LOCK_HARDWARE( rmesa );
    }
 
@@ -513,7 +513,7 @@ void r200CopyBuffer( const __DRIdrawablePrivate *dPriv,
    }
 }
 
-void r200PageFlip( const __DRIdrawablePrivate *dPriv )
+void r200PageFlip( __DRIdrawablePrivate *dPriv )
 {
    r200ContextPtr rmesa;
    GLint ret;
@@ -553,7 +553,7 @@ void r200PageFlip( const __DRIdrawablePrivate *dPriv )
     */
    r200WaitForFrameCompletion( rmesa );
    UNLOCK_HARDWARE( rmesa );
-   driWaitForVBlank( dPriv, & rmesa->vbl_seq, rmesa->vblank_flags, & missed_target );
+   driWaitForVBlank( dPriv, & dPriv->vblSeq, dPriv->vblFlags, & missed_target );
    if ( missed_target ) {
       rmesa->swap_missed_count++;
       (void) (*dri_interface->getUST)( & rmesa->swap_missed_ust );
diff --git a/src/mesa/drivers/dri/r200/r200_ioctl.h b/src/mesa/drivers/dri/r200/r200_ioctl.h
index bf12679947..4521fbabf1 100644
--- a/src/mesa/drivers/dri/r200/r200_ioctl.h
+++ b/src/mesa/drivers/dri/r200/r200_ioctl.h
@@ -89,9 +89,9 @@ extern void r200ReleaseDmaRegion( r200ContextPtr rmesa,
 				    struct r200_dma_region *region,
 				    const char *caller );
 
-extern void r200CopyBuffer( const __DRIdrawablePrivate *drawable,
+extern void r200CopyBuffer( __DRIdrawablePrivate *drawable,
 			    const drm_clip_rect_t      *rect);
-extern void r200PageFlip( const __DRIdrawablePrivate *drawable );
+extern void r200PageFlip( __DRIdrawablePrivate *drawable );
 extern void r200Flush( GLcontext *ctx );
 extern void r200Finish( GLcontext *ctx );
 extern void r200WaitForIdleLocked( r200ContextPtr rmesa );
diff --git a/src/mesa/drivers/dri/r300/radeon_context.c b/src/mesa/drivers/dri/r300/radeon_context.c
index 6dfaf3c647..8316b745ce 100644
--- a/src/mesa/drivers/dri/r300/radeon_context.c
+++ b/src/mesa/drivers/dri/r300/radeon_context.c
@@ -127,6 +127,7 @@ GLboolean radeonInitContext(radeonContextPtr radeon,
 			    void *sharedContextPrivate)
 {
 	__DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+	__DRIdrawablePrivate *dPriv = driContextPriv->driDrawablePriv;
 	radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private);
 	GLcontext* ctx;
 	GLcontext* shareCtx;
@@ -177,7 +178,7 @@ GLboolean radeonInitContext(radeonContextPtr radeon,
 			radeon->do_usleeps ? "usleeps" : "busy waits",
 			fthrottle_mode, radeon->radeonScreen->irq);
 
-	radeon->vblank_flags = (radeon->radeonScreen->irq != 0)
+	dPriv->vblFlags = (radeon->radeonScreen->irq != 0)
 	    ? driGetDefaultVBlankFlags(&radeon->optionCache) : VBLANK_FLAG_NO_IRQ;
 
 	(*dri_interface->getUST) (&radeon->swap_ust);
@@ -277,9 +278,7 @@ GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv,
 				radeon->glCtx);
 
 		if (radeon->dri.drawable != driDrawPriv) {
-			driDrawableInitVBlank(driDrawPriv,
-					      radeon->vblank_flags,
-					      &radeon->vbl_seq);
+		    driDrawableInitVBlank(driDrawPriv);
 		}
 
 		radeon->dri.readable = driReadPriv;
diff --git a/src/mesa/drivers/dri/r300/radeon_context.h b/src/mesa/drivers/dri/r300/radeon_context.h
index 2f239417a9..38d8930601 100644
--- a/src/mesa/drivers/dri/r300/radeon_context.h
+++ b/src/mesa/drivers/dri/r300/radeon_context.h
@@ -182,10 +182,7 @@ struct radeon_context {
 	GLuint irqsEmitted;
 	drm_radeon_irq_wait_t iw;
 
-	/* VBI / buffer swap */
-	GLuint vbl_seq;
-	GLuint vblank_flags;
-
+	/* buffer swap */
 	int64_t swap_ust;
 	int64_t swap_missed_ust;
 
diff --git a/src/mesa/drivers/dri/r300/radeon_ioctl.c b/src/mesa/drivers/dri/r300/radeon_ioctl.c
index 0b8656b9c1..eeef71aaaf 100644
--- a/src/mesa/drivers/dri/r300/radeon_ioctl.c
+++ b/src/mesa/drivers/dri/r300/radeon_ioctl.c
@@ -157,7 +157,7 @@ static void radeonWaitForFrameCompletion(radeonContextPtr radeon)
 
 /* Copy the back color buffer to the front color buffer.
  */
-void radeonCopyBuffer(const __DRIdrawablePrivate * dPriv,
+void radeonCopyBuffer(__DRIdrawablePrivate * dPriv,
 		      const drm_clip_rect_t	 * rect)
 {
 	radeonContextPtr radeon;
@@ -187,7 +187,7 @@ void radeonCopyBuffer(const __DRIdrawablePrivate * dPriv,
 	if (!rect)
 	{
 	    UNLOCK_HARDWARE(radeon);
-	    driWaitForVBlank(dPriv, &radeon->vbl_seq, radeon->vblank_flags,
+	    driWaitForVBlank(dPriv, &dPriv->vblSeq, dPriv->vblFlags,
 			     &missed_target);
 	    LOCK_HARDWARE(radeon);
 	}
@@ -253,7 +253,7 @@ void radeonCopyBuffer(const __DRIdrawablePrivate * dPriv,
 	}
 }
 
-void radeonPageFlip(const __DRIdrawablePrivate * dPriv)
+void radeonPageFlip(__DRIdrawablePrivate * dPriv)
 {
 	radeonContextPtr radeon;
 	GLint ret;
@@ -293,7 +293,7 @@ void radeonPageFlip(const __DRIdrawablePrivate * dPriv)
 	 */
 	radeonWaitForFrameCompletion(radeon);
 	UNLOCK_HARDWARE(radeon);
-	driWaitForVBlank(dPriv, &radeon->vbl_seq, radeon->vblank_flags,
+	driWaitForVBlank(dPriv, &dPriv->vblSeq, dPriv->vblFlags,
 			 &missed_target);
 	if (missed_target) {
 		radeon->swap_missed_count++;
diff --git a/src/mesa/drivers/dri/r300/radeon_ioctl.h b/src/mesa/drivers/dri/r300/radeon_ioctl.h
index 3a80d36c62..210001e8e0 100644
--- a/src/mesa/drivers/dri/r300/radeon_ioctl.h
+++ b/src/mesa/drivers/dri/r300/radeon_ioctl.h
@@ -46,9 +46,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #endif
 #include "radeon_drm.h"
 
-extern void radeonCopyBuffer(const __DRIdrawablePrivate * drawable,
+extern void radeonCopyBuffer(__DRIdrawablePrivate * drawable,
 			     const drm_clip_rect_t	* rect);
-extern void radeonPageFlip(const __DRIdrawablePrivate * drawable);
+extern void radeonPageFlip(__DRIdrawablePrivate * drawable);
 extern void radeonFlush(GLcontext * ctx);
 extern void radeonFinish(GLcontext * ctx);
 extern void radeonWaitForIdleLocked(radeonContextPtr radeon);
diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c
index defc82fa26..fe6d3c21b8 100644
--- a/src/mesa/drivers/dri/radeon/radeon_context.c
+++ b/src/mesa/drivers/dri/radeon/radeon_context.c
@@ -594,8 +594,7 @@ radeonMakeCurrent( __DRIcontextPrivate *driContextPriv,
 
       if ( newCtx->dri.drawable != driDrawPriv ) {
          /* XXX we may need to validate the drawable here!!! */
-	 driDrawableInitVBlank( driDrawPriv, newCtx->vblank_flags,
-				&newCtx->vbl_seq );
+	  driDrawableInitVBlank( driDrawPriv );
       }
 
       newCtx->dri.readable = driReadPriv;
diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c
index 10d3c2b27c..4cc87a95ae 100644
--- a/src/mesa/drivers/dri/radeon/radeon_screen.c
+++ b/src/mesa/drivers/dri/radeon/radeon_screen.c
@@ -961,6 +961,7 @@ static struct __DriverAPIRec radeonAPI = {
    .UnbindContext   = radeonUnbindContext,
    .GetSwapInfo     = getSwapInfo,
    .GetMSC          = driGetMSC32,
+   .GetDrawableMSC  = driDrawableGetMSC32,
    .WaitForMSC      = driWaitForMSC32,
    .WaitForSBC      = NULL,
    .SwapBuffersMSC  = NULL,
@@ -978,6 +979,7 @@ static const struct __DriverAPIRec r200API = {
    .UnbindContext   = r200UnbindContext,
    .GetSwapInfo     = getSwapInfo,
    .GetMSC          = driGetMSC32,
+   .GetDrawableMSC  = driDrawableGetMSC32,
    .WaitForMSC      = driWaitForMSC32,
    .WaitForSBC      = NULL,
    .SwapBuffersMSC  = NULL,
diff --git a/src/mesa/drivers/dri/sis/sis_screen.c b/src/mesa/drivers/dri/sis/sis_screen.c
index 79682a7253..671193577d 100644
--- a/src/mesa/drivers/dri/sis/sis_screen.c
+++ b/src/mesa/drivers/dri/sis/sis_screen.c
@@ -314,6 +314,7 @@ static struct __DriverAPIRec sisAPI = {
    .UnbindContext   = sisUnbindContext,
    .GetSwapInfo     = NULL,
    .GetMSC          = NULL,
+   .GetDrawableMSC  = NULL,
    .WaitForMSC      = NULL,
    .WaitForSBC      = NULL,
    .SwapBuffersMSC  = NULL
diff --git a/src/mesa/drivers/dri/tdfx/tdfx_screen.c b/src/mesa/drivers/dri/tdfx/tdfx_screen.c
index 5bdb446d15..6298de82f4 100644
--- a/src/mesa/drivers/dri/tdfx/tdfx_screen.c
+++ b/src/mesa/drivers/dri/tdfx/tdfx_screen.c
@@ -355,6 +355,7 @@ static const struct __DriverAPIRec tdfxAPI = {
    .UnbindContext   = tdfxUnbindContext,
    .GetSwapInfo     = NULL,
    .GetMSC          = NULL,
+   .GetDrawableMSC  = NULL,
    .WaitForMSC      = NULL,
    .WaitForSBC      = NULL,
    .SwapBuffersMSC  = NULL
diff --git a/src/mesa/drivers/dri/unichrome/via_context.c b/src/mesa/drivers/dri/unichrome/via_context.c
index 66e92cc602..5d95d97d53 100644
--- a/src/mesa/drivers/dri/unichrome/via_context.c
+++ b/src/mesa/drivers/dri/unichrome/via_context.c
@@ -465,6 +465,7 @@ viaCreateContext(const __GLcontextModes *visual,
     GLcontext *ctx, *shareCtx;
     struct via_context *vmesa;
     __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+    __DRIdrawablePrivate *dPriv = driContextPriv->driDrawablePriv;
     viaScreenPrivate *viaScreen = (viaScreenPrivate *)sPriv->private;
     drm_via_sarea_t *saPriv = (drm_via_sarea_t *)
         (((GLubyte *)sPriv->pSAREA) + viaScreen->sareaPrivOffset);
@@ -658,7 +659,7 @@ viaCreateContext(const __GLcontextModes *visual,
         driQueryOptionb(&vmesa->optionCache, "no_rast"))
        FALLBACK(vmesa, VIA_FALLBACK_USER_DISABLE, 1);
 
-    vmesa->vblank_flags =
+    dPriv->vblFlags =
        vmesa->viaScreen->irqEnabled ?
         driGetDefaultVBlankFlags(&vmesa->optionCache) : VBLANK_FLAG_NO_IRQ;
 
@@ -838,8 +839,7 @@ viaMakeCurrent(__DRIcontextPrivate *driContextPriv,
         readBuffer = (GLframebuffer *)driReadPriv->driverPrivate;
 
 	if (vmesa->driDrawable != driDrawPriv) {
-	   driDrawableInitVBlank(driDrawPriv, vmesa->vblank_flags,
-				 &vmesa->vbl_seq);
+	    driDrawableInitVBlank(driDrawPriv);
 	}
 
        if ((vmesa->driDrawable != driDrawPriv)
diff --git a/src/mesa/drivers/dri/unichrome/via_context.h b/src/mesa/drivers/dri/unichrome/via_context.h
index 6321713688..acd6f2e2b1 100644
--- a/src/mesa/drivers/dri/unichrome/via_context.h
+++ b/src/mesa/drivers/dri/unichrome/via_context.h
@@ -321,9 +321,6 @@ struct via_context {
     */
    driOptionCache optionCache;
 
-   GLuint vblank_flags;
-   GLuint vbl_seq;
-
    int64_t swap_ust;
    int64_t swap_missed_ust;
 
diff --git a/src/mesa/drivers/dri/unichrome/via_ioctl.c b/src/mesa/drivers/dri/unichrome/via_ioctl.c
index 4a733fb00c..3c7dafd0e6 100644
--- a/src/mesa/drivers/dri/unichrome/via_ioctl.c
+++ b/src/mesa/drivers/dri/unichrome/via_ioctl.c
@@ -507,7 +507,7 @@ void viaWaitIdleLocked( struct via_context *vmesa, GLboolean light )
  * except that WAIT_IDLE() will spin the CPU polling, while this is
  * IRQ driven.
  */
-static void viaWaitIdleVBlank( const __DRIdrawablePrivate *dPriv, 
+static void viaWaitIdleVBlank(  __DRIdrawablePrivate *dPriv, 
 			       struct via_context *vmesa,
 			       GLuint value )
 {
@@ -523,8 +523,8 @@ static void viaWaitIdleVBlank( const __DRIdrawablePrivate *dPriv,
 	  vmesa->thrashing)
 	 viaSwapOutWork(vmesa);
 
-      driWaitForVBlank( dPriv, & vmesa->vbl_seq, 
-			vmesa->vblank_flags, & missed_target );
+      driWaitForVBlank( dPriv, & dPriv->vblSeq, dPriv->vblFlags,
+			& missed_target );
       if ( missed_target ) {
 	 vmesa->swap_missed_count++;
 	 (*dri_interface->getUST)( &vmesa->swap_missed_ust );
@@ -591,7 +591,7 @@ void viaResetPageFlippingLocked(struct via_context *vmesa)
 /*
  * Copy the back buffer to the front buffer. 
  */
-void viaCopyBuffer(const __DRIdrawablePrivate *dPriv)
+void viaCopyBuffer(__DRIdrawablePrivate *dPriv)
 {
    struct via_context *vmesa = 
       (struct via_context *)dPriv->driContextPriv->driverPrivate;
@@ -607,7 +607,7 @@ void viaCopyBuffer(const __DRIdrawablePrivate *dPriv)
 
    VIA_FLUSH_DMA(vmesa);
 
-   if (vmesa->vblank_flags == VBLANK_FLAG_SYNC &&
+   if (dPriv->vblFlags == VBLANK_FLAG_SYNC &&
        vmesa->lastBreadcrumbWrite > 1)
       viaWaitIdleVBlank(dPriv, vmesa, vmesa->lastBreadcrumbWrite-1);
    else
@@ -634,14 +634,14 @@ void viaCopyBuffer(const __DRIdrawablePrivate *dPriv)
 }
 
 
-void viaPageFlip(const __DRIdrawablePrivate *dPriv)
+void viaPageFlip(__DRIdrawablePrivate *dPriv)
 {
     struct via_context *vmesa = 
        (struct via_context *)dPriv->driContextPriv->driverPrivate;
     struct via_renderbuffer buffer_tmp;
 
     VIA_FLUSH_DMA(vmesa);
-   if (vmesa->vblank_flags == VBLANK_FLAG_SYNC &&
+   if (dPriv->vblFlags == VBLANK_FLAG_SYNC &&
        vmesa->lastBreadcrumbWrite > 1)
       viaWaitIdleVBlank(dPriv, vmesa, vmesa->lastBreadcrumbWrite - 1);
    else
diff --git a/src/mesa/drivers/dri/unichrome/via_ioctl.h b/src/mesa/drivers/dri/unichrome/via_ioctl.h
index a81b427d80..44fc439c9f 100644
--- a/src/mesa/drivers/dri/unichrome/via_ioctl.h
+++ b/src/mesa/drivers/dri/unichrome/via_ioctl.h
@@ -33,8 +33,8 @@ void viaFlushDma(struct via_context *vmesa);
 void viaFlushDmaLocked(struct via_context *vmesa, GLuint flags);
 
 void viaInitIoctlFuncs(GLcontext *ctx);
-void viaCopyBuffer(const __DRIdrawablePrivate *dpriv);
-void viaPageFlip(const __DRIdrawablePrivate *dpriv);
+void viaCopyBuffer(__DRIdrawablePrivate *dpriv);
+void viaPageFlip(__DRIdrawablePrivate *dpriv);
 void viaCheckDma(struct via_context *vmesa, GLuint bytes);
 void viaResetPageFlippingLocked(struct via_context *vmesa);
 void viaWaitIdle(struct via_context *vmesa, GLboolean light);
diff --git a/src/mesa/drivers/dri/unichrome/via_screen.c b/src/mesa/drivers/dri/unichrome/via_screen.c
index f3912ac352..0ad18b4300 100644
--- a/src/mesa/drivers/dri/unichrome/via_screen.c
+++ b/src/mesa/drivers/dri/unichrome/via_screen.c
@@ -334,6 +334,7 @@ static struct __DriverAPIRec viaAPI = {
    .UnbindContext   = viaUnbindContext,
    .GetSwapInfo     = getSwapInfo,
    .GetMSC          = driGetMSC32,
+   .GetDrawableMSC  = driDrawableGetMSC32,
    .WaitForMSC      = driWaitForMSC32,
    .WaitForSBC      = NULL,
    .SwapBuffersMSC  = NULL
-- 
cgit v1.2.3