2ef8eba484
support for some Intel chipsets - mesa-7.0-use_master-r300.patch - Add r300 driver from master
1448 lines
49 KiB
Diff
1448 lines
49 KiB
Diff
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! */
|
|
|