rpms/mesa/devel mesa-7.0-use_master-r300.patch, NONE, 1.1 mesa-7.0.1-stable-branch.patch, NONE, 1.1 mesa.spec, 1.137, 1.138

Dave Airlie (airlied) fedora-extras-commits at redhat.com
Wed Aug 15 10:18:20 UTC 2007


Author: airlied

Update of /cvs/pkgs/rpms/mesa/devel
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv22848

Modified Files:
	mesa.spec 
Added Files:
	mesa-7.0-use_master-r300.patch mesa-7.0.1-stable-branch.patch 
Log Message:
* Wed Aug 15 2007 Dave Airlie <airlied at redhat.com> - 7.0.1-3
- mesa-7.0.1-stable-branch.patch - Add patches from stable branch
  includes support for some Intel chipsets
- mesa-7.0-use_master-r300.patch - Add r300 driver from master


mesa-7.0-use_master-r300.patch:

--- NEW FILE mesa-7.0-use_master-r300.patch ---
diff --git a/src/mesa/drivers/dri/r300/Makefile b/src/mesa/drivers/dri/r300/Makefile
index c1d223c..4424896 100644
--- a/src/mesa/drivers/dri/r300/Makefile
+++ b/src/mesa/drivers/dri/r300/Makefile
@@ -41,6 +41,7 @@ DRIVER_SOURCES = \
 		 r300_fragprog.c \
 		 r300_shader.c \
 		 r300_emit.c \
+		 r300_swtcl.c \
 		 $(EGL_SOURCES)
 
 C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES)
diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c
index d13649d..9eca41f 100644
--- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c
+++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c
@@ -133,13 +133,15 @@ static void r300PrintStateAtom(r300ContextPtr r300, struct r300_state_atom *stat
 	int i;
 	int dwords = (*state->check) (r300, state);
 
-	fprintf(stderr, "  emit %s/%d/%d\n", state->name, dwords,
+	fprintf(stderr, "  emit %s %d/%d\n", state->name, dwords,
 		state->cmd_size);
 
-	if (RADEON_DEBUG & DEBUG_VERBOSE)
-		for (i = 0; i < dwords; i++)
-			fprintf(stderr, "      %s[%d]: %08X\n",
+	if (RADEON_DEBUG & DEBUG_VERBOSE) {
+		for (i = 0; i < dwords; i++) {
+			fprintf(stderr, "      %s[%d]: %08x\n",
 				state->name, i, state->cmd[i]);
+		}
+	}
 }
 
 /**
@@ -148,28 +150,14 @@ static void r300PrintStateAtom(r300ContextPtr r300, struct r300_state_atom *stat
  * The caller must have ensured that there is enough space in the command
  * buffer.
  */
-static __inline__ void r300EmitAtoms(r300ContextPtr r300, GLboolean dirty)
+static inline void r300EmitAtoms(r300ContextPtr r300, GLboolean dirty)
 {
 	struct r300_state_atom *atom;
 	uint32_t *dest;
+	int dwords;
 
 	dest = r300->cmdbuf.cmd_buf + r300->cmdbuf.count_used;
 
-	if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_STATE) {
-		foreach(atom, &r300->hw.atomlist) {
-			if ((atom->dirty || r300->hw.all_dirty) == dirty) {
-				int dwords = (*atom->check) (r300, atom);
-
-				if (dwords)
-					r300PrintStateAtom(r300, atom);
-				else
-					fprintf(stderr,
-						"  skip state %s\n",
-						atom->name);
-			}
-		}
-	}
-
 	/* Emit WAIT */
 	*dest = cmdwait(R300_WAIT_3D | R300_WAIT_3D_CLEAN);
 	dest++;
@@ -193,13 +181,20 @@ static __inline__ void r300EmitAtoms(r300ContextPtr r300, GLboolean dirty)
 
 	foreach(atom, &r300->hw.atomlist) {
 		if ((atom->dirty || r300->hw.all_dirty) == dirty) {
-			int dwords = (*atom->check) (r300, atom);
-
+			dwords = (*atom->check) (r300, atom);
 			if (dwords) {
+				if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_STATE) {
+					r300PrintStateAtom(r300, atom);
+				}
 				memcpy(dest, atom->cmd, dwords * 4);
 				dest += dwords;
 				r300->cmdbuf.count_used += dwords;
 				atom->dirty = GL_FALSE;
+			} else {
+				if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_STATE) {
+					fprintf(stderr, "  skip state %s\n",
+						atom->name);
+				}
 			}
 		}
 	}
@@ -245,22 +240,28 @@ void r300EmitState(r300ContextPtr r300)
 	r300->hw.all_dirty = GL_FALSE;
 }
 
-#define CHECK( NM, COUNT )				\
-static int check_##NM( r300ContextPtr r300, 		\
-			struct r300_state_atom* atom )	\
-{							\
-   (void) atom;	(void) r300;				\
-   return (COUNT);					\
-}
-
 #define packet0_count(ptr) (((drm_r300_cmd_header_t*)(ptr))->packet0.count)
 #define vpu_count(ptr) (((drm_r300_cmd_header_t*)(ptr))->vpu.count)
 
