wined3d: Dirtify the shader and declaration states if the bound interface is destroyed.
This commit is contained in:
parent
21e6beed5c
commit
0d88a38238
|
@ -73,6 +73,18 @@ static ULONG WINAPI IWineD3DPixelShaderImpl_Release(IWineD3DPixelShader *iface)
|
||||||
TRACE("(%p) : Releasing from %d\n", This, This->ref);
|
TRACE("(%p) : Releasing from %d\n", This, This->ref);
|
||||||
ref = InterlockedDecrement(&This->ref);
|
ref = InterlockedDecrement(&This->ref);
|
||||||
if (ref == 0) {
|
if (ref == 0) {
|
||||||
|
/* SetPixelShader does not AddRef. If the bound pixel shader is destroyed, the pointer in the stateblock remains
|
||||||
|
* unchanged. Drawing again will most likely crash, even on windows. A problem can occur if the application creates
|
||||||
|
* a new pixel shader which resides at the same address. Then SetPixelShader will think it is a NOP change, and won't
|
||||||
|
* dirtify the state.
|
||||||
|
*
|
||||||
|
* Do NOT call GetPixelShader here. This will addRef and cause a recursion. And do NOT set the pixel shader to NULL,
|
||||||
|
* Windows does not do that(Although no test exists since they'd crash randomly)
|
||||||
|
*/
|
||||||
|
if(iface == ((IWineD3DDeviceImpl *) This->baseShader.device)->stateBlock->pixelShader) {
|
||||||
|
IWineD3DDeviceImpl_MarkStateDirty((IWineD3DDeviceImpl *) This->baseShader.device, STATE_PIXELSHADER);
|
||||||
|
}
|
||||||
|
|
||||||
if (This->baseShader.shader_mode == SHADER_GLSL && This->baseShader.prgId != 0) {
|
if (This->baseShader.shader_mode == SHADER_GLSL && This->baseShader.prgId != 0) {
|
||||||
struct list *linked_programs = &This->baseShader.linked_programs;
|
struct list *linked_programs = &This->baseShader.linked_programs;
|
||||||
|
|
||||||
|
|
|
@ -98,6 +98,11 @@ static ULONG WINAPI IWineD3DVertexDeclarationImpl_Release(IWineD3DVertexDeclarat
|
||||||
TRACE("(%p) : Releasing from %d\n", This, This->ref);
|
TRACE("(%p) : Releasing from %d\n", This, This->ref);
|
||||||
ref = InterlockedDecrement(&This->ref);
|
ref = InterlockedDecrement(&This->ref);
|
||||||
if (ref == 0) {
|
if (ref == 0) {
|
||||||
|
if(iface == This->wineD3DDevice->stateBlock->vertexDecl) {
|
||||||
|
/* See comment in PixelShader::Release */
|
||||||
|
IWineD3DDeviceImpl_MarkStateDirty(This->wineD3DDevice, STATE_VDECL);
|
||||||
|
}
|
||||||
|
|
||||||
HeapFree(GetProcessHeap(), 0, This->pDeclarationWine);
|
HeapFree(GetProcessHeap(), 0, This->pDeclarationWine);
|
||||||
HeapFree(GetProcessHeap(), 0, This);
|
HeapFree(GetProcessHeap(), 0, This);
|
||||||
}
|
}
|
||||||
|
|
|
@ -464,6 +464,11 @@ static ULONG WINAPI IWineD3DVertexShaderImpl_Release(IWineD3DVertexShader *iface
|
||||||
TRACE("(%p) : Releasing from %d\n", This, This->ref);
|
TRACE("(%p) : Releasing from %d\n", This, This->ref);
|
||||||
ref = InterlockedDecrement(&This->ref);
|
ref = InterlockedDecrement(&This->ref);
|
||||||
if (ref == 0) {
|
if (ref == 0) {
|
||||||
|
if(iface == ((IWineD3DDeviceImpl *) This->baseShader.device)->stateBlock->vertexShader) {
|
||||||
|
/* See comment in PixelShader::Release */
|
||||||
|
IWineD3DDeviceImpl_MarkStateDirty((IWineD3DDeviceImpl *) This->baseShader.device, STATE_VSHADER);
|
||||||
|
}
|
||||||
|
|
||||||
if (This->baseShader.shader_mode == SHADER_GLSL && This->baseShader.prgId != 0) {
|
if (This->baseShader.shader_mode == SHADER_GLSL && This->baseShader.prgId != 0) {
|
||||||
struct list *linked_programs = &This->baseShader.linked_programs;
|
struct list *linked_programs = &This->baseShader.linked_programs;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue