Lots more work on making the frame aui stuff functional.
[dolphin.git] / Source / Plugins / Plugin_VideoDX11 / Src / main.cpp
blob864f0b977c31b105e5e20de6b32eb458d7d6bc69
1 // Copyright (C) 2003 Dolphin Project.
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, version 2.0.
7 // This program is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 // GNU General Public License 2.0 for more details.
12 // A copy of the GPL 2.0 should have been included with the program.
13 // If not, see http://www.gnu.org/licenses/
15 // Official SVN repository and contact information can be found at
16 // http://code.google.com/p/dolphin-emu/
18 #include <tchar.h>
19 #include <windows.h>
20 #include <d3dx11.h>
22 #include <wx/wx.h>
23 #include <wx/notebook.h>
25 #include "Common.h"
26 #include "Atomic.h"
27 #include "Thread.h"
28 #include "LogManager.h"
30 #include "VideoConfig.h"
31 #include "Fifo.h"
32 #include "OpcodeDecoding.h"
33 #include "BPStructs.h"
34 #include "VertexLoaderManager.h"
35 #include "VertexShaderManager.h"
36 #include "PixelShaderManager.h"
37 #include "CommandProcessor.h"
38 #include "PixelEngine.h"
39 #include "OnScreenDisplay.h"
40 #include "VideoState.h"
41 #include "XFBConvert.h"
42 #include "Render.h"
44 #include "main.h"
45 #include "resource.h"
46 #include "DlgSettings.h"
47 #include "TextureCache.h"
48 #include "VertexManager.h"
49 #include "VertexShaderCache.h"
50 #include "PixelShaderCache.h"
51 #include "D3DTexture.h"
52 #include "D3DUtil.h"
53 #include "W32Util/Misc.h"
54 #include "EmuWindow.h"
55 #include "FBManager.h"
58 #if defined(DEBUGFAST)
59 #define DLL_PLUGIN_NAME "Dolphin Direct3D 11 (DebugFast)"
60 #elif defined(_DEBUG)
61 #define DLL_PLUGIN_NAME "Dolphin Direct3D 11 (Debug)"
62 #else
63 #define DLL_PLUGIN_NAME "Dolphin Direct3D 11"
64 #endif
67 HINSTANCE g_hInstance = NULL;
68 SVideoInitialize g_VideoInitialize;
69 PLUGIN_GLOBALS* globals = NULL;
70 static bool s_PluginInitialized = false;
72 volatile u32 s_swapRequested = FALSE;
73 static u32 s_efbAccessRequested = FALSE;
74 static volatile u32 s_FifoShuttingDown = FALSE;
76 static volatile struct
78 u32 xfbAddr;
79 FieldType field;
80 u32 fbWidth;
81 u32 fbHeight;
82 } s_beginFieldArgs;
84 static volatile EFBAccessType s_AccessEFBType;
86 bool HandleDisplayList(u32 address, u32 size)
88 return false;
91 bool IsD3D()
93 return true;
96 // This is used for the functions right below here which use wxwidgets
97 #if defined(HAVE_WX) && HAVE_WX
98 WXDLLIMPEXP_BASE void wxSetInstance(HINSTANCE hInst);
100 wxWindow* GetParentedWxWindow(HWND Parent)
102 wxSetInstance((HINSTANCE)g_hInstance);
103 wxWindow* win = new wxWindow();
104 win->SetHWND((WXHWND)Parent);
105 win->AdoptAttributesFromHWND();
106 return win;
108 #endif
110 void *DllDebugger(void *_hParent, bool Show)
112 return NULL;
115 #if defined(HAVE_WX) && HAVE_WX
116 class wxDLLApp : public wxApp
118 bool OnInit()
120 return true;
123 IMPLEMENT_APP_NO_MAIN(wxDLLApp)
124 WXDLLIMPEXP_BASE void wxSetInstance(HINSTANCE hInst);
125 #endif
127 BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved)
129 switch (dwReason)
131 case DLL_PROCESS_ATTACH:
133 #if defined(HAVE_WX) && HAVE_WX
134 wxSetInstance((HINSTANCE)hinstDLL);
135 wxInitialize();
136 #endif
138 break;
139 case DLL_PROCESS_DETACH:
140 #if defined(HAVE_WX) && HAVE_WX
141 wxUninitialize();
142 #endif
143 break;
146 g_hInstance = hinstDLL;
147 return TRUE;
150 unsigned int Callback_PeekMessages()
152 MSG msg;
153 while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
155 if (msg.message == WM_QUIT)
156 return FALSE;
157 TranslateMessage(&msg);
158 DispatchMessage(&msg);
160 return TRUE;
164 void UpdateFPSDisplay(const char* text)
166 char temp[512];
167 sprintf_s(temp, 512, "SVN R%s: DX11: %s", svn_rev_str, text);
168 SetWindowTextA(EmuWindow::GetWnd(), temp);
171 void GetDllInfo(PLUGIN_INFO* _PluginInfo)
173 _PluginInfo->Version = 0x0100;
174 _PluginInfo->Type = PLUGIN_TYPE_VIDEO;
175 sprintf_s(_PluginInfo->Name, 100, DLL_PLUGIN_NAME);
178 void SetDllGlobals(PLUGIN_GLOBALS* _pPluginGlobals)
180 globals = _pPluginGlobals;
181 LogManager::SetInstance((LogManager*)globals->logManager);
184 void DllAbout(HWND _hParent)
186 MessageBoxA(NULL, "DllAbout not implemented, how did you come here? Anyway, report this to the devs.", "Error!", MB_OK);
189 void DllConfig(HWND _hParent)
191 DlgSettings_Show(g_hInstance, _hParent);
194 void Initialize(void* init)
196 frameCount = 0;
197 SVideoInitialize* _pVideoInitialize = (SVideoInitialize*)init;
198 g_VideoInitialize = *_pVideoInitialize;
199 InitXFBConvTables();
201 g_Config.Load((std::string(File::GetUserPath(D_CONFIG_IDX)) + "gfx_dx11.ini").c_str());
202 g_Config.GameIniLoad(globals->game_ini);
203 UpdateActiveConfig();
205 g_VideoInitialize.pWindowHandle = (void*)EmuWindow::Create((HWND)g_VideoInitialize.pWindowHandle, g_hInstance, _T("Loading - Please wait."));
206 if (g_VideoInitialize.pWindowHandle == NULL)
208 ERROR_LOG(VIDEO, "An error has occurred while trying to create the window.");
209 return;
212 g_VideoInitialize.pPeekMessages = &Callback_PeekMessages;
213 g_VideoInitialize.pUpdateFPSDisplay = &UpdateFPSDisplay;
215 _pVideoInitialize->pPeekMessages = g_VideoInitialize.pPeekMessages;
216 _pVideoInitialize->pUpdateFPSDisplay = g_VideoInitialize.pUpdateFPSDisplay;
217 _pVideoInitialize->pWindowHandle = g_VideoInitialize.pWindowHandle;
219 OSD::AddMessage("Dolphin Direct3D 11 Video Plugin.", 5000);
220 s_PluginInitialized = true;
223 void Video_Prepare()
225 s_efbAccessRequested = FALSE;
226 s_FifoShuttingDown = FALSE;
227 s_swapRequested = FALSE;
229 // internal interfaces
230 Renderer::Init();
231 TextureCache::Init();
232 VertexManager::Init();
233 VertexShaderCache::Init();
234 PixelShaderCache::Init();
235 D3D::InitUtils();
237 // VideoCommon
238 BPInit();
239 Fifo_Init();
240 VertexLoaderManager::Init();
241 OpcodeDecoder_Init();
242 VertexShaderManager::Init();
243 PixelShaderManager::Init();
244 CommandProcessor::Init();
245 PixelEngine::Init();
247 // tell the host that the window is ready
248 g_VideoInitialize.pCoreMessage(WM_USER_CREATE);
251 void Shutdown()
253 s_efbAccessRequested = FALSE;
254 s_FifoShuttingDown = FALSE;
255 s_swapRequested = FALSE;
257 // VideoCommon
258 CommandProcessor::Shutdown();
259 PixelShaderManager::Shutdown();
260 VertexShaderManager::Shutdown();
261 OpcodeDecoder_Shutdown();
262 VertexLoaderManager::Shutdown();
263 Fifo_Shutdown();
265 // internal interfaces
266 D3D::ShutdownUtils();
267 PixelShaderCache::Shutdown();
268 VertexShaderCache::Shutdown();
269 VertexManager::Shutdown();
270 TextureCache::Shutdown();
271 Renderer::Shutdown();
272 EmuWindow::Close();
274 s_PluginInitialized = false;
277 void DoState(unsigned char** ptr, int mode)
279 // clear texture cache because it might have written to RAM
280 CommandProcessor::FifoCriticalEnter();
281 TextureCache::Invalidate(false);
282 CommandProcessor::FifoCriticalLeave();
283 // no need to clear shader caches
284 PointerWrap p(ptr, mode);
285 VideoCommon_DoState(p);
288 void EmuStateChange(PLUGIN_EMUSTATE newState)
290 Fifo_RunLoop((newState == PLUGIN_EMUSTATE_PLAY) ? true : false);
293 void Video_EnterLoop()
295 Fifo_EnterLoop(g_VideoInitialize);
298 void Video_ExitLoop()
300 Fifo_ExitLoop();
301 s_FifoShuttingDown = TRUE;
304 void Video_SetRendering(bool bEnabled)
306 Fifo_SetRendering(bEnabled);
309 // Run from the graphics thread (from Fifo.cpp)
310 void VideoFifo_CheckSwapRequest()
312 if(g_ActiveConfig.bUseXFB)
314 if (Common::AtomicLoadAcquire(s_swapRequested))
316 EFBRectangle rc;
317 Renderer::Swap(s_beginFieldArgs.xfbAddr, s_beginFieldArgs.field, s_beginFieldArgs.fbWidth, s_beginFieldArgs.fbHeight,rc);
318 Common::AtomicStoreRelease(s_swapRequested, FALSE);
323 // Run from the graphics thread (from Fifo.cpp)
324 void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight)
326 if (g_ActiveConfig.bUseXFB)
328 if(Common::AtomicLoadAcquire(s_swapRequested))
330 u32 aLower = xfbAddr;
331 u32 aUpper = xfbAddr + 2 * fbWidth * fbHeight;
332 u32 bLower = s_beginFieldArgs.xfbAddr;
333 u32 bUpper = s_beginFieldArgs.xfbAddr + 2 * s_beginFieldArgs.fbWidth * s_beginFieldArgs.fbHeight;
335 if (addrRangesOverlap(aLower, aUpper, bLower, bUpper))
336 VideoFifo_CheckSwapRequest();
341 // Run from the CPU thread (from VideoInterface.cpp)
342 void Video_BeginField(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight)
344 if (s_PluginInitialized && g_ActiveConfig.bUseXFB)
346 if (g_VideoInitialize.bOnThread)
348 while (Common::AtomicLoadAcquire(s_swapRequested) && !s_FifoShuttingDown)
349 //Common::SleepCurrentThread(1);
350 Common::YieldCPU();
352 else
353 VideoFifo_CheckSwapRequest();
354 s_beginFieldArgs.xfbAddr = xfbAddr;
355 s_beginFieldArgs.field = field;
356 s_beginFieldArgs.fbWidth = fbWidth;
357 s_beginFieldArgs.fbHeight = fbHeight;
359 Common::AtomicStoreRelease(s_swapRequested, TRUE);
363 void Video_EndField()
367 void Video_AddMessage(const char* pstr, u32 milliseconds)
369 OSD::AddMessage(pstr, milliseconds);
372 void Video_Screenshot(const char* _szFilename)
374 Renderer::SetScreenshot(_szFilename);
377 static struct
379 EFBAccessType type;
380 u32 x;
381 u32 y;
382 u32 Data;
383 } s_accessEFBArgs;
385 static u32 s_AccessEFBResult = 0;
387 void VideoFifo_CheckEFBAccess()
389 if (Common::AtomicLoadAcquire(s_efbAccessRequested))
391 s_AccessEFBResult = Renderer::AccessEFB(s_accessEFBArgs.type, s_accessEFBArgs.x, s_accessEFBArgs.y);
393 Common::AtomicStoreRelease(s_efbAccessRequested, FALSE);
397 u32 Video_AccessEFB(EFBAccessType type, u32 x, u32 y, u32 InputData)
399 if (s_PluginInitialized)
401 s_accessEFBArgs.type = type;
402 s_accessEFBArgs.x = x;
403 s_accessEFBArgs.y = y;
404 s_accessEFBArgs.Data = InputData;
405 Common::AtomicStoreRelease(s_efbAccessRequested, TRUE);
407 if (g_VideoInitialize.bOnThread)
409 while (Common::AtomicLoadAcquire(s_efbAccessRequested) && !s_FifoShuttingDown)
410 //Common::SleepCurrentThread(1);
411 Common::YieldCPU();
413 else
414 VideoFifo_CheckEFBAccess();
416 return s_AccessEFBResult;
418 return 0;
422 void Video_CommandProcessorRead16(u16& _rReturnValue, const u32 _Address)
424 CommandProcessor::Read16(_rReturnValue, _Address);
427 void Video_CommandProcessorWrite16(const u16 _Data, const u32 _Address)
429 CommandProcessor::Write16(_Data, _Address);
432 void Video_PixelEngineRead16(u16& _rReturnValue, const u32 _Address)
434 PixelEngine::Read16(_rReturnValue, _Address);
437 void Video_PixelEngineWrite16(const u16 _Data, const u32 _Address)
439 PixelEngine::Write16(_Data, _Address);
442 void Video_PixelEngineWrite32(const u32 _Data, const u32 _Address)
444 PixelEngine::Write32(_Data, _Address);
447 inline void Video_GatherPipeBursted(void)
449 CommandProcessor::GatherPipeBursted();
452 void Video_WaitForFrameFinish(void)
454 CommandProcessor::WaitForFrameFinish();
457 bool Video_IsFifoBusy(void)
459 return CommandProcessor::isFifoBusy;