Henri Verbeet : wined3d: Properly keep texture references in the stateblock .
Alexandre Julliard
julliard at winehq.org
Mon Sep 28 11:54:36 CDT 2009
Module: wine
Branch: master
Commit: 709aedf5f9bdfd0cdeab3d2189f6382680356922
URL: http://source.winehq.org/git/wine.git/?a=commit;h=709aedf5f9bdfd0cdeab3d2189f6382680356922
Author: Henri Verbeet <hverbeet at codeweavers.com>
Date: Mon Sep 28 10:04:59 2009 +0200
wined3d: Properly keep texture references in the stateblock.
---
dlls/wined3d/device.c | 4 ++++
dlls/wined3d/stateblock.c | 29 ++++++++++++++++-------------
2 files changed, 20 insertions(+), 13 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 70656b7..42d78ac 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -4460,6 +4460,10 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetTexture(IWineD3DDevice *iface, DWORD
/* Handle recording of state blocks */
if (This->isRecordingState) {
TRACE("Recording... not performing anything\n");
+
+ if (pTexture) IWineD3DBaseTexture_AddRef(pTexture);
+ if (oldTexture) IWineD3DBaseTexture_Release(oldTexture);
+
return WINED3D_OK;
}
diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c
index feb9808..0e097aa 100644
--- a/dlls/wined3d/stateblock.c
+++ b/dlls/wined3d/stateblock.c
@@ -5,6 +5,7 @@
* Copyright 2004 Jason Edmeades
* Copyright 2005 Oliver Stieber
* Copyright 2007 Stefan Dösinger for CodeWeavers
+ * Copyright 2009 Henri Verbeet for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -278,17 +279,9 @@ static ULONG WINAPI IWineD3DStateBlockImpl_Release(IWineD3DStateBlock *iface) {
if (!refCount) {
int counter;
- /* type 0 represents the primary stateblock, so free all the resources */
- if (This->blockType == WINED3DSBT_INIT) {
- /* NOTE: according to MSDN: The application is responsible for making sure the texture references are cleared down */
- for (counter = 0; counter < MAX_COMBINED_SAMPLERS; counter++) {
- if (This->textures[counter]) {
- /* release our 'internal' hold on the texture */
- if(0 != IWineD3DBaseTexture_Release(This->textures[counter])) {
- TRACE("Texture still referenced by stateblock, applications has leaked Stage = %u Texture = %p\n", counter, This->textures[counter]);
- }
- }
- }
+ for (counter = 0; counter < MAX_COMBINED_SAMPLERS; counter++)
+ {
+ if (This->textures[counter]) IWineD3DBaseTexture_Release(This->textures[counter]);
}
for (counter = 0; counter < MAX_STREAMS; counter++) {
@@ -605,13 +598,14 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface)
}
/* Samplers */
- /* TODO: move over to using memcpy */
map = This->changed.textures;
for (i = 0; map; map >>= 1, ++i)
{
if (!(map & 1)) continue;
TRACE("Updating texture %u to %p (was %p)\n", i, targetStateBlock->textures[i], This->textures[i]);
+ if (targetStateBlock->textures[i]) IWineD3DBaseTexture_AddRef(targetStateBlock->textures[i]);
+ if (This->textures[i]) IWineD3DBaseTexture_Release(This->textures[i]);
This->textures[i] = targetStateBlock->textures[i];
}
@@ -650,11 +644,20 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface)
memcpy(This->pixelShaderConstantI, targetStateBlock->pixelShaderConstantI, sizeof(This->pixelShaderConstantF));
memcpy(This->pixelShaderConstantF, targetStateBlock->pixelShaderConstantF, sizeof(float) * GL_LIMITS(pshader_constantsF) * 4);
memcpy(This->renderState, targetStateBlock->renderState, sizeof(This->renderState));
- memcpy(This->textures, targetStateBlock->textures, sizeof(This->textures));
memcpy(This->textureState, targetStateBlock->textureState, sizeof(This->textureState));
memcpy(This->samplerState, targetStateBlock->samplerState, sizeof(This->samplerState));
This->scissorRect = targetStateBlock->scissorRect;
+ for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i)
+ {
+ if (targetStateBlock->textures[i] != This->textures[i])
+ {
+ if (targetStateBlock->textures[i]) IWineD3DBaseTexture_AddRef(targetStateBlock->textures[i]);
+ if (This->textures[i]) IWineD3DBaseTexture_Release(This->textures[i]);
+ This->textures[i] = targetStateBlock->textures[i];
+ }
+ }
+
if(targetStateBlock->pIndexData != This->pIndexData ||
targetStateBlock->IndexFmt != This->IndexFmt) {
if (targetStateBlock->pIndexData) IWineD3DBuffer_AddRef(targetStateBlock->pIndexData);
More information about the wine-cvs
mailing list