summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichel Dänzer <daenzer@vmware.com>2009-05-14 11:07:49 +0200
committerMichel Dänzer <daenzer@vmware.com>2009-05-14 11:13:06 +0200
commit09c04db3c900e4ed833d060853b48c7ca23697e1 (patch)
tree9545ec91bb3ad2ef88c4ad5293797961a48b0c17
parent99960393edb3d6c0d3702cf51b59c2e4189117c7 (diff)
r300: Make sure to drop current hardware state reference to texture objects.
Fixes potential texture object leaks.
-rw-r--r--src/mesa/drivers/dri/r300/r300_context.c7
-rw-r--r--src/mesa/drivers/dri/r300/r300_texstate.c22
2 files changed, 21 insertions, 8 deletions
diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c
index 12bee1a8fb..8f0effd83e 100644
--- a/src/mesa/drivers/dri/r300/r300_context.c
+++ b/src/mesa/drivers/dri/r300/r300_context.c
@@ -43,6 +43,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "main/matrix.h"
#include "main/extensions.h"
#include "main/state.h"
+#include "main/texobj.h"
#include "main/bufferobj.h"
#include "swrast/swrast.h"
@@ -500,6 +501,7 @@ void r300DestroyContext(__DRIcontextPrivate * driContextPriv)
r300ContextPtr r300 = (r300ContextPtr) driContextPriv->driverPrivate;
radeonContextPtr radeon = (radeonContextPtr) r300;
radeonContextPtr current = ctx ? RADEON_CONTEXT(ctx) : NULL;
+ int i;
if (RADEON_DEBUG & DEBUG_DRI) {
fprintf(stderr, "Destroying context !\n");
@@ -553,6 +555,11 @@ void r300DestroyContext(__DRIcontextPrivate * driContextPriv)
assert(is_empty_list(&r300->swapped));
}
+ /* Drop texture object references from current hardware state */
+ for (i = 0; i < 8; i++) {
+ _mesa_reference_texobj(&r300->state.texture.unit[i].texobj, NULL);
+ }
+
radeonCleanupContext(&r300->radeon);
#ifdef USER_BUFFERS
diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c
index abe613e27b..f6ae4b675b 100644
--- a/src/mesa/drivers/dri/r300/r300_texstate.c
+++ b/src/mesa/drivers/dri/r300/r300_texstate.c
@@ -557,12 +557,15 @@ static GLboolean r300UpdateTexture(GLcontext * ctx, int unit)
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
- struct gl_texture_object *tObj = texUnit->_Current;
- r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
+ struct gl_texture_object *tObj = texUnit->_ReallyEnabled ?
+ texUnit->_Current : NULL;
+ r300TexObjPtr t = tObj ? (r300TexObjPtr) tObj->DriverData : NULL;
/* Fallback if there's a texture border */
- if (tObj->Image[0][tObj->BaseLevel]->Border > 0)
- return GL_FALSE;
+ if (tObj && tObj->Image[0][tObj->BaseLevel]->Border > 0) {
+ tObj = NULL;
+ t = NULL;
+ }
/* Update state if this is a different texture object to last
* time.
@@ -579,11 +582,14 @@ static GLboolean r300UpdateTexture(GLcontext * ctx, int unit)
}
_mesa_reference_texobj(&rmesa->state.texture.unit[unit].texobj, tObj);
- t->base.bound |= (1 << unit);
- driUpdateTextureLRU(&t->base); /* XXX: should be locked! */
+
+ if (t) {
+ t->base.bound |= (1 << unit);
+ driUpdateTextureLRU(&t->base); /* XXX: should be locked! */
+ }
}
- return !t->border_fallback;
+ return !t || !t->border_fallback;
}
void r300SetTexOffset(__DRIcontext * pDRICtx, GLint texname,
@@ -651,7 +657,7 @@ static GLboolean r300UpdateTextureUnit(GLcontext * ctx, int unit)
} else if (texUnit->_ReallyEnabled) {
return GL_FALSE;
} else {
- return GL_TRUE;
+ return r300UpdateTexture(ctx, unit);
}
}