-CHECK(always, atom->cmd_size)
-    CHECK(variable, packet0_count(atom->cmd) ? (1 + packet0_count(atom->cmd)) : 0)
-    CHECK(vpu, vpu_count(atom->cmd) ? (1 + vpu_count(atom->cmd) * 4) : 0)
-#undef packet0_count
-#undef vpu_count
+static int check_always(r300ContextPtr r300, struct r300_state_atom *atom)
+{
+	return atom->cmd_size;
+}
+
+static int check_variable(r300ContextPtr r300, struct r300_state_atom *atom)
+{
+	int cnt;
+	cnt = packet0_count(atom->cmd);
+	return cnt ? cnt + 1 : 0;
+}
+
+static int check_vpu(r300ContextPtr r300, struct r300_state_atom *atom)
+{
+	int cnt;
+	cnt = vpu_count(atom->cmd);
+	return cnt ? (cnt * 4) + 1 : 0;
+}
+
 #define ALLOC_STATE( ATOM, CHK, SZ, IDX )				\
    do {									\
       r300->hw.ATOM.cmd_size = (SZ);					\
@@ -318,10 +319,14 @@ void r300InitCmdBuf(r300ContextPtr r300)
 	r300->hw.unk21DC.cmd[0] = cmdpacket0(0x21DC, 1);
 	ALLOC_STATE(unk221C, always, 2, 0);
 	r300->hw.unk221C.cmd[0] = cmdpacket0(R300_VAP_UNKNOWN_221C, 1);
-	ALLOC_STATE(unk2220, always, 5, 0);
-	r300->hw.unk2220.cmd[0] = cmdpacket0(0x2220, 4);
-	ALLOC_STATE(unk2288, always, 2, 0);
-	r300->hw.unk2288.cmd[0] = cmdpacket0(R300_VAP_UNKNOWN_2288, 1);
+	ALLOC_STATE(vap_clip, always, 5, 0);
+	r300->hw.vap_clip.cmd[0] = cmdpacket0(R300_VAP_CLIP_X_0, 4);
+
+	if (has_tcl) {
+		ALLOC_STATE(unk2288, always, 2, 0);
+		r300->hw.unk2288.cmd[0] = cmdpacket0(R300_VAP_UNKNOWN_2288, 1);
+	}
+
 	ALLOC_STATE(vof, always, R300_VOF_CMDSIZE, 0);
 	r300->hw.vof.cmd[R300_VOF_CMD_0] =
 	    cmdpacket0(R300_VAP_OUTPUT_VTX_FMT_0, 2);
diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.h b/src/mesa/drivers/dri/r300/r300_cmdbuf.h
index bfb2eda..acb6e38 100644
--- a/src/mesa/drivers/dri/r300/r300_cmdbuf.h
+++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.h
@@ -52,7 +52,7 @@ extern void r300DestroyCmdBuf(r300ContextPtr r300);
  *
  * \param dwords The number of dwords we need to be free on the command buffer
  */
-static __inline__ void r300EnsureCmdBufSpace(r300ContextPtr r300,
+static inline void r300EnsureCmdBufSpace(r300ContextPtr r300,
 					     int dwords, const char *caller)
 {
 	assert(dwords < r300->cmdbuf.size);
@@ -68,7 +68,7 @@ static __inline__ void r300EnsureCmdBufSpace(r300ContextPtr r300,
  * causes state reemission after a flush. This is necessary to ensure
  * correct hardware state after an unlock.
  */
-static __inline__ uint32_t *r300RawAllocCmdBuf(r300ContextPtr r300,
+static inline uint32_t *r300RawAllocCmdBuf(r300ContextPtr r300,
 					       int dwords, const char *caller)
 {
 	uint32_t *ptr;
@@ -80,7 +80,7 @@ static __inline__ uint32_t *r300RawAllocCmdBuf(r300ContextPtr r300,
 	return ptr;
 }
 
-static __inline__ uint32_t *r300AllocCmdBuf(r300ContextPtr r300,
+static inline uint32_t *r300AllocCmdBuf(r300ContextPtr r300,
 					    int dwords, const char *caller)
 {
 	uint32_t *ptr;
diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c
index 9ea14ab..14e0f05 100644
--- a/src/mesa/drivers/dri/r300/r300_context.c
+++ b/src/mesa/drivers/dri/r300/r300_context.c
@@ -63,6 +63,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "r300_ioctl.h"
 #include "r300_tex.h"
 #include "r300_emit.h"
+#include "r300_swtcl.h"
 
 #ifdef USER_BUFFERS
 #include "r300_mem.h"
@@ -317,15 +318,17 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
 	_tnl_allow_vertex_fog(ctx, GL_TRUE);
 
 	/* currently bogus data */
-	ctx->Const.VertexProgram.MaxInstructions = VSF_MAX_FRAGMENT_LENGTH / 4;
[...5558 lines suppressed...]
-				o_inst->src[2] = ZERO_SRC_1;
-				break;
-
-			case 3:
-				o_inst->src[0] = t_src_scalar(vp, &src[0]);
-				o_inst->src[1] = t_src_scalar(vp, &src[1]);
-				o_inst->src[2] = t_src_scalar(vp, &src[2]);
-				break;
-
-			default:
-				fprintf(stderr,
-					"scalars and op RCC not handled yet");
-				_mesa_exit(-1);
-				break;
-			}
-		} else {
-			switch (operands) {
-			case 1:
-				o_inst->src[0] = t_src(vp, &src[0]);
-				o_inst->src[1] = ZERO_SRC_0;
-				o_inst->src[2] = ZERO_SRC_0;
-				break;
-
-			case 2:
-				o_inst->src[0] = t_src(vp, &src[0]);
-				o_inst->src[1] = t_src(vp, &src[1]);
-				o_inst->src[2] = ZERO_SRC_1;
-				break;
-
-			case 3:
-				o_inst->src[0] = t_src(vp, &src[0]);
-				o_inst->src[1] = t_src(vp, &src[1]);
-				o_inst->src[2] = t_src(vp, &src[2]);
-				break;
-
-			default:
-				fprintf(stderr,
-					"scalars and op RCC not handled yet");
-				_mesa_exit(-1);
-				break;
-			}
-		}
-	      next:;
 	}
 
-	/* Will most likely segfault before we get here... fix later. */
-	if (o_inst - vp->program.body.i >= VSF_MAX_FRAGMENT_LENGTH / 4) {
+	vp->program.length = (inst - vp->program.body.i);
+	if (vp->program.length >= VSF_MAX_FRAGMENT_LENGTH) {
 		vp->program.length = 0;
 		vp->native = GL_FALSE;
-		return;
 	}
-	vp->program.length = (o_inst - vp->program.body.i) * 4;
 #if 0
 	fprintf(stderr, "hw program:\n");
 	for (i = 0; i < vp->program.length; i++)
@@ -1065,7 +1309,8 @@ static void position_invariant(struct gl_program *prog)
 	struct gl_program_parameter_list *paramList;
 	int i;
 
-	gl_state_index tokens[STATE_LENGTH] = { STATE_MVP_MATRIX, 0, 0, 0, 0 };
+	gl_state_index tokens[STATE_LENGTH] =
+	    { STATE_MVP_MATRIX, 0, 0, 0, 0 };
 
 	/* tokens[4] = matrix modifier */
 #ifdef PREFER_DP4
@@ -1159,8 +1404,8 @@ static void insert_wpos(struct r300_vertex_program *vp,
 				prog->NumInstructions - 1);
 	/* END */
 	_mesa_copy_instructions(&vpi[prog->NumInstructions + 1],
-				&prog->Instructions[prog->NumInstructions - 1],
-				1);
+				&prog->Instructions[prog->NumInstructions -
+						    1], 1);
 	vpi_insert = &vpi[prog->NumInstructions - 1];
 
 	vpi_insert[i].Opcode = OPCODE_MOV;
@@ -1206,8 +1451,8 @@ static void pos_as_texcoord(struct r300_vertex_program *vp,
 	prog->NumTemporaries++;
 
 	for (vpi = prog->Instructions; vpi->Opcode != OPCODE_END; vpi++) {
-		if (vpi->DstReg.File == PROGRAM_OUTPUT &&
-		    vpi->DstReg.Index == VERT_RESULT_HPOS) {
+		if (vpi->DstReg.File == PROGRAM_OUTPUT
+		    && vpi->DstReg.Index == VERT_RESULT_HPOS) {
 			vpi->DstReg.File = PROGRAM_TEMPORARY;
 			vpi->DstReg.Index = tempregi;
 		}
@@ -1223,20 +1468,18 @@ static struct r300_vertex_program *build_program(struct r300_vertex_program_key
 
 	vp = _mesa_calloc(sizeof(*vp));
 	_mesa_memcpy(&vp->key, wanted_key, sizeof(vp->key));
-
 	vp->wpos_idx = wpos_idx;
 
 	if (mesa_vp->IsPositionInvariant) {
 		position_invariant(&mesa_vp->Base);
 	}
 
-	if (wpos_idx > -1)
+	if (wpos_idx > -1) {
 		pos_as_texcoord(vp, &mesa_vp->Base);
+	}
 
 	assert(mesa_vp->Base.NumInstructions);
-
 	vp->num_temporaries = mesa_vp->Base.NumTemporaries;
-
 	r300TranslateVertexShader(vp, mesa_vp->Base.Instructions);
 
 	return vp;
@@ -1252,11 +1495,10 @@ void r300SelectVertexShader(r300ContextPtr r300)
 	struct r300_vertex_program *vp;
 	GLint wpos_idx;
 
-	vpc = (struct r300_vertex_program_cont *)ctx->VertexProgram._Current;
+	vpc =
+	    (struct r300_vertex_program_cont *)ctx->VertexProgram._Current;
 	InputsRead = ctx->FragmentProgram._Current->Base.InputsRead;
 
-	wanted_key.OutputsWritten |= 1 << VERT_RESULT_HPOS;
-
 	wpos_idx = -1;
 	if (InputsRead & FRAG_BIT_WPOS) {
 		for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
@@ -1271,28 +1513,35 @@ void r300SelectVertexShader(r300ContextPtr r300)
 		InputsRead |= (FRAG_BIT_TEX0 << i);
 		wpos_idx = i;
 	}
+	wanted_key.InputsRead = vpc->mesa_program.Base.InputsRead;
+	wanted_key.OutputsWritten = vpc->mesa_program.Base.OutputsWritten;
+
+	wanted_key.OutputsWritten |= 1 << VERT_RESULT_HPOS;
 
-	if (InputsRead & FRAG_BIT_COL0)
+	if (InputsRead & FRAG_BIT_COL0) {
 		wanted_key.OutputsWritten |= 1 << VERT_RESULT_COL0;
+	}
 
-	if ((InputsRead & FRAG_BIT_COL1)	/*||
-						   (InputsRead & FRAG_BIT_FOGC) */ )
+	if ((InputsRead & FRAG_BIT_COL1)) {
 		wanted_key.OutputsWritten |= 1 << VERT_RESULT_COL1;
+	}
 
-	for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
-		if (InputsRead & (FRAG_BIT_TEX0 << i))
+	for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
+		if (InputsRead & (FRAG_BIT_TEX0 << i)) {
 			wanted_key.OutputsWritten |=
 			    1 << (VERT_RESULT_TEX0 + i);
+		}
+	}
 
-	wanted_key.InputsRead = vpc->mesa_program.Base.InputsRead;
 	if (vpc->mesa_program.IsPositionInvariant) {
 		/* we wan't position don't we ? */
 		wanted_key.InputsRead |= (1 << VERT_ATTRIB_POS);
+		wanted_key.OutputsWritten |= (1 << VERT_RESULT_HPOS);
 	}
 
 	for (vp = vpc->progs; vp; vp = vp->next)
-		if (_mesa_memcmp(&vp->key, &wanted_key, sizeof(wanted_key)) ==
-		    0) {
+		if (_mesa_memcmp(&vp->key, &wanted_key, sizeof(wanted_key))
+		    == 0) {
 			r300->selected_vp = vp;
 			return;
 		}
diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.h b/src/mesa/drivers/dri/r300/r300_vertprog.h
index 252d5a9..3df0eee 100644
--- a/src/mesa/drivers/dri/r300/r300_vertprog.h
+++ b/src/mesa/drivers/dri/r300/r300_vertprog.h
@@ -3,11 +3,6 @@
 
 #include "r300_reg.h"
 
-typedef struct {
-	GLuint op;
-	GLuint src[3];
-} VERTEX_SHADER_INSTRUCTION;
-
 #define VSF_FLAG_X	1
 #define VSF_FLAG_Y	2
 #define VSF_FLAG_Z	4
diff --git a/src/mesa/drivers/dri/r300/radeon_lock.h b/src/mesa/drivers/dri/r300/radeon_lock.h
index c47adc9..a344837 100644
--- a/src/mesa/drivers/dri/r300/radeon_lock.h
+++ b/src/mesa/drivers/dri/r300/radeon_lock.h
@@ -42,9 +42,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #ifndef __RADEON_LOCK_H__
 #define __RADEON_LOCK_H__
 
-#if 0
-#include "r200_ioctl.h"
-#endif
 #include "radeon_context.h"
 
 extern void radeonGetLock(radeonContextPtr rmesa, GLuint flags);

mesa-7.0.1-stable-branch.patch:

--- NEW FILE mesa-7.0.1-stable-branch.patch ---
Brian (21):
      added md5 sums
      fix even-sized point positioning (bug 11874)
      Merge branch 'mesa_7_0_branch' of git+ssh://brianp@git.freedesktop.org/git/mesa/mesa into mesa_7_0_branch
      fix bug 9962 (vbo splitting) as in trunk
      initial 7.0.2 notes
      fix swizzle error test (bug 11881)
      fix potential NULL dereference (bug 11880)
      remove SHELL line, replace -e test with new logic (Daniel Stone)
      fix potential NULL dereference (bug 11879)
      move free() after dereference (bug 11878)
      fix byte swap bug for GLuint stencil indexes (bug 11909)
      fix link to 7.0.1 relnotes
      Implement mutex/locking around texture object reference counting.
      free any render/framebuffers left in hash tables when freeing shared state
      Add PCI IDs for the G33, Q33, and Q35 chipsets.
      added more i915/945 chipsets
      fix blending/banding bug
      Fix a few more problems with freeing FBOs/textures during context destruction.
      added some temporary texobj ref counting debug output
      more tex obj ref count debugging (temporary)
      Added _mesa_free_attrib_data() to free anything left in the attribute stack upon context destruction.

Dan Torop (1):
      fix spantmp2 READ_RGBA inline asm (#11931)

Michel Dänzer (1):
      i915tex: Make sure pitch is aligned properly for render-to-texture.

Wang Zhenyu (1):
      i915tex: Add support for 945GME

diff --git a/Makefile b/Makefile
index 3cab262..56efa83 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,5 @@
 # Top-level Mesa makefile
 
-SHELL = /bin/bash
-
 TOP = .
 
 SUBDIRS = src progs
@@ -156,7 +154,7 @@ sunos5-v9 \
 sunos5-v9-static \
 sunos5-v9-cc-g++ \
 ultrix-gcc:
-	@ if [ -e configs/current ] ; then \
+	@ if test -f configs/current || test -L configs/current ; then \
 		echo "Please run 'make realclean' before changing configs" ; \
 		exit 1 ; \
 	fi
diff --git a/docs/news.html b/docs/news.html
index 1f66d4e..e5f2adb 100644
--- a/docs/news.html
+++ b/docs/news.html
@@ -13,7 +13,7 @@
 
 <h2>August 3, 2007</h2>
 <p>
-<a href="relnotes-7.0.html">Mesa 7.0.1</a> is released.
+<a href="relnotes-7.0.1.html">Mesa 7.0.1</a> is released.
 This is a bug-fix release.
 </p>
 
diff --git a/docs/relnotes-7.0.1.html b/docs/relnotes-7.0.1.html
index 47ee162..02713ad 100644
--- a/docs/relnotes-7.0.1.html
+++ b/docs/relnotes-7.0.1.html
@@ -17,6 +17,15 @@ Mesa 7.0.1 is a stable release with bug fixes since version 7.0.
 
 <h2>MD5 checksums</h2>
 <pre>
+db55141a44b902fcc61d9265b7862c06  MesaLib-7.0.1.tar.gz
+c056abd763e899114bf745c9eedbf9ad  MesaLib-7.0.1.tar.bz2
+ecc2637547fae2b38271ae362d013afa  MesaLib-7.0.1.zip
+b85a4a5be4e829f4a1165e4514b13183  MesaDemos-7.0.1.tar.gz
+3b66b3268df12ca8a6c4e0c4c457912c  MesaDemos-7.0.1.tar.bz2
+b1c18006f16e44e80fea66774c59b391  MesaDemos-7.0.1.zip
+b87a69986839ae43ce12fc8e3dc1ebb4  MesaGLUT-7.0.1.tar.gz
+25f30d0c1651997b4412366ba0572f7f  MesaGLUT-7.0.1.tar.bz2
+676ee6682a6ce78a5540554fd975c03e  MesaGLUT-7.0.1.zip
 </pre>
 
 
diff --git a/docs/relnotes-7.0.2.html b/docs/relnotes-7.0.2.html
new file mode 100644
index 0000000..f1fd3d2
--- /dev/null
+++ b/docs/relnotes-7.0.2.html
@@ -0,0 +1,70 @@
+<HTML>
+
+<TITLE>Mesa Release Notes</TITLE>
+
+<head><link rel="stylesheet" type="text/css" href="mesa.css"></head>
+
+<BODY>
+
+<body bgcolor="#eeeeee">
+
+<H1>Mesa 7.0.2 Release Notes / (TBD) 2007</H1>
+
+<p>
+Mesa 7.0.2 is a stable release with bug fixes since version 7.0.
+</p>
+
+
+<h2>MD5 checksums</h2>
+<pre>
+</pre>
+
+
+<h2>New features</h2>
+<ul>
+</ul>
+
+<h2>Bug fixes</h2>
+<ul>
+<li>Fixed a vertex buffer wrapping issue (bug 9962)
+<li>Added mutex protection around texture object reference counters
+<li>Added checking/support for additional chips in the i915/i945 family
+(see 11978)
+<li>Fixed a blending/banding issue (bug 11931)
+</ul>
+
+
+<h2>Changes</h2>
+<ul>
+</ul>
+
+
+<h2>To Do (someday) items</h2>
+<ul>
+<li>Switch to freeglut
+<li>Fix linux-glide target/driver.
+<li>Improved lambda and derivative calculation for frag progs.
+</ul>
+
+
+<h2>Driver Status</h2>
+
+<pre>
+Driver			Status
+----------------------	----------------------
+DRI drivers		varies with the driver
+XMesa/GLX (on Xlib)	implements OpenGL 2.1
+OSMesa (off-screen)	implements OpenGL 2.1
+Windows/Win32		implements OpenGL 2.1
+Glide (3dfx Voodoo1/2)	implements OpenGL 1.3
+SVGA			unsupported
+Wind River UGL		unsupported
+DJGPP			unsupported
+GGI			unsupported
+BeOS			unsupported
+Allegro			unsupported
+D3D			unsupported
+</pre>
+
+</body>
+</html>
diff --git a/docs/relnotes.html b/docs/relnotes.html
index 9a978d9..7464f5c 100644
--- a/docs/relnotes.html
+++ b/docs/relnotes.html
@@ -20,6 +20,7 @@ The release notes summarize what's new or changed in each Mesa release.
 </p>
 
 <UL>
+<LI><A HREF="relnotes-7.0.2.html">7.0.2 release notes</A>
 <LI><A HREF="relnotes-7.0.1.html">7.0.1 release notes</A>
 <LI><A HREF="relnotes-7.0.html">7.0 release notes</A>
 <LI><A HREF="relnotes-6.5.3.html">6.5.3 release notes</A>
diff --git a/src/mesa/drivers/dri/common/spantmp2.h b/src/mesa/drivers/dri/common/spantmp2.h
index 50f3cf5..53f5f84 100644
--- a/src/mesa/drivers/dri/common/spantmp2.h
+++ b/src/mesa/drivers/dri/common/spantmp2.h
@@ -114,7 +114,7 @@
     do {                                                                \
         GLuint p = *(volatile GLuint *) GET_PTR(_x, _y);                \
        __asm__ __volatile__( "bswap	%0; rorl $8, %0"                \
-				: "=r" (p) : "r" (p) );                 \
+				: "=r" (p) : "0" (p) );                 \
        ((GLuint *)rgba)[0] = p;                                         \
     } while (0)
 # elif defined( MESA_BIG_ENDIAN )
diff --git a/src/mesa/drivers/dri/i810/i810screen.c b/src/mesa/drivers/dri/i810/i810screen.c
index f64c10a..f8cf050 100644
--- a/src/mesa/drivers/dri/i810/i810screen.c
+++ b/src/mesa/drivers/dri/i810/i810screen.c
@@ -288,8 +288,8 @@ i810InitDriver(__DRIscreenPrivate *sPriv)
 	      i810Screen->depth.handle,
 	      i810Screen->depth.size,
 	      (drmAddress *)&i810Screen->depth.map) != 0) {
-      FREE(i810Screen);
       drmUnmap(i810Screen->back.map, i810Screen->back.size);
+      FREE(i810Screen);
       sPriv->private = NULL;
       __driUtilMessage("i810InitDriver: drmMap (2) failed");
       return GL_FALSE;
diff --git a/src/mesa/drivers/dri/i915/i915_texstate.c b/src/mesa/drivers/dri/i915/i915_texstate.c
index 9f0c949..a19d4b6 100644
--- a/src/mesa/drivers/dri/i915/i915_texstate.c
+++ b/src/mesa/drivers/dri/i915/i915_texstate.c
@@ -491,12 +491,19 @@ static void i915SetTexImages( i915ContextPtr i915,
       abort();
    }
 
-
-   if (i915->intel.intelScreen->deviceID == PCI_CHIP_I945_G ||
-       i915->intel.intelScreen->deviceID == PCI_CHIP_I945_GM)
-      i945LayoutTextureImages( i915, tObj );	 
-   else
-      i915LayoutTextureImages( i915, tObj );
+   switch (i915->intel.intelScreen->deviceID) {
+   case PCI_CHIP_I945_G:
+   case PCI_CHIP_I945_GM:
+   case PCI_CHIP_I945_GME:
+   case PCI_CHIP_G33_G:
+   case PCI_CHIP_Q33_G:
+   case PCI_CHIP_Q35_G:
+       i945LayoutTextureImages( i915, tObj );
+       break;
+   default:
+       i915LayoutTextureImages( i915, tObj );
+       break;
+   }
 
    t->Setup[I915_TEXREG_MS3] = 
       (((tObj->Image[0][t->intel.base.firstLevel]->Height - 1) << MS3_HEIGHT_SHIFT) |
diff --git a/src/mesa/drivers/dri/i915/intel_context.c b/src/mesa/drivers/dri/i915/intel_context.c
index e1e7cdb..bb5ce64 100644
--- a/src/mesa/drivers/dri/i915/intel_context.c
+++ b/src/mesa/drivers/dri/i915/intel_context.c
@@ -123,6 +123,14 @@ const GLubyte *intelGetString( GLcontext *ctx, GLenum name )
 	 chipset = "Intel(R) 945G"; break;
       case PCI_CHIP_I945_GM:
 	 chipset = "Intel(R) 945GM"; break;
+      case PCI_CHIP_I945_GME:
+	 chipset = "Intel(R) 945GME"; break;
+      case PCI_CHIP_G33_G:
+	 chipset = "Intel(R) G33"; break;
+      case PCI_CHIP_Q35_G:
+	 chipset = "Intel(R) Q35"; break;
+      case PCI_CHIP_Q33_G:
+	 chipset = "Intel(R) Q33"; break;
       default:
 	 chipset = "Unknown Intel Chipset"; break;
       }
diff --git a/src/mesa/drivers/dri/i915/intel_context.h b/src/mesa/drivers/dri/i915/intel_context.h
index 05195e7..50e6178 100644
--- a/src/mesa/drivers/dri/i915/intel_context.h
+++ b/src/mesa/drivers/dri/i915/intel_context.h
@@ -454,6 +454,10 @@ extern int INTEL_DEBUG;
 #define PCI_CHIP_I915_GM		0x2592
 #define PCI_CHIP_I945_G			0x2772
 #define PCI_CHIP_I945_GM		0x27A2
+#define PCI_CHIP_I945_GME		0x27AE
+#define PCI_CHIP_G33_G			0x29C2
+#define PCI_CHIP_Q35_G			0x29B2
+#define PCI_CHIP_Q33_G			0x29D2
 
 
 /* ================================================================
diff --git a/src/mesa/drivers/dri/i915/intel_screen.c b/src/mesa/drivers/dri/i915/intel_screen.c
index 67e176a..ca8610b 100644
--- a/src/mesa/drivers/dri/i915/intel_screen.c
+++ b/src/mesa/drivers/dri/i915/intel_screen.c
@@ -514,6 +514,10 @@ static GLboolean intelCreateContext( const __GLcontextModes *mesaVis,
    case PCI_CHIP_I915_GM:
    case PCI_CHIP_I945_G:
    case PCI_CHIP_I945_GM:
+   case PCI_CHIP_I945_GME:
+   case PCI_CHIP_G33_G:
+   case PCI_CHIP_Q35_G:
+   case PCI_CHIP_Q33_G:
       return i915CreateContext( mesaVis, driContextPriv, 
 			       sharedContextPrivate );
  
diff --git a/src/mesa/drivers/dri/i915/intel_tex.c b/src/mesa/drivers/dri/i915/intel_tex.c
index 98ddc79..5bd2806 100644
--- a/src/mesa/drivers/dri/i915/intel_tex.c
+++ b/src/mesa/drivers/dri/i915/intel_tex.c
@@ -677,7 +677,11 @@ static void intelUploadTexImage( intelContextPtr intel,
    /* Time for another vtbl entry:
     */
    else if (intel->intelScreen->deviceID == PCI_CHIP_I945_G ||
-            intel->intelScreen->deviceID == PCI_CHIP_I945_GM) {
+            intel->intelScreen->deviceID == PCI_CHIP_I945_GM ||
+            intel->intelScreen->deviceID == PCI_CHIP_I945_GME ||
+            intel->intelScreen->deviceID == PCI_CHIP_G33_G ||
+            intel->intelScreen->deviceID == PCI_CHIP_Q33_G ||
+            intel->intelScreen->deviceID == PCI_CHIP_Q35_G) {
       GLuint row_len = image->Width * image->TexFormat->TexelBytes;
       GLubyte *dst = (GLubyte *)(t->BufAddr + offset);
       GLubyte *src = (GLubyte *)image->Data;
diff --git a/src/mesa/drivers/dri/i915tex/intel_context.c b/src/mesa/drivers/dri/i915tex/intel_context.c
index 093b3b4..40ea756 100644
--- a/src/mesa/drivers/dri/i915tex/intel_context.c
+++ b/src/mesa/drivers/dri/i915tex/intel_context.c
@@ -130,6 +130,18 @@ intelGetString(GLcontext * ctx, GLenum name)
       case PCI_CHIP_I945_GM:
          chipset = "Intel(R) 945GM";
          break;
+      case PCI_CHIP_I945_GME:
+         chipset = "Intel(R) 945GME";
+         break;
+      case PCI_CHIP_G33_G:
+	 chipset = "Intel(R) G33";
+	 break;
+      case PCI_CHIP_Q35_G:
+	 chipset = "Intel(R) Q35";
+	 break;
+      case PCI_CHIP_Q33_G:
+	 chipset = "Intel(R) Q33";
+	 break;
       default:
          chipset = "Unknown Intel Chipset";
          break;
diff --git a/src/mesa/drivers/dri/i915tex/intel_context.h b/src/mesa/drivers/dri/i915tex/intel_context.h
index bcbbb12..5fc8eb3 100644
--- a/src/mesa/drivers/dri/i915tex/intel_context.h
+++ b/src/mesa/drivers/dri/i915tex/intel_context.h
@@ -385,6 +385,10 @@ extern int INTEL_DEBUG;
 #define PCI_CHIP_I915_GM		0x2592
 #define PCI_CHIP_I945_G			0x2772
 #define PCI_CHIP_I945_GM		0x27A2
+#define PCI_CHIP_I945_GME		0x27AE
+#define PCI_CHIP_G33_G			0x29C2
+#define PCI_CHIP_Q35_G			0x29B2
+#define PCI_CHIP_Q33_G			0x29D2
 
 
 /* ================================================================
diff --git a/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c b/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c
index 8e83028..6c28543 100644
--- a/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c
@@ -79,6 +79,10 @@ intel_miptree_create(struct intel_context *intel,
    switch (intel->intelScreen->deviceID) {
    case PCI_CHIP_I945_G:
    case PCI_CHIP_I945_GM:
+   case PCI_CHIP_I945_GME:
+   case PCI_CHIP_G33_G:
+   case PCI_CHIP_Q33_G:
+   case PCI_CHIP_Q35_G:
       ok = i945_miptree_layout(mt);
       break;
    case PCI_CHIP_I915_G:
@@ -93,9 +97,19 @@ intel_miptree_create(struct intel_context *intel,
       break;
    }
 
-   if (ok)
+   if (ok) {
+      if (!mt->compressed) {
+	 /* XXX: Align pitch to multiple of 64 bytes for now to allow
+	  * render-to-texture to work in all cases. This should probably be
+	  * replaced at some point by some scheme to only do this when really
+	  * necessary.
+	  */
+	 mt->pitch = ((mt->pitch * cpp + 63) & ~63) / cpp;
+      }
+
       mt->region = intel_region_alloc(intel->intelScreen,
                                       mt->cpp, mt->pitch, mt->total_height);
+   }
 
    if (!mt->region) {
       free(mt);
diff --git a/src/mesa/drivers/dri/i915tex/intel_screen.c b/src/mesa/drivers/dri/i915tex/intel_screen.c
index 5e6df81..2acdead 100644
--- a/src/mesa/drivers/dri/i915tex/intel_screen.c
+++ b/src/mesa/drivers/dri/i915tex/intel_screen.c
@@ -752,6 +752,10 @@ intelCreateContext(const __GLcontextModes * mesaVis,
    case PCI_CHIP_I915_GM:
    case PCI_CHIP_I945_G:
    case PCI_CHIP_I945_GM:
+   case PCI_CHIP_I945_GME:
+   case PCI_CHIP_G33_G:
+   case PCI_CHIP_Q35_G:
+   case PCI_CHIP_Q33_G:
       return i915CreateContext(mesaVis, driContextPriv, sharedContextPrivate);
 
    default:
diff --git a/src/mesa/drivers/dri/unichrome/via_context.c b/src/mesa/drivers/dri/unichrome/via_context.c
index 4d25d32..7c73877 100644
--- a/src/mesa/drivers/dri/unichrome/via_context.c
+++ b/src/mesa/drivers/dri/unichrome/via_context.c
@@ -733,14 +733,15 @@ void viaXMesaWindowMoved(struct via_context *vmesa)
 {
    __DRIdrawablePrivate *const drawable = vmesa->driDrawable;
    __DRIdrawablePrivate *const readable = vmesa->driReadable;
-   struct via_renderbuffer *const draw_buffer = 
-     (struct via_renderbuffer *) drawable->driverPrivate;
-   struct via_renderbuffer *const read_buffer =
-     (struct via_renderbuffer *) readable->driverPrivate;
+   struct via_renderbuffer * draw_buffer;
+   struct via_renderbuffer * read_buffer;
    GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
 
    if (!drawable)
       return;
+
+   draw_buffer =  (struct via_renderbuffer *) drawable->driverPrivate;
+   read_buffer =  (struct via_renderbuffer *) readable->driverPrivate;
    
    switch (vmesa->glCtx->DrawBuffer->_ColorDrawBufferMask[0]) {
    case BUFFER_BIT_BACK_LEFT: 
diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c
index 0b821cf..df40b88 100644
--- a/src/mesa/main/attrib.c
+++ b/src/mesa/main/attrib.c
@@ -342,6 +342,12 @@ _mesa_PushAttrib(GLbitfield mask)
       /* Bump the texture object reference counts so that they don't
        * inadvertantly get deleted.
        */
+#ifdef DEBUG
+      printf("%lu: MESA PUSH TEX ATTRIB, INCR REF COUNT BY %d\n",
+             _glthread_GetID(),
+             ctx->Const.MaxTextureUnits);
+#endif
+
       for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
 	 ctx->Texture.Unit[u].Current1D->RefCount++;
 	 ctx->Texture.Unit[u].Current2D->RefCount++;
@@ -349,6 +355,7 @@ _mesa_PushAttrib(GLbitfield mask)
 	 ctx->Texture.Unit[u].CurrentCubeMap->RefCount++;
 	 ctx->Texture.Unit[u].CurrentRect->RefCount++;
       }
+
       attr = MALLOC_STRUCT( gl_texture_attrib );
       MEMCPY( attr, &ctx->Texture, sizeof(struct gl_texture_attrib) );
       /* copy state of the currently bound texture objects */
@@ -792,6 +799,11 @@ pop_texture_group(GLcontext *ctx, const struct gl_texture_attrib *texAttrib)
     * wouldn't inadvertantly get deleted while they were still referenced
     * inside the attribute state stack.
     */
+#ifdef DEBUG
+   printf("%lu: MESA POP TEX ATTRIB, DECR REF COUNT BY %d\n",
+          _glthread_GetID(),
+          ctx->Const.MaxTextureUnits);
+#endif
    for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
       ctx->Texture.Unit[u].Current1D->RefCount--;
       ctx->Texture.Unit[u].Current2D->RefCount--;
@@ -1401,6 +1413,84 @@ _mesa_PopClientAttrib(void)
 }
 
 
+static struct gl_texture_object *
+get_texobj(GLcontext *ctx, GLenum target, GLuint name)
+{
+   struct gl_texture_object *texObj;
+   if (name) {
+      texObj = _mesa_lookup_texture(ctx, name);
+   }
+   else {
+      switch (target) {
+      case GL_TEXTURE_1D:
+         texObj = ctx->Shared->Default1D;
+         break;
+      case GL_TEXTURE_2D:
+         texObj = ctx->Shared->Default2D;
+         break;
+      case GL_TEXTURE_3D:
+         texObj = ctx->Shared->Default3D;
+         break;
+      case GL_TEXTURE_CUBE_MAP_ARB:
+         texObj = ctx->Shared->DefaultCubeMap;
+         break;
+      case GL_TEXTURE_RECTANGLE_NV:
+         texObj = ctx->Shared->DefaultRect;
+         break;
+      default:
+         abort();
+      }
+   }
+   return texObj;
+}
+
+
+void
+_mesa_free_attrib_data(GLcontext *ctx)
+{
+#ifdef DEBUG
+   printf("%lu: MESA FREEING ATTRIB STACK DATA\n",
+          _glthread_GetID());
+#endif
+   while (ctx->AttribStackDepth > 0) {
+      struct gl_attrib_node *attr, *next;
+
+      ctx->AttribStackDepth--;
+      attr = ctx->AttribStack[ctx->AttribStackDepth];
+
+      while (attr) {
+         struct gl_texture_attrib *texAttrib
+            = (struct gl_texture_attrib *) attr->data;
+         GLuint u;
+
+         for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
+            struct gl_texture_unit *unit = &texAttrib->Unit[u];
+            struct gl_texture_object *texObj;
+            texObj = get_texobj(ctx, GL_TEXTURE_1D, unit->Saved1D.Name);
+            MESA_REF_TEXOBJ(&texObj, NULL);
+            texObj = get_texobj(ctx, GL_TEXTURE_2D, unit->Saved2D.Name);
+            MESA_REF_TEXOBJ(&texObj, NULL);
+            texObj = get_texobj(ctx, GL_TEXTURE_3D, unit->Saved3D.Name);
+            MESA_REF_TEXOBJ(&texObj, NULL);
+            texObj = get_texobj(ctx, GL_TEXTURE_CUBE_MAP, unit->SavedCubeMap.Name);
+            MESA_REF_TEXOBJ(&texObj, NULL);
+            texObj = get_texobj(ctx, GL_TEXTURE_RECTANGLE_NV, unit->SavedRect.Name);
+            MESA_REF_TEXOBJ(&texObj, NULL);
+         }
+
+         next = attr->next;
+         _mesa_free(attr->data);
+         _mesa_free(attr);
+         attr = next;
+      }
+   }
+#ifdef DEBUG
+   printf("%lu: MESA DONE FREEING ATTRIB STACK DATA\n",
+          _glthread_GetID());
+#endif
+}
+
+
 void _mesa_init_attrib( GLcontext *ctx )
 {
    /* Renderer and client attribute stacks */
diff --git a/src/mesa/main/attrib.h b/src/mesa/main/attrib.h
index 09d7519..ea28859 100644
--- a/src/mesa/main/attrib.h
+++ b/src/mesa/main/attrib.h
@@ -58,10 +58,14 @@ _mesa_PopClientAttrib( void );
 extern void 
 _mesa_init_attrib( GLcontext *ctx );
 
+extern void 
+_mesa_free_attrib_data( GLcontext *ctx );
+
 #else
 
 /** No-op */
 #define _mesa_init_attrib( c ) ((void)0)
+#define _mesa_free_attrib_data( c ) ((void)0)
 
 #endif
 
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index e067840..64f3a7f 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -467,17 +467,12 @@ alloc_shared_state( GLcontext *ctx )
    if (!ss->DefaultRect)
       goto cleanup;
 
-   /* Effectively bind the default textures to all texture units */
-   ss->Default1D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
-   ss->Default2D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
-   ss->Default3D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
-   ss->DefaultCubeMap->RefCount += MAX_TEXTURE_IMAGE_UNITS;
-   ss->DefaultRect->RefCount += MAX_TEXTURE_IMAGE_UNITS;
+   /* sanity check */
+   assert(ss->Default1D->RefCount == 1);
 
    _glthread_INIT_MUTEX(ss->TexMutex);
    ss->TextureStateStamp = 0;
 
-
 #if FEATURE_EXT_framebuffer_object
    ss->FrameBuffers = _mesa_NewHashTable();
    if (!ss->FrameBuffers)
@@ -487,10 +482,9 @@ alloc_shared_state( GLcontext *ctx )
       goto cleanup;
 #endif
 
-
    return GL_TRUE;
 
- cleanup:
+cleanup:
    /* Ran out of memory at some point.  Free everything and return NULL */
    if (ss->DisplayList)
       _mesa_DeleteHashTable(ss->DisplayList);
@@ -567,6 +561,10 @@ delete_texture_cb(GLuint id, void *data, void *userData)
 {
    struct gl_texture_object *texObj = (struct gl_texture_object *) data;
    GLcontext *ctx = (GLcontext *) userData;
+#ifdef DEBUG
+   printf("MESA TEX DELETE %p (%u) from DestroyContext\n",
+          (void *) texObj, texObj->Name);
+#endif
    ctx->Driver.DeleteTexture(ctx, texObj);
 }
 
@@ -634,6 +632,33 @@ delete_shader_cb(GLuint id, void *data, void *userData)
    }
 }
 
+/**
+ * Callback for deleting a framebuffer object.  Called by _mesa_HashDeleteAll()
+ */
+static void
+delete_framebuffer_cb(GLuint id, void *data, void *userData)
+{
+   struct gl_framebuffer *fb = (struct gl_framebuffer *) data;
+   /* The fact that the framebuffer is in the hashtable means its refcount
+    * is one, but we're removing from the hashtable now.  So clear refcount.
+    */
+   /*assert(fb->RefCount == 1);*/
+   fb->RefCount = 0;
+   fb->Delete(fb);
+}
+
+/**
+ * Callback for deleting a renderbuffer object. Called by _mesa_HashDeleteAll()
+ */
+static void
+delete_renderbuffer_cb(GLuint id, void *data, void *userData)
+{
+   struct gl_renderbuffer *rb = (struct gl_renderbuffer *) data;
+   rb->RefCount = 0;  /* see comment for FBOs above */
+   rb->Delete(rb);
+}
+
+
 
 /**
  * Deallocate a shared state object and all children structures.
@@ -656,20 +681,6 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
    _mesa_HashDeleteAll(ss->DisplayList, delete_displaylist_cb, ctx);
    _mesa_DeleteHashTable(ss->DisplayList);
 
-   /*
-    * Free texture objects
-    */
-   ASSERT(ctx->Driver.DeleteTexture);
-   /* the default textures */
-   ctx->Driver.DeleteTexture(ctx, ss->Default1D);
-   ctx->Driver.DeleteTexture(ctx, ss->Default2D);
-   ctx->Driver.DeleteTexture(ctx, ss->Default3D);
-   ctx->Driver.DeleteTexture(ctx, ss->DefaultCubeMap);
-   ctx->Driver.DeleteTexture(ctx, ss->DefaultRect);
-   /* all other textures */
-   _mesa_HashDeleteAll(ss->TexObjects, delete_texture_cb, ctx);
-   _mesa_DeleteHashTable(ss->TexObjects);
-
 #if defined(FEATURE_NV_vertex_program) || defined(FEATURE_NV_fragment_program)
    _mesa_HashDeleteAll(ss->Programs, delete_program_cb, ctx);
    _mesa_DeleteHashTable(ss->Programs);
@@ -701,10 +712,27 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
 #endif
 
 #if FEATURE_EXT_framebuffer_object
+   _mesa_HashDeleteAll(ss->FrameBuffers, delete_framebuffer_cb, ctx);
    _mesa_DeleteHashTable(ss->FrameBuffers);
+   _mesa_HashDeleteAll(ss->RenderBuffers, delete_renderbuffer_cb, ctx);
    _mesa_DeleteHashTable(ss->RenderBuffers);
 #endif
 
+   /*
+    * Free texture objects (after FBOs since some textures might have
+    * been bound to FBOs).
+    */
+   ASSERT(ctx->Driver.DeleteTexture);
+   /* the default textures */
+   ctx->Driver.DeleteTexture(ctx, ss->Default1D);
+   ctx->Driver.DeleteTexture(ctx, ss->Default2D);
+   ctx->Driver.DeleteTexture(ctx, ss->Default3D);
+   ctx->Driver.DeleteTexture(ctx, ss->DefaultCubeMap);
+   ctx->Driver.DeleteTexture(ctx, ss->DefaultRect);
+   /* all other textures */
+   _mesa_HashDeleteAll(ss->TexObjects, delete_texture_cb, ctx);
+   _mesa_DeleteHashTable(ss->TexObjects);
+
    _glthread_DESTROY_MUTEX(ss->Mutex);
 
    _mesa_free(ss);
@@ -1157,18 +1185,27 @@ _mesa_create_context(const GLvisual *visual,
 void
 _mesa_free_context_data( GLcontext *ctx )
 {
-   /* if we're destroying the current context, unbind it first */
-   if (ctx == _mesa_get_current_context()) {
-      _mesa_make_current(NULL, NULL, NULL);
+   if (!_mesa_get_current_context()){
+      /* No current context, but we may need one in order to delete
+       * texture objs, etc.  So temporarily bind the context now.
+       */
+      _mesa_make_current(ctx, NULL, NULL);
    }
-   else {
-      /* unreference WinSysDraw/Read buffers */
-      _mesa_unreference_framebuffer(&ctx->WinSysDrawBuffer);
-      _mesa_unreference_framebuffer(&ctx->WinSysReadBuffer);
-      _mesa_unreference_framebuffer(&ctx->DrawBuffer);
-      _mesa_unreference_framebuffer(&ctx->ReadBuffer);
+
+   if (ctx->AttribStackDepth > 0) {
+#ifdef DEBUG
+      printf("%lu: MESA: DESTROY CONTEXT WITH NON-EMPTRY ATTRIB STACK!\n",
+             _glthread_GetID());
+#endif
    }
 
+   /* unreference WinSysDraw/Read buffers */
+   _mesa_unreference_framebuffer(&ctx->WinSysDrawBuffer);
+   _mesa_unreference_framebuffer(&ctx->WinSysReadBuffer);
+   _mesa_unreference_framebuffer(&ctx->DrawBuffer);
+   _mesa_unreference_framebuffer(&ctx->ReadBuffer);
+
+   _mesa_free_attrib_data(ctx);
    _mesa_free_lighting_data( ctx );
    _mesa_free_eval_data( ctx );
    _mesa_free_texture_data( ctx );
@@ -1200,6 +1237,11 @@ _mesa_free_context_data( GLcontext *ctx )
 
    if (ctx->Extensions.String)
       _mesa_free((void *) ctx->Extensions.String);
+
+   /* unbind the context if it's currently bound */
+   if (ctx == _mesa_get_current_context()) {
+      _mesa_make_current(NULL, NULL, NULL);
+   }
 }
 
 
diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
index eac2f78..f0e413b 100644
--- a/src/mesa/main/fbobject.c
+++ b/src/mesa/main/fbobject.c
@@ -150,22 +150,18 @@ _mesa_remove_attachment(GLcontext *ctx, struct gl_renderbuffer_attachment *att)
 {
    if (att->Type == GL_TEXTURE) {
       ASSERT(att->Texture);
-      att->Texture->RefCount--;
-      if (att->Texture->RefCount == 0) {
-	 ctx->Driver.DeleteTexture(ctx, att->Texture);
+      if (ctx->Driver.FinishRenderTexture) {
+         /* tell driver we're done rendering to this texobj */
+         ctx->Driver.FinishRenderTexture(ctx, att);
       }
-      else {
-         /* tell driver that we're done rendering to this texture. */
-         if (ctx->Driver.FinishRenderTexture) {
-            ctx->Driver.FinishRenderTexture(ctx, att);
-         }
-      }
-      att->Texture = NULL;
+      MESA_REF_TEXOBJ(&att->Texture, NULL); /* unbind */
+      ASSERT(!att->Texture);
    }
    if (att->Type == GL_TEXTURE || att->Type == GL_RENDERBUFFER_EXT) {
       ASSERT(att->Renderbuffer);
       ASSERT(!att->Texture);
-      _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
+      _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); /* unbind */
+      ASSERT(!att->Renderbuffer);
    }
    att->Type = GL_NONE;
    att->Complete = GL_TRUE;
@@ -191,8 +187,8 @@ _mesa_set_texture_attachment(GLcontext *ctx,
       /* new attachment */
       _mesa_remove_attachment(ctx, att);
       att->Type = GL_TEXTURE;
-      att->Texture = texObj;
-      texObj->RefCount++;
+      assert(!att->Texture);
+      MESA_REF_TEXOBJ(&att->Texture, texObj);
    }
 
    /* always update these fields */
diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c
index 1fd31a5..09f0994 100644
--- a/src/mesa/main/framebuffer.c
+++ b/src/mesa/main/framebuffer.c
@@ -38,6 +38,7 @@
 #include "fbobject.h"
 #include "framebuffer.h"
 #include "renderbuffer.h"
+#include "texobj.h"
 
 
 
@@ -190,17 +191,11 @@ _mesa_free_framebuffer_data(struct gl_framebuffer *fb)
          _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
       }
       if (att->Texture) {
-         /* render to texture */
-         att->Texture->RefCount--;
-         if (att->Texture->RefCount == 0) {
-            GET_CURRENT_CONTEXT(ctx);
-            if (ctx) {
-               ctx->Driver.DeleteTexture(ctx, att->Texture);
-            }
-         }
+         MESA_REF_TEXOBJ(&att->Texture, NULL);
       }
+      ASSERT(!att->Renderbuffer);
+      ASSERT(!att->Texture);
       att->Type = GL_NONE;
-      att->Texture = NULL;
    }
 
    /* unbind _Depth/_StencilBuffer to decr ref counts */
diff --git a/src/mesa/main/image.c b/src/mesa/main/image.c
index 803f478..d7a96f7 100644
--- a/src/mesa/main/image.c
+++ b/src/mesa/main/image.c
@@ -3794,7 +3794,7 @@ _mesa_pack_stencil_span( const GLcontext *ctx, GLuint n,
          GLint *dst = (GLint *) dest;
          GLuint i;
          for (i=0;i<n;i++) {
-            *dst++ = (GLint) source[i];
+            dst[i] = (GLint) source[i];
          }
          if (dstPacking->SwapBytes) {
             _mesa_swap4( (GLuint *) dst, n );
diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c
index 56d816e..fa14d91 100644
--- a/src/mesa/main/texobj.c
+++ b/src/mesa/main/texobj.c
@@ -154,8 +154,18 @@ _mesa_delete_texture_object( GLcontext *ctx, struct gl_texture_object *texObj )
 {
    GLuint i, face;
 
+#ifdef DEBUG
+   printf("%lu: MESA TEX DELETE %p (%u) REF COUNT = %d\n",
+          _glthread_GetID(),
+          (void*) texObj, texObj->Name, texObj->RefCount);
+#endif
    (void) ctx;
 
+   /* Set Target to an invalid value.  With some assertions elsewhere
+    * we can try to detect possible use of deleted textures.
+    */
+   texObj->Target = 0x99;
+
    _mesa_free_colortable_data(&texObj->Palette);
 
    /* free the texture images */
@@ -220,6 +230,106 @@ _mesa_copy_texture_object( struct gl_texture_object *dest,
 
 
 /**
+ * Check if the given texture object is valid by examining its Target field.
+ * For debugging only.
+ */
+static GLboolean
+valid_texture_object(const struct gl_texture_object *tex)
+{
+   switch (tex->Target) {
+   case 0:
+   case GL_TEXTURE_1D:
+   case GL_TEXTURE_2D:
+   case GL_TEXTURE_3D:
+   case GL_TEXTURE_CUBE_MAP_ARB:
+   case GL_TEXTURE_RECTANGLE_NV:
+      return GL_TRUE;
+   case 0x99:
+      _mesa_problem(NULL, "invalid reference to a deleted texture object");
+      return GL_FALSE;
+   default:
+      _mesa_problem(NULL, "invalid texture object Target value");
+      return GL_FALSE;
+   }
+}
+
+
+/**
+ * Reference (or unreference) a texture object.
+ * If '*ptr', decrement *ptr's refcount (and delete if it becomes zero).
+ * If 'tex' is non-null, increment its refcount.
+ */
+void
+_mesa_reference_texobj(struct gl_texture_object **ptr,
+                       struct gl_texture_object *tex,
+                       const char *where)
+{
+   assert(ptr);
+   if (*ptr == tex) {
+      /* no change */
+      return;
+   }
+
+   if (*ptr) {
+      /* Unreference the old texture */
+      GLboolean deleteFlag = GL_FALSE;
+      struct gl_texture_object *oldTex = *ptr;
+
+      assert(valid_texture_object(oldTex));
+
+      _glthread_LOCK_MUTEX(oldTex->Mutex);
+      ASSERT(oldTex->RefCount > 0);
+      oldTex->RefCount--;
+
+#ifdef DEBUG
+      printf("%lu: MESA TEX REF DECR %p (%u) to %d from %s\n",
+             _glthread_GetID(),
+             (void*) oldTex, oldTex->Name, oldTex->RefCount, where);
+#endif
+
+      deleteFlag = (oldTex->RefCount == 0);
+      _glthread_UNLOCK_MUTEX(oldTex->Mutex);
+
+      if (deleteFlag) {
+         GET_CURRENT_CONTEXT(ctx);
+         if (ctx)
+            ctx->Driver.DeleteTexture(ctx, oldTex);
+         else
+            _mesa_problem(NULL, "Unable to delete texture, no context");
+      }
+
+      *ptr = NULL;
+   }
+   assert(!*ptr);
+
+   if (tex) {
+      /* reference new texture */
+      assert(valid_texture_object(tex));
+      _glthread_LOCK_MUTEX(tex->Mutex);
+      if (tex->RefCount == 0) {
+         /* this texture's being deleted (look just above) */
+         /* Not sure this can every really happen.  Warn if it does. */
+         _mesa_problem(NULL, "referencing deleted texture object");
+         *ptr = NULL;
+      }
+      else {
+         tex->RefCount++;
+
+#ifdef DEBUG
+         printf("%lu: MESA TEX REF INCR %p (%u) to %d from %s\n",
+                _glthread_GetID(),
+                (void*) tex, tex->Name, tex->RefCount, where);
+#endif
+
+         *ptr = tex;
+      }
+      _glthread_UNLOCK_MUTEX(tex->Mutex);
+   }
+}
+
+
+
+/**
  * Report why a texture object is incomplete.  
  *
  * \param t texture object.
@@ -620,8 +730,7 @@ unbind_texobj_from_fbo(GLcontext *ctx, struct gl_texture_object *texObj)
 
 /**
  * Check if the given texture object is bound to any texture image units and
- * unbind it if so.
- * XXX all RefCount accesses should be protected by a mutex.
+ * unbind it if so (revert to default textures).
  */
 static void
 unbind_texobj_from_texunits(GLcontext *ctx, struct gl_texture_object *texObj)
@@ -630,34 +739,20 @@ unbind_texobj_from_texunits(GLcontext *ctx, struct gl_texture_object *texObj)
 
    for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++) {
       struct gl_texture_unit *unit = &ctx->Texture.Unit[u];
-      struct gl_texture_object **curr = NULL;
-
       if (texObj == unit->Current1D) {
-         curr = &unit->Current1D;
-         unit->Current1D = ctx->Shared->Default1D;
+         MESA_REF_TEXOBJ(&unit->Current1D, ctx->Shared->Default1D);
       }
       else if (texObj == unit->Current2D) {
-         curr = &unit->Current2D;
-         unit->Current2D = ctx->Shared->Default2D;
+         MESA_REF_TEXOBJ(&unit->Current2D, ctx->Shared->Default2D);
       }
       else if (texObj == unit->Current3D) {
-         curr = &unit->Current3D;
-         unit->Current3D = ctx->Shared->Default3D;
+         MESA_REF_TEXOBJ(&unit->Current3D, ctx->Shared->Default3D);
       }
       else if (texObj == unit->CurrentCubeMap) {
-         curr = &unit->CurrentCubeMap;
-         unit->CurrentCubeMap = ctx->Shared->DefaultCubeMap;
+         MESA_REF_TEXOBJ(&unit->CurrentCubeMap, ctx->Shared->DefaultCubeMap);
       }
       else if (texObj == unit->CurrentRect) {
-         curr = &unit->CurrentRect;
-         unit->CurrentRect = ctx->Shared->DefaultRect;
-      }
-
-      if (curr) {
-         (*curr)->RefCount++;
-         texObj->RefCount--;
-         if (texObj == unit->_Current)
-            unit->_Current = *curr;
+         MESA_REF_TEXOBJ(&unit->CurrentRect, ctx->Shared->DefaultRect);
       }
    }
 }
@@ -693,8 +788,6 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures)
             = _mesa_lookup_texture(ctx, textures[i]);
 
          if (delObj) {
-	    GLboolean deleted;
-
 	    _mesa_lock_texture(ctx, delObj);
 
             /* Check if texture is bound to any framebuffer objects.
@@ -704,10 +797,12 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures)
             unbind_texobj_from_fbo(ctx, delObj);
 
             /* Check if this texture is currently bound to any texture units.
-             * If so, unbind it and decrement the reference count.
+             * If so, unbind it.
              */
             unbind_texobj_from_texunits(ctx, delObj);
 
+	    _mesa_unlock_texture(ctx, delObj);
+
             ctx->NewState |= _NEW_TEXTURE;
 
             /* The texture _name_ is now free for re-use.
@@ -717,23 +812,10 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures)
             _mesa_HashRemove(ctx->Shared->TexObjects, delObj->Name);
             _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
 
-            /* The actual texture object will not be freed until it's no
-             * longer bound in any context.
-             * XXX all RefCount accesses should be protected by a mutex.
+            /* Unreference the texobj.  If refcount hits zero, the texture
+             * will be deleted.
              */
-            delObj->RefCount--;
-	    deleted = (delObj->RefCount == 0);
-	    _mesa_unlock_texture(ctx, delObj);
-
-	    /* We know that refcount went to zero above, so this is
-	     * the only pointer left to delObj, so we don't have to
-	     * worry about locking any more:
-	     */
-            if (deleted) {
-               ASSERT(delObj->Name != 0); /* Never delete default tex objs */
-               ASSERT(ctx->Driver.DeleteTexture);
-               (*ctx->Driver.DeleteTexture)(ctx, delObj);
-            }
+            MESA_REF_TEXOBJ(&delObj, NULL);
          }
       }
    }
@@ -761,7 +843,6 @@ _mesa_BindTexture( GLenum target, GLuint texName )
    GET_CURRENT_CONTEXT(ctx);
    const GLuint unit = ctx->Texture.CurrentUnit;
    struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
-   struct gl_texture_object *oldTexObj;
    struct gl_texture_object *newTexObj = NULL;
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
@@ -770,48 +851,6 @@ _mesa_BindTexture( GLenum target, GLuint texName )
                   _mesa_lookup_enum_by_nr(target), (GLint) texName);
 
    /*
-    * Get pointer to currently bound texture object (oldTexObj)
-    */
-   switch (target) {
-      case GL_TEXTURE_1D:
-         oldTexObj = texUnit->Current1D;
-         break;
-      case GL_TEXTURE_2D:
-         oldTexObj = texUnit->Current2D;
-         break;
-      case GL_TEXTURE_3D:
-         oldTexObj = texUnit->Current3D;
-         break;
-      case GL_TEXTURE_CUBE_MAP_ARB:
-         if (!ctx->Extensions.ARB_texture_cube_map) {
-            _mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" );
-            return;
-         }
-         oldTexObj = texUnit->CurrentCubeMap;
-         break;
-      case GL_TEXTURE_RECTANGLE_NV:
-         if (!ctx->Extensions.NV_texture_rectangle) {
-            _mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" );
-            return;
-         }
-         oldTexObj = texUnit->CurrentRect;
-         break;
-      default:
-         _mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" );
-         return;
-   }
-
-   if (oldTexObj->Name == texName) {
-      /* XXX this might be wrong.  If the texobj is in use by another
-       * context and a texobj parameter was changed, this might be our
-       * only chance to update this context's hardware state.
-       * Note that some applications re-bind the same texture a lot so we
-       * want to handle that case quickly.
-       */
-      return;   /* rebinding the same texture- no change */
-   }
-
-   /*
     * Get pointer to new texture object (newTexObj)
     */
    if (texName == 0) {
@@ -879,28 +918,30 @@ _mesa_BindTexture( GLenum target, GLuint texName )
       newTexObj->Target = target;
    }
 
-   /* XXX all RefCount accesses should be protected by a mutex. */
-   newTexObj->RefCount++;
+   assert(valid_texture_object(newTexObj));
 
-   /* do the actual binding, but first flush outstanding vertices:
-    */
+   /* flush before changing binding */
    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
 
+   /* Do the actual binding.  The refcount on the previously bound
+    * texture object will be decremented.  It'll be deleted if the
+    * count hits zero.
+    */
    switch (target) {
       case GL_TEXTURE_1D:
-         texUnit->Current1D = newTexObj;
+         MESA_REF_TEXOBJ(&texUnit->Current1D, newTexObj);
          break;
       case GL_TEXTURE_2D:
-         texUnit->Current2D = newTexObj;
+         MESA_REF_TEXOBJ(&texUnit->Current2D, newTexObj);
          break;
       case GL_TEXTURE_3D:
-         texUnit->Current3D = newTexObj;
+         MESA_REF_TEXOBJ(&texUnit->Current3D, newTexObj);
          break;
       case GL_TEXTURE_CUBE_MAP_ARB:
-         texUnit->CurrentCubeMap = newTexObj;
+         MESA_REF_TEXOBJ(&texUnit->CurrentCubeMap, newTexObj);
          break;
       case GL_TEXTURE_RECTANGLE_NV:
-         texUnit->CurrentRect = newTexObj;
+         MESA_REF_TEXOBJ(&texUnit->CurrentRect, newTexObj);
          break;
       default:
          _mesa_problem(ctx, "bad target in BindTexture");
@@ -910,18 +951,6 @@ _mesa_BindTexture( GLenum target, GLuint texName )
    /* Pass BindTexture call to device driver */
    if (ctx->Driver.BindTexture)
       (*ctx->Driver.BindTexture)( ctx, target, newTexObj );
-
-   /* Decrement the reference count on the old texture and check if it's
-    * time to delete it.
-    */
-   /* XXX all RefCount accesses should be protected by a mutex. */
-   oldTexObj->RefCount--;
-   ASSERT(oldTexObj->RefCount >= 0);
-   if (oldTexObj->RefCount == 0) {
-      ASSERT(oldTexObj->Name != 0);
-      ASSERT(ctx->Driver.DeleteTexture);
-      (*ctx->Driver.DeleteTexture)( ctx, oldTexObj );
-   }
 }
 
 
diff --git a/src/mesa/main/texobj.h b/src/mesa/main/texobj.h
index ec7cf8c..78e7933 100644
--- a/src/mesa/main/texobj.h
+++ b/src/mesa/main/texobj.h
@@ -57,6 +57,14 @@ extern void
 _mesa_copy_texture_object( struct gl_texture_object *dest,
                            const struct gl_texture_object *src );
 
+#define MESA_REF_TEXOBJ(PTR, TEX) \
+   _mesa_reference_texobj(PTR, TEX, __FUNCTION__)
+
+extern void
+_mesa_reference_texobj(struct gl_texture_object **ptr,
+                       struct gl_texture_object *tex,
+                       const char *where);
+
 extern void
 _mesa_test_texobj_completeness( const GLcontext *ctx,
                                 struct gl_texture_object *obj );
diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c
index 1b45eae..c4b678b 100644
--- a/src/mesa/main/texstate.c
+++ b/src/mesa/main/texstate.c
@@ -63,31 +63,6 @@ static const struct gl_tex_env_combine_state default_combine_state = {
 };
 
 
-/**
- * Copy a texture binding.  Helper used by _mesa_copy_texture_state().
- */
-static void
-copy_texture_binding(const GLcontext *ctx,
-                     struct gl_texture_object **dst,
-                     struct gl_texture_object *src)
-{
-   /* only copy if names differ (per OpenGL SI) */
-   if ((*dst)->Name != src->Name) {
-      /* unbind/delete dest binding which we're changing */
-      (*dst)->RefCount--;
-      if ((*dst)->RefCount == 0) {
-         /* time to delete this texture object */
-         ASSERT((*dst)->Name != 0);
-         ASSERT(ctx->Driver.DeleteTexture);
-         /* XXX cast-away const, unfortunately */
-         (*ctx->Driver.DeleteTexture)((GLcontext *) ctx, *dst);
-      }
-      /* make new binding, incrementing ref count */
-      *dst = src;
-      src->RefCount++;
-   }
-}
-
 
 /**
  * Used by glXCopyContext to copy texture state from one context to another.
@@ -144,16 +119,16 @@ _mesa_copy_texture_state( const GLcontext *src, GLcontext *dst )
       /* copy texture object bindings, not contents of texture objects */
       _mesa_lock_context_textures(dst);
 
-      copy_texture_binding(src, &dst->Texture.Unit[i].Current1D,
-                           src->Texture.Unit[i].Current1D);
-      copy_texture_binding(src, &dst->Texture.Unit[i].Current2D,
-                           src->Texture.Unit[i].Current2D);
-      copy_texture_binding(src, &dst->Texture.Unit[i].Current3D,
-                           src->Texture.Unit[i].Current3D);
-      copy_texture_binding(src, &dst->Texture.Unit[i].CurrentCubeMap,
-                           src->Texture.Unit[i].CurrentCubeMap);
-      copy_texture_binding(src, &dst->Texture.Unit[i].CurrentRect,
-                           src->Texture.Unit[i].CurrentRect);
+      MESA_REF_TEXOBJ(&dst->Texture.Unit[i].Current1D,
+                             src->Texture.Unit[i].Current1D);
+      MESA_REF_TEXOBJ(&dst->Texture.Unit[i].Current2D,
+                             src->Texture.Unit[i].Current2D);
+      MESA_REF_TEXOBJ(&dst->Texture.Unit[i].Current3D,
+                             src->Texture.Unit[i].Current3D);
+      MESA_REF_TEXOBJ(&dst->Texture.Unit[i].CurrentCubeMap,
+                             src->Texture.Unit[i].CurrentCubeMap);
+      MESA_REF_TEXOBJ(&dst->Texture.Unit[i].CurrentRect,
+                             src->Texture.Unit[i].CurrentRect);
 
       _mesa_unlock_context_textures(dst);
    }
@@ -3032,6 +3007,8 @@ alloc_proxy_textures( GLcontext *ctx )
    if (!ctx->Texture.ProxyRect)
       goto cleanup;
 
+   assert(ctx->Texture.Proxy1D->RefCount == 1);
+
    return GL_TRUE;
 
  cleanup:
@@ -3087,11 +3064,12 @@ init_texture_unit( GLcontext *ctx, GLuint unit )
    ASSIGN_4V( texUnit->EyePlaneR, 0.0, 0.0, 0.0, 0.0 );
    ASSIGN_4V( texUnit->EyePlaneQ, 0.0, 0.0, 0.0, 0.0 );
 
-   texUnit->Current1D = ctx->Shared->Default1D;
-   texUnit->Current2D = ctx->Shared->Default2D;
-   texUnit->Current3D = ctx->Shared->Default3D;
-   texUnit->CurrentCubeMap = ctx->Shared->DefaultCubeMap;
-   texUnit->CurrentRect = ctx->Shared->DefaultRect;
+   /* initialize current texture object ptrs to the shared default objects */
+   MESA_REF_TEXOBJ(&texUnit->Current1D, ctx->Shared->Default1D);
+   MESA_REF_TEXOBJ(&texUnit->Current2D, ctx->Shared->Default2D);
+   MESA_REF_TEXOBJ(&texUnit->Current3D, ctx->Shared->Default3D);
+   MESA_REF_TEXOBJ(&texUnit->CurrentCubeMap, ctx->Shared->DefaultCubeMap);
+   MESA_REF_TEXOBJ(&texUnit->CurrentRect, ctx->Shared->DefaultRect);
 }
 
 
@@ -3106,21 +3084,20 @@ _mesa_init_texture(GLcontext *ctx)
    assert(MAX_TEXTURE_LEVELS >= MAX_3D_TEXTURE_LEVELS);
    assert(MAX_TEXTURE_LEVELS >= MAX_CUBE_TEXTURE_LEVELS);
 
-   /* Effectively bind the default textures to all texture units */
-   ctx->Shared->Default1D->RefCount += MAX_TEXTURE_UNITS;
-   ctx->Shared->Default2D->RefCount += MAX_TEXTURE_UNITS;
-   ctx->Shared->Default3D->RefCount += MAX_TEXTURE_UNITS;
-   ctx->Shared->DefaultCubeMap->RefCount += MAX_TEXTURE_UNITS;
-   ctx->Shared->DefaultRect->RefCount += MAX_TEXTURE_UNITS;
-
    /* Texture group */
    ctx->Texture.CurrentUnit = 0;      /* multitexture */
    ctx->Texture._EnabledUnits = 0;
-   for (i=0; i<MAX_TEXTURE_UNITS; i++)
-      init_texture_unit( ctx, i );
    ctx->Texture.SharedPalette = GL_FALSE;
    _mesa_init_colortable(&ctx->Texture.Palette);
 
+   for (i = 0; i < MAX_TEXTURE_UNITS; i++)
+      init_texture_unit( ctx, i );
+
+   /* After we're done initializing the context's texture state the default
+    * texture objects' refcounts should be at least MAX_TEXTURE_UNITS + 1.
+    */
+   assert(ctx->Shared->Default1D->RefCount >= MAX_TEXTURE_UNITS + 1);
+
    _mesa_TexEnvProgramCacheInit( ctx );
 
    /* Allocate proxy textures */
@@ -3132,12 +3109,22 @@ _mesa_init_texture(GLcontext *ctx)
 
 
 /**
- * Free dynamically-allocted texture data attached to the given context.
+ * Free dynamically-allocated texture data attached to the given context.
  */
 void
 _mesa_free_texture_data(GLcontext *ctx)
 {
-   GLuint i;
+   GLuint u;
+
+   /* unreference current textures */
+   for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++) {
+      struct gl_texture_unit *unit = ctx->Texture.Unit + u;
+      MESA_REF_TEXOBJ(&unit->Current1D, NULL);
+      MESA_REF_TEXOBJ(&unit->Current2D, NULL);
+      MESA_REF_TEXOBJ(&unit->Current3D, NULL);
+      MESA_REF_TEXOBJ(&unit->CurrentCubeMap, NULL);
+      MESA_REF_TEXOBJ(&unit->CurrentRect, NULL);
+   }
 
    /* Free proxy texture objects */
    (ctx->Driver.DeleteTexture)(ctx,  ctx->Texture.Proxy1D );
@@ -3146,8 +3133,8 @@ _mesa_free_texture_data(GLcontext *ctx)
    (ctx->Driver.DeleteTexture)(ctx,  ctx->Texture.ProxyCubeMap );
    (ctx->Driver.DeleteTexture)(ctx,  ctx->Texture.ProxyRect );
 
-   for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++)
-      _mesa_free_colortable_data( &ctx->Texture.Unit[i].ColorTable );
+   for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++)
+      _mesa_free_colortable_data( &ctx->Texture.Unit[u].ColorTable );
 
    _mesa_TexEnvProgramCacheDestroy( ctx );
 }
diff --git a/src/mesa/shader/atifragshader.c b/src/mesa/shader/atifragshader.c
index 4727c1a..854c911 100644
--- a/src/mesa/shader/atifragshader.c
+++ b/src/mesa/shader/atifragshader.c
@@ -440,7 +440,7 @@ _mesa_PassTexCoordATI(GLuint dst, GLuint coord, GLenum swizzle)
       _mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoordATI(coord)");
       return;
    }
-   if ((swizzle < GL_SWIZZLE_STR_ATI) && (swizzle > GL_SWIZZLE_STQ_DQ_ATI)) {
+   if (!(swizzle >= GL_SWIZZLE_STR_ATI) && (swizzle <= GL_SWIZZLE_STQ_DQ_ATI)) {
       _mesa_error(ctx, GL_INVALID_ENUM, "glPassTexCoordATI(swizzle)");
       return;
    }
@@ -513,7 +513,7 @@ _mesa_SampleMapATI(GLuint dst, GLuint interp, GLenum swizzle)
       _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(interp)");
       return;
    }
-   if ((swizzle < GL_SWIZZLE_STR_ATI) && (swizzle > GL_SWIZZLE_STQ_DQ_ATI)) {
+   if (!(swizzle >= GL_SWIZZLE_STR_ATI) && (swizzle <= GL_SWIZZLE_STQ_DQ_ATI)) {
       _mesa_error(ctx, GL_INVALID_ENUM, "glSampleMapATI(swizzle)");
       return;
    }
diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c
index b794e30..06d24b4 100644
--- a/src/mesa/shader/shader_api.c
+++ b/src/mesa/shader/shader_api.c
@@ -378,7 +378,7 @@ _mesa_attach_shader(GLcontext *ctx, GLuint program, GLuint shader)
    struct gl_shader_program *shProg
       = _mesa_lookup_shader_program(ctx, program);
    struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
-   const GLuint n = shProg->NumShaders;
+   GLuint n;
    GLuint i;
 
    if (!shProg || !sh) {
@@ -387,6 +387,8 @@ _mesa_attach_shader(GLcontext *ctx, GLuint program, GLuint shader)
       return;
    }
 
+   n = shProg->NumShaders;
+
    for (i = 0; i < n; i++) {
       if (shProg->Shaders[i] == sh) {
          /* already attached */
@@ -548,7 +550,7 @@ _mesa_detach_shader(GLcontext *ctx, GLuint program, GLuint shader)
 {
    struct gl_shader_program *shProg
       = _mesa_lookup_shader_program(ctx, program);
-   const GLuint n = shProg->NumShaders;
+   GLuint n;
    GLuint i, j;
 
    if (!shProg) {
@@ -557,6 +559,8 @@ _mesa_detach_shader(GLcontext *ctx, GLuint program, GLuint shader)
       return;
    }
 
+   n = shProg->NumShaders;
+
    for (i = 0; i < n; i++) {
       if (shProg->Shaders[i]->Name == shader) {
          /* found it */
diff --git a/src/mesa/swrast/s_pointtemp.h b/src/mesa/swrast/s_pointtemp.h
index dddc2f7..9436464 100644
--- a/src/mesa/swrast/s_pointtemp.h
+++ b/src/mesa/swrast/s_pointtemp.h
@@ -217,9 +217,9 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
       }
       else {
          /* even size */
-         xmin = (GLint) vert->win[0] - iRadius + 1;
+         xmin = (GLint) vert->win[0] - iRadius;
          xmax = xmin + iSize - 1;
-         ymin = (GLint) vert->win[1] - iRadius + 1;
+         ymin = (GLint) vert->win[1] - iRadius;
          ymax = ymin + iSize - 1;
       }
 #endif /*SMOOTH*/
diff --git a/src/mesa/vbo/vbo_split_copy.c b/src/mesa/vbo/vbo_split_copy.c
index e142dde..b71a935 100644
--- a/src/mesa/vbo/vbo_split_copy.c
+++ b/src/mesa/vbo/vbo_split_copy.c
@@ -129,6 +129,13 @@ static GLuint attr_size( const struct gl_client_array *array )
  */
 static GLboolean check_flush( struct copy_context *copy )
 {
+   GLenum mode = copy->dstprim[copy->dstprim_nr].mode;
+
+   if (GL_TRIANGLE_STRIP == mode &&
+       copy->dstelt_nr & 1) { /* see bug9962 */
+      return GL_FALSE;
+   }
+
    if (copy->dstbuf_nr + 4 > copy->dstbuf_size)
       return GL_TRUE;
 
@@ -458,7 +465,7 @@ static void replay_init( struct copy_context *copy )
       dst->StrideB = copy->vertex_size;
       dst->Ptr = copy->dstbuf + offset;
       dst->Enabled = GL_TRUE;
-      dst->Normalized = GL_TRUE;
+      dst->Normalized = src->Normalized;
       dst->BufferObj = ctx->Array.NullBufferObj;
       dst->_MaxElement = copy->dstbuf_size; /* may be less! */
 


Index: mesa.spec
===================================================================
RCS file: /cvs/pkgs/rpms/mesa/devel/mesa.spec,v
retrieving revision 1.137
retrieving revision 1.138
diff -u -r1.137 -r1.138
--- mesa.spec	14 Aug 2007 05:44:52 -0000	1.137
+++ mesa.spec	15 Aug 2007 10:17:48 -0000	1.138
@@ -32,7 +32,7 @@
 Summary: Mesa graphics libraries
 Name: mesa
 Version: 7.0.1
-Release: 2%{?dist}
+Release: 3%{?dist}
 License: MIT
 Group: System Environment/Libraries
 URL: http://www.mesa3d.org
@@ -50,6 +50,8 @@
 Patch23: mesa-6.5.2-bindcontext-paranoia.patch
 Patch24: mesa-7.0-i-already-defined-glapi-you-twit.patch
 Patch25: mesa-7.0-symlinks-before-depend.patch
+Patch26: mesa-7.0.1-stable-branch.patch
+Patch27: mesa-7.0-use_master-r300.patch
 
 BuildRequires: pkgconfig
 %if %{with_dri}
@@ -179,6 +181,8 @@
 %patch23 -p1 -b .bindcontext
 %patch24 -p1 -b .glapi
 %patch25 -p1 -b .makej
+%patch26 -p1 -b .stable
+%patch27 -p1 -b .r300
 
 # WARNING: The following files are copyright "Mark J. Kilgard" under the GLUT
 # license and are not open source/free software, so we remove them.
@@ -408,6 +412,11 @@
 %{_libdir}/mesa-demos-data
 
 %changelog
+* Wed Aug 15 2007 Dave Airlie <airlied at redhat.com> - 7.0.1-3
+- mesa-7.0.1-stable-branch.patch - Add patches from stable branch
+  includes support for some Intel chipsets
+- mesa-7.0-use_master-r300.patch - Add r300 driver from master
+
 * Tue Aug 14 2007 Dave Airlie <airlied at redhat.com> - 7.0.1-2
 - missing build requires for Xfixes-devel and Xdamage-devel
 




More information about the scm-commits mailing list