mirror of
https://github.com/FunkyFr3sh/cnc-ddraw.git
synced 2025-03-15 06:04:49 +01:00
fix d3d9 multi threading
This commit is contained in:
parent
227bbc8280
commit
28c9886dbe
2
ddraw.rc
2
ddraw.rc
@ -2,7 +2,7 @@
|
||||
#define vxstr(a,b,c,d) str(a##.##b##.##c##.##d)
|
||||
#define str(s) #s
|
||||
|
||||
#define VERSION 1,2,1,1
|
||||
#define VERSION 1,2,1,2
|
||||
|
||||
1 VERSIONINFO
|
||||
FILEVERSION VERSION
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
#define WM_AUTORENDERER WM_USER+111
|
||||
#define WM_WINEFULLSCREEN WM_USER+112
|
||||
#define WM_D3D9FULLSCREEN WM_USER+113
|
||||
#define WM_D3D9DEVICELOST WM_USER+113
|
||||
|
||||
extern BOOL ShowDriverWarning;
|
||||
|
||||
@ -99,7 +99,6 @@ typedef struct IDirectDrawImpl
|
||||
char shader[MAX_PATH];
|
||||
BOOL wine;
|
||||
int sleep;
|
||||
LONG displayModeChanged;
|
||||
LONG minimized;
|
||||
|
||||
} IDirectDrawImpl;
|
||||
|
72
src/main.c
72
src/main.c
@ -38,9 +38,13 @@ void mouse_unlock();
|
||||
BOOL screenshot(struct IDirectDrawSurfaceImpl *);
|
||||
#endif
|
||||
|
||||
extern BOOL D3D9_Enabled;
|
||||
extern HMODULE D3D9_hModule;
|
||||
|
||||
BOOL CreateDirect3D9();
|
||||
BOOL ResetDirect3D9();
|
||||
BOOL ReleaseDirect3D9();
|
||||
BOOL DeviceLostDirect3D9();
|
||||
|
||||
IDirectDrawImpl *ddraw = NULL;
|
||||
|
||||
DWORD WINAPI render_main(void);
|
||||
@ -51,6 +55,7 @@ DWORD WINAPI render_d3d9_main(void);
|
||||
int WindowPosX;
|
||||
int WindowPosY;
|
||||
char SettingsIniPath[MAX_PATH];
|
||||
BOOL Direct3D9Active;
|
||||
|
||||
//BOOL WINAPI DllMainCRTStartup(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved)
|
||||
BOOL WINAPI DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
|
||||
@ -226,7 +231,7 @@ HRESULT __stdcall ddraw_RestoreDisplayMode(IDirectDrawImpl *This)
|
||||
}
|
||||
|
||||
/* only stop drawing in GL mode when minimized */
|
||||
if (This->renderer == render_main)
|
||||
if (This->renderer != render_soft_main)
|
||||
{
|
||||
EnterCriticalSection(&This->cs);
|
||||
This->render.run = FALSE;
|
||||
@ -235,19 +240,31 @@ HRESULT __stdcall ddraw_RestoreDisplayMode(IDirectDrawImpl *This)
|
||||
|
||||
WaitForSingleObject(This->render.thread, INFINITE);
|
||||
This->render.thread = NULL;
|
||||
|
||||
if (This->renderer == render_d3d9_main)
|
||||
ReleaseDirect3D9();
|
||||
}
|
||||
|
||||
if(!ddraw->windowed)
|
||||
{
|
||||
if (!D3D9_Enabled)
|
||||
if (!Direct3D9Active)
|
||||
ChangeDisplaySettings(&This->mode, 0);
|
||||
|
||||
InterlockedExchange(&ddraw->minimized, TRUE);
|
||||
}
|
||||
|
||||
return DD_OK;
|
||||
}
|
||||
|
||||
void InitDirect3D9()
|
||||
{
|
||||
Direct3D9Active = CreateDirect3D9();
|
||||
if (!Direct3D9Active)
|
||||
{
|
||||
ReleaseDirect3D9();
|
||||
ShowDriverWarning = TRUE;
|
||||
ddraw->renderer = render_soft_main;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT __stdcall ddraw_SetDisplayMode(IDirectDrawImpl *This, DWORD width, DWORD height, DWORD bpp)
|
||||
{
|
||||
printf("DirectDraw::SetDisplayMode(This=%p, width=%d, height=%d, bpp=%d)\n", This, (unsigned int)width, (unsigned int)height, (unsigned int)bpp);
|
||||
@ -448,14 +465,23 @@ HRESULT __stdcall ddraw_SetDisplayMode(IDirectDrawImpl *This, DWORD width, DWORD
|
||||
SetWindowPos(ddraw->hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
|
||||
MoveWindow(This->hWnd, dst.left, dst.top, (dst.right - dst.left), (dst.bottom - dst.top), TRUE);
|
||||
This->windowed_init = TRUE;
|
||||
|
||||
if (This->renderer == render_d3d9_main)
|
||||
InitDirect3D9();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!This->devmode && ChangeDisplaySettings(&This->render.mode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
|
||||
if (This->renderer == render_d3d9_main)
|
||||
InitDirect3D9();
|
||||
|
||||
if(!This->devmode)
|
||||
{
|
||||
This->render.run = FALSE;
|
||||
return DDERR_INVALIDMODE;
|
||||
if (!Direct3D9Active && ChangeDisplaySettings(&This->render.mode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
|
||||
{
|
||||
This->render.run = FALSE;
|
||||
return DDERR_INVALIDMODE;
|
||||
}
|
||||
}
|
||||
|
||||
if (ddraw->wine)
|
||||
@ -522,7 +548,7 @@ void ToggleFullscreen()
|
||||
if (ddraw->windowed)
|
||||
{
|
||||
mouse_unlock();
|
||||
if(ChangeDisplaySettings(&ddraw->render.mode, CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL)
|
||||
if(ChangeDisplaySettings(&ddraw->render.mode, CDS_TEST) == DISP_CHANGE_SUCCESSFUL)
|
||||
{
|
||||
ddraw->windowed = FALSE;
|
||||
|
||||
@ -530,15 +556,17 @@ void ToggleFullscreen()
|
||||
SetWindowPos(ddraw->hWnd, HWND_TOPMOST, 0, 0, ddraw->render.width, ddraw->render.height, SWP_SHOWWINDOW);
|
||||
LastSetWindowPosTick = timeGetTime();
|
||||
|
||||
InterlockedExchange(&ddraw->displayModeChanged, TRUE);
|
||||
if (Direct3D9Active)
|
||||
ResetDirect3D9();
|
||||
else
|
||||
ChangeDisplaySettings(&ddraw->render.mode, CDS_FULLSCREEN);
|
||||
}
|
||||
mouse_lock();
|
||||
}
|
||||
else
|
||||
{
|
||||
mouse_unlock();
|
||||
InterlockedExchange(&ddraw->displayModeChanged, TRUE);
|
||||
if(D3D9_Enabled || ChangeDisplaySettings(&ddraw->mode, 0) == DISP_CHANGE_SUCCESSFUL)
|
||||
if(Direct3D9Active || ChangeDisplaySettings(&ddraw->mode, 0) == DISP_CHANGE_SUCCESSFUL)
|
||||
{
|
||||
if (!ddraw->border)
|
||||
{
|
||||
@ -559,8 +587,11 @@ void ToggleFullscreen()
|
||||
|
||||
ddraw->windowed = TRUE;
|
||||
ddraw->windowed_init = TRUE;
|
||||
InterlockedExchange(&ddraw->displayModeChanged, TRUE);
|
||||
|
||||
if (Direct3D9Active)
|
||||
ResetDirect3D9();
|
||||
}
|
||||
mouse_lock();
|
||||
}
|
||||
}
|
||||
|
||||
@ -570,13 +601,11 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
|
||||
switch(uMsg)
|
||||
{
|
||||
case WM_D3D9FULLSCREEN:
|
||||
case WM_D3D9DEVICELOST:
|
||||
{
|
||||
if (!ddraw->windowed)
|
||||
if (Direct3D9Active && DeviceLostDirect3D9())
|
||||
{
|
||||
if (GetSystemMetrics(SM_CYSCREEN) == ddraw->render.mode.dmPelsHeight &&
|
||||
GetSystemMetrics(SM_CXSCREEN) == ddraw->render.mode.dmPelsWidth &&
|
||||
GetForegroundWindow() == ddraw->hWnd)
|
||||
if (!ddraw->windowed)
|
||||
mouse_lock();
|
||||
}
|
||||
return 0;
|
||||
@ -639,7 +668,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (!ddraw->windowed)
|
||||
{
|
||||
if (!D3D9_Enabled)
|
||||
if (!Direct3D9Active)
|
||||
{
|
||||
ChangeDisplaySettings(&ddraw->render.mode, CDS_FULLSCREEN);
|
||||
|
||||
@ -662,7 +691,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
/* minimize our window on defocus when in fullscreen */
|
||||
if (!ddraw->windowed)
|
||||
{
|
||||
if (!D3D9_Enabled)
|
||||
if (!Direct3D9Active)
|
||||
{
|
||||
ShowWindow(ddraw->hWnd, SW_MINIMIZE);
|
||||
ChangeDisplaySettings(&ddraw->mode, 0);
|
||||
@ -944,6 +973,9 @@ ULONG __stdcall ddraw_Release(IDirectDrawImpl *This)
|
||||
|
||||
WaitForSingleObject(This->render.thread, INFINITE);
|
||||
This->render.thread = NULL;
|
||||
|
||||
if (This->renderer == render_d3d9_main)
|
||||
ReleaseDirect3D9();
|
||||
}
|
||||
|
||||
if(This->render.hDC)
|
||||
|
@ -7,7 +7,6 @@
|
||||
|
||||
typedef struct CUSTOMVERTEX { float x, y, z, rhw, u, v; } CUSTOMVERTEX;
|
||||
|
||||
BOOL D3D9_Enabled;
|
||||
HMODULE D3D9_hModule;
|
||||
|
||||
static D3DPRESENT_PARAMETERS D3dpp;
|
||||
@ -23,14 +22,16 @@ static int MaxFPS;
|
||||
static DWORD FrameLength;
|
||||
static int BitsPerPixel;
|
||||
|
||||
static BOOL CreateDirect3D();
|
||||
static BOOL CreateResources();
|
||||
static BOOL SetStates();
|
||||
static BOOL UpdateVertices(BOOL inCutscene);
|
||||
static BOOL Reset();
|
||||
static void SetMaxFPS();
|
||||
static void Render();
|
||||
static BOOL ReleaseDirect3D();
|
||||
|
||||
BOOL CreateDirect3D9();
|
||||
BOOL ResetDirect3D9();
|
||||
BOOL ReleaseDirect3D9();
|
||||
BOOL DeviceLostDirect3D9();
|
||||
|
||||
BOOL detect_cutscene();
|
||||
DWORD WINAPI render_soft_main(void);
|
||||
@ -39,29 +40,15 @@ DWORD WINAPI render_d3d9_main(void)
|
||||
{
|
||||
Sleep(500);
|
||||
|
||||
D3D9_Enabled = CreateDirect3D();
|
||||
if (D3D9_Enabled)
|
||||
{
|
||||
SetMaxFPS();
|
||||
|
||||
Render();
|
||||
}
|
||||
|
||||
ReleaseDirect3D();
|
||||
|
||||
if (!D3D9_Enabled)
|
||||
{
|
||||
ShowDriverWarning = TRUE;
|
||||
ddraw->renderer = render_soft_main;
|
||||
render_soft_main();
|
||||
}
|
||||
SetMaxFPS();
|
||||
Render();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static BOOL CreateDirect3D()
|
||||
BOOL CreateDirect3D9()
|
||||
{
|
||||
if (!ReleaseDirect3D())
|
||||
if (!ReleaseDirect3D9())
|
||||
return FALSE;
|
||||
|
||||
if (!D3D9_hModule)
|
||||
@ -102,7 +89,7 @@ static BOOL CreateDirect3D()
|
||||
D3DADAPTER_DEFAULT,
|
||||
D3DDEVTYPE_HAL,
|
||||
ddraw->hWnd,
|
||||
D3DCREATE_MULTITHREADED | D3DCREATE_NOWINDOWCHANGES | behaviorFlags[i],
|
||||
D3DCREATE_MULTITHREADED | behaviorFlags[i], //D3DCREATE_NOWINDOWCHANGES |
|
||||
&D3dpp,
|
||||
&D3dDev)))
|
||||
return D3dDev && CreateResources() && SetStates();
|
||||
@ -203,8 +190,17 @@ static BOOL UpdateVertices(BOOL inCutscene)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL Reset()
|
||||
BOOL DeviceLostDirect3D9()
|
||||
{
|
||||
if (D3dDev && D3dDev->lpVtbl->TestCooperativeLevel(D3dDev) == D3DERR_DEVICENOTRESET)
|
||||
return ResetDirect3D9();
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL ResetDirect3D9()
|
||||
{
|
||||
D3dpp.Windowed = ddraw->windowed;
|
||||
D3dpp.BackBufferWidth = D3dpp.Windowed ? 0 : ddraw->render.width;
|
||||
D3dpp.BackBufferHeight = D3dpp.Windowed ? 0 : ddraw->render.height;
|
||||
D3dpp.BackBufferFormat = BitsPerPixel == 16 ? D3DFMT_R5G6B5 : D3DFMT_X8R8G8B8;
|
||||
@ -236,25 +232,12 @@ static void Render()
|
||||
{
|
||||
DWORD tickStart = 0;
|
||||
DWORD tickEnd = 0;
|
||||
BOOL active = TRUE;
|
||||
BOOL released = TRUE;
|
||||
LONG minimized = TRUE;
|
||||
|
||||
while (ddraw->render.run && WaitForSingleObject(ddraw->render.sem, 200) != WAIT_FAILED)
|
||||
{
|
||||
if (!active)
|
||||
if (InterlockedExchangeAdd(&ddraw->minimized, 0))
|
||||
{
|
||||
Sleep(500);
|
||||
|
||||
if (!released && (released = ReleaseDirect3D()) && minimized)
|
||||
ShowWindow(ddraw->hWnd, SW_MINIMIZE);
|
||||
|
||||
if (!InterlockedExchangeAdd(&ddraw->minimized, 0) && CreateDirect3D())
|
||||
{
|
||||
active = TRUE;
|
||||
PostMessage(ddraw->hWnd, WM_D3D9FULLSCREEN, 0, 0);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -322,29 +305,14 @@ static void Render()
|
||||
|
||||
LeaveCriticalSection(&ddraw->cs);
|
||||
|
||||
HRESULT hr = D3dDev->lpVtbl->TestCooperativeLevel(D3dDev);
|
||||
LONG modeChanged = InterlockedExchange(&ddraw->displayModeChanged, FALSE);
|
||||
minimized = InterlockedExchangeAdd(&ddraw->minimized, 0);
|
||||
D3dDev->lpVtbl->BeginScene(D3dDev);
|
||||
D3dDev->lpVtbl->DrawPrimitive(D3dDev, D3DPT_TRIANGLESTRIP, 0, 2);
|
||||
D3dDev->lpVtbl->EndScene(D3dDev);
|
||||
|
||||
if (minimized || modeChanged)
|
||||
if (D3dDev->lpVtbl->Present(D3dDev, NULL, NULL, NULL, NULL) == D3DERR_DEVICELOST)
|
||||
{
|
||||
active = FALSE;
|
||||
released = ReleaseDirect3D();
|
||||
|
||||
if (released && minimized)
|
||||
ShowWindow(ddraw->hWnd, SW_MINIMIZE);
|
||||
}
|
||||
else if (hr == D3DERR_DEVICENOTRESET && D3dpp.Windowed)
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
else if (SUCCEEDED(hr))
|
||||
{
|
||||
D3dDev->lpVtbl->BeginScene(D3dDev);
|
||||
D3dDev->lpVtbl->DrawPrimitive(D3dDev, D3DPT_TRIANGLESTRIP, 0, 2);
|
||||
D3dDev->lpVtbl->EndScene(D3dDev);
|
||||
|
||||
D3dDev->lpVtbl->Present(D3dDev, NULL, NULL, NULL, NULL);
|
||||
DWORD_PTR dwResult;
|
||||
SendMessageTimeout(ddraw->hWnd, WM_D3D9DEVICELOST, 0, 0, 0, 1000, &dwResult);
|
||||
}
|
||||
|
||||
#if _DEBUG
|
||||
@ -361,7 +329,7 @@ static void Render()
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL ReleaseDirect3D()
|
||||
BOOL ReleaseDirect3D9()
|
||||
{
|
||||
if (VertexBuf)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user