Module: wine Branch: master Commit: d170aabe2087c969dd7f2711c10810bf4895481b URL: http://source.winehq.org/git/wine.git/?a=commit;h=d170aabe2087c969dd7f2711c1...
Author: Stefan Dösinger stefan@codeweavers.com Date: Sun Aug 19 20:40:44 2007 +0200
wined3d: Non-primary stateblocks also hold an internal reference to buffers.
---
dlls/wined3d/device.c | 21 +++++++++++++++++++++ dlls/wined3d/stateblock.c | 32 ++++++++++++++++++++++++-------- 2 files changed, 45 insertions(+), 8 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 2b2dac5..6b53729 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -514,6 +514,12 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface, } }
+ for(i = 0; i < MAX_STREAMS; i++) { + if(object->streamSource[i]) { + IWineD3DVertexBuffer_AddRef(object->streamSource[i]); + } + } + } else if (Type == WINED3DSBT_PIXELSTATE) {
TRACE("PIXELSTATE => Pretend all pixel shates have changed\n"); @@ -560,6 +566,13 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface, } }
+ /* Pixel state blocks do not contain vertex buffers. Set them to NULL to avoid wrong refcounting + * on them. This makes releasing the buffer easier + */ + for(i = 0; i < MAX_STREAMS; i++) { + object->streamSource[i] = NULL; + } + } else if (Type == WINED3DSBT_VERTEXSTATE) {
TRACE("VERTEXSTATE => Pretend all vertex shates have changed\n"); @@ -613,6 +626,12 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface, light->enabledChanged = TRUE; } } + + for(i = 0; i < MAX_STREAMS; i++) { + if(object->streamSource[i]) { + IWineD3DVertexBuffer_AddRef(object->streamSource[i]); + } + } } else { FIXME("Unrecognized state block type %d\n", Type); } @@ -2237,6 +2256,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetStreamSource(IWineD3DDevice *iface, /* Handle recording of state blocks */ if (This->isRecordingState) { TRACE("Recording... not performing anything\n"); + if(pStreamData) IWineD3DVertexBuffer_AddRef(pStreamData); + if(oldSrc) IWineD3DVertexBuffer_Release(oldSrc); return WINED3D_OK; }
diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index dfe62c9..0362053 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -262,15 +262,15 @@ static ULONG WINAPI IWineD3DStateBlockImpl_Release(IWineD3DStateBlock *iface) { } } } - for (counter = 0; counter < MAX_STREAMS; counter++) { - if(This->streamSource[counter]) { - if(0 != IWineD3DVertexBuffer_Release(This->streamSource[counter])) { - TRACE("Vertex buffer still referenced by stateblock, applications has leaked Stream %u, buffer %p\n", counter, This->streamSource[counter]); - } - } - } if(This->pIndexData) IWineD3DIndexBuffer_Release(This->pIndexData); + }
+ for (counter = 0; counter < MAX_STREAMS; counter++) { + if(This->streamSource[counter]) { + if(0 != IWineD3DVertexBuffer_Release(This->streamSource[counter])) { + TRACE("Vertex buffer still referenced by stateblock, applications has leaked Stream %u, buffer %p\n", counter, This->streamSource[counter]); + } + } }
for(counter = 0; counter < LIGHTMAP_SIZE; counter++) { @@ -532,6 +532,8 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface) TRACE("Updating stream source %d to %p, stride to %d\n", i, targetStateBlock->streamSource[i], targetStateBlock->streamStride[i]); This->streamStride[i] = targetStateBlock->streamStride[i]; + if(targetStateBlock->streamSource[i]) IWineD3DVertexBuffer_AddRef(targetStateBlock->streamSource[i]); + if(This->streamSource[i]) IWineD3DVertexBuffer_Release(This->streamSource[i]); This->streamSource[i] = targetStateBlock->streamSource[i]; }
@@ -600,7 +602,6 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface) memcpy(This->vertexShaderConstantF, targetStateBlock->vertexShaderConstantF, sizeof(float) * GL_LIMITS(vshader_constantsF) * 4); memcpy(This->streamStride, targetStateBlock->streamStride, sizeof(This->streamStride)); memcpy(This->streamOffset, targetStateBlock->streamOffset, sizeof(This->streamOffset)); - memcpy(This->streamSource, targetStateBlock->streamSource, sizeof(This->streamSource)); memcpy(This->streamFreq, targetStateBlock->streamFreq, sizeof(This->streamFreq)); memcpy(This->streamFlags, targetStateBlock->streamFlags, sizeof(This->streamFlags)); This->pIndexData = targetStateBlock->pIndexData; @@ -621,6 +622,14 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface) 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_STREAMS; i++) { + if(targetStateBlock->streamSource[i] != This->streamSource[i]) { + if(targetStateBlock->streamSource[i]) IWineD3DVertexBuffer_AddRef(targetStateBlock->streamSource[i]); + if(This->streamSource[i]) IWineD3DVertexBuffer_Release(This->streamSource[i]); + This->streamSource[i] = targetStateBlock->streamSource[i]; + } + } } else if(This->blockType == WINED3DSBT_VERTEXSTATE) { This->vertexShader = targetStateBlock->vertexShader; memcpy(This->vertexShaderConstantB, targetStateBlock->vertexShaderConstantB, sizeof(This->vertexShaderConstantI)); @@ -640,6 +649,13 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface) This->textureState[j][SavedVertexStates_R[i]] = targetStateBlock->textureState[j][SavedVertexStates_R[i]]; } } + for(i = 0; i < MAX_STREAMS; i++) { + if(targetStateBlock->streamSource[i] != This->streamSource[i]) { + if(targetStateBlock->streamSource[i]) IWineD3DVertexBuffer_AddRef(targetStateBlock->streamSource[i]); + if(This->streamSource[i]) IWineD3DVertexBuffer_Release(This->streamSource[i]); + This->streamSource[i] = targetStateBlock->streamSource[i]; + } + } } else if(This->blockType == WINED3DSBT_PIXELSTATE) { This->pixelShader = targetStateBlock->pixelShader; memcpy(This->pixelShaderConstantB, targetStateBlock->pixelShaderConstantB, sizeof(This->pixelShaderConstantI));