Skip to content

Commit

Permalink
overlay/d3d9: pass through IDirect3DDevice9 AddRef/Release methods to…
Browse files Browse the repository at this point in the history
… originals on Windows 8.

We were getting unbalanced AddRef/Releases on Direct3D9 apps running on Windows 8 that ran
fine on Windows 7.  Windows 8 seems to be doing somthing funky with the internal ref count
of IDirect3DDevice9.

For now, piggyback on the orignal ref count methods to be able to determine when to release
ourselves. And cross our fingers that we won't be getting useless ref counts from some other
overlay.

This is a band-aid solution until we find something better.
  • Loading branch information
mkrautz committed Nov 16, 2012
1 parent e661969 commit 46d659d
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 4 deletions.
78 changes: 74 additions & 4 deletions overlay/d3d9.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,27 @@ static ULONG __stdcall myAddRef(IDirect3DDevice9 *idd) {
return res;
}

static ULONG __stdcall myWin8AddRef(IDirect3DDevice9 *idd) {
Mutex m;

DevState *ds = devMap[idd];
if (ds && ds->dwMyThread == GetCurrentThreadId()) {
ds->myRefCount++;
return ds->refCount;
}

AddRefType oAddRef = (AddRefType) hhAddRef.call;
hhAddRef.restore();
LONG res = oAddRef(idd);
if (ds)
ds->refCount = res;
hhAddRef.inject();

ods("D3D9: Chaining AddRef (Win8): %d", res);

return res;
}

typedef ULONG(__stdcall *ReleaseType)(IDirect3DDevice9 *);
static ULONG __stdcall myRelease(IDirect3DDevice9 *idd) {
Mutex m;
Expand Down Expand Up @@ -484,6 +505,45 @@ static ULONG __stdcall myRelease(IDirect3DDevice9 *idd) {
return res;
}

static ULONG __stdcall myWin8Release(IDirect3DDevice9 *idd) {
Mutex m;

DevState *ds = devMap[idd];
if (ds) {
if (ds->dwMyThread == GetCurrentThreadId()) {
ds->myRefCount--;
return ds->refCount;
}
if (ds->refCount == 1) {
ds->disconnect();

ods("D3D9: Final release. MyRefs = %d, Tot = %d", ds->myRefCount, ds->refCount);
DWORD dwOldThread = ds->dwMyThread;
if (dwOldThread)
ods("finalRelease from other thread");
ds->dwMyThread = GetCurrentThreadId();
ds->releaseAll();
ds->dwMyThread = dwOldThread;
ods("D3D9: Final release, MyRefs = %d Tot = %d", ds->myRefCount, ds->refCount);

devMap.erase(idd);
delete ds;
ds = NULL;
}
}

ReleaseType oRelease = (ReleaseType) hhRelease.call;
hhRelease.restore();
LONG res = oRelease(idd);
if (ds)
ds->refCount = res;
hhRelease.inject();

ods("D3D9: Chaining Release (Win8): %d", res);

return res;
}

typedef HRESULT(__stdcall *CreateDeviceType)(IDirect3D9 *, UINT, D3DDEVTYPE, HWND, DWORD, D3DPRESENT_PARAMETERS *, IDirect3DDevice9 **);
static HRESULT __stdcall myCreateDevice(IDirect3D9 * id3d, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS *pPresentationParameters, IDirect3DDevice9 **ppReturnedDeviceInterface) {
ods("D3D9: Chaining CreateDevice");
Expand Down Expand Up @@ -533,8 +593,13 @@ static HRESULT __stdcall myCreateDevice(IDirect3D9 * id3d, UINT Adapter, D3DDEVT

devMap[idd] = ds;

hhAddRef.setupInterface(idd, 1, reinterpret_cast<voidFunc>(myAddRef));
hhRelease.setupInterface(idd, 2, reinterpret_cast<voidFunc>(myRelease));
if (bIsWin8) {
hhAddRef.setupInterface(idd, 1, reinterpret_cast<voidFunc>(myWin8AddRef));
hhRelease.setupInterface(idd, 2, reinterpret_cast<voidFunc>(myWin8Release));
} else {
hhAddRef.setupInterface(idd, 1, reinterpret_cast<voidFunc>(myAddRef));
hhRelease.setupInterface(idd, 2, reinterpret_cast<voidFunc>(myRelease));
}
hhReset.setupInterface(idd, 16, reinterpret_cast<voidFunc>(myReset));
hhPresent.setupInterface(idd, 17, reinterpret_cast<voidFunc>(myPresent));

Expand Down Expand Up @@ -577,8 +642,13 @@ static HRESULT __stdcall myCreateDeviceEx(IDirect3D9Ex * id3d, UINT Adapter, D3D

devMap[idd] = ds;

hhAddRef.setupInterface(idd, 1, reinterpret_cast<voidFunc>(myAddRef));
hhRelease.setupInterface(idd, 2, reinterpret_cast<voidFunc>(myRelease));
if (bIsWin8) {
hhAddRef.setupInterface(idd, 1, reinterpret_cast<voidFunc>(myWin8AddRef));
hhRelease.setupInterface(idd, 2, reinterpret_cast<voidFunc>(myWin8Release));
} else {
hhAddRef.setupInterface(idd, 1, reinterpret_cast<voidFunc>(myAddRef));
hhRelease.setupInterface(idd, 2, reinterpret_cast<voidFunc>(myRelease));
}
hhReset.setupInterface(idd, 16, reinterpret_cast<voidFunc>(myReset));
hhPresent.setupInterface(idd, 17, reinterpret_cast<voidFunc>(myPresent));

Expand Down
10 changes: 10 additions & 0 deletions overlay/lib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ static HANDLE hHookMutex = NULL;
static HHOOK hhookWnd = 0;

HMODULE hSelf = NULL;
BOOL bIsWin8 = FALSE;

static BOOL bMumble = FALSE;
static BOOL bDebug = FALSE;
static BOOL bBlackListed = FALSE;
Expand Down Expand Up @@ -601,6 +603,14 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD fdwReason, LPVOID) {
}
ods("Lib: ProcAttach: %s", procname);

OSVERSIONINFOEX ovi;
memset(&ovi, 0, sizeof(ovi));
ovi.dwOSVersionInfoSize = sizeof(ovi);
GetVersionEx(reinterpret_cast<OSVERSIONINFO *>(&ovi));
bIsWin8 = (ovi.dwMajorVersion >= 7) || ((ovi.dwMajorVersion == 6) &&(ovi.dwBuildNumber >= 9200));

ods("Lib: bIsWin8: %i", bIsWin8);

hHookMutex = CreateMutex(NULL, false, "MumbleHookMutex");
if (hHookMutex == NULL) {
ods("Lib: CreateMutex failed");
Expand Down
1 change: 1 addition & 0 deletions overlay/lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ extern void checkOpenGLHook();
extern Direct3D9Data *d3dd;
extern DXGIData *dxgi;
extern HMODULE hSelf;
extern BOOL bIsWin8;
extern unsigned int uiAudioCount;
extern bool bVideoHooked;

Expand Down

0 comments on commit 46d659d

Please sign in to comment